从列表中逐行构建数据框

时间:2014-06-22 19:59:35

标签: json r dataframe

我正在解析R中的数据结构:

[
  { 'firstName': 'abc', 'lastName' : 'def' },
  { 'firstName': 'abc2', 'lastName' : 'def2' }
]

我想将这些数据存储在数据框中。我目前的做法存在缺陷,感觉非常混乱。我有几个数据集,但需要指定列。任何人都可以提出“清洁”的建议吗?

问题1:我需要指定数据名称

library(rjson)
listData <- fromJSON(jsonData)
listNames <- c('firstName', 'lastName')

for (player in listData){
  playerCols = c()
  for (name in listNames){
    value <- player[[name]]
    if (is.null(value}{value <- "NA"}
    playerCols <- c(playerCols, value)
  }
  # code to convert playerCols to data.frame currently goes here. 
}

如果可能的话,我想在不使用列名的情况下运行此提取,或者以这种方式从我提取的数据中提取列。这里棘手的部分是并非所有列都填充在每个条目中。我希望最终数据框能够知道所有列并将缺失值设置为NA

问题2:我似乎无法添加一行数据,而是将列表创建为列

for (player in listData){
  # code to extract columns here
  df = data.frame(playerCols, name=listNames)
  print(df)
}

我没有创建包含所有数据和所有名称的行的2列数据框,而是想要一个带有命名列的行,然后我可以rbind一起。

1 个答案:

答案 0 :(得分:3)

尝试逐行构建data.frame几乎总是一个坏主意。这不是一个有效的过程。最好逐列构建数据列,最后组合成data.frame。首先,让我们使用一些实际上具有缺失值的样本数据

a<-'[
  { "firstName": "abc", "lastName" : "def" },
  { "firstName": "abc2" }
]'

让我们构建一个辅助函数,如果它存在,将从列表中提取一个值,如果不存在则返回NA

extr<-function(list,ele) {
    x<-list[[ele]]
    if (is.null(x)) x=NA;
    x
}

如果您想要获取所有值而无需明确指定标记名称,可以使用

找到它们
listNames <- unique(unlist(lapply(listData, names)))

现在我们可以将json转换为列表,然后每次提取一列列值,然后最终将它们组合成一个data.frame with

listData <- fromJSON(a)
data.frame(Map(function(n) sapply(listData, extr, n), listNames))

我在这里使用Map而不是更习惯的lapply,因为它会正确使用listNames的值作为返回列表的名称。