R语言base
工具包中有一系列操作文件和文件夹的函数,比如读取文件目录、复制文件到文件夹、增删文件夹等。
本篇来介绍其中的读取文件目录功能,该类函数一共有三个:list.files()
、dir()
、list.dirs()
;其中前两个函数的功能完全一致。它们的语法结构如下:
list.files(path = ".", pattern = NULL, all.files = FALSE,
full.names = FALSE, recursive = FALSE,
ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE)
dir(path = ".", pattern = NULL, all.files = FALSE,
full.names = FALSE, recursive = FALSE,
ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE)
list.dirs(path = ".", full.names = TRUE, recursive = TRUE)
list.dirs()
先来看看参数比较少的list.dirs()
函数。这个函数的功能是读取指定路径下的所有下级文件夹的路径。它有三个参数:
❝❞
path:路径名称;默认为R环境的工作路径(可通过
getwd()
函数查看);full.names、recursive:默认值均为
TRUE
,用法见下文示例。
这里学堂君制作了一个示例文件夹123.示例文件夹
用于下面的操作,后台发送关键词「示例数据」可以获取。
list.dirs(path = "123.示例文件夹")
## [1] "123.示例文件夹" "123.示例文件夹/file1"
## [3] "123.示例文件夹/file1/file3" "123.示例文件夹/file1/file4"
## [5] "123.示例文件夹/file2"
在上面的例子中,输出结果是5个文件夹的路径信息,按名称排序:
第一个文件夹是根目录(路径)本身;
第二个文件夹是根目录下的一个子文件夹file1
;而第三、四个文件夹又是该子文件夹下的子文件夹file3
、file4
;
第四个文件夹是根目录的另一个子文件夹file2
。
通过以上示例,可以看出该函数有如下功能:
❝❞
第一,该函数只读取文件夹路径,而不读取具体的文件路径(如csv、txt文件);
第二,它不仅会读取根目录下的一级文件夹路径,还会读取更下级的子文件夹路径。
在输出结果显示上,每个文件夹都包含根目录。如果设置参数full.names = FALSE
,则会使用点号.
代替根目录。
list.dirs(path = "123.示例文件夹", full.names = F)
## [1] "" "file1" "file1/file3" "file1/file4" "file2"
如果要只读取根目录下的一级文件夹路径,需要将递归参数recursive
设置为FALSE
。
list.dirs(path = "123.示例文件夹",
full.names = F, recursive = F)
## [1] "file1" "file2"
❝❞
可以看到输出结果既不包括根目录,也不包括二级文件夹
file3
和file4
。
list.files()
list.files()
和dir()
两个函数的功能和用法完全一致,互为别名函数,本例中仅使用list.files()
。
full.names
和recursive
参数」该函数也有full.names
和recursive
两个参数,但默认值本身就是FALSE
,因此在输出结果上,该函数默认使用.
代替根目录,并只读取根目录下的文件和文件夹路径。
list.files(path = "123.示例文件夹")
## [1] "c.csv.txt" "ccsv.txt" "csv.txt" "example_1.csv"
## [5] "example_2.csv" "example_3.csv" "example_8.txt" "example_9.CSV"
## [9] "file1" "file2"
❝❞
该函数既读取文件夹(
file1
和file2
)路径,也读取文件(本例中的csv、txt文件)路径。
将递归参数recursive
设置为TRUE
的效果:
list.files(path = "123.示例文件夹", recursive = T)
## [1] "c.csv.txt" "ccsv.txt"
## [3] "csv.txt" "example_1.csv"
## [5] "example_2.csv" "example_3.csv"
## [7] "example_8.txt" "example_9.CSV"
## [9] "file1/example_4.csv" "file1/example_5.csv"
## [11] "file1/file3/example_9.csv" "file2/example_6.csv"
## [13] "file2/example_7.csv"
❝❞
这个时候,函数读取的就是根目录下各级文件的路径信息,但不包含文件夹路径本身;空文件夹如
file4
被忽略。
pattern
参数」在大多数情况下,我们需要读取的是特定类型的文件路径,这个时候可以通过参数pattern
进行设置。pattern
参数的赋值遵循正则表达式,详见推文base | 文本处理方法(Ⅰ-2):正则表达式。
大多数情况下可以使用文件拓展名对pattern
参数进行赋值。
比如,要读取根目录下的所有csv格式的文件夹。先比较pattern = ".csv"
和pattern = "csv"
的区别(即带不带点号.
):
list.files(path = "123.示例文件夹", pattern = "csv")
## [1] "c.csv.txt" "ccsv.txt" "csv.txt" "example_1.csv"
## [5] "example_2.csv" "example_3.csv"
list.files(path = "123.示例文件夹", pattern = ".csv")
## [1] "c.csv.txt" "ccsv.txt" "example_1.csv" "example_2.csv"
## [5] "example_3.csv"
可以看到,除了csv格式的文件外,两种写法还读取到了其他格式的文件路径。在本例中,两种情况的输出结果仅有一个区别,即前者包含csv.txt
,后者不包括。
第一种情况容易理解,因为所有输出结果都包含csv
这个字符,只不过有的是在拓展名上,有的是在文件名上;
而第二种情况,"ccsv.txt"
并不包含.csv
这个字符但其路径却被读取到了。原因在于点号.
在正则表达式中属于通配符,用来表示任意一个字符。因此只要文件名中的字符串csv
前还有一个字符就符合.csv
所表达的形式,而csv
则不符合。
如果要表达点号.
本身,需在其前加转义符\
:
list.files(path = "123.示例文件夹", pattern = "\\.csv")
## [1] "c.csv.txt" "example_1.csv" "example_2.csv" "example_3.csv"
尽管如此,"c.csv.txt"
仍然符合这种形式,因此该方法并不能确保读取到的全是csv
格式的文件。最好的方法是使用定位符——对于csv文件来说,字符串csv
总是出现在文件名的最后部分。
list.files(path = "123.示例文件夹", pattern = "csv$")
## [1] "example_1.csv" "example_2.csv" "example_3.csv"
❝❞
csv$
表示以csv
结束的字符串。
该函数其他几个参数及其默认值如下:
all.files = FALSE
该参数默认情况下函数不会读取以点号.
开头的文件名,而设置为TRUE
则会读取,如常见的R文件.Rhistory
:
list.files(path = "123.示例文件夹", all.files = T)
## [1] "." ".." ".Rhistory" "c.csv.txt"
## [5] "ccsv.txt" "csv.txt" "example_1.csv" "example_2.csv"
## [9] "example_3.csv" "example_8.txt" "example_9.CSV" "file1"
## [13] "file2"
ignore.case = FALSE
该参数配合pattern
参数使用,指定在正则匹配时是否不区分字母大小写。默认为FALSE
,表示区分字母大小写。
电脑对文件拓展名不会区分大小写,如.CSV
和.csv
表示的是同一类型的文件。
list.files(path = "123.示例文件夹", pattern = "CSV$")
## [1] "example_9.CSV"
list.files(path = "123.示例文件夹",
pattern = "CSV$", ignore.case = T)
## [1] "example_1.csv" "example_2.csv" "example_3.csv" "example_9.CSV"
include.dirs = FALSE
该参数配合recursive
参数使用。设置为TRUE
时,不仅会读取文件名,还会读取各级文件夹名称。
list.files(path = "123.示例文件夹/",
recursive = T, include.dirs = T)
## [1] "c.csv.txt" "ccsv.txt"
## [3] "csv.txt" "example_1.csv"
## [5] "example_2.csv" "example_3.csv"
## [7] "example_8.txt" "example_9.CSV"
## [9] "file1" "file1/example_4.csv"
## [11] "file1/example_5.csv" "file1/file3"
## [13] "file1/file3/example_9.csv" "file1/file4"
## [15] "file2" "file2/example_6.csv"
## [17] "file2/example_7.csv"
no.. = FALSE
表示是否在结果中包含.
和..
;其中.
表示根目录,..
表示根目录的上一级目录。该参数仅在recursive = F
的情况下起作用。
list.files(path = "123.示例文件夹", all.files = T)
## [1] "." ".." ".Rhistory" "c.csv.txt"
## [5] "ccsv.txt" "csv.txt" "example_1.csv" "example_2.csv"
## [9] "example_3.csv" "example_8.txt" "example_9.CSV" "file1"
## [13] "file2"
list.files(path = "123.示例文件夹",
all.files = T, no.. = T)
## [1] ".Rhistory" "c.csv.txt" "ccsv.txt" "csv.txt"
## [5] "example_1.csv" "example_2.csv" "example_3.csv" "example_8.txt"
## [9] "example_9.CSV" "file1" "file2"
list.dirs()
函数读取的是文件夹路径;list.files()
函数读取所有文件(包括文件夹)路径;
两个函数都可以只读取根目录下的一级文件(夹)路径,也可以读取各级文件(夹)路径,关键在于参数recursive
的取值,并且两个函数的默认项不同;
pattern
参数遵循「正则表达式」语法,可参考推文base | 文本处理方法(Ⅰ-2):正则表达式;
示例数据请在后台发送关键词「示例数据」获取。