【问题标题】:Unnesting a list of lists in a data frame column取消嵌套数据框列中的列表列表
【发布时间】:2016-12-16 01:39:06
【问题描述】:

要取消嵌套我可以使用的数据框:

df <- data_frame(
    x = 1,
    y = list(a = 1, b = 2)
)

tidyr::unnest(df)

但是如何在数据框列内的列表中取消嵌套列表?

df <- data_frame(
    x = 1,
    y = list(list(a = 1, b = 2))
)
tidyr::unnest(df)

错误:

每一列必须是向量列表或数据框列表 [y]

【问题讨论】:

  • 结果应该是什么样的?
  • 与第一个代码块相同。 data_frame(x = c(1, 1), y = c(1, 2))
  • 如果你想走得更远,df %&gt;% mutate(y = list(as.data.frame(y))) %&gt;% unnest() 很长一段时间,也许是df %&gt;% do(data_frame(x = .$x, y = unlist(.$y)))df %&gt;% mutate(y = data_frame(unlist(y))) %&gt;% unnest()
  • unnest(unnest(df)) 有什么问题?

标签: r tidyr


【解决方案1】:

使用purrr,这对于列表来说非常有用,

library(purrr)

df %>% dmap(unlist)
## # A tibble: 2 x 2
##       x     y
##   <dbl> <dbl>
## 1     1     1
## 2     1     2

或多或少等价于

as.data.frame(lapply(df, unlist))
##   x y
## a 1 1
## b 1 2

更新:

dmap 已被弃用并移至purrrlyr,这是有趣但命运多舛的函数的所在地,现在会向您发出大量弃用警告。您可以将基本的 R 习语翻译成 tidyverse:

df %>% map(unlist) %>% as_data_frame()

这在这种情况下可以正常工作,但不能超过一行(所有这些方法都面临的问题)。一个更强大的解决方案可能是

library(tidyverse)

df %>% bind_rows(df) %>%    # make larger sample data
    mutate_if(is.list, simplify_all) %>%    # flatten each list element internally 
    unnest()    # expand
#> # A tibble: 4 × 2
#>       x     y
#>   <dbl> <dbl>
#> 1     1     1
#> 2     1     2
#> 3     1     1
#> 4     1     2

【讨论】:

  • dmap 似乎不在 purrr 中
  • as_data_frame() was deprecated in tibble 2.0.0.。另外,我建议将Update 放在帖子顶部,因为大多数新搜索将来自最近发布软件包的用户,并且会遇到dmap 错误。
【解决方案2】:

这可以通过使用unnest_longer() 以简单的步骤完成,因为tidyr 1.0.0

df <- tibble::tibble(
  x = 1,
  y = list(list(a = 1, b = 2))
)

library(tidyr)
unnest_longer(df,y,indices_include = FALSE)
#> # A tibble: 2 x 2
#>       x     y
#>   <dbl> <dbl>
#> 1     1     1
#> 2     1     2

reprex package (v0.3.0) 于 2019-09-14 创建

【讨论】:

    猜你喜欢
    • 2019-11-10
    • 2018-07-10
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    相关资源
    最近更新 更多