简体   繁体   中英

How do I create a loop function to apply acoustic indices from “soundecology” to specific sections of .wav files using R

I have a large quantity of.wav files that I need to analyze using the acoustic indices from the "soundecology" package in R. However, the recordings do not have uniform start times and I need to analyze specific periods of time within the files. I want to create a function and loop for automating the process. I have created a spread sheet for each folder of recordings (each folder is a different location) that lays out the recording and the times within each recording that I need to analyze. Basically, a row contains: the sound file name, the time when the sample should start (eg. 09:00:00, the number of seconds from the start of the file that that time occurs, and the munber of seconds from the start time of the file that the end of the sample should occur. That data looks like this: Spread sheet of data

I am using the package "tuneR" and "warbleR" to select the specific portion of a sound file that I want to analyze. Here is the the code and the output that I would like to loop across all the sound files:

wavrow1 <-read_wave(mvb$sound.files[1], from = mvb$start[1], to = mvb$end[1]) wavrow1.aci <- acoustic_complexity(wavrow1, j=10)

which yeilds

     max_freq not set, using value of: 22050 


 min_freq not set, using value of: 0 


 This is a mono file.

 Calculating index. Please wait... 

  Acoustic Complexity Index (total): 934.568

However, when I put this into a function in order to then put it into a loop I get a different output.

acianalyzeFUN <- function(mvb, i){
  r <- read_wave(mvb$sound.files[i], mvb$start[i], mvb$end[i])
  soundfile.aci <- acoustic_complexity(r, j=10)
}

row1.test <- acianalyzeFUN(mvb, 1)

This gives the output:

max_freq not set, using value of: 22050 


 min_freq not set, using value of: 0 


 This is a mono file.

 Calculating index. Please wait... 

  Acoustic Complexity Index (total): 19183.03

  Acoustic Complexity Index (by minute): 931.98

Which is different. So I need to fix this function and put it into a loop so that I can apply it across all the files and save the results into a data frame or ultimately another spread sheet.

I was thinking a loop like the following might work but I am also getting errors with it:

output <- vector("logical", length(97)) 
for (i in seq_along(mvb$sound.files)) {     
  output[[i]] <- acianalyzeFUN(mvb, i) 
}

Which returns this error:

max_freq not set, using value of: 22050 


 min_freq not set, using value of: 0 


 This is a mono file.

 Calculating index. Please wait... 

  Acoustic Complexity Index (total): 19183.03

  Acoustic Complexity Index (by minute): 931.98

Error in output[[i]] <- acianalyzeFUN(mvb, i) : 
  more elements supplied than there are to replace

Thanks for any help and advice on this. Please let me know if there are any other pieces of information that would be helpful.

the read_wave function takes following arguments:

read_wave(X, index, from = X$start[index], to = X$end[index], channel = NULL, header = FALSE, path = NULL)

In the manual test, you specify from = mvb$start[1], to = mvb$end[1]

In the function you created, you dont specify the arguments:

r <- read_wave(mvb$sound.files[i], mvb$start[i], mvb$end[i])

so that mvb$start[i] gets affected to index and mvb$end[i] to from . You should write:

acianalyzeFUN <- function(mvb, i){
  r <- read_wave(mvb$sound.files[i], from = mvb$start[i], to = mvb$end[i])
  soundfile.aci <- acoustic_complexity(r, j=10)
}

This should explain the difference you observe.

Regarding the error, you create a vector of logical to collect the result, but acianalyzeFUN returns nothing: it just sets two variables r and soundfileaci without returning anything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM