Jmath
Jmath

Reputation: 13

Want my for loop to return letters instead of numbers in R

for(k in seq(0,length(Gs@left)-nl,len=30))
{
fcs <- abs(fft(Gs@left[(k+1):(k+nl)]))
tmp <- lsfit(X,fcs,inter=F)
print(order(-tmp$coef)[1])
}

I have a for loop that returns a list of numbers:

[1] 3
[1] 1
[1] 1
[1] 2

These numbers correspond to notes on a piano and it would be a lot more useful for it to return G4 instead of 1, A4 instead of 2 etc...

Is there a way of coding my for loop to return this (ie 1 = "G4" etc...)?

I have tried assign(paste("G4"), 1) and this doesn't work.

Thank you

Upvotes: 1

Views: 314

Answers (5)

mondano
mondano

Reputation: 875

You could build a list pianoNotes and access the items by index [[i]].

For your example this would be:

pianoNotes <- list("1" = "G4") # and more
for(k in seq(0,length(Gs@left)-nl,len=30))
{
  fcs <- abs(fft(Gs@left[(k+1):(k+nl)]))
  tmp <- lsfit(X,fcs,inter=F)
  print(pianoNotes[[order(-tmp$coef)[1]]])
}

Upvotes: 0

IRTFM
IRTFM

Reputation: 263362

Just set up a string that has the notes in the order implied by you musical conventions (which I am not able to intuit being entirely amusical, and seeing that @user295691 may actually understand the mathematical underpinning) . Since you only give two notes:

# Above the loop
notes=c("G4", "A4", "B4")   # not sure if third one is sensible musically
                            # would have guessed that A5 was next to G4
# in the loop
print( notes[ order(-tmp$coef)[1] ] )

Upvotes: 0

user295691
user295691

Reputation: 7248

Writing a function to do the translation probably makes the most sense.

strfnote <- function(notes, base_octave=4) {
  paste0(LETTERS[(notes %% 7) + 1], trunc(notes / 7) + base_octave)
}

Which would give us

> strfnote(0:10)
 [1] "A4" "B4" "C4" "D4" "E4" "F4" "G4" "A5" "B5" "C5" "D5"

You could make the strfnote more complete, handling things like accidentals, and specifying exactly what note corresponds to "0" to set the offset. But after some basic processing, your code can produce numbers, and then for rendering you can just pass them to this function to get a readable form.

Upvotes: 2

Zakkery
Zakkery

Reputation: 420

Try using factors instead:

Example:

data <- c(1,2,3,4,5, 1,3,4)
labeled_data <- factor(data, labels = c("a1", "a2", "a3", "a4", "a5"))
labeled_data

would return

[1] a1 a2 a3 a4 a5 a1 a3 a4
Levels: a1 a2 a3 a4 a5

Upvotes: 0

Ananta
Ananta

Reputation: 3711

Not exact answer because of lack of required info in question, but this should give you some hint

df<-data.frame(id=1:10, note=LETTERS[1:10], stringsAsFactors = F)

for (i in 1:5){
  x=sample(1:10,1)
  #print(x)
  print(df[match(x,df$id),2])
}

Upvotes: 3

Related Questions