Convert R list to dataframe with missing/NULL elem

2019-01-17 21:57发布

Given a list:

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

what's the best way to convert this into a dataframe with name and age columns, with missing values (I'll accept NA or "" in that order of preference)?

Simple methods using ldply fail because it tries to convert each list element into a data frame, but the one with the NULL barfs because the lengths don't match. Best I have at the moment is:

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

but that's pretty icky and the numeric variable becomes a factor...

2条回答
啃猪蹄的小仙女
2楼-- · 2019-01-17 22:05

Step1: remove NULL items

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

Step2: stack everything together:

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

Edit: In case you had a variable that is NULL for all your list items, it would not show up in your final output. If instead, you'd like a column filled with NA, the first step should not remove NULLs but replace them with NAs:

Step 1 alternative: replace NULL with NA:

non.null.list <- lapply(alist, lapply, function(x)ifelse(is.null(x), NA, x))
查看更多
欢心
3楼-- · 2019-01-17 22:06

A comment mentioned wanting only a single loop, which can be achieved with @flodel's answer just by putting the body of the two loops together:

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

giving

  name age
1  Foo  22
2  Bar  NA
3  Baz  NA
查看更多
登录 后发表回答