复制噩梦,根据另一个文件夹中的文件选择要复制的文件
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
作为长度为一的正则表达式。如果你给它多个正则表达式,它会使用第一个(带有警告,如果你禁用它们则看不到)。
要使用多个匹配项,您可以使用 apply
和 sapply
:filesinRAW[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.tif
和 filename12.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)
我在使用 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
作为长度为一的正则表达式。如果你给它多个正则表达式,它会使用第一个(带有警告,如果你禁用它们则看不到)。
要使用多个匹配项,您可以使用apply
和sapply
:filesinRAW[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.tif
和filename12.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)