【问题标题】:as_tibble control level of flatteningas_tibble 控制水平的展平
【发布时间】:2018-09-09 20:52:25
【问题描述】:

在下面的示例中,我有一个列表,其中一个元素是带有子列表的列表。 as_tibble() 似乎正在变平,直到列表的第 3 级才停止。能够控制展平会很好,这样我就可以在示例的元素"c" 中保留整个列表和子列表。我怀疑需要map()flatten() 等的某种组合,但无法弄清楚。

问题转载

as_tibble() 返回 2 行,但我真的只想要 1 行,其中一列对应于每个列表元素(“a”、“b”、“c”)。

library(dplyr)
x <- list(a = 1, 
          b = 2, 
          c = list(x=list(y=3, 
                          z=4), 
                   xx=NULL))
parsed <- as_tibble(x)
parsed
#> # A tibble: 2 x 3
#>       a     b c         
#>   <dbl> <dbl> <list>    
#> 1    1.    2. <list [2]>
#> 2    1.    2. <NULL>

parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4

parsed[2,]$c
#> $xx
#> NULL

我只取消第一级的期望行为

parsed <- as_tibble(x)
parsed
#> # A tibble: 1 x 3
#>       a     b c         
#>   <dbl> <dbl> <list>    
#> 1    1.    2. <list [2]>

parsed[1,]$c
#> $x
#> $x$y
#> [1] 3
#> $x$z
#> [1] 4
#> $xx
#> NULL

【问题讨论】:

    标签: r dplyr tidyr purrr tibble


    【解决方案1】:

    这并不优雅,但这是一种方法。

    library(purrr)
    x <- list(a = 1, 
              b = 2, 
              c = list(x=list(y=3, 
                              z=4), 
                       xx=NULL))
    
    # define a function to preserve the list
    unnest_one_level <- function(x){
      if(is.list(x)) list(x) else x
    }
    
    res <- x %>% map_dfr(unnest_one_level)
    res
    #> # A tibble: 1 x 3
    #>       a     b c         
    #>   <dbl> <dbl> <list>    
    #> 1    1.    2. <list [2]>
    
    res$c
    #> [[1]]
    #> [[1]]$x
    #> [[1]]$x$y
    #> [1] 3
    #> 
    #> [[1]]$x$z
    #> [1] 4
    #> 
    #> [[1]]$xx
    #> NULL
    

    【讨论】:

      【解决方案2】:

      as.tibble 将重复每一列回收每一列的值,直到它们都具有共享数量的元素。在这里,ab 的长度为 1,但 c 的长度为 2。所以看起来你真的想把它当作一个长度为一的列表,你只需要将它嵌套在一个列表中。我认为这至少在这种情况下会做你想要的。

      parsed <- as_tibble(modify_if(x, ~length(.x)>1, list))
      

      【讨论】:

      • 减少到一个共同的长度是有道理的。你的代码很好而且很紧凑。有什么方法可以展开我们必须创建的长度为 1 的列表以使其首先工作?
      • 它必须是一个列表才能在一个小标题中。这就是 tibbles 的工作原理。每列需要是相同长度的集合。如果这不是您想要的,那么您不需要 tibble(或 data.frame)。只需使用一个列表。
      • 为什么列表的长度必须相同?一个列表的长度可以是 2,另一个列表的长度可以是 4,但这并不意味着它们都不是列表。
      • 对于小标题和数据框的要求是每列具有相同数量的元素,以便具有“行”的概念。所以列本身必须是一个列表,但它可以有不同数量的元素的子列表。但是每一列的length() 必须相同。这只是数据结构的基本要求。您希望通过使用 tibble 而不是简单列表获得什么好处?
      • 在上面的例子中,列表代表一个单一的观察。现在图像我有一千个观察结果。我希望它是一个包含 1000 行 x 3 列的小标题,而不是包含子列表的长度为 1000 的列表。只是为了一致性和可读性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      相关资源
      最近更新 更多