【问题标题】:Read in and merge many CSV files into data.table读入多个 CSV 文件并将其合并到 data.table
【发布时间】:2016-02-26 14:31:45
【问题描述】:

我有许多 .csv 文件,包含相同“人口”的变量,由 surnamefirst.name 键入。 所以每个csv 都有三列:名字、姓氏和感兴趣的变量。 我将它们中的每一个加载到单独的数据表中,然后我想将它们合并。

library(data.table)
surnames <- c('A', 'B')
first.names <- c('C', 'D')
weights <- c(80, 90)
heights <- c(180, 190)

write.csv(data.frame(surname = surnames, first.name = first.names, 
                     height = heights), file = 'variable-height.csv')
write.csv(data.frame(surname = surnames, first.name = first.names,  
                     weight = weights), file = 'variable-weight.csv')

variables.to.load <- c('height', 'weight')
for (i in variables.to.load) {
assign(paste0('DT.', i), fread(paste0('variable-', i, '.csv')))
print(dim(eval(parse(text = paste0('DT.', i)))))
setkey(eval(parse(text = paste0('DT.', i))), surname, first.name)
}

加载它们并正确设置键。 不过,我缺少的是自动合并。

DT.merged <- Reduce(merge, list(DT.height, DT.weight))

有效,但我想以自动方式进行,因为实际变量更多。也就是我想自动写list():DT.height,DT.weight等的内容。

我试过了:

library('stringr')
DT.merged <- Reduce(merge, list(eval(parse(text = str_c(paste0('DT.', variables.to.load), collapse = ', ')))))

没有结果。

我完成了整个过程,因为我想为我的人口有选择地使用不同的变量(总计超过 30GB 和大约 30 个变量的 csv)。所以在完整的csv 上使用fread 来选择性地读取列似乎相当慢。

【问题讨论】:

  • 重复一遍:“在我们成为 R 专家并需要它之前,我们不会使用 assign,因为我们使用的是环境”。 fread 将文件放入list(最简单的lapply)。然后您可以在该列表中使用Reduce
  • 一开始你说你有很多 CSV 文件要阅读,但最后你似乎暗示你可以打开其他包含所有列的文件,这将消除其中的棘手部分你正在尝试做。几乎不可能打开大量 CSV 文件并合并它们,而不是打开一个包含所有数据的 csv 文件。
  • 你是不是偶然在寻找freadselect参数?
  • @DeanMacGregor 你是对的。我没有正确解释这一点。我这样做是因为在我的分析过程中,我想为我的 DT 添加和删除列/变量,以提高我可怜的笔记本电脑的内存效率,因为原来的“合并”.csv 大约是 35Gb。因此,正如@Roland 建议的那样,如果我只需要阅读一列,在fread 中使用非常有用的select 也会变慢。
  • @Roland 在assign 评论:) 是的,使用列表确实是诀窍!谢谢!

标签: r csv data.table eval


【解决方案1】:

这应该适用于您的问题

DTlist <- lapply(paste0('variable-', variables.to.load, '.csv'), 
    function(x) {
       d <- fread(x) 
       setkey(d, surname, first.name)
       d
     }
   )
DT.merged <- Reduce(merge, DT)

话虽如此,正如 Roland 和我在 cmets 中提到的那样,如果您可以访问包含所有所需数据的单个 CSV 文件,这不太可能是最佳方法。

如果您确实有权访问此类文件,则最好使用freadselect 参数

DT <- fread('master.csv', select=c(variables.to.load))

【讨论】:

  • 谢谢!网络迷们注意:{ 之前应该有第二个括号:for(i in 1:length(variables.to.load)) {fread 之后应该少一个括号:variables.to.load[i], '.csv'))
  • 只需使用DTlist &lt;- lapply(paste0('variable-', variables.to.load, '.csv'), function(x) {d &lt;- fread(x), setkey(d, surname, first.name); d}); DT.merged &lt;- Reduce(merge, DTlist)
  • @Roland 我根据您的建议进行了编辑。我知道每个人都讨厌forR 中循环,所以我相信这看起来会更好。我试图让建议看起来像 OP 已经拥有的那样。
  • @pidosaurus 我相信我也修正了括号。
  • 如果您不需要返回值,for 循环很有用。
猜你喜欢
  • 2020-02-05
  • 2019-10-05
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2015-05-23
相关资源
最近更新 更多