gpt4 book ai didi

r - rbind data.frames 与不同列的有效方法

转载 作者:行者123 更新时间:2023-12-03 09:04:22 25 4
gpt4 key购买 nike

我有一个包含不同列集的数据框列表。我想将它们按行组合成一个数据框。我用 plyr::rbind.fill要做到这一点。我正在寻找可以更有效地做到这一点的东西,但类似于给出的答案 here

require(plyr)

set.seed(45)
sample.fun <- function() {
nam <- sample(LETTERS, sample(5:15))
val <- data.frame(matrix(sample(letters, length(nam)*10,replace=TRUE),nrow=10))
setNames(val, nam)
}
ll <- replicate(1e4, sample.fun())
rbind.fill(ll)

最佳答案

更新:this updated answer反而。
更新(eddi):现在已在 version 1.8.11 中实现。作为 fill rbind 的参数.例如:

DT1 = data.table(a = 1:2, b = 1:2)
DT2 = data.table(a = 3:4, c = 1:2)

rbind(DT1, DT2, fill = TRUE)
# a b c
#1: 1 1 NA
#2: 2 2 NA
#3: 3 NA 1
#4: 4 NA 2

FR #4790现在添加 - rbind.fill(来自 plyr),类似于合并 data.frames/data.tables 列表的功能
注1:
此解决方案使用 data.tablerbindlist用于“rbind”data.tables 列表的函数,为此, 请务必使用 1.8.9 版本,因为 this bug在版本 < 1.8.9 .
笔记2: rbindlist当绑定(bind) data.frames/data.tables 列表时,截至目前,将保留第一列的数据类型。也就是说,如果第一个 data.frame 中的列是字符,并且第二个 data.frame 中的同一列是“因子”,那么 rbindlist将导致该列成为一个字符。因此,如果您的 data.frame 包含所有字符列,那么您使用此方法的解决方案将与 plyr 方法相同。如果不是,则值仍然相同,但某些列将是字符而不是因子。之后您必须自己转换为“因素”。 Hopefully this behaviour will change in the future .
现在这里使用 data.table (以及与 rbind.fill 的基准比较 plyr ):
require(data.table)
rbind.fill.DT <- function(ll) {
# changed sapply to lapply to return a list always
all.names <- lapply(ll, names)
unq.names <- unique(unlist(all.names))
ll.m <- rbindlist(lapply(seq_along(ll), function(x) {
tt <- ll[[x]]
setattr(tt, 'class', c('data.table', 'data.frame'))
data.table:::settruelength(tt, 0L)
invisible(alloc.col(tt))
tt[, c(unq.names[!unq.names %chin% all.names[[x]]]) := NA_character_]
setcolorder(tt, unq.names)
}))
}

rbind.fill.PLYR <- function(ll) {
rbind.fill(ll)
}

require(microbenchmark)
microbenchmark(t1 <- rbind.fill.DT(ll), t2 <- rbind.fill.PLYR(ll), times=10)
# Unit: seconds
# expr min lq median uq max neval
# t1 <- rbind.fill.DT(ll) 10.8943 11.02312 11.26374 11.34757 11.51488 10
# t2 <- rbind.fill.PLYR(ll) 121.9868 134.52107 136.41375 184.18071 347.74724 10


# for comparison change t2 to data.table
setattr(t2, 'class', c('data.table', 'data.frame'))
data.table:::settruelength(t2, 0L)
invisible(alloc.col(t2))
setcolorder(t2, unique(unlist(sapply(ll, names))))

identical(t1, t2) # [1] TRUE
需要注意的是 plyrrbind.fill超越这个特殊的 data.table解决方案,直到列表大小约为 500。
基准图:
这是带有 seq(1000, 10000, by=1000) 的 data.frames 列表长度的运行图.我用过 microbenchmark在每个不同的列表长度上重复 10 次。
enter image description here
基准测试要点:
Here's the gist for benchmarking ,以防有人想要复制结果。

关于r - rbind data.frames 与不同列的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18003717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com