如何在R中使用Reduce读取多个csv文件

时间:2016-02-18 18:53:04

标签: r reduce

我正在尝试使用Reduce从多个.csv文件中提取一列。 我拥有的是

带有每个.csv

路径的向量
filepaths

读取.csv并返回其中一列的函数

getData <- function(path,column) {
   d = read.csv(path)
   d[,column]
}

和Reduce函数,将getData函数应用于每个文件路径并将结果存储在单个集合中(对于演示,我只采用前三个路径字符串)

Reduce(function(path,acc) append(acc, getData(path,column)), filepaths[1:3],c())

如果我这样做,我会收到以下错误,当使用其中一个文件路径调用read.csv时会发生错误

  

read.table出错(file = file,header = header,sep = sep,quote = quote,:     'file'必须是字符串或连接

这很奇怪,因为如果我像

那样手动调用“getData”函数
getData(filepaths[1],col)
getData(filepaths[2],col)
getData(filepaths[3],col)

它有效。

我知道,我可以用for循环做到这一点。但我想明白,问题是什么。

4 个答案:

答案 0 :(得分:1)

您可以使用fread中的data.table来仅读取所需的列,而不是读取整个csv,从而删除所有列,只需一个,就像在函数中一样。

library(data.table)
unlist(lapply(filepaths, fread, select= "colname")) #output is a vector

答案 1 :(得分:1)

我只是想通了。问题是,Reduce需要一个函数,它将累加器作为FIRST参数,并将元素作为第二个参数。我换了他们。所以解决方案看起来像这样:

getData <- function(path,column) {
  d = read.csv(path)
  d[,column]
}

Reduce(function(acc,path) append(acc, getData(path,column)), filepaths[1:3],c())

感谢fread的提示。我发现这比read.csv

要好得多

答案 2 :(得分:0)

Reduce()用于处理数据并返回相同类型数据的函数。例如,比较x1和x2并且返回max的reduceFun(x1,x2)将首先使用x1调用,而x2是向量的2个第一个元素,然后结果将作为x1传递,第三个元素将作为x2传递:< / p>

reduceFun <- function(x1,x2) 
{
  print(paste("x1=",x1, " : x2=",x2, " : max=",max(x1,x2)));
  return(max(x1,x2))
}
> res <- Reduce(reduceFun, 1:10)
[1] "x1= 1  : x2= 2  : max= 2"
[1] "x1= 2  : x2= 3  : max= 3"
[1] "x1= 3  : x2= 4  : max= 4"
[1] "x1= 4  : x2= 5  : max= 5"
[1] "x1= 5  : x2= 6  : max= 6"
[1] "x1= 6  : x2= 7  : max= 7"
[1] "x1= 7  : x2= 8  : max= 8"
[1] "x1= 8  : x2= 9  : max= 9"
[1] "x1= 9  : x2= 10  : max= 10"
> res
[1] 10

所以Reduce()可能不是您想要使用的,其他答案中还有很多其他方法。

答案 3 :(得分:0)

这对我有用!

library(data.table)
setwd("C:/Users/your_path_here/CSV Files/")

WD="C:/Users/your_path_here/CSV Files/"
data<-data.table(read.csv(text="CashFlow,Cusip,Period"))

csv.list<- list.files(WD)
k=1

for (i in csv.list){
  temp.data<-read.csv(i)
  data<-data.table(rbind(data,temp.data))

  if (k %% 100 == 0)
    print(k/length(csv.list))

  k<-k+1
}