19

给定一个列表:

alist = list(
  list(name="Foo",age=22),
  list(name="Bar"),
  list(name="Baz",age=NULL)
 )

将其转换为具有名称和年龄列且缺少值的数据框的最佳方法是什么(我将按优先顺序接受 NA 或“”)?

使用失败的简单方法ldply是因为它尝试将每个列表元素转换为数据框,但由于长度不匹配,所以使用 NULL barfs 的那个。我目前最好的是:

> ldply(alist,function(s){t(data.frame(unlist(s)))})
  name  age
1  Foo   22
2  Bar <NA>
3  Baz <NA>

但这很恶心,数字变量成为一个因素......

4

2 回答 2

18

Step1:删除NULL项目

non.null.list <- lapply(alist, Filter, f = Negate(is.null))

Step2:将所有内容堆叠在一起:

library(plyr)
rbind.fill(lapply(non.null.list, as.data.frame))
#   name age
# 1  Foo  22
# 2  Bar  NA
# 3  Baz  NA

编辑:如果您有一个NULL适用于所有列表项的变量,它不会出现在您的最终输出中。相反,如果您想要一个用 填充的列NA,则第一步不应该删除NULLs,而是用 s 替换它们NA

第 1 步替代方案:替换NULLNA

non.null.list <- lapply(alist, lapply, function(x)ifelse(is.null(x), NA, x))
于 2013-04-03T17:22:24.983 回答
10

提到只需要一个循环的评论,只需将两个循环的主体放在一起,就可以通过@flodel 的回答来实现:

rbind.fill(lapply(alist, function(f) {
  as.data.frame(Filter(Negate(is.null), f))
}))

给予

  name age
1  Foo  22
2  Bar  NA
3  Baz  NA
于 2013-04-03T21:06:15.187 回答