Кошмар копирования, выбор файлов для копирования на основе файлов в другой папке - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть небольшая проблема с использованием 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, если можно, я могу загрузить примеры данных и поделиться ссылкой.

Спасибо за помощь, сообщество!

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

После большой помощи @Emil Bode у меня есть следующее решение проблемы (возможно, не самое элегантное, но оно работает достаточно быстро на тысячах файлов .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)
0 голосов
/ 16 декабря 2018

При отладке попробуйте разбить ваш код, чтобы увидеть, все ли ваши переменные соответствуют вашим ожиданиям.

Тем не менее, сейчас я вижу несколько проблем в вашем коде:

  • grep работает с pattern регулярным выражением длины один.Если вы даете ему несколько регулярных выражений, оно использует первое (с предупреждением, которое вы не увидите, отключили ли вы их).
    Чтобы использовать несколько совпадений, вы можете использовать apply и sapply: filesinRAW[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), которые затем сравниваете с полным списком ваших файлов.И вы пытаетесь заставить их соответствовать точно.Тогда зачем использовать регулярное выражение?Регулярные выражения полезны, если вы просто знаете, как выглядят ваши имена файлов, но это ваша цель.Например, если в вашем ValidatedDirectory находится filename1._hc, нужно ли копировать также файлы filename11.tif и filename12.tif?Если вы просто ищете точные совпадения, вы можете напрямую сравнить их:
    tocopy <- tocopy[tocopy %in% pattern]

Но, как правило, работать в R легко, потому что вы можете делать все шаг за шагом,и если вы просто осмотрите tocopy, вы увидите, имеет ли смысл ваш звонок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...