Как создать циклическую функцию для применения акустических индексов из звуковой экологии к определенным разделам файлов .wav с помощью R

У меня есть большое количество файлов .wav, которые мне нужно проанализировать с помощью акустических индексов из пакета «soundecology» в R. Однако записи не имеют одинакового времени начала, и мне нужно проанализировать определенные периоды времени в файлах. Я хочу создать функцию и цикл для автоматизации процесса. Я создал электронную таблицу для каждой папки с записями (каждая папка находится в другом месте), в которой указаны записи и время в каждой записи, которые мне нужно проанализировать. По сути, строка содержит: имя звукового файла, время, когда семпл должен начаться (например, 09:00:00, количество секунд от начала файла, в котором происходит это время, и количество секунд от начала время файла, в котором должен произойти конец выборки. Эти данные выглядят следующим образом: данные

Я использую пакет «tuneR» и «warbleR», чтобы выбрать определенную часть звукового файла, которую я хочу проанализировать. Вот код и вывод, который я хотел бы зациклить на всех звуковых файлах:

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

что дает

     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

Однако, когда я помещаю это в функцию, чтобы затем поместить ее в цикл, я получаю другой результат.

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)

Это дает результат:

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

Что отличается. Поэтому мне нужно исправить эту функцию и поместить ее в цикл, чтобы я мог применить ее ко всем файлам и сохранить результаты во фрейме данных или, в конечном счете, в другой электронной таблице.

Я думал, что цикл, подобный следующему, может работать, но я также получаю ошибки:

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

Который возвращает эту ошибку:

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

Спасибо за любую помощь и совет по этому поводу. Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которая была бы полезна.


person parksnrec1    schedule 12.06.2020    source источник
comment
исходит ли read_wave из пакета soundecology или из другого пакета, и в данном случае из какого?   -  person Waldi    schedule 12.06.2020
comment
Извините, read_wave из пакета warbleR.   -  person parksnrec1    schedule 12.06.2020


Ответы (1)


функция read_wave принимает следующие аргументы:

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

В ручном тесте вы указываете from = mvb$start[1], to = mvb$end[1]

В созданной вами функции вы не указываете аргументы:

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

так что mvb$start[i] влияет на index и mvb$end[i] на from. Вы должны написать:

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)
}

Это должно объяснить разницу, которую вы наблюдаете.

Что касается ошибки, вы создаете логический вектор для сбора результата, но acianalyzeFUN ничего не возвращает: он просто устанавливает две переменные r и soundfileaci, ничего не возвращая.

person Waldi    schedule 12.06.2020
comment
Да, поэтому в ручном тесте я указываю строку 1 с помощью 1, но затем я хочу, чтобы функция, которую я создаю, была применима к любой строке, поэтому я использовал [i]. Я думал, что 1 должен указывать на первую строку мой фрейм данных, где время начала и время окончания находятся там. Я думал, что когда я выполняю: row1.test ‹-acianalyzeFUN(mvb, 1), он вызывает ту же строку, что и в примере, который я хочу автоматизировать. Однако, если это не так или я ошибаюсь, дайте мне знать. Я также подумал, что мне это нужно, чтобы затем применить его к функции цикла? - person parksnrec1; 12.06.2020
comment
Я понимаю вашу цель: см. редактирование моего ответа - person Waldi; 12.06.2020
comment
Спасибо @Waldi, который помогает объяснить проблему. Я обновил функцию, как вы описали, и это устранило первую проблему. Я также добавил: return(soundfile.aci$AciTotAll_left) в функцию, которая помогла устранить ошибку с циклом. Теперь я получаю другую ошибку в цикле: Error in readBin(con, int, n = N, size = bytes, signed = (bytes != 1), : invalid 'n' argument У вас есть идеи, почему это может происходить? - person parksnrec1; 15.06.2020
comment
Обновите, ошибка выше была просто результатом ошибки в моем файле .csv. Теперь все работает хорошо! - person parksnrec1; 15.06.2020