R: поиск файлов, имена которых содержат указанную строку c из каталога и соответствуют моему списку требуемых файлов - PullRequest
0 голосов
/ 20 февраля 2020

Я снова новичок ie с еще одной беспорядочной ситуацией с файлами и папками (благодаря нам, биологам): я получил этот каталог, содержащий огромное количество файлов .txt (~ 900 000+), все файлы были переданы ранее с несовместимым форматом именования: (*

Например, грязные файлы в каталоге выглядят так:

ctrl_S978765_uns_dummy_00_none.txt
ctrl_S978765_3S_Cookie_00_none.txt
S59607_3S_goody_3M_V10.txt
ctrlnuc30-100_S3245678_DMSO_00_none.txt
ctrlRAP_S0846567_3S_Dex_none.txt
S6498432_2S_Fulra_30mM_V100.txt
.....

Как видите, наименование не имеет надежной согласованности. Для меня важен идентификационный код встроенный в них, такой как S978765. Теперь у меня есть список (100 идентификационных кодов) этих идентификационных кодов, которые я хочу.

CSV-файл, содержащий список, как показано ниже, учтите, что у списка есть повторяющийся идентификатор коды в строке из-за различного значения CLnumber во вторых столбцах:

ID code  CLnumber
S978765  1
S978765  2
S306223  1
S897458  1
S514486  2
....

Итак, я хочу выполнить следующую задачу: найти все грязные именованные файлы, используя идентификаторы кода, сопоставив их с моим списком. И скопировать их в новый каталог.

Я подумал об использовании list.files (), чтобы получить все файлы .txt и их имена, затем я застрял на следующем шаге в matc По именам кодовых идентификаторов я знаю, как сделать это одной строкой, скажем, «S978765», но если я делаю это один за другим, это почти как ручная копка папки.

Как я могу представить имена кодов ID в столбце 1 в виде списка и сравнить / сопоставить их с грязными именами файлов в каталоге, а затем скопировать их в новую папку?

Большое спасибо , ML

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

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

Здесь я использовал шаблон «S», за которым следуют 5 или более чисел. Как только мы извлечем ID_codes, мы можем сравнить их с теми, которые есть в csv.

Предполагая, что CSV называется df и имя столбца ID_Codes, мы можем использовать %in% для их фильтрации.

Затем мы можем использовать file.copy для перемещения файлов из одной папки в другую.

all_files <- list.files(path = '/Path/To/Folder', full.names = TRUE)
selected_files <- all_files[sub('.*(S\\d{5,}).*', '\\1', basename(all_files)) 
                                 %in% unique(df$ID_Codes)]
file.copy(selected_files, 'new_path/for/files')
1 голос
/ 20 февраля 2020

Это работает:

library(stringr)

# get this via list.files in your actual code
files <- c("ctrl_S978765_uns_dummy_00_none.txt",
           "ctrl_S978765_3S_Cookie_00_none.txt",
           "S59607_3S_goody_3M_V10.txt",
           "ctrlnuc30-100_S3245678_DMSO_00_none.txt",
           "ctrlRAP_S0846567_3S_Dex_none.txt",
           "S6498432_2S_Fulra_30mM_V100.txt")

ids <- data.frame(`ID Code` = c("S978765", "S978765", "S306223", "S897458", "S514486"),
                  CLnumber = c(1, 2, 1, 1, 2),
                  stringsAsFactors = FALSE)

str_subset(files, paste(ids$ID.Code, collapse = "|"))
#> [1] "ctrl_S978765_uns_dummy_00_none.txt" "ctrl_S978765_3S_Cookie_00_none.txt"

str_subset принимает символьный вектор и возвращает элементы, соответствующие некоторому шаблону. В этом случае это шаблон "S978765|S978765|S306223|S897458|S514486" (созданный с использованием paste), который представляет собой регулярное выражение , которое соответствует любому из кодов ID, разделенных |. Поэтому мы берем files и оставляем только элементы, которые совпадают, в ID Code.

Есть много других способов сделать это, которые могут быть или не быть более ясными. Например, вы можете передать ids$ID.Code непосредственно в str_subset вместо создания регулярного выражения с помощью paste, но это каждый раз будет выдавать предупреждение о длине объекта, что может привести к путанице (или вызвать проблемы, если вы привыкнете к игнорировать его, а затем игнорировать его в другом контексте, где это имеет значение). Другим методом будет использование purrr и keep, но, хотя это может быть немного более понятным для записи, это будет намного более неэффективно, поскольку это будет означать многократные проходы по вектору файлов - не имеет значения в этот контекст, но, возможно, очень актуален, если вам вдруг понадобится сделать это для сотен тысяч файлов и идентификаторов.

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