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;而第三、四个文件夹又是该子文件夹下的子文件夹file3file4

  • 第四个文件夹是根目录的另一个子文件夹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"
  • 可以看到输出结果既不包括根目录,也不包括二级文件夹file3file4

list.files()

list.files()dir()两个函数的功能和用法完全一致,互为别名函数,本例中仅使用list.files()

full.namesrecursive参数」

该函数也有full.namesrecursive两个参数,但默认值本身就是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"
  • 该函数既读取文件夹(file1file2)路径,也读取文件(本例中的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):正则表达式

  • 示例数据请在后台发送关键词「示例数据」获取。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐