说我有以下列表:
X = list(data.table(1:2,3:4,5:6),
data.table(letters[1:2], letters[3:4]))
我想将列的元素按列绑定到单个data.table中。 输出与
产生的输出相同do.call(cbind, X)
但是,由于我的原始列表和包含数据表非常大,如果我可以通过引用来完成此操作会更好,而不是使用cbind()
复制整个对象。有办法吗?像rbindlist()
等同于按列绑定的东西,我已经看到这标记为待办事项......
如果这个简单的问题已经在其他地方得到解答,我会道歉并且我错过了答案。
答案 0 :(得分:5)
bind_cols
dplyr
与do.call(cbind
相比似乎效率更高,并且返回data.table
library(dplyr)
bind_cols(X)
# V1 V2 V3 V11 V21
#1: 1 3 5 a c
#2: 2 4 6 b d
set.seed(24)
X1 <- lapply(1:10, function(i)
as.data.table(matrix(sample(1:9, 1e5*1e3, replace = TRUE), nrow = 1e5, ncol = 1e3)))
system.time({
bind_cols(X1)
})
#user system elapsed
# 0.01 0.00 0.02
system.time({
do.call(cbind, X1)
})
#user system elapsed
# 2.22 37.84 40.93
system.time({
setDT(unlist(X1, recursive = FALSE), check.names = TRUE)
})
# user system elapsed
# 0.05 0.00 0.05
或check.names = FALSE
system.time({
setDT(unlist(X1, recursive = FALSE), check.names = FALSE)
})
# user system elapsed
# 0.01 0.00 0.02
同样基于@ MichaelChirico的测试示例数据
set.seed(24)
NN <- 1e6
L <- lapply(integer(20L), function(ii) {
setDT(lapply(integer(sample(15L, 1L)), function(x) rnorm(NN))) })
system.time({
bind_cols(L)
})
# user system elapsed
# 0 0 0
system.time({
do.call(cbind, L)
})
# user system elapsed
# 0.44 0.53 0.97
system.time({
base = L[[1L]]
jj = ncol(base) + 1L
for (ii in 2L:length(L)) {
for (col_j in seq_len(ncol(L[[ii]]))) {
set(base, , sprintf('V%d', jj), L[[ii]][[col_j]])
jj = jj + 1L
}
}
})
#user system elapsed
# 0.12 0.33 0.46
并使用@ MichaelChirico的更新方法
system.time({
setDT(unlist(L, recursive = FALSE), check.names = TRUE)
})
# user system elapsed
# 0 0 0
答案 1 :(得分:4)
以下情况如何?
# check.names = TRUE forces unique names on the output
setDT(unlist(X, recursive = FALSE), check.names = TRUE)[]
# V1 V2 V3 V4 V5
# 1: 1 3 5 a c
# 2: 2 4 6 b d