You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:26:09