45  Взаимодействие директорий

На этой странице мы рассмотрим распространенные сценарии создания, взаимодействия, сохранения и импорта директорий (папок).

45.1 Подготовка

пакет fs

Пакет fs - это пакет tidyverse, который способствует взаимодействиям директорий, улучшая некоторые базовые функции R. В разделах ниже мы часто будем использовать функции из fs.

pacman::p_load(
  fs,             # взаимодействия файлов/директорий
  rio,            # импорт/экспорт
  here,           # относительные пути к файлам
  tidyverse)      # управление данными и визуализация

Печать директории в виде дерева дендрограмм

Используем функцию dir_tree() из fs.

Задайте путь к папке в path =. Используйте recurse = FALSE, чтобы показать только один уровень, или recurse = TRUE, чтобы показать все файлы на всех суб-уровнях. Ниже мы используем here() в качестве сокращения для проекта R и уточняем подпапку “data”, которая содержит примеры данных этого руководства. Мы задаем отображение всех файлов в “data” и подпапках.

fs::dir_tree(path = here("data"), recurse = TRUE)
data
├── case_linelists
│   └── linelist_cleaned.rds
├── example
│   ├── Central Hospital.csv
│   ├── Military Hospital.csv
│   ├── Missing.csv
│   ├── Other.csv
│   ├── Port Hospital.csv
│   ├── St. Mark's Maternity Hospital (SMMH).csv
│   ├── district_weekly_count_data.xlsx
│   ├── fluH7N9_China_2013.csv
│   ├── hospital_linelists.xlsx
│   └── linelists
│       ├── 20201007linelist.csv
│       ├── case_linelist20201006.csv
│       ├── case_linelist_2020-10-02.csv
│       ├── case_linelist_2020-10-03.csv
│       ├── case_linelist_2020-10-04.csv
│       ├── case_linelist_2020-10-05.csv
│       └── case_linelist_2020-10-08.xlsx
├── flexdashboard
│   ├── outbreak_dashboard.Rmd
│   ├── outbreak_dashboard.html
│   └── outbreak_dashboard_test.html
└── malaria_app
    ├── app.R
    ├── data
    │   └── facility_count_data.rds
    ├── funcs
    │   └── plot_epicurve.R
    ├── global.R
    ├── malaria_app.Rproj
    ├── server.R
    └── ui.R

45.2 Список файлов в директории

Чтобы указать только имена файлов в директории, вы можете использовать dir() из базового R. Например, эта команда создает список имен файлов из подпапки “linelists” в папке “example” проекта R. Относительный путь к файлу задается, используя here() (о которой вы можете больше прочитать на странице Импорт и экспорт).

# file names
dir(here("data", "example", "linelists"))
[1] "20201007linelist.csv"          "case_linelist_2020-10-02.csv" 
[3] "case_linelist_2020-10-03.csv"  "case_linelist_2020-10-04.csv" 
[5] "case_linelist_2020-10-05.csv"  "case_linelist_2020-10-08.xlsx"
[7] "case_linelist20201006.csv"    

Чтобы указать полные пути к файлам для файлов директории, вы можете использовать dir_ls() из fs. Альтернативой в базовом R является list.files().

# file paths
dir_ls(here("data", "example", "linelists"))
data/example/linelists/20201007linelist.csv
data/example/linelists/case_linelist20201006.csv
data/example/linelists/case_linelist_2020-10-02.csv
data/example/linelists/case_linelist_2020-10-03.csv
data/example/linelists/case_linelist_2020-10-04.csv
data/example/linelists/case_linelist_2020-10-05.csv
data/example/linelists/case_linelist_2020-10-08.xlsx

Чтобы получить всю информацию о метаданных для каждого файла в директории, (например, путь, дата изменения и т.п.) вы можете использовать dir_info() из fs.

Это может быть особенно полезным, если вы хотите извлечь время последнего изменения из файла, например, если вы хотите импортировать наиболее последнюю версию файла. Для примера см. страницу Импорт и экспорт.

# file info
dir_info(here("data", "example", "linelists"))

Вот выдан датафрейм. Пролистайте вправо, чтобы увидеть все столбцы.

45.3 Информация о файле

Чтобы извлечь информацию о метаданных о конкретном файле, вы можете использовать file_info() из fs (или file.info() из базового R).

file_info(here("data", "case_linelists", "linelist_cleaned.rds"))

Здесь мы используем $, чтобы индексировать результат и выдать только значение времени изменения modification_time.

file_info(here("data", "case_linelists", "linelist_cleaned.rds"))$modification_time
[1] "2026-10-06 07:27:10 UTC"

45.4 Проверка существования

Объекты R

Вы можете использовать exists() из базового R, чтобы проверить, существует ли объект R внутри R (задайте имя объекта в кавычках).

exists("linelist")
[1] FALSE

Обратите внимание, что некоторые базовые пакеты R используют общие имена объектов, такие как “data” фоново, они будут отражены как TRUE (ИСТИНА), если не уточнить inherit = FALSE. Это одна из причин, почему не стоит называть ваш набор данных “data”.

exists("data")
[1] TRUE
exists("data", inherit = FALSE)
[1] FALSE

Если вы пишите функцию, вам следует использовать missing() из базового R, чтобы проверить наличие аргумента вместо exists().

Директории

Чтобы проверить, существует ли директория, задайте путь к файлу (и имя файла) в is_dir() из fs. Пролистайте вправо, чтобы увидеть, что напечатано TRUE.

is_dir(here("data"))
data 
TRUE 

Альтернативой будет file.exists() из базового R.

Файлы

Чтобы проверить, существует ли конкретный файл, используйте is_file() из fs. Пролистайте вправо, чтобы увидеть, что напечатано TRUE.

is_file(here("data", "case_linelists", "linelist_cleaned.rds"))
data/case_linelists/linelist_cleaned.rds 
                                    TRUE 

Альтернативой из базового R будет file.exists().

45.5 Создание

Директории

Чтобы создать новую директорию (папку), вы можете использовать dir_create() из fs. Если директория уже существует, она не будет перезаписана сверу, и не будет выдаваться ошибка.

dir_create(here("data", "test"))

Альтернативой является dir.create() из базового R, которая выдаст ошибку, если директория уже существует. Наоборот, dir_create() в этом сценарии не выдаст никаких сообщений.

Файлы

вы можете создать (пустой) файл с помощью file_create() из fs. Если файл уже существует, он не будет перезаписан или изменен.

file_create(here("data", "test.rds"))

Альтернативой из базового R является file.create(). Но если файл уже существует, эта опция его обрезан. Если вы используете file_create(), файл останется неизменным.

Создание, если не существует

В РАЗРАБОТКЕ

45.6 Удаление

Объекты R

Используйте rm() из базового R, чтобы удалить объект R.

Директории

Используйте dir_delete() из fs.

Файлы

Вы можете удалить файлы с помощью file_delete() из fs.

45.7 Выполнение других файлов

source()

Чтобы выполнить один скрипт R из другого скрипта R, вы можете использовать команду source() (из базового R).

source(here("scripts", "cleaning_scripts", "clean_testing_data.R"))

Это эквивалентно просмотру приведенного выше скрипта R и нажатию кнопки “Source” в правом верхнем углу скрипта. Это приведет к выполнению скрипта, но сделает это незаметно (без вывода на консоль R), если это не предусмотрено специально. См. страницу [Интерактивная консоль], где есть примеры использования source() для взаимодействия с пользователем через консоль R в режиме вопросов и ответов.

render()

render() - вариация source(), наиболее часто используемая для скриптов R markdown. Вы задаете input =, который является файлом R markdown, а также output_format = (как правило, “html_document”, “pdf_document”, “word_document”, ““)

См. дополнительные детали на странице Отчеты с помощью R Markdown. Также см. документацию по render() тут или введя ?render.

Выполнение файлов в директории

Вы можете создать цикл for и использовать его для source() для каждого файла в директории, указанного в dir().

for(script in dir(here("scripts"), pattern = ".R$")) {   # для каждого имени скрипта в папке проекта R "scripts" (с расширением .R)
  source(here("scripts", script))                        # запрос файла с соответствующим именем, который существует в папке скриптов
}

Если вы хотите выполнить только определенные скрипты, вы можете определить их по имени следующим образом:

scripts_to_run <- c(
     "epicurves.R",
     "demographic_tables.R",
     "survival_curves.R"
)

for(script in scripts_to_run) {
  source(here("scripts", script))
}

Вот сравнение функций fs и базового R.

Импорт файлов в директорию

По вопросам импорта и экспорта отдельных файлов см. страницу [Импорт и экспорт].

Также см. на странице [Импорт и экспорт] методы автоматического импорта наиболее свежего файла на основе даты в имени файла или с помощью рассмотрения мета-данных файла.

См. страницу [Итерации, циклы и списки] для примера с пакетом purrr, демонстрирующего:

  • Разделение датафрейма и сохранение его как нескольких файлов CSV
  • Разделения датафрейма и сохранения каждой части как отдельного листа в рабочей книге Excel
  • Импорта нескольких файлов CSV и объединения их в один датафрейм
  • Импорта рабочей книги Excel с несколькими листами и объединения их в один датафрейм

45.8 базовый R

См. функции ниже list.files() и dir(), которые проводят те же операции создания списка файлов в указанной директории. Вы можете задать ignore.case = или конкретную последовательность, которую надо найти.

list.files(path = here("data"))

list.files(path = here("data", "example"), pattern = "\\.csv$")
# dir(path = here("data", "example"), pattern = "\\.csv$")

list.files(path = here("data", "example"), pattern = "hospital", ignore.case = TRUE)

Если файл в настоящее время “открыт”, он будет отображаться в вашей папкой с тильдой в начале, например, “~$hospital_linelists.xlsx”.

45.9 Ресурсы

https://cran.r-project.org/web/packages/fs/vignettes/function-comparisons.html