rbinding data.table 列表的列表
rbinding a list of list of data.table
这听起来很愚蠢,但我有一个 data.table
的清单列表
list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
我想rbind
每个tableX
在一起,和return一个列表data.table
,即
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2)))
在现实世界的场景中,输入将是一个包含数千个列表的列表,每个列表有数十个 data.table
s,每个列表有数百列,因此硬编码不是一种选择。
它可能不是最优雅或最有效的解决方案,但我的建议是首先为给定数字 X
创建一个仅包含 tableX
的列表。然后在此列表上执行 rbind
,并将输出放入正确索引的新列表中。您可能需要根据实际数据的具体情况进行修改——我假设列表中的每个列表都有每个 tableX,并且它们是有序的。
见下文:
library(data.table)
library(testthat)
dt.list <- list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
dt.output <-
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2)))
# Extract number of tableX's -- assuming same number in each list element.
mylist <- vector(mode = "list", length = length(dt.list[[1]]))
for (li in seq(length(mylist))) {
# Extract tableXs, put into list.
list.tableX <- lapply(dt.list, function(x) {
return(x[[li]])
})
# Use rbind to put together
mylist[[li]] <- do.call("rbind", list.tableX)
names(mylist)[li] <- paste0("table", li)
}
testthat::expect_identical(dt.output, mylist)
一个选择是先purrr::transpose
你的列表,然后使用rbindlist
和Map
out <- Map(data.table::rbindlist, purrr::transpose(l))
检查输出
identical(out,
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2))))
#[1] TRUE
数据
l <- list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
考虑使用具有提取功能的基础 R 应用系列解决方案,[[
:
table_names <- unlist(unique(lapply(my_original_list, names)))
final_list <- sapply(table_names, function(t)
rbindlist(lapply(my_original_list, `[[`, t)),
simplify=FALSE)
final_list
我的第一个想法是先 transpose
,但转置的计算量可能很大。可以简洁地使用 purrr::map_dfr
:
的正常索引
library(purrr)
map(1:2, ~ map_dfr(l, .))
这是一个基本解决方案(data.table 和 rbindlist
)
library(data.table)
apply(simplify2array(lst), 1, rbindlist)
结果与预期相同:
identical(list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2))),
apply(simplify2array(lst), 1, rbindlist))
# [1] TRUE
这听起来很愚蠢,但我有一个 data.table
的清单列表
list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
我想rbind
每个tableX
在一起,和return一个列表data.table
,即
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2)))
在现实世界的场景中,输入将是一个包含数千个列表的列表,每个列表有数十个 data.table
s,每个列表有数百列,因此硬编码不是一种选择。
它可能不是最优雅或最有效的解决方案,但我的建议是首先为给定数字 X
创建一个仅包含 tableX
的列表。然后在此列表上执行 rbind
,并将输出放入正确索引的新列表中。您可能需要根据实际数据的具体情况进行修改——我假设列表中的每个列表都有每个 tableX,并且它们是有序的。
见下文:
library(data.table)
library(testthat)
dt.list <- list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
dt.output <-
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2)))
# Extract number of tableX's -- assuming same number in each list element.
mylist <- vector(mode = "list", length = length(dt.list[[1]]))
for (li in seq(length(mylist))) {
# Extract tableXs, put into list.
list.tableX <- lapply(dt.list, function(x) {
return(x[[li]])
})
# Use rbind to put together
mylist[[li]] <- do.call("rbind", list.tableX)
names(mylist)[li] <- paste0("table", li)
}
testthat::expect_identical(dt.output, mylist)
一个选择是先purrr::transpose
你的列表,然后使用rbindlist
和Map
out <- Map(data.table::rbindlist, purrr::transpose(l))
检查输出
identical(out,
list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2))))
#[1] TRUE
数据
l <- list(list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)),
list(table1=data.table(A1=-1:3, B1=-2:2),
table2=data.table(A2=-3:1, B2=-4:0)),
list(table1=data.table(A1=1:3, B1=2:4),
table2=data.table(A2=3:1, B2=4:2)))
考虑使用具有提取功能的基础 R 应用系列解决方案,[[
:
table_names <- unlist(unique(lapply(my_original_list, names)))
final_list <- sapply(table_names, function(t)
rbindlist(lapply(my_original_list, `[[`, t)),
simplify=FALSE)
final_list
我的第一个想法是先 transpose
,但转置的计算量可能很大。可以简洁地使用 purrr::map_dfr
:
library(purrr)
map(1:2, ~ map_dfr(l, .))
这是一个基本解决方案(data.table 和 rbindlist
)
library(data.table)
apply(simplify2array(lst), 1, rbindlist)
结果与预期相同:
identical(list(table1=data.table(A1=c(1:3, -1:3, 1:3), B1=c(2:4, -2:2, 2:4)),
table2=data.table(A2=c(3:1, -3:1, 3:1), B2=c(4:2, -4:0, 4:2))),
apply(simplify2array(lst), 1, rbindlist))
# [1] TRUE