将具有NULL子元素的R列表转换为数据帧

时间:2015-06-08 09:36:12

标签: r dataframe

说我有一个列表

> str(lll)
List of 2
 $ :List of 3
  ..$ Name : chr "Sghokbt"
  ..$ Title: NULL
  ..$ Value: int 7
 $ :List of 3
  ..$ Name : chr "Sgnglio"
  ..$ Title: chr "Mr"
  ..$ Value: num 5

如何将此列表转换为数据框,如下所示?

> df
     Name Title Value
1 Sghokbt  <NA>     7
2 Sgnglio    Mr     5

as.data.frame不起作用,我怀疑是由于第一个列表元素中的NULL编辑:我也按照另一个问题的建议尝试了do.call(rbind, list),但结果是列表矩阵,而不是数据框。

要重现列表:

list(structure(list(Name = "Sghokbt", Title = NULL, Value = 7L), .Names = c("Name", 
"Title", "Value")), structure(list(Name = "Sgnglio", Title = "Mr", 
    Value = 5), .Names = c("Name", "Title", "Value")))

2 个答案:

答案 0 :(得分:0)

我想我自己找到了解决方案。

我的方法是首先将所有子列表转换为数据帧,因此我有一个数据帧列表而不是列表列表。这些数据框只会丢弃NULL个变量。

ldf <- lapply(lll, function(x) {
  nonnull <- sapply(x, typeof)!="NULL"  # find all NULLs to omit
  do.call(data.frame, c(x[nonnull], stringsAsFactors=FALSE))
})

结果数据帧列表:

> str(ldf)
List of 2
 $ :'data.frame':   1 obs. of  2 variables:
  ..$ Name : chr "Sghokbt"
  ..$ Value: int 7
 $ :'data.frame':   1 obs. of  3 variables:
  ..$ Name : chr "Sgnglio"
  ..$ Title: chr "Mr"
  ..$ Value: num 5

从这里我得到plyr的一些帮助。

require(plyr)
df <- ldply(ldf)

结果列没有乱序,但我很高兴。

> str(df)
'data.frame':   2 obs. of  3 variables:
 $ Name : chr  "Sghokbt" "Sgnglio"
 $ Value: num  7 5
 $ Title: chr  NA "Mr"

如果有更好的解决方案,我现在不会接受这个答案。

答案 1 :(得分:-1)

data.frame(do.call(rbind, lll))
     Name Title Value
1 Sghokbt  NULL     7
2 Sgnglio    Mr     5 

do.call非常有用,因为它接受列表作为参数。它将执行函数rbind,它通过观察结合列表观察。 data.frame根据需要构造输出。缺点是因为数据框架也接受列表,新对象将保留列表属性,并且难以对元素执行计算。下面是另一种选择,但也可能存在问题。

首先删除NULL值:

null.remove <- function(lst) {
  lapply(lst, function(x) {x <- paste(x, ""); x})
}

newlist <- lapply(lll, null.remove)
asvec <- unlist(newlist)
col.length <- length(newlist[[1]])
data.frame(rbind(asvec[1:col.length], 
                 asvec[(col.length+1):length(asvec)]))
      Name Title Value
1 Sghokbt           7 
2 Sgnglio    Mr     5 

'data.frame':   2 obs. of  3 variables:
 $ Name : Factor w/ 2 levels "Sghokbt ","Sgnglio ": 1 2
 $ Title: Factor w/ 2 levels " ","Mr ": 1 2
 $ Value: Factor w/ 2 levels "5 ","7 ": 2 1

此方法通过将空格粘贴到现有对象上,将值强制转换为列表中的NULL元素。下一个unlist允许将列表元素视为命名向量。 col.length注意到在新数据框中使用了多少变量。最后一个函数调用通过使用col.length值来分割矢量来创建数据框。

这仍然是一个中间结果。在进行常规数据帧操作之前,必须从因子中修剪额外空间。还必须将数字强制转换为班级numeric

当我有另一次机会更新时,我可以继续这个过程。