如何以更快的方式处理和组合列表中的data.frames

时间:2017-10-12 14:11:10

标签: r list dataframe dplyr data.table

最后,我遇到了一个非常慢的数据处理和追加多个data.frames行的问题。我使用lapplydplyr组合进行数据处理。 OTH,由于每个数据帧中有20000行乘以目录中的100个文件,因此进程变得非常慢。

目前这对我来说是一个巨大的瓶颈,因为即使在lapply进程完成后我也没有足够的内存来bind_rows进程。

这是我的数据处理方法,

首先制作文件列表

files <- list.files("file_directory",pattern = "w.*.csv",recursive=T,full.names = TRUE)

然后处理此文件列表

  library(tidyr)
  library(dplyr)

data<- lapply(files,function(x){
    tmp <- read.table(file=x, sep=',', header = T,fill=F,skip=0, stringsAsFactors = F,row.names=NULL)%>%

      select(A,B, C)%>%
      unite(BC,BC,sep='_')%>%

      mutate(D=C*A)%>%
      group_by(BC)%>%
      mutate(KK=median(C,na.rm=TRUE))%>%
      select(BC,KK,D)
  })

data <- bind_rows(data)

我收到错误消息,

  

“错误:无法分配大小的矢量...... Mb”......取决于我的公羊剩余多少。我有8 Gb ram,但似乎还在挣扎;(

我也试过do.call但没有改变!对于这个问题,谁是我友好的职责或方法? 我使用R版本3.4.2和dplyr 0.7.4。

2 个答案:

答案 0 :(得分:4)

我无法测试这个答案,因为没有可重现的数据,但我想它可能类似于以下内容,使用data.table:

library(data.table)

data <- setNames(lapply(files, function(x) {
  fread(x, select = c("A", "B", "C"))
}), basename(files))

data <- rbindlist(data, use.names = TRUE, fill = TRUE, id = "file_id")
data[, BC := paste(B, C, sep = "_")]
data[, D := C * A]
data[, KK := median(C, na.rm = TRUE), by = .(BC, file_id)]
data[, setdiff(names(data), c("BC", "KK", "D")) := NULL]

答案 1 :(得分:2)

使用ldply包中的plyr将无需在处理后绑定列表,因为它将输出data.frame

library(tidyr)
library(dplyr)
library(plyr)

files <- list.files("file_directory", pattern = "w.*.csv", recursive = TRUE, full.names = TRUE)

data<- ldply(files, function(x){
  read.table(file=x, sep=',', header = TRUE, fill = FALSE, skip = 0, stringsAsFactors = FALSE, row.names = NULL) %>%
    select(A, B, C) %>%
    unite(BC, BC, sep='_') %>%
    mutate(D = C * A) %>%
    group_by(BC) %>%
    mutate(KK = median(C, na.rm = TRUE)) %>%
    select(BC, KK, D)
})