我有一个列表,其中每个元素都是一个命名列表,但元素在各处都不相同。我已阅读有关如何将列表列表转换为数据框的解决方案 here和 here ,但是当列表不相同时,这些都不起作用。
示例 - 注意我也有混合类型,如果解决方案强制所有内容都可以。
lisnotOK <- list(list(a=1, b=2, c="hi"), list(b=2, c="hello", d="nope"))
结果应该只是 NA 列不能被列表填充,就像
rbind.fill
来自 plyr,或 rbind_all
来自 dplyr。例子
lisOK <- list(list(a=1, b=2, c="hi"), list(a=3, b=5, c="bye"))
# One of many solutions
do.call(rbind.data.frame, lisOK)
# gives
a b c
2 1 2 hi
21 3 5 bye
任何使用
rbind
的解决方案, 或尝试制作 lisnotOK
进入矩阵将失败,而上面链接的帖子中的任何示例都不起作用,即使我尝试使用 rbind_all
或 rbind.fill
.一种解决方案是丑陋的 for 循环,其中每个连续列表都更改为数据帧,并使用
rbind_all
绑定(bind)到数据框。有谁知道有效的解决方案?
最佳答案
任何使用 data.frame(.)
的函数在绑定(bind)之前在列表的每个元素上都将非常低效(更不用说不必要了)。这是使用 data.table
的另一种方式的rbindlist
(从 v1.9.3 开始),您可以获得 here .
require(data.table) ## 1.9.3
rbindlist(lisnotOK, fill=TRUE)
# a b c d
# 1: 1 2 hi NA
# 2: NA 2 hello nope
它适用于列表列表(如在这个问题中)、data.frames 和 data.tables。
如果不是这个,那么我会选择 Ananda 的
list2mat
功能(如果您的类型都相同)。Ananda 的基准
L2
数据:fun1 <- function(inList) ldply(inList, as.data.frame)
fun2 <- function(inList) list2mat(inList)
fun3 <- function(inList) rbindlist(inList, fill=TRUE)
fun4 <- function(inList) rbind_all(lapply(inList, as.data.frame))
microbenchmark(fun1(L2), fun2(L2), fun3(L2), fun4(L2), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1(L2) 1927.857847 2161.432665 2221.999940 2276.241366 2366.649614 10
# fun2(L2) 12.039652 12.167613 12.361629 12.483751 16.040885 10
# fun3(L2) 1.225929 1.374395 1.473621 1.510876 1.858597 10
# fun4(L2) 1435.153576 1457.053482 1492.334965 1548.547706 1630.443430 10
注意:我用过
as.data.frame(.)
而不是 data.frame(.)
(前者稍快)。
关于r - 如何将列表列表转换为数据框 - 不相同的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24609112/