在R中如何从tibble::enframe转换后的线性数据框重构嵌套列表
从线性数据框重构嵌套命名列表(R语言)
当你用unlist() + tibble::enframe()把嵌套列表转成键值对数据框后,直接用deframe()只能得到单层列表,无法还原原有的嵌套结构——因为deframe()不会解析键名里的.层级分隔符。下面是针对你的示例的几种解决方法:
方法一:针对固定两层级的场景(适配你的示例)
利用tidyr拆分键名列,再分组构建嵌套列表:
library(tidyr) library(dplyr) # 拆分键名为层级列 df_split <- df %>% separate(name, into = c("level1", "level2"), sep = "\\.", remove = FALSE) # 重构嵌套列表 lst_rebuilt <- df_split %>% group_by(level1) %>% summarise(sub_list = set_names(as.list(value), level2)) %>% deframe()
验证结果:
> lst_rebuilt$vehicles$a [1] 8 > identical(lst_rebuilt, modifyList(lst, list(vehicles = list(a = 8)))) [1] TRUE
方法二:通用递归方法(支持任意嵌套层级)
如果你的嵌套列表层级不固定,可以用递归函数解析键名的层级结构,自动构建嵌套列表:
library(purrr) rebuild_nested <- function(df) { # 拆分每个键为层级向量 key_paths <- strsplit(df$name, "\\.") max_depth <- max(sapply(key_paths, length)) # 递归构建嵌套结构 build_layer <- function(depth) { # 获取当前层级的键 current_keys <- sapply(key_paths, function(path) path[depth]) # 按当前键分组处理 split(df, current_keys) %>% map(function(sub_df) { if (depth == max_depth) { # 最后一层,直接生成命名列表 set_names(sub_df$value, sapply(strsplit(sub_df$name, "\\."), function(p) p[depth])) } else { # 递归处理下一层 build_layer(depth + 1) } }) } build_layer(1) } # 调用函数重构 lst_rebuilt <- rebuild_nested(df)
关键原理
unlist()在展开嵌套列表时,会用.连接各层级的名称(比如vehicles.a)。重构的核心就是把这些带分隔符的键名拆分成层级路径,再按路径逐层组装成嵌套列表。
内容的提问来源于stack exchange,提问作者Edd
相关产品推荐
相关产品推荐

