如何将多个 .txt 文件读入 R?

38
我正在使用R语言可视化一些数据,这些数据都是以.txt格式存储的。在一个目录下有几百个文件,我想一次性将它们全部加载到一个表格中。
有什么帮助吗?
编辑:
列出文件不是问题。但我在从列表转换为内容方面遇到了麻烦。我尝试了 这里 的一些代码,但是我在这部分代码中遇到了一个错误:
all.the.data <- lapply( all.the.files,  txt  , header=TRUE)
 Error in match.fun(FUN) : object 'txt' not found

有任何能够澄清这个问题的代码片段将不胜感激。


1
问题是 txt 不是一个函数。你指向的链接是关于 read.csv 函数的。 - Wok
5个回答

41
你可以尝试这个方法:
filelist = list.files(pattern = ".*.txt")

#assuming tab separated values with a header    
datalist = lapply(filelist, function(x)read.table(x, header=T)) 

#assuming the same header/columns for all files
datafr = do.call("rbind", datalist) 

6
稍微修改一下:lapply(filelist, FUN=read.table, header=TRUE) 的意思是对 filelist 中的每个文件使用 read.table 函数进行读取,并指定 header=TRUE 参数,表示第一行为列名。 - RockScience
1
有没有办法使用这种方法添加文件名?这样每个数据框的列标题就以文件名的一部分开头了吗? - joffie
是的,这种方法存在一个问题,即数据列表的文件名仍然为空。 - nouse

35

有三种快速的方法来读取多个文件并将它们放入一个数据框或数据表中

首先获取所有txt文件的列表(包括子文件夹中的文件)

list_of_files <- list.files(path = ".", recursive = TRUE,
                            pattern = "\\.txt$", 
                            full.names = TRUE)

1)使用fread()rbindlist()函数来自data.table

#install.packages("data.table", repos = "https://cran.rstudio.com")
library(data.table)

# Read all the files and create a FileName column to store filenames
DT <- rbindlist(sapply(list_of_files, fread, simplify = FALSE),
                use.names = TRUE, idcol = "FileName")

2)使用readr :: read_table2()purrr :: map_df()tidyverse框架:

#install.packages("tidyverse", 
#                 dependencies = TRUE, repos = "https://cran.rstudio.com")
library(tidyverse)

# Read all the files and create a FileName column to store filenames
df <- list_of_files %>%
  set_names(.) %>%
  map_df(read_table2, .id = "FileName")

3) (可能是三个中最快的)使用vroom::vroom()

#install.packages("vroom", 
#                 dependencies = TRUE, repos = "https://cran.rstudio.com")
library(vroom)

# Read all the files and create a FileName column to store filenames
df <- vroom(list_of_files, .id = "FileName")

   

注意: 为了清理文件名,请使用basenamegsub函数。

基准测试: readrdata.tablevroom在处理大数据方面的比较。

vroom-benchmark


编辑1: 使用readr::read_csv读取多个csv文件并跳过header

list_of_files <- list.files(path = ".", recursive = TRUE,
                            pattern = "\\.csv$", 
                            full.names = TRUE)

df <- list_of_files %>%
  purrr::set_names(nm = (basename(.) %>% tools::file_path_sans_ext())) %>%
  purrr::map_df(read_csv, 
                col_names = FALSE,
                skip = 1,
                .id = "FileName")

编辑 2: 如果要将包含通配符的模式转换为等效的正则表达式,请使用glob2rx()


1
我该如何选择list_of_files中的前三个变量/列? - mRiddle
1
如果您使用 fread:请使用 select = c(1:3)select = c("colname 1", "colname 2", "colname 3")。如果您使用 read_table2,请检查参数 col_types = cols_only(colname1 = "i", colname2 = "d"),其中 i 表示整数,d 表示双精度浮点数。希望对您有所帮助。 - Tung
1
请查看我最近的答案,了解更多清理文件名的选项:https://stackoverflow.com/a/49546846/786542 - Tung
1
必须使用 data.table 给某人点赞。 - WestCoastProjects
1
@BappaDas:你试过使用map_dfc()了吗? - Tung
显示剩余2条评论

11

现在有一种非常简单的方法可以实现这个:使用readtext包。

readtext::readtext("path_to/your_files/*.txt")

真的就是那么简单。


1
这是一个不错的函数,但是readtext只会将所有文本导入到单个列中。在大多数情况下,此后还需要进行其他操作才能使数据可用。 - EcologyTom
1
是的,这就是 quanteda 包的作用。 - Ken Benoit

5

感谢所有的回答!

同时,我也自己研究出了一种方法。如果有用的话,请告诉我:

library(foreign)

setwd("/path/to/directory")

files <-list.files()

data <- 0


for (f in files) {

tempData = scan( f, what="character")

data <- c(data,tempData)    

} 

5
请查看有关函数 dir()list.files() 的帮助文档。这将允许您获取一个文件列表,可能会通过正则表达式进行过滤,然后您可以循环遍历它们。
如果您想要同时处理所有文件,首先必须将内容保存在一个文件中。一种选项是使用 cat 将所有文件输出到 stdout 并使用 popen() 读取该输出。有关更多信息,请参阅 help(Connections)

谢谢,但还是不太清楚。看看我的修改 :) - Eric Brotto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接