【问题标题】:How to unnest_wider() with loop over all the columns containing lists?如何在包含列表的所有列上循环 unnest_wider()?
【发布时间】:2020-09-08 02:37:26
【问题描述】:

我有以下数据

A   B            C             D
1   1501583974   <list [3]>  <tibble>
1   1501616585   <list [3]>  <tibble>
1   1501583344   <list [3]>  <tibble>
1   1501573386   <list [3]>  <tibble>

我用过的代码

data %>%
unnest_wider(c, names_sep="_") %>%
unnest_wider(d, names_sep="_")

给出输出

    A   B            C_1  C_2 C_3  D_1         D_2   
    1   1501583974   1    2   3   <list [1]>  <list [1]>
    1   1501616585   1    2   3   <list [1]>  <list [1]>
    1   1501583344   1    2   3   <list [1]>  <list [1]>
    1   1501573386   1    2   3   <list [1]>  <list [1]>

然后在所有列上再次 unnest_wider() 非常繁琐。
如何设计一个循环,直到所有带有列表的列都没有被取消嵌套?

谢谢

【问题讨论】:

  • 如果您包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出,则更容易为您提供帮助。
  • 请在您的问题中添加dput(data)

标签: r dplyr tidyr


【解决方案1】:

这是一个带有嵌套列表和数据框列的数据框。

library(tidyverse)

l <- list(y1 = 1, y2 = list(z1 = 1))

data <- tribble(
  ~x1,  ~list1,     ~tibble1,
    1,       l, as.tibble(l),
    1,       l, as.tibble(l),
    1,       l, as.tibble(l),
    1,       l, as.tibble(l)
)
data
#> # A tibble: 4 x 3
#>      x1 list1            tibble1         
#>   <dbl> <list>           <list>          
#> 1     1 <named list [2]> <tibble [1 × 2]>
#> 2     1 <named list [2]> <tibble [1 × 2]>
#> 3     1 <named list [2]> <tibble [1 × 2]>
#> 4     1 <named list [2]> <tibble [1 × 2]>

我们可以创建一个函数unnest_all,它递归地取消所有列表列的嵌套。

  • 首先,它会查找所有列表列。
  • 那么,如果有任何列表 列,它会取消每个列的嵌套。
  • 最后,它再次调用unnest_all 取消嵌套任何剩余的列表列。
unnest_all <- function(df) {
  list_columns <- df %>% keep(is.list) %>% names()
  
  if (length(list_columns) == 0) {
    return(df)
  }

  for (list_column in list_columns) {
    df <-
      df %>%
      unnest_wider(list_column, names_sep = "_")
  }
  unnest_all(df)
}
unnest_all(data)
#> # A tibble: 4 x 5
#>      x1 list1_y1 list1_y2_z1 tibble1_y1 tibble1_y2_z1
#>   <dbl>    <dbl>       <dbl>      <dbl>         <dbl>
#> 1     1        1           1          1             1
#> 2     1        1           1          1             1
#> 3     1        1           1          1             1
#> 4     1        1           1          1             1

【讨论】:

  • 我收到以下错误 - 名称(x)中的错误
  • 您的数据集包含无法取消嵌套的空列表。修改函数以忽略空列表:list_columns &lt;- df %&gt;% keep(is.list) %&gt;% discard(~any(map_lgl(., is_empty))) %&gt;% names().
  • 我不知道您可以在其内部调用函数。我什至无法理解这是如何工作的。
猜你喜欢
  • 2022-09-24
  • 2021-10-24
  • 2018-08-10
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 2016-01-11
  • 2016-12-22
  • 1970-01-01
相关资源
最近更新 更多