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

How to read multiple csv files with Reduce in R

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

带有每个 .csv 路径的向量

filepaths

读取 .csv 和return其中一列的函数

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 时会发生此错误

Error in read.table(file = file, header = header, sep = sep, quote = quote, : 'file' must be a character string or connection

这很奇怪,因为如果我像

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

有效。

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

您可以使用 data.table 中的 fread 来只读入所需的列,而不是像在您的函数中那样读入整个 csv,然后删除除一列之外的所有列。

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

Reduce() 与处理数据和 return 同类数据的函数一起使用。例如 reduceFun(x1,x2) 比较 x1 和 x2 和 returns 将首先调用 max,x1 和 x2 是向量的前 2 个元素,然后结果将作为 x1 传递,然后是第三个元素为 x2:

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()可能不是你想要使用的,还有许多其他方法,如其他答案所示。

我刚刚弄明白了。问题是,Reduce 需要一个函数,它将累加器作为第一个参数,将元素作为第二个参数。我换了他们。所以解决方案如下所示:

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

好多了

这对我有用!

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
}