将多个.csv文件导入到R中
假设我们有一个包含多个data.csv文件的文件夹,每个文件包含相同数量的variables,但每个文件都来自不同的时间。
R中有没有办法同时导入它们,而不是单独导入它们?
我的问题是,我有大约2000个数据文件导入,不得不单独导入他们只是通过使用代码:
read.delim(file="filename", header=TRUE, sep="\t")
效率不高。
像下面的东西应该工作:
temp = list.files(pattern="*.csv") myfiles = lapply(temp, read.delim)
这假定你在一个目录中有这些CSV–你当前的工作目录 – 并且它们都有小写的扩展名.csv
。
更新
快速和肮脏的解决scheme,以获得单独的data.frames(“脏”,因为我没有打扰清理.csv
扩展名,但很容易做一些regex
):
temp = list.files(pattern="*.csv") for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))
或者,如果没有assign
,并演示(1)如何清理文件名和(2)显示如何使用list2env
,您可以尝试以下操作:
temp = list.files(pattern="*.csv") list2env( lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))), read.csv), envir = .GlobalEnv)
这是将.csv文件转换为一个data.frame的另一种select。 使用R基函数。 这比下面的选项慢了几个数量级。
# Get the files names files = list.files(pattern="*.csv") # First apply read.csv, then rbind myfiles = do.call(rbind, lapply(files, function(x) read.csv(x, stringsAsFactors = FALSE)))
编辑: – 使用data.table
和readr
多一些额外的select
fread()
版本,它是data.table
包的一个函数。 这应该是最快的select。
library(data.table) DT = do.call(rbind, lapply(files, fread) # the same using `rbindlist()` DT = rbindlist(lapply(files, fread))
使用readr ,这是一个新的hadley包读取CSV文件。 比fread稍慢,但function不同。
library(readr) library(dplyr) tbl = lapply(files, read_csv) %>% bind_rows()
除了在R中使用lapply
或其他循环结构外,还可以将CSV文件合并到一个文件中。
在Unix中,如果这些文件没有标题,那么就像下面这样简单:
cat *.csv > all.csv
或者如果有标题,你可以find一个匹配标题和只有标题(即假设标题行都以“Age”开头)的string,你可以这样做:
cat *.csv | grep -v ^Age > all.csv
我想在Windows中,你可以在DOS命令框中使用COPY
和SEARCH
(或者FIND
或者其他)来做到这一点,但是为什么不安装cygwin
并获得Unix命令shell的权力呢?
更快,更简洁的tidyverse
(aka: dplyr
)解决scheme:
Tbl <- list.files(pattern="*.csv") %>% map_df(~read_csv(.))
如果types转换是厚脸皮的,你可以强制所有的列作为字符。
Tbl <- list.files(pattern="*.csv") %>% map_df(~read_csv(., col_types = cols(.default = "c")))
如果您想要插入子目录来构build您的文件列表以最终绑定,请确保包含path名称,并在列表中注册文件的全名。 这将允许绑定工作在当前目录之外进行。 (想像完整的path名称,像护照一样操作,以允许移回目录“边界”)。
Tbl <- list.files(path = "./subdirectory/", pattern="*.csv", full.names = T) %>% map_df(~read_csv(., col_types = cols(.default = "c")))
正如哈德利在这里所描述的(大约一半):
map_df(x, f)
与do.call("rbind", lapply(x, f))
实际上是一样的,但引擎盖下效率更高。
并感谢Jake Kaupp向我介绍map_df()
在这里 。
这是我开发的将所有csv文件读入R的代码。它将为每个csv文件单独创build一个数据框,并将该数据框标题为该文件的原始名称(删除空格和.csv),希望您觉得它有用!
path <- "C:/Users/cfees/My Box Files/Fitness/" files <- list.files(path=path, pattern="*.csv") for(file in files) { perpos <- which(strsplit(file, "")[[1]]==".") assign( gsub(" ","",substr(file, 1, perpos-1)), read.csv(paste(path,file,sep=""))) }
根据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,您将在文件列表中将每个文件的完整path作为单独的string,例如,List_of_file_paths [1]将类似于“C:/ Users / Anon / Documents / Folder_with_csv_files / file1.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) }
您可以使用data.table包的fread或base R read.csv而不是read_csv。 file_name步骤允许您整理名称,以便每个数据框不保留文件的完整path,因为它的名称。 在将数据表传输到全球环境之前,您可以扩展循环以进一步处理数据表,例如:
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) }
使用plyr::ldply
,通过启用.parallel
选项,读取大约30-40 MB的400 csv文件大约可以提高50%的速度。 例子包括一个文本进度条。
library(plyr) library(data.table) library(doSNOW) csv.list <- list.files(path="t:/data", pattern=".csv$", full.names=TRUE) cl <- makeCluster(4) registerDoSNOW(cl) pb <- txtProgressBar(max=length(csv.list), style=3) pbu <- function(i) setTxtProgressBar(pb, i) dt <- setDT(ldply(csv.list, fread, .parallel=TRUE, .paropts=list(.options.snow=list(progress=pbu)))) stopCluster(cl)
你可以使用这个极好的sparklyr
包:
# RStudio will help you get set-up with the Spark dependencies library(sparklyr) library(dplyr) sc <- spark_connect(master = "local", version = "2.0.2") df <- spark_read_csv(sc, "dummy", "file:////Users/bob/dev/data/results/*/*/*-metrics.csv") %>% collect()
我不能评论,因为我是一个n00b,所以你不得不原谅回答这个问题。 上面的Ananda的答案完全回答了原来的问题,但是我想添加一些我很难find的东西:导入所有这些CSV文件之后,如何对它们做任何事情? 答案是ls()和get()。
temp = list.files(pattern=".csv$") #list all the files in dir that have .csv at the end for (i in 1:length(temp)) { assign(temp[i], prettify(toJSON(read.csv(temp[i])))) #read each csv, convert to JSON,make pretty, give it a name write(get(temp[i]),paste(temp[i],"json", sep=".")) #write the json to a file }
我的用例是导入一堆CSV文件,将它们转换为JSON,对它们进行美化,然后将它们写入一个.json文件。 如果您从新导入的数据框的名称中删除了“.csv”,则可能需要使用ls()再次查找数据框。
我希望能帮助别人。
来源: https : //stackoverflow.com/a/3585976/3063793
我成功地使用了这个:
xlist<-list.files(pattern = "*.csv") for(i in xlist) { x <- read.csv((i)) assign(i, x) }
如果要将不同的csv文件收集到一个data.frame中,可以使用以下内容。 注意应该预先创build“x”data.frame。
temp <- list.files(pattern="*.csv") for (i in 1:length(temp)) { temp2 = read.csv(temp[i], header = TRUE) x <- rbind(x,temp2) }
这是我的脚本的一部分。
#This cycle read the files in a directory and assign the filenames to datasets files <- list.files(pattern=".csv$") for(i in files) { X <- read.table(i, header=TRUE) SN<-X$A/X$B X<-cbind(X,SN) ds<-paste("data_",i, sep="")#this add "data_" to the name of file ds<-substr(ds, 1, nchar(ds)-4)#remove the last 4 char (.csv) assign(ds, X) }