Подтвердить что ты не робот

Список всех файлов, соответствующих шаблону полного пути в R

Я пытаюсь получить список файлов, соответствующих шаблону полный путь. До сих пор я использовал list.files(), но это не сработало.

Предположим, что у нас есть следующая организация каталогов:

results
   |- A
   |  |- data-1.csv
   |  |- data-2.csv
   |
   |- B
      |- data-1.csv
      |- data-2.csv

Затем выполните следующую команду:

list.files(pattern='data-.*\\.csv', recursive=TRUE)

вернет все файлы, соответствующие шаблону. Это работает, но проблема возникает при использовании шаблона полный путь. Например, если я хочу получить все CSV файлы из результатов каталога /A, я мог бы сделать:

list.files(pattern='results/A/data-.*\\.csv', recursive=TRUE)

Это не работает. Так или иначе, похоже, что R не может использовать шаблон полного пути в качестве регулярного выражения. В этом случае решением может быть просто использовать результаты /A в качестве базового пути. Но в более сложных проблемах это невозможно. Например, в какой-то момент мы можем захотеть сопоставить подкаталоги, содержащие только символы:

list.files(pattern='results/[A-Z]+/data-.*\\.csv', recursive=TRUE)

Возможно ли это сделать в R?

ОБНОВЛЕНИЕ:. Некоторое время после использования специальных решений я решил перестать набирать то же самое снова и снова. Итак, я создал библиотеку для упрощения этой задачи.

4b9b3361

Ответ 1

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

list.files(pattern='data-.*\\.csv', recursive=TRUE)

Затем кажется, что совпадение шаблонов внутри list.files применяется к базовым именам файлов (т.е. не включая путь к каталогу), поэтому вы можете разбить задачу на:

  • Найти все файлы, соответствующие только basename, вернуть их полные пути:

    basename.matches <- list.files(pattern='data-.*\\.csv', recursive=TRUE,
                                   full.names = TRUE)
    basename.matches
    # [1] "./results/A/data-1.csv" "./results/A/data-2.csv" "./results/B/data-1.csv"
    # [4] "./results/B/data-2.csv"
    
  • Сохраняйте только те, которые соответствуют ожидаемой директории (-ий):

    full.matches <- grep(pattern='^\\./results/A/', basename.matches, value = TRUE)
    full.matches
    # [1] "./results/A/data-1.csv" "./results/A/data-2.csv"
    

Ответ 2

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

dirs <- grep("[A-Z]+$",list.dirs("results",recursive=FALSE),value=TRUE)
list.files(dirs, "data-.*\\.csv", recursive=TRUE, full.names=TRUE)

Ответ 3

Я думаю, что есть еще более простое решение:

Sys.glob(file.path(results, "[A-Z]", "data-*.csv"))