【问题标题】:How to read multiple csv files with Reduce in R如何在 R 中使用 Reduce 读取多个 csv 文件
【发布时间】:2016-05-31 02:59:51
【问题描述】:

我正在尝试使用 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 中的错误(文件 = 文件,标题 = 标题,sep = sep,quote = quote,: 'file' 必须是字符串或连接

这很奇怪,因为如果我像手动调用“getData”函数

getData(filepaths[1],col)
getData(filepaths[2],col)
getData(filepaths[3],col)

它有效。

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

【问题讨论】:

  • 试试do.call(rbind,lapply(filepaths, fread, select="colname"))
  • 您也可以这样做,您的函数unlist(lapply(filepaths, function(x){ getData(x,1) })) 将读取第一列。
  • 为什么要读取整个 .csv 然后只提取一列?效率低下。 fread 例如有一个 select 参数...

标签: r reduce


【解决方案1】:

这对我有用!

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
}

【讨论】:

    【解决方案2】:

    我刚刚想通了。问题是,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好很多了

    【讨论】:

      【解决方案3】:

      您可以使用 data.table 中的 fread 仅读取所需的列,而不是像在您的函数中那样读取整个 csv 并因此删除除一列之外的所有列。

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

      【讨论】:

      • 感谢这是一个不错的方法。但我也想知道如何使用 Reduce。
      • 不确定您是否可以使用 Reduce() 执行此操作,或者您为什么要这样做,当周围有更简单的替代方案时。
      • 我对 Erlang 和 Scala 等其他函数编程语言有一些经验,我想采用我从那里知道的概念。 Reduce 是这些典型的功能元素之一,幸运的是,它也可以在 R
      • 这就是为什么你正在尝试做的事情非常不像 R。
      【解决方案4】:

      Reduce() 与处理数据并返回相同类型数据的函数一起使用。例如 reduceFun(x1,x2) 比较 x1 和 x2 并返回最大值将首先被调用,其中 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()可能不是你想要使用的,还有很多其他的方法如其他答案所示。

      【讨论】:

      • 我明白了,但实际上,您可以将一个空向量作为累加器(作为“init”),并在每次迭代中将其传递给您的函数(作为 x1)。一个例子是,每次迭代都将 read.csv 的结果添加到累加器中。最后,您将所有数据集中在一个集合中。这就是我想做的事情
      • 这就是为什么您不能像这样使用Reduce() 进行此操作
      • 不,没问题,因为我的函数没有返回一个data.frame,而是一个通过累加器使用append的向量,以及getData的结果
      猜你喜欢
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 2016-06-14
      • 2015-08-23
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多