假设我们有一个包含多个data.csv文件的文件夹,每个文件包含相同数量的变量,但每个变量来自不同的时间。 在R中是否有一种方法可以同时导入它们而不是逐个导入?

我的问题是我有大约2000个数据文件要导入,并且只能通过使用代码单独导入它们:

read.delim(file="filename", header=TRUE, sep="\t")

效率不高。


当前回答

基于dnlbrk的注释,对于大文件,assign可以比list2env快得多。

library(readr)
library(stringr)

List_of_file_paths <- list.files(path ="C:/Users/Anon/Documents/Folder_with_csv_files/", pattern = ".csv", all.files = TRUE, full.names = TRUE)

通过将full.names参数设置为true,您将在文件列表中获得每个文件的完整路径作为单独的字符串,例如,List_of_file_paths[1]将类似于"C:/Users/Anon/Documents/Folder_with_csv_files/ fil1 .csv"

for(f in 1:length(List_of_filepaths)) {
  file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5)
  file_df <- read_csv(List_of_filepaths[f])  
  assign( x = file_name, value = file_df, envir = .GlobalEnv)
}

你可以利用这些数据。table package的fread或base R read.csv而不是read_csv。file_name步骤允许您整理名称,以便每个数据帧不保留文件的完整路径作为其名称。 在将数据表传输到全局环境之前,您可以扩展循环对数据表做进一步的处理,例如:

for(f in 1:length(List_of_filepaths)) {
  file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5)
  file_df <- read_csv(List_of_filepaths[f])  
  file_df <- file_df[,1:3] #if you only need the first three columns
  assign( x = file_name, value = file_df, envir = .GlobalEnv)
}

其他回答

基于dnlbrk的注释,对于大文件,assign可以比list2env快得多。

library(readr)
library(stringr)

List_of_file_paths <- list.files(path ="C:/Users/Anon/Documents/Folder_with_csv_files/", pattern = ".csv", all.files = TRUE, full.names = TRUE)

通过将full.names参数设置为true,您将在文件列表中获得每个文件的完整路径作为单独的字符串,例如,List_of_file_paths[1]将类似于"C:/Users/Anon/Documents/Folder_with_csv_files/ fil1 .csv"

for(f in 1:length(List_of_filepaths)) {
  file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5)
  file_df <- read_csv(List_of_filepaths[f])  
  assign( x = file_name, value = file_df, envir = .GlobalEnv)
}

你可以利用这些数据。table package的fread或base R read.csv而不是read_csv。file_name步骤允许您整理名称,以便每个数据帧不保留文件的完整路径作为其名称。 在将数据表传输到全局环境之前,您可以扩展循环对数据表做进一步的处理,例如:

for(f in 1:length(List_of_filepaths)) {
  file_name <- str_sub(string = List_of_filepaths[f], start = 46, end = -5)
  file_df <- read_csv(List_of_filepaths[f])  
  file_df <- file_df[,1:3] #if you only need the first three columns
  assign( x = file_name, value = file_df, envir = .GlobalEnv)
}

除了使用lapply或R中的其他循环构造,您还可以将CSV文件合并到一个文件中。

在Unix中,如果文件没有头文件,那么很简单:

cat *.csv > all.csv

或者如果有标题,你可以找到一个字符串匹配标题,只有标题(即假设标题行都以“年龄”开头),你会这样做:

cat *.csv | grep -v ^Age > all.csv

我认为在Windows中,你可以通过DOS命令框中的COPY和SEARCH(或FIND或其他什么)来做到这一点,但为什么不安装cygwin并获得Unix命令shell的强大功能呢?

这是我读取多个文件并将它们组合成1个数据帧的具体示例:

path<- file.path("C:/folder/subfolder")
files <- list.files(path=path, pattern="/*.csv",full.names = T)
library(data.table)
data = do.call(rbind, lapply(files, function(x) read.csv(x, stringsAsFactors = FALSE)))

有人要求我将此功能添加到stackoverflow R包中。鉴于它是一个tinyverse包(不能依赖于第三方包),以下是我想到的:

#' Bulk import data files 
#' 
#' Read in each file at a path and then unnest them. Defaults to csv format.
#' 
#' @param path        a character vector of full path names
#' @param pattern     an optional \link[=regex]{regular expression}. Only file names which match the regular expression will be returned.
#' @param reader      a function that can read data from a file name.
#' @param ...         optional arguments to pass to the reader function (eg \code{stringsAsFactors}).
#' @param reducer     a function to unnest the individual data files. Use I to retain the nested structure. 
#' @param recursive     logical. Should the listing recurse into directories?
#'  
#' @author Neal Fultz
#' @references \url{https://stackoverflow.com/questions/11433432/how-to-import-multiple-csv-files-at-once}
#' 
#' @importFrom utils read.csv
#' @export
read.directory <- function(path='.', pattern=NULL, reader=read.csv, ..., 
                           reducer=function(dfs) do.call(rbind.data.frame, dfs), recursive=FALSE) {
  files <- list.files(path, pattern, full.names = TRUE, recursive = recursive)

  reducer(lapply(files, reader, ...))
}

通过参数化读卡器和减速器功能,人们可以使用数据。table或dplyr(如果他们选择的话),或者只使用适用于较小数据集的基本R函数。

在我看来,大多数其他答案都被里约热内卢::import_list淘汰了,这是一个简洁的一行程序:

library(rio)
my_data <- import_list(dir("path_to_directory", pattern = ".csv"), rbind = TRUE)

任何额外的参数都传递给里约热内卢::import。里约热内卢几乎可以处理R可以读取的任何文件格式,而且它使用数据。桌子的fread在可能的地方,所以它也应该快。