Reputation: 13
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
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
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
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
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
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