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

如何用purrr重命名含空元素的嵌套列表并转为数据框

问题解决:处理含NULL的嵌套列表并转换为数据框

一、报错原因与解决

当tag为NULL时,modify_at会尝试对NULL执行set_names,但set_names要求输入必须是向量或非空列表,因此触发报错。解决思路是:处理tag时先判断是否为NULL,如果是则生成包含tag_id和tag_name为NA的列表,否则再重命名。

二、as_tibble()无法替代as.data.frame()的原因

as.data.frame()会自动递归展开嵌套列表,将子列表的元素转换为带点分隔符的列(比如app.app_id);而as_tibble()默认保留嵌套列表的结构,会把app和tag作为列表类型的列,不会自动展开。如果想用as_tibble(),需要先调用flatten()扁平化列表,再转换为 tibble。

三、完整可行代码

方案1:使用as.data.frame()的版本

library(tidyverse)

my_list <- 
  list(
    list(
      app = list(id = 123, name = "abc"), 
      tag = list(id = 456, name = "def")
    ),
    list(
      app = list(id = 345, name = "xyz"), 
      tag = NULL
    )
  ) 

result <- my_list |> 
  map(
    ~ .x |> 
      modify_at("app", ~set_names(.x, glue("app_{names(.x)}"))) |> 
      # 处理NULL的tag,生成带NA的列表
      modify_at("tag", ~if (is.null(.x)) list(tag_id = NA, tag_name = NA) else set_names(.x, glue("tag_{names(.x)}"))) |> 
      as.data.frame() |> 
      rename_all(str_replace_all, "\\.", "_")
  ) |> 
  list_rbind()

print(result)

方案2:使用as_tibble()的版本

result_tibble <- my_list |> 
  map(
    ~ .x |> 
      modify_at("app", ~set_names(.x, glue("app_{names(.x)}"))) |> 
      modify_at("tag", ~if (is.null(.x)) list(tag_id = NA, tag_name = NA) else set_names(.x, glue("tag_{names(.x)}"))) |> 
      flatten() |> # 扁平化嵌套列表
      as_tibble()
  ) |> 
  list_rbind()

print(result_tibble)

运行后两种方案都会得到如下结果:

app_id app_name tag_id tag_name
1    123      abc    456      def
2    345      xyz     NA     <NA>

内容的提问来源于stack exchange,提问作者yake84

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:23:18