Reputation: 141
I have a dataframe with one column containing a bunch of sound file filenames (.wav). I would like to measure something within each sound file, and have each measurement listed in a second new column next to the corresponding filename. In my code, each measurement is not being put into the second column. If I take each line of the for-loop and run it independently with the values 1, 2, 3 etc substituted for i, the resulting dataframe has the output measurements correctly entered.
I have written a toy example below, which cannot be run without some wav files, but perhaps the problem can be spotted based on the code alone:
library(seewave); library(tuneR)
setwd("D:/wavs")
#make a dataframe containing a column of wav filenames
file_list <-data.frame(c("wav1.wav", "wav2.wav", "wav3.wav"))
colnames(file_list)[1] <-"filelist" #give it a sensible column name
file_list$filelist <-as.character(file_list$filelist) #convert from factor
file_list$mx <-NA #a new empty vector for the measurement results
str(file_list) #this is how it will look before adding measurements
#now read in each wav file, measure something,
#and put the outcome in the empty cell next to that corresponding filename.
for (i in length(file_list$filelist)){
a <-as.character(file_list$filelist[[i]]) #this seemed to be a requirement, that 'wav1.wav' etc be a character
temp <-readWave(a) #read the file using tuneR package
mx <-max(range(temp@left)) #take some measurement from the left channel
file_list$mx[[i]] <-mx #put it in a new column next to the original filename
rm(mx); rm(temp); rm(a) #kill unnecessary things before starting again, for just in case
}
Needless to say, I have scoured the web and Stackoverflow for guidance without success, and tried a bunch of things (e.g. using }next{
). Perhaps I need something similar to: file_list2$mx[i,] <-mx
. Maybe some easy points for someone? Thank you, I am always grateful for help on SO.
Upvotes: 1
Views: 61
Reputation: 974
How about a tidyverse
solution?
library(dplyr)
library(purrr)
data.frame(filelist=c("wav1.wav", "wav2.wav", "wav3.wav"), stringsAsFactors = F) %>%
mutate(mx = map_dbl(filelist, ~ readWave(.x)@left %>% max))
Upvotes: 1
Reputation: 936
The only problem with your code is that, You have not iterated the for loop. Means as per your code the for loop runs only one time i.e i=3. The correct code given below:
for (i in 1:length(file_list$filelist)){
a <-as.character(file_list$filelist[[i]]) #this seemed to be a requirement, that 'wav1.wav' etc be a character
temp <-readWave(a) #read the file using tuneR package
mx <-max(range(temp@left)) #take some measurement from the left channel
file_list$mx[[i]] <-mx #put it in a new column next to the original filename
rm(mx); rm(temp); rm(a) #kill unnecessary things before starting again, for just in case
}
Hope this could help you !
Upvotes: 1