当某些元素为空时重命名嵌套列表

标签 r purrr

如何使用 purrr 重命名可能有值或没有值的嵌套列表?我尝试了 modify_at() 但如果其中一个列表为空,则会出现错误

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 = list(id = 678, name = "abc")   # <--- works
    # tag = NULL                           # <--- doesn't work

    )
  ) 

我希望 app$idapp$name 成为 app_idapp_name 并最终返回数据框架

| app_id | app_name | tag_id | tag_name |
|--------|----------|--------|----------|
|    123 |      abc |    456 |      def |
|    345 |      xyz |        |          |

如果两个应用都有标签,则此示例有效,但如果任何标签为 null(切换上面的注释),则 modify_at("tag") 步骤将失败

my_list |> 
  map(
    ~.x |> 
      modify_at("app", ~set_names(.x, glue("app_{names(.x)}"))) |> 
      modify_at("tag", ~set_names(.x, glue("tag_{names(.x)}"))) |> 
      as.data.frame() |>   # also why doesn't as_tibble() work here?
      rename_all(str_replace_all, "\\.", "_")
  ) |> 
  list_rbind()

具体来说,在这里:

my_list |> 
  map(
    ~modify_at(.x, "tag",  ~set_names(.x, glue("tag_{names(.x)}")))
  )
# Error in `map()`:
#   ℹ In index: 2.
# Caused by error in `map()`:
#   ℹ In index: 1.
# ℹ With name: tag.
# Caused by error in `set_names()`:
#   ! `x` must be a vector

我在 GitHub 上找到了 this issue 但仍然存在问题

最佳答案

这是一个具有自定义函数的解决方案:

通过此函数,我们通过将 NULL 元素替换为 NA 元素列表来处理它们。然后,我们使用 map_vec 将列表转换为数据框。


library(tidyverse)

my_func <- function(list, prefix) {
  if(is.null(list)) {
    list <- list(id = NA, name = NA)
  }
  set_names(list, paste0(prefix, "_", names(list)))
}

my_list |> 
  map(
    ~ list(
      app = my_func(.x$app, "app"),
      tag = my_func(.x$tag, "tag")
    )
  ) |> 
  map_vec(
    ~ bind_cols(.x$app, .x$tag)
  )

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

关于当某些元素为空时重命名嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76853820/

相关文章:

r - 映射列表,获取项目名称和内容

r - 使用 purrr::map 进行递归函数调用

r - 部分虚线ggplot

将列重命名为 Y X1 X2 X3 X4 .. XN

r - 在 R 中对 ARIMA AIC 进行排序

r - 将嵌套列表展平为 1-deep 列表

将共享数据列中的多个值重新编码/替换为跨数据帧的单个值

r - 有没有办法抑制 R 中 tbl_regression 函数中的 p 值?

在嵌套的 tibble 上使用 select 时保留嵌套变量

r - 通过自定义函数在循环中创建一个新的均值列