【问题标题】:A copying nightmare, choosing files to copy based on files in another folder复制的噩梦,根据另一个文件夹中的文件选择要复制的文件
【发布时间】:2018-12-16 12:46:33
【问题描述】:

我在使用 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 错误,文件确实存在(显然),因此我必须在命名上做错了。

我已经有一段时间了,如果有帮助,我可以上传示例数据并分享链接。

感谢社区的任何帮助!

【问题讨论】:

    标签: r copying


    【解决方案1】:

    在调试时,试着分解你的代码,看看在每一步你的变量是否仍然和你期望的一样。

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

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

    但通常,在 R 中工作很容易,因为您可以逐步完成所有操作,如果您只检查 tocopy,您可以查看您的调用是否有意义。

    【讨论】:

    • 太棒了,多么全面的答案。我使用了 as.list 函数,因为我有一个类似的代码用于另一个目的,它只在作为列表时才有效。我暂时把它放在那里了。今晚(格林威治标准时间)我将解决这些问题。我对 R 的这一方面相当陌生,主要将其用于统计数据,但我知道一切皆有可能。再次感谢您详细且内容丰富的回答!吉姆
    【解决方案2】:

    在@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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 2019-02-15
      • 2023-01-14
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多