如何在R中将嵌套列表转换为分组行数据框?
将嵌套列表转换为分组数据框的方法
原始数据
给定的嵌套列表dput代码:
l <- list(A = list(`1` = c(1, 2, 3), `2` = c(3, 2, 1)), B = list(`1` = c(2, 2, 2), `2` = c(3, 4, 3)))
其结构输出为:
> l $A $A$`1` [1] 1 2 3 $A$`2` [1] 3 2 1 $B $B$`1` [1] 2 2 2 $B$`2` [1] 3 4 3
需求目标
需要将上述嵌套列表转换为包含三列的分组数据框:
group:对应外层列表的名称(A、B)subgroup:对应内层列表的名称(1、2)values:将每个子列表中的向量展开为单独行
目标输出示例:
group subgroup values 1 A 1 1 2 A 1 2 3 A 1 3 4 A 2 3 5 A 2 2 6 A 2 1 7 B 1 2 8 B 1 2 9 B 1 2 10 B 2 3 11 B 2 4 12 B 2 3
解决方案
方法1:tidyverse简洁实现
利用tidyr::enframe将列表转为数据框,再通过两次unnest_longer完成层级展开:
library(tidyverse) df <- enframe(l, name = "group", value = "subgroup_list") %>% # 展开内层子列表,将子列表名称存入subgroup列 unnest_longer(subgroup_list, indices_to = "subgroup") %>% # 展开数值向量为单独行 unnest_longer(subgroup_list) %>% # 重命名列名 rename(values = subgroup_list) # 查看结果 df
方法2:base R原生实现
通过嵌套循环遍历列表层级,收集每行数据后合并为数据框:
# 初始化空列表存储每行数据 result_rows <- list() row_num <- 1 # 遍历外层分组 for (group_name in names(l)) { subgroup_data <- l[[group_name]] # 遍历子分组 for (subgroup_name in names(subgroup_data)) { values_vec <- subgroup_data[[subgroup_name]] # 为每个数值生成一行数据 for (val in values_vec) { result_rows[[row_num]] <- data.frame( group = group_name, subgroup = subgroup_name, values = val, stringsAsFactors = FALSE ) row_num <- row_num + 1 } } } # 合并所有行并重置行名 df <- do.call(rbind, result_rows) rownames(df) <- NULL # 查看结果 df
方法3:data.table高效实现
适合处理大规模数据,通过嵌套lapply结合rbindlist快速拼接:
library(data.table) dt <- rbindlist( lapply(names(l), function(group) { rbindlist( lapply(names(l[[group]]), function(subgroup) { data.table( group = group, subgroup = subgroup, values = l[[group]][[subgroup]] ) }) ) }) ) # 查看结果 dt
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

