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”, которая содержит все данные, используемые для этого руководства по R. Мы задаем отображение всех файлов в “data” и подпапках (например, “cache”, “epidemic models”, “population”, “shp” и “weather”).

fs::dir_tree(path = here("data"), recurse = TRUE)
C:/Users/ngulu864/AppData/Local/Temp/RtmpQXbGPz/file917c23c175b0/epiRhandbook_eng/data
├── africa_countries.geo.json
├── cache
│   └── epidemic_models
│       ├── 2015-04-30
│       │   ├── estimated_reported_cases_samples.rds
│       │   ├── estimate_samples.rds
│       │   ├── latest_date.rds
│       │   ├── reported_cases.rds
│       │   ├── summarised_estimated_reported_cases.rds
│       │   ├── summarised_estimates.rds
│       │   └── summary.rds
│       ├── epinow_res.rds
│       ├── epinow_res_small.rds
│       ├── generation_time.rds
│       └── incubation_period.rds
├── case_linelists
│   ├── cleaning_dict.csv
│   ├── fluH7N9_China_2013.csv
│   ├── linelist_cleaned.rds
│   ├── linelist_cleaned.xlsx
│   └── linelist_raw.xlsx
├── country_demographics.csv
├── covid_example_data
│   ├── covid_example_data.xlsx
│   └── covid_shapefile
│       ├── FultonCountyZipCodes.cpg
│       ├── FultonCountyZipCodes.dbf
│       ├── FultonCountyZipCodes.prj
│       ├── FultonCountyZipCodes.sbn
│       ├── FultonCountyZipCodes.sbx
│       ├── FultonCountyZipCodes.shp
│       ├── FultonCountyZipCodes.shp.xml
│       └── FultonCountyZipCodes.shx
├── covid_incidence.csv
├── covid_incidence_map.R
├── district_count_data.xlsx
├── example
│   ├── Central Hospital.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
│   ├── Military Hospital.csv
│   ├── Missing.csv
│   ├── Other.csv
│   ├── Port Hospital.csv
│   └── St. Mark's Maternity Hospital (SMMH).csv
├── facility_count_data.rds
├── flexdashboard
│   ├── outbreak_dashboard.html
│   ├── outbreak_dashboard.Rmd
│   ├── outbreak_dashboard_shiny.Rmd
│   ├── outbreak_dashboard_test.html
│   └── outbreak_dashboard_test.Rmd
├── fluH7N9_China_2013.csv
├── gis
│   ├── africa_countries.geo.json
│   ├── covid_incidence.csv
│   ├── covid_incidence_map.R
│   ├── linelist_cleaned_with_adm3.rds
│   ├── population
│   │   ├── sle_admpop_adm3_2020.csv
│   │   └── sle_population_statistics_sierraleone_2020.xlsx
│   └── shp
│       ├── README.txt
│       ├── sle_adm3.CPG
│       ├── sle_adm3.dbf
│       ├── sle_adm3.prj
│       ├── sle_adm3.sbn
│       ├── sle_adm3.sbx
│       ├── sle_adm3.shp
│       ├── sle_adm3.shp.xml
│       ├── sle_adm3.shx
│       ├── sle_hf.CPG
│       ├── sle_hf.dbf
│       ├── sle_hf.prj
│       ├── sle_hf.sbn
│       ├── sle_hf.sbx
│       ├── sle_hf.shp
│       └── sle_hf.shx
├── godata
│   ├── cases_clean.rds
│   ├── contacts_clean.rds
│   ├── followups_clean.rds
│   └── relationships_clean.rds
├── likert_data.csv
├── linelist_cleaned.rds
├── linelist_cleaned.xlsx
├── linelist_raw.xlsx
├── make_evd_dataset-DESKTOP-JIEUMMI.R
├── make_evd_dataset.R
├── malaria_app
│   ├── app.R
│   ├── data
│   │   └── facility_count_data.rds
│   ├── funcs
│   │   └── plot_epicurve.R
│   ├── global.R
│   ├── malaria_app.Rproj
│   ├── server.R
│   └── ui.R
├── malaria_facility_count_data.rds
├── phylo
│   ├── sample_data_Shigella_tree.csv
│   ├── Shigella_subtree_2.nwk
│   ├── Shigella_subtree_2.txt
│   └── Shigella_tree.txt
├── rmarkdown
│   ├── outbreak_report.docx
│   ├── outbreak_report.html
│   ├── outbreak_report.pdf
│   ├── outbreak_report.pptx
│   ├── outbreak_report.Rmd
│   ├── report_tabbed_example.html
│   └── report_tabbed_example.Rmd
├── standardization
│   ├── country_demographics.csv
│   ├── country_demographics_2.csv
│   ├── deaths_countryA.csv
│   ├── deaths_countryB.csv
│   └── world_standard_population_by_sex.csv
├── surveys
│   ├── population.xlsx
│   ├── survey_data.xlsx
│   └── survey_dict.xlsx
└── time_series
    ├── campylobacter_germany.xlsx
    └── weather
        ├── germany_weather2002.nc
        ├── germany_weather2003.nc
        ├── germany_weather2004.nc
        ├── germany_weather2005.nc
        ├── germany_weather2006.nc
        ├── germany_weather2007.nc
        ├── germany_weather2008.nc
        ├── germany_weather2009.nc
        ├── germany_weather2010.nc
        └── germany_weather2011.nc

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

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

# file names
dir(here("data", "gis", "population"))
[1] "sle_admpop_adm3_2020.csv"                       
[2] "sle_population_statistics_sierraleone_2020.xlsx"

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

# file paths
dir_ls(here("data", "gis", "population"))
C:/Users/ngulu864/AppData/Local/Temp/RtmpQXbGPz/file917c23c175b0/epiRhandbook_eng/data/gis/population/sle_admpop_adm3_2020.csv
C:/Users/ngulu864/AppData/Local/Temp/RtmpQXbGPz/file917c23c175b0/epiRhandbook_eng/data/gis/population/sle_population_statistics_sierraleone_2020.xlsx

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

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

# file info
dir_info(here("data", "gis", "population"))

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

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] "2024-02-18 20:56:16 +07"

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"))
C:/Users/ngulu864/AppData/Local/Temp/RtmpQXbGPz/file917c23c175b0/epiRhandbook_eng/data 
                                                                                  TRUE 

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

Файлы

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

is_file(here("data", "case_linelists", "linelist_cleaned.rds"))
C:/Users/ngulu864/AppData/Local/Temp/RtmpQXbGPz/file917c23c175b0/epiRhandbook_eng/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"), pattern = ".csv")
# dir(path = here("data"), pattern = ".csv")

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

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

45.9 Ресурсы

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