ptenax
ptenax

Reputation: 141

For-loop error - values not being entered into column

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

Answers (2)

Vlad C.
Vlad C.

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

Ankur Singh
Ankur Singh

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

Related Questions