【发布时间】:2019-12-19 22:27:10
【问题描述】:
我有数百万个带有不同标题的 csv 文件,我想将它们合并到一个大数据框中。
我的问题是我尝试过的解决方案有效,但是太慢了!顺便说一句,我可以在我的实验室中使用 Sparklyr 在多节点集群上工作,这个大数据工具会有帮助吗?
文件如下所示:
文件1
标头1,标头3,标头5
a,b,c
文件2
标头4,标头2
e,f
文件3
header2,header6
a,c
我想把它们合并成:
header1,header2,header3,header4,header5,header6
a,,b,,c, ,f,,e,, ,a,,,,c
我曾尝试将它们直接与 R 绑定,但程序在服务器中运行几天后崩溃。代码如下所示:
library(plyr)
library(dplyr)
library(readr)
csvfiles <- list.files(pattern = "file\\d+.csv")
for (i in 1:length(csvfiles)) {
assign(paste0("files", i),read_csv(csvfiles[[i]]))
}
csvlist <- mget(ls(pattern = "files\\d"))
result <- data.frame()
for (i in 1:length(csvlist)){
my_list <- list(result,csvlist[[i]])
result <- rbindlist(my_list,use.names=TRUE, fill=TRUE)
}
然后我尝试首先使用sed、awk和csvtk等命令行工具提取标题。我使用的代码如下所示
for file in $(ls file*.csv); do cat $file | sed "2 d" | csvtk transpose >> name_combined.csv; done
awk '{ lines[$1] = $0 } END { for (l in lines) print lines[l] }' name_combined.csv >> long_head.csv
我得到名为 long_head.csv 的 csv 文件,它看起来像这样(实际上我得到了超过 3000 列)
header1,header2,header3,header4,header5,header6
然后我在dplyr 中使用bind_rows。我想首先输出具有相同列的多个 csv 文件,然后将它们全部合并。
library(readr)
library(dplyr)
csvfiles <- list.files(pattern = "file\\d+.csv")
long_head <- read_csv("long_head.csv")
new_file <- paste("new_file",1:length(csvfiles),sep = "")
for (i in 1:length(csvfiles)) {
bind_rows(long_head,read_csv(csvfiles[[i]])) %>%
write_csv (file = paste0(new_file [[i]], ".csv"))
}
代码一天只能输出大约 10 万个 csv 文件,这意味着我必须等待整整一个月才能让这些 csv 文件合并它们。
我也试过不写多个csv文件直接组合起来:
library(readr)
library(dplyr)
csvfiles <- list.files(pattern = "file\\d+.csv")
long_head <- read_csv("long_head.csv")
for (i in 1:length(csvfiles)) {
a <- bind_rows(read_csv(csvfiles[[i]]),long_head)
result <- rbind(a,long_head)
}
它跑得更快,但也落后于我的预期。
【问题讨论】:
-
试试
data.table::rbindlist() -
嗨,你自己尝试了什么?你提到你有一些运行速度很慢的代码。你能也给我们看看吗?
-
首先,转置所有文件。所以每一行都变成了列。然后开始一个接一个地追加文件。之后,转置你的大文件,所以每一列都变成了行。瞧,您已经根据需要合并了文件
-
我已经明确了我的问题...我的问题是我无法一次将所有 csv 文件读入 R,因此速度很慢。