【问题标题】:Increase speed of bind_rows within loop (3000 dataframes)提高循环内 bind_rows 的速度(3000 个数据帧)
【发布时间】:2019-05-10 11:26:00
【问题描述】:

我已经解析了一个非常大的数据库,其中包含超过 500 万条数据行和 40 列。 出于实际原因,结果被分成小的“.Rdata”文件。 我总共有 3000 多个文件,每个文件大小不超过 1Mb。

我设计了一个快速循环来使用 dplyr 将这些文件组合到一个数据帧中,但是这非常慢,我相信有更快的方法。

我尝试使用预分配矩阵,但我的数据既是文本又是数字,并且出现错误。 使用基本 R 时,数据帧甚至更慢。

list_files = as.data.frame(list.files(path = "output", pattern = 'Rdata'))
names(list_files) = 'full_name'

list_files = list_files %>% 
    separate(full_name, sep ="_", into = c('col1','col2')) %>% 
        separate(col2, sep = '.R', into = c('col3','col4')) %>%
            mutate(col3 = as.numeric(col3)) %>% 
            arrange(col3) %>%  mutate(col3 = as.character(col3))

datax <- c()

for(i in 1:length(list_files$col3))
    {
        load(paste('output/MyData_',list_files$col3[i],'.Rdata',sep=''))
##here loads results_df2
        datax = datax %>% bind_rows(results_df2)
        if((i %% 100) == 0) { print(i)}
    }

有没有更有效的方法来编写这个循环?

【问题讨论】:

  • 太棒了!现在将发布此内容。

标签: r dplyr tidyverse tibble


【解决方案1】:

使用 purrr::mappurrr::reduce,您可以在不使用 for 循环的情况下导入和绑定它们。

library(purrr)
library(dplyr)

# save data frame as rds
# mtcars %>% saveRDS("mtcars1.rds")
# mtcars %>% saveRDS("mtcars2.rds")

# list files
files <- list.files(pattern = "rds")

# read and bind
files %>% map(readRDS) %>% 
                reduce(bind_rows)

【讨论】:

  • 如果我错了,请纠正我,但即使 map 也是一个循环,只是用 rcpp 或 cpp 或更智能的方式编写的?无论如何将通过基准测试进行测试。谢谢。
  • 我不知道这个问题的答案。
  • 我无法将此代码应用于我的 Rdata 文件,因为在使用 load() 类比时我收到以下错误:Error: Argument 1 must have names
【解决方案2】:

data.table 的另一个选项

library(data.table)
library(dplyr)

list_files = list.files(path = "output", pattern = 'Rdata')
lapply(list_files, function(x) load(x) %>% data.table() ) %>% rbindlist()  

【讨论】:

  • @Arkadiw 完成后请发布结果
  • 您的代码需要永远运行,而 bind_rows 需要 7 秒才能运行 50 个文件。
【解决方案3】:

使用 dplyrbind_rows

system.time( for(i in 1:50) { datax = datax %>% bind_rows( ll[[i]]) })

结果

user  system elapsed 
2.70    0.15    2.87  

使用 rbindlist 函数

system.time(ans1 &lt;- rbindlist(ll))

结果

 user  system elapsed 
 0.05    0.00    0.04 

这正是我所需要的。问题得到解答。谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2019-08-01
    • 2014-07-27
    • 1970-01-01
    • 2021-03-14
    • 2022-01-25
    • 2017-07-04
    相关资源
    最近更新 更多