1

我想从列表中的列表形成一个 data.frame

L1 <- list(A = c(1, 2, 3), B = c(5, 6, 7))
L2 <- list(A = c(11, 22, 33), B = c(15, 16, 17))
L3 <- list(L1, L2)
L3

library(data.table)

根据'data.table'手册:“'rbindlist'与do.call(“rbind”,l)相同,但要快得多“

我想使用 R 基础包来实现“rbindlist”的功能

rbindlist 完全符合我的需要,但 'do.call' 没有!

rbindlist(L3)

do.call 没有做我想做的事

do.call(rbind, L3)

identical(rbindlist(L3), do.call(rbind, L3))
4

2 回答 2

5

我认为as.data.frame每次打电话可能会很昂贵。怎么样?

as.data.frame(do.call(mapply, c(L3, FUN=c, SIMPLIFY=FALSE)))

mapply基本上采用 L3 的第一个元素并应用 function FUN,然后是第二个元素等等......假设你有两个列表(L3[[1]]L3[[2]]),那么你会这样做:

mapply(FUN=c, L3[[1]], L3[[2]], SIMPLIFY=FALSE)

此处SIMPLIFY=FALSE确保输出未转换(或简化)为矩阵。因此它将是一个列表。对于一般情况,我们使用do.call并将列表与所有其他参数一起传递给 function mapply。希望这可以帮助。


大数据基准测试:

ll <- unlist(replicate(1e3, L3, simplify=FALSE), rec=FALSE)

aa <- function() as.data.frame(do.call(mapply, c(ll, FUN=c, SIMPLIFY=FALSE)))
bb <- function() do.call(rbind, lapply(ll, as.data.frame))

require(microbenchmark)
microbenchmark(o1 <- aa(), o2 <- bb(), times=10)

Unit: milliseconds
       expr        min         lq     median         uq      max neval
 o1 <- aa()   4.356838   4.931118   5.462995   7.623445  20.5797    10
 o2 <- bb() 673.773795 683.754535 701.557972 710.535860 724.2267    10

identical(o1, o2) # [1] TRUE
于 2013-08-28T13:19:10.087 回答
3

您需要先将子列表转换L3data.frames:

> do.call(rbind, lapply(L3, as.data.frame))
   A  B
1  1  5
2  2  6
3  3  7
4 11 15
5 22 16
6 33 17
于 2013-08-28T12:35:18.827 回答