复制噩梦,根据另一个文件夹中的文件选择要复制的文件

A copying nightmare, choosing files to copy based on files in another folder

我在使用 copy.file 时遇到了一些问题。

我需要根据另一个文件目录中的文件名,从具有多个子目录(.tif 文件所在的位置)的目录中复制 .tif 文件。我有以下代码(几乎可以正常工作)

ValidatedDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Validated"
RawDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Raw"
OutputDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Ouputfolder"

ValidatedImages <- list.files(ValidatedDirectory)


# this is to remove the extra bit that is added onto the validated images [working]
pattern <- gsub("_hc", "", ValidatedImages) 
pattern <- paste(gsub("([.|()\^{}+$*?]|\[|\])", "\\\1", pattern), collapse="|")

# this bit tackles finding the relevant files based on the ValidatedImages
filesinRAW <- list.files(
  path = RawDirectory,
  recursive = TRUE,
  include.dirs = FALSE,
  full.names = FALSE)
filesinRAW <- as.list(filesinRAW)

# this removes subdirectory prefix in front of the file and .tif which confuses it
filesinRAW <- as.list(gsub("\d\d\d\d/", "", filesinRAW)) 
filesinRaw <- as.list(gsub(".tif", "", filesinRAW))

tocopy <- grep(filesinRAW, pattern = pattern, value = TRUE)
tocopy <- as.list(tocopy)
tocopy <- as.list(gsub(".tif", "", tocopy))

setwd(RawDirectory)

file.copy(from = tocopy, to = OutputDirectory, overwrite = TRUE)

我收到 No such file or directory 错误,文件确实存在(很明显),因此我一定是在命名方面做错了什么。

我已经 bash 研究了好一阵子了,如果有帮助我可以上传示例数据并分享 link。

感谢社区的帮助!

调试时,尝试分解您的代码,看看您的变量是否在每一步都如您所愿。

也就是说,我现在在您的代码中发现了几个问题:

  • grep 使用 pattern 作为长度为一的正则表达式。如果你给它多个正则表达式,它会使用第一个(带有警告,如果你禁用它们则看不到)。
    要使用多个匹配项,您可以使用 applysapplyfilesinRAW[apply(sapply(pattern, grepl, x=filesinRAW), 2, any)]。但是看到最后一点
  • grep 默认使用 pattern 作为正则表达式,如果你的 pattern 包含被解析的字符,这可能会破坏事情。例如,grep('^test', '^test') 给出零结果。要检查字符串是否包含文字字符串,可以使用 grep(..., fixed=TRUE)
  • 在最后一步中,您使用 sub(".tif", "", to copy),这将删除 任何模式,例如 .tif。我想你是想在最后再次 add .tif,现在你正试图复制没有扩展名的文件,而扩展名是找不到的。要添加,您可以使用 paste.
  • 在几个步骤中您使用 as.list。为什么?在 R 中,一切都是矢量化的,这意味着已经使用了多个值。列表和向量之间的区别在于列表可以存储不同种类的对象,但无论如何您都不会这样做。据我所知,as.lists 不会造成任何伤害,因为所有函数都会首先将您的列表转换回字符向量。
  • 最后,据我所知,您首先制作了一个需要复制的文件名列表 (pattern),然后将其与完整的文件列表进行比较。并且您尝试使它们完全匹配。那为什么要用正则表达式呢?如果您只知道文件名的一部分,那么正则表达式很有用,但这是您的目标。例如。如果 filename1._hc 在您的 ValidatedDirectory 中,是否还需要复制文件 filename11.tiffilename12.tif? 如果您只是寻找精确匹配,您可以直接比较它们:
    tocopy <- tocopy[tocopy %in% pattern]

但一般来说,在 R 中工作很容易,因为您可以按部就班地做所有事情,如果您只是检查 tocopy,您可以看到您的调用是否有意义。

在@Emil Bode 的大力帮助下,我得到了以下问题的解决方案(也许不是最优雅的,但它在 1000 个 .tif 文件上运行得足够快。

ValidatedDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Validated"
RawDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Raw"
OutputDirectory <- "C:/Users/JS22/Desktop/R_Experiments/Raw_Folder_Testa/Ouputfolder"

ValidatedImages <- list.files(ValidatedDirectory)

pattern <- gsub("_hc", "", ValidatedImages)
pattern <- paste(gsub("([.|()\^{}+$*?]|\[|\])", "\\\1", pattern), collapse="|")

filesinRAW <- list.files(
  path = RawDirectory,
  recursive = TRUE,
  include.dirs = FALSE,
  full.names = FALSE,
  pattern = pattern)

setwd(RawDirectory)

file.copy(from = filesinRAW, to = OutputDirectory, overwrite = TRUE)