# R语言文件系统操作{#file:system-operation}
即使是数据处理、分析也涉及到文件系统操作。比如一些表单中包含公司全部合作伙伴的数据,现在需要按照合作伙伴名称切割数据并将数据以附件的形式通过邮件发送?我们就需要将数据按照合作伙伴切割并分开保存打包,最后以邮件发送。那这个过程中就涉及到文件、目录等文件系统操作。
在使用Rstudio-server、部署shiny-server时,文件系统操作将会变得尤其重要。我们掌握好R里面的文件系统操作,就不用使用`bash`命令操作文件系统,让我们自己更加方便。
本章节主要讲R语言里的文件操作。分为:
- base R
- fs package介绍
- base and fs and shell 对比
## base R {#file:base-r}
base R 中提供了一组函数与计算机系统文件交互,从文件创建、复制、删除等常规文件操作。
### 用法{#base:r-usage}
本小节主要将base R中常用的文件函数举例说明用法。
- 常用函数
```{r}
# 查看路径下的文件列表
list.files()
# 创建文件夹
dir.create('test folder')
# 是否存在
dir.exists('test folder')
# 删除文件夹
unlink('test folder',recursive = TRUE,force=TRUE)
# 注意recursive参数为TRUE,文件夹才能被删除
```
- 函数介绍
```{r eval=FALSE}
file.create(..., showWarnings = TRUE)
file.exists(...)
file.remove(...)
file.rename(from, to)
file.append(file1, file2)
file.copy(from, to, overwrite = recursive, recursive = FALSE,
copy.mode = TRUE, copy.date = FALSE)
file.symlink(from, to)
file.link(from, to)
```
其中需要注意的参数即recursive,是否递归?像macos或linux上的`cp -R`命令。
```{r}
getwd()
```
`file.create()`:用指定的名称创建文件。创建成功则返回TRUE,失败将返回警告。
```{r}
file.create('test.txt')
file.create('test.csv')
```
`file.exists()`:返回文件是否存在的逻辑向量,如果存在则返回TRUE
```{r}
file.exists(c('test.txt','test.csv'))
```
`file.remove()`:删除指定名称文件。
```{r}
file.remove('test.txt')
```
`file.rename()`:尝试重命名文件。
```{r}
file.rename(from = 'test.csv',to = 'newtest.csv')
```
`file.append()`:尝试将第二个文件追加到第一个文件
```{r}
cat("文件ta的内容\n", file = "ta.txt")
cat("文件tb的内容\n", file = "tb.txt")
file.append("ta.txt", "tb.txt")
cat(readLines('ta.txt'))
```
`file.copy()`:复制文件
```{r}
dir.create('test')
file.copy(from = 'ta.txt',to = './test',overwrite = T,recursive = TRUE)
```
`file.symlink()`:建立符号链接[^文件链接],在winOS系统上即快捷方式,MacOS上即替身,linux上即软连接类似`ln -s`。
```{r}
file.symlink(from = 'ta.txt',to = 'newab.txt')
```
`file.link()`:建立硬链接
[^文件链接]:对数据分析而言,没有特别重要(可能在shiny部署时能用到),请自行了解软链接硬链接。
```{r include=FALSE}
unlink(x = c('ta.txt','tb.txt','newtest.csv'))
unlink(x = 'test',recursive = TRUE)
```
详情可以[参考文章](https://www.ouq.net/%E5%88%A9%E7%94%A8r%E8%AF%AD%E8%A8%80%E6%89%B9%E9%87%8F%E5%88%9B%E5%BB%BA%E3%80%81%E7%A7%BB%E5%8A%A8%E3%80%81%E5%88%A0%E9%99%A4%E3%80%81%E4%BF%AE%E6%94%B9%E6%96%87%E4%BB%B6.html)
## fs package{#fs-package}
fs[github](https://github.com/r-lib/fs)项目地址,fs为文件系统操作提供了一个跨平台的统计接口。本节基本从fs项目照搬demo。
### 安装{#fs-install}
使用以下命令从[CRAN](https://cran.r-project.org/)安装
```{r eval=FALSE}
install.packages("fs")
```
安装来自GitHub的开发版本,其中包括:
```{r eval=FALSE}
# install.packages("devtools")
devtools::install_github("r-lib/fs")
```
### 优势{#fs-advanced}
相比base R相同功能,fs包的优势:
- 向量化。所有fs的函数都是矢量化的,可以批量操作。
- 编码一致性。fs将输入的路径统一转化为UTF-8。
- 函数名一致性。fs函数使用一致的命名约定。
- 函数使用返回“tidy”paths,整洁的路径,和tidyverse一脉相承的概念。
### 基础用法{#fs-usage}
fs函数主要有四大类:
- `path_`系列用于路径构造
- `file_`系列用于文件
- `dir_`系列用木目录
- `link_`系列用于链接
目录和链接是文件的特殊类型,因为`file_`在用于目录和链接时,功能通常可以使用。
```{r}
library(fs)
# `path()`函数构造路径
path('事业部',c('华东','华西','华南','华北'),'周补货数据')
# 当前目录文件列表
dir_ls()
# 以Rmd结尾的文件
dir_ls(regexp = 'Rmd$')
# 创建一个文件夹
tmp 使用Rvest包将[官网介绍](https://fs.r-lib.org/articles/function-comparisons.html)的信息"爬"下来。由于是外网,想要快速正确爬虫确保网络通畅。
爬取代码如下:
```{r eval=FALSE}
library(rvest)
library(tidyverse,warn.conflicts = FALSE)
# 目录功能对比
directory_functions_dt %
html_nodes('#directory-functions') %>%
rvest::html_table() %>% `[[`(1)
# 文件功能对比
file_functions_dt %
html_nodes('#file-functions') %>%
rvest::html_table() %>% `[[`(1)
# 路径功能对比
path_functions_dt %
html_nodes('#path-functions') %>%
rvest::html_table() %>% `[[`(1)
```
```{r message=FALSE,warning=FALSE,echo=FALSE}
library(DT)
directory_functions_dt
2. R file manipulation:
3. fs package: