如何用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
相关产品推荐
相关产品推荐

