将结构一致的JSON数据读取为R语言DataFrame的问题
将嵌套列表转换为常规R DataFrame的解决方案
问题说明
需要把结构一致的嵌套列表(如下方test数据)转成可直接使用的常规R DataFrame。用df <- data.frame(Reduce(rbind, test))得到的结果中,每一列都是嵌套列表,无法正常分析使用。
给定的嵌套列表数据
test <- list( `0` = list(Code = "A", Name = "Agilent Technologies Inc", StartDate = "2000-06-05", EndDate = NULL, IsActiveNow = 1, IsDelisted = 0), `1` = list(Code = "AAL", Name = "American Airlines Group", StartDate = "2015-03-23", EndDate = "2024-09-23", IsActiveNow = 0, IsDelisted = 0), `2` = list(Code = "AAP", Name = "Advance Auto Parts Inc", StartDate = "2015-07-09", EndDate = "2023-08-25", IsActiveNow = 0, IsDelisted = 0), `3` = list(Code = "AAPL", Name = "Apple Inc", StartDate = "1982-11-30", EndDate = NULL, IsActiveNow = 1, IsDelisted = 0), `4` = list(Code = "ABBV", Name = "AbbVie Inc", StartDate = "2013-01-02", EndDate = NULL, IsActiveNow = 1, IsDelisted = 0) )
错误方法得到的嵌套结构
用Reduce(rbind, test)生成的DataFrame结构如下,所有列都是嵌套列表:
str(df) # 'data.frame': 5 obs. of 6 variables: # $ Code :List of 5 # ..$ init: chr "A" # ..$ : chr "AAL" # ..$ : chr "AAP" # ..$ : chr "AAPL" # ..$ : chr "ABBV" # $ Name :List of 5 # ..$ init: chr "Agilent Technologies Inc" # ..$ : chr "American Airlines Group" # ..$ : chr "Advance Auto Parts Inc" # ..$ : chr "Apple Inc" # ..$ : chr "AbbVie Inc" # $ StartDate :List of 5 # ..$ init: chr "2000-06-05" # ..$ : chr "2015-03-23" # ..$ : chr "2015-07-09" # ..$ : chr "1982-11-30" # ..$ : chr "2013-01-02" # $ EndDate :List of 5 # ..$ init: NULL # ..$ : chr "2024-09-23" # ..$ : chr "2023-08-25" # ..$ : NULL # ..$ : NULL # $ IsActiveNow:List of 5 # ..$ init: num 1 # ..$ : num 0 # ..$ : num 0 # ..$ : num 1 # ..$ : num 1 # $ IsDelisted :List of 5 # ..$ init: num 0 # ..$ : num 0 # ..$ : num 0 # ..$ : num 0 # ..$ : num 0
可行解决方案
方法1:用purrr+dplyr(推荐,代码简洁)
先安装并加载tidyverse包(包含purrr和dplyr):
install.packages("tidyverse") library(tidyverse)
直接将嵌套列表转为标准DataFrame,自动把NULL转为NA:
df <- map_dfr(test, as.data.frame)
查看转换后的结构:
str(df) # 'data.frame': 5 obs. of 6 variables: # $ Code : chr "A" "AAL" "AAP" "AAPL" "ABBV" # $ Name : chr "Agilent Technologies Inc" "American Airlines Group" "Advance Auto Parts Inc" "Apple Inc" ... # $ StartDate : chr "2000-06-05" "2015-03-23" "2015-07-09" "1982-11-30" ... # $ EndDate : chr NA "2024-09-23" "2023-08-25" NA ... # $ IsActiveNow: num 1 0 0 1 1 # $ IsDelisted : num 0 0 0 0 0
方法2:基础R实现(无需额外包)
如果不想加载第三方包,可以用do.call+lapply组合直接转换原始嵌套列表:
df <- do.call(rbind, lapply(test, as.data.frame))
要是已经生成了嵌套列的DataFrame,也可以逐个展开列:
# 针对已有的嵌套列DataFrame df_clean <- data.frame(lapply(df, function(col) sapply(col, function(x) if(is.null(x)) NA else x)))
方法3:用data.table(适合大数据量)
data.table的rbindlist处理嵌套列表效率更高,适合数据量大的场景:
install.packages("data.table") library(data.table) # 转换为data.table,fill=TRUE自动补全缺失值 df <- rbindlist(test, fill = TRUE) # 可选:转为普通DataFrame df <- as.data.frame(df)
内容的提问来源于stack exchange,提问作者JohnS
相关产品推荐
相关产品推荐

