【问题标题】:Naming files in R loop在 R 循环中命名文件
【发布时间】:2017-01-18 15:34:31
【问题描述】:

我有多个音频文件,它们保存在我工作目录的多个子文件夹中。我有一个循环读取每个文件的第一分钟,然后将它们保存为新文件。

library(tuneR)

dir.create("New files")

FILES<-list.files(PATH, pattern = "audio", recursive = TRUE)

for(i in 1:length(FILES)){
  OneMIN <- readWave(FILES[i], from = 0, to = 60, units = "seconds")
  writeWave(OneMIN, filename = (file=paste0(FILES[i], "_1-min.wav")))
}

现在,这有几个问题;

1) 新文件被称为例如“File1.wav_1-min.wav”,所以我需要将它们重命名为“File_1-min.wav”

2) 新文件位于多个子文件夹中,然后我必须使用循环外的其他步骤将它们复制到“新文件”文件夹中。

我有解决这些问题的变通方法,但我确信有一种更优雅的方法可以解决这些问题,即在循环中包含额外的行。我想:

1) 去掉文件名中的第一个“.wav”

2) 自动将它们保存到“新文件”文件夹中

但是,我不知道该怎么做。任何建议表示赞赏。谢谢。

【问题讨论】:

  • fillesOut &lt;- sub("\\.wav$", "", FILES) 应该适用于第一部分。 paste0("./NewFiles/", filesOut[i], "_1-min.wav") 应该获得第二个。另请参阅dir.create 以在 R 中创建目录,但如果这是一次性的,您可以手动进行。还有exists 用于检查对象的存在。
  • @lmo,第一部分运行良好,但第二部分出现错误; Error in file(filename, "wb") : cannot open the connection In addition: Warning message: In file(filename, "wb") : cannot open file './Newfiles/2017-01-05/File1_1 min.wav': No such file or directory
  • 看我评论的后半部分。见?dir.create。

标签: r loops audio


【解决方案1】:

file.path() 函数可用于将目录和文件名组合到一个文件路径中,而sub() 函数将允许您轻松修改文件名:

library(tuneR)

dir.create("New files")

FILES <- list.files(PATH, pattern = "audio", recursive = TRUE)

for(infile in FILES){
  OneMIN <- readWave(infile, from = 0, to = 60, units = "seconds")
  outfile <- file.path("New files", sub('.wav', '_1-min.wav', infile))
  writeWave(OneMIN, filename=outfile)
}

另外,值得注意的是,在原始代码示例中,list.files() 函数只会返回每个文件路径的文件名部分。

因此,您可能需要将代码修改为如下所示:

FILES <- list.files(PATH, pattern = "audio", recursive = TRUE, full.names=TRUE)

和:

outfile <- file.path("New files", sub('.wav', '_1-min.wav', basename(infile)))

这将确保infile 和outfile 都指向正确的位置。

【讨论】:

    【解决方案2】:

    我想我会发布我的解决方案,它借鉴了@Keith Hughitt 的答案和@lmo 的 cmets。感谢他们两位帮助我解决了我的需要。

    for(i in 1:length(FILES)){
     OneMIN <- readWave(FILES[i], from = 0, to = 60, units = "seconds")
     FILE.OUT <- sub("\\.wav$", "_1 min.wav", FILES)
     OUT.PATH <- file.path("New files", basename(FILE.OUT))
     writeWave(OneMIN, filename = OUT.PATH[i])
    }
    

    正如两者所暗示的,由于路径问题,我遇到了错误。我在 FILES 分配中不需要 full.names = TRUE,但我确实需要在循环中包含 basename()。

    正如 Keith 在他的回答中所展示的,FILE.OUT 行并不是绝对必要的,但它可以帮助我跟踪不同的步骤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 2018-08-02
      • 2014-06-17
      • 1970-01-01
      • 2017-12-04
      • 2016-11-13
      • 2011-12-04
      相关资源
      最近更新 更多