【问题标题】:Using the try and try catch function on .WAV files对 .WAV 文件使用 try and try catch 函数
【发布时间】:2021-06-28 11:52:12
【问题描述】:

尝试在 R 中将一堆音频 (.WAV) 文件切割成更小的样本。对于这个示例,我使用循环在 140 分钟时切割出 1 分钟的样本。

对于某些文件,由于录制设备出错,录制会在 140 分钟前结束。发生这种情况时,会出现错误——并且循环停止。我正在尝试通过使用 try 或 tryCatch 函数继续循环,但不断收到错误。

代码如下:

for(i in 1:length(AR_CD288)){
  CUT_AR288_5 <- try({readWave(AR_CD288[i], from = 140, to = 141, units = "minutes")})
  FILE.OUT_AR288_5<- sub("\\.wav$", "_140.wav", AR_CD288)
  OUT.PATH_AR288_5 <- file.path("New files", basename(FILE.OUT_AR288_5))
  writeWave(CUT_AR288_5, extensible=FALSE, filename = OUT.PATH_AR288_5[i])
  }

我从代码中得到以下两个错误:

Error in readBin(con, int, n = N, size = bytes, signed = (bytes != 1),  : 
  invalid 'n' argument
Error in writeWave(CUT_AR288_5, extensible = FALSE, filename = OUT.PATH_AR288_5[i]) : 
  'object' needs to be of class 'Wave' or 'WaveMC

循环仍然将一些样本保存到“新文件”目录中,但是,一旦循环到达

我很困!任何帮助将不胜感激。

干杯。

【问题讨论】:

  • 为什么你只在循环的第一行使用try?将整个循环体包裹在try中。

标签: r for-loop try-catch wav


【解决方案1】:

当我使用try 时,我总是执行以下一项(或两项):

  • 查看返回值是否继承"try-error",说明命令失败;或

  • 添加try(., silent = TRUE),表示我不在乎它是否成功(但这意味着我也不会使用它的返回值)。

试试这个:

for (i in seq_along(AR_CD288)) {
  CUT_AR288_5 <- try({
    readWave(AR_CD288[i], from = 140, to = 141, units = "minutes")
  }, silent = TRUE)
  if (!inherits(CUT_AR288_5, "try_error")) {
    FILE.OUT_AR288_5 <- sub("\\.wav$", "_140.wav", AR_CD288)
    OUT.PATH_AR288_5 <- file.path("New files", basename(FILE.OUT_AR288_5))
    writeWave(CUT_AR288_5, extensible = FALSE, filename = OUT.PATH_AR288_5[i])
  }
}

三个注意事项:

  1. 我把1:length(.)改成了seq_along(.);当向量的长度可能为 0 时,后者在自动使用中更具弹性。例如,如果 AR_CD288 的长度可以为 2,直觉上我们希望 1:length(AR_CD288) 不返回任何内容,因此 for 循环不会运行;不幸的是,它解析为1:0,它返回一个长度为2的向量,这通常会失败(基于循环中正在运行的任何代码)。 seq_along(.) 的使用总是会返回一个长度为 0 且输入为空的向量,这正是我们所需要的。 (替代和等效,seq_len(length(AR_CD288)),虽然这确实是 seq_along 的意图。)
  • 如果不添加silent=TRUE(或显式添加silent=FALSE),则会收到一条错误消息,指示命令失败。不幸的是,错误消息可能无法指示哪个i 失败,因此您可能无法修复或删除错误文件。您可能更愿意在if (inherits(.,"try-error")) 子句中添加else,以便提供更清晰的错误,例如

      if (inherits(CUT_AR288_5, "try_error")) {
        warning("'readWave' failed on ", sQuote(AR_CD288[i]), call. = FALSE)
      } else {
        FILE.OUT_AR288_5 <- sub("\\.wav$", "_140.wav", AR_CD288)
        # ...
      }
    

    (请注意我在这里将“工作正常”代码放在else 子句中......我觉得这样做很奇怪if (!...) {} else {},似乎是双重否定:-)。

  • 包装一个函数或整个块的选择取决于您的需求:我倾向于确切知道失败的地方,因此将可能失败的函数通常用try单独包装,这样我就可以做出反应(或日志/消息)相应地。如果您不需要错误检测的分辨率,那么您当然可以在某种意义上包装整个代码块:

    for (i in seq_along(AR_CD288)) {
      ret <- try({
        CUT_AR288_5 <- readWave(AR_CD288[i], from = 140, to = 141, units = "minutes")
        FILE.OUT_AR288_5 <- sub("\\.wav$", "_140.wav", AR_CD288)
        OUT.PATH_AR288_5 <- file.path("New files", basename(FILE.OUT_AR288_5))
        writeWave(CUT_AR288_5, extensible = FALSE, filename = OUT.PATH_AR288_5[i])
      }, silent = TRUE)
      if (inherits(ret, "try-error")) {
        # do or log something
      }
    }
    

【讨论】:

  • 非常感谢!如果我不包装整个块,代码仍然不会运行。但是当我包裹整个块时它完美地工作:)
  • 是的,根据您的错误,您可以将所有错误打包成一个,或者将writeWave 打包在一个单独的try 中。任何一个都有效,它有点风格。如果这对您有用,请accept the answer。谢谢!
  • 这回答了您的问题吗?如果是这样,请accept它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2016-02-19
  • 2021-11-25
  • 2011-01-24
  • 1970-01-01
相关资源
最近更新 更多