我想从列表中的列表中形成一个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)
Run Code Online (Sandbox Code Playgroud)
根据'data.table'手册:"'rbindlist'与do.call("rbind",l)相同,但更快"
我想用R base包来实现'rbindlist'的功能
rbindlist正是我需要的,但'do.call'却没有!
rbindlist(L3)
Run Code Online (Sandbox Code Playgroud)
do.call没有做我想做的事
do.call(rbind, L3)
identical(rbindlist(L3), do.call(rbind, L3))
Run Code Online (Sandbox Code Playgroud)
我认为as.data.frame每次打电话费用都很高.怎么样?
as.data.frame(do.call(mapply, c(L3, FUN=c, SIMPLIFY=FALSE)))
Run Code Online (Sandbox Code Playgroud)
mapply基本上取L3的第一个元素并应用函数FUN,然后应用第二个元素等等......假设你有两个列表(L3[[1]]和L3[[2]]),那你就做:
mapply(FUN=c, L3[[1]], L3[[2]], SIMPLIFY=FALSE)
Run Code Online (Sandbox Code Playgroud)
这里SIMPLIFY=FALSE确保输出不会转换(或简化)为矩阵.因此它将是一个列表.对于一般情况,我们使用do.call并传递我们的列表以及函数的所有其他参数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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |