如何修改R函数实现跨多时间段批量计算ADI并输出单一CSV文件
优化后实现方案
核心优化点
- 自动识别数据表中所有时间列,自动配对相邻时间段,无需手动修改参数
- 修复原函数中重复
return、输出向量初始化错误的问题 - 支持自定义输出文件路径,所有时间段计算结果自动追加到原数据表后统一导出
# 提前安装并加载所需依赖包 library(tuneR) library(soundecology) library(stringr) ADIanalyzeFUN <- function(X, output_path = "ADI_result.csv") { # 1. 提取所有时间列并按数字顺序排序,自动生成相邻时间对 time_cols <- grep("(start|end)", colnames(X), value = TRUE) time_cols <- str_sort(time_cols, numeric = TRUE) time_pairs <- lapply(seq(length(time_cols)-1), function(k) c(time_cols[k], time_cols[k+1])) # 2. 单音频单片段ADI计算函数 calc_adi_one <- function(sound_path, from_sec, to_sec) { r <- read_wave(sound_path, from = from_sec, to = to_sec) sound_adi <- acoustic_diversity(r) return(list( adi_left = sound_adi$adi_left, adi_right = sound_adi$adi_right )) } # 3. 遍历所有时间对批量计算 for (pair in time_pairs) { from_col <- pair[1] to_col <- pair[2] col_prefix <- paste0(from_col, "-", to_col) res_left <- numeric(nrow(X)) res_right <- numeric(nrow(X)) for (i in seq_len(nrow(X))) { adi_res <- calc_adi_one( sound_path = X$sound.files[i], from_sec = X[[from_col]][i], to_sec = X[[to_col]][i] ) res_left[i] <- adi_res$adi_left res_right[i] <- adi_res$adi_right } # 结果写入数据表,不需要右声道可删除对应行 X[[paste0(col_prefix, "_left")]] <- res_left X[[paste0(col_prefix, "_right")]] <- res_right # 仅保留左声道则替换为下行代码,和你期望的输出格式完全匹配 # X[[col_prefix]] <- res_left } # 4. 统一导出结果 write.csv(X, output_path, row.names = FALSE) return(invisible(X)) }
使用方法
确保你的数据表X包含sound.files列存储音频完整路径,直接调用即可:
# 结果默认保存到工作目录ADI_result.csv result <- ADIanalyzeFUN(X) # 也可自定义输出路径 result <- ADIanalyzeFUN(X, output_path = "/media/parks/Seagate Portable Drive 2 (2tb)/Parks/2021 Threat Experiment/ADI index values/all_ADI_result.csv")
注意事项
- 时间列自动排序依赖你示例中的命名规则,只要列名包含数字序号即可正常配对
- 数据量较大时可引入
pbapply包替换基础循环,添加进度提示提升使用体验
内容的提问来源于stack exchange,提问作者parksnrec1
相关产品推荐
相关产品推荐

