【发布时间】:2019-11-10 16:01:36
【问题描述】:
我有一个包含列表的数据框,如下所示:
# Load packages
library(dplyr)
# Create data frame
df <- structure(list(ID = 1:3,
A = structure(list(c(9, 8), c(7,6), c(6, 9)), ptype = numeric(0), class = c("vctrs_list_of", "vctrs_vctr")),
B = structure(list(c(3, 5), c(2, 6), c(1, 5)), ptype = numeric(0), class = c("vctrs_list_of", "vctrs_vctr")),
C = structure(list(c(6, 5), c(7, 6), c(8, 7)), ptype = numeric(0), class = c("vctrs_list_of", "vctrs_vctr")),
D = structure(list(c(5, 3), c(4, 1), c(6, 5)), ptype = numeric(0), class = c("vctrs_list_of", "vctrs_vctr"))),
row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
# Peek at data
df
#> # A tibble: 3 x 5
#> ID A B C D
#> <int> <list> <list> <list> <list>
#> 1 1 <dbl [2]> <dbl [2]> <dbl [2]> <dbl [2]>
#> 2 2 <dbl [2]> <dbl [2]> <dbl [2]> <dbl [2]>
#> 3 3 <dbl [2]> <dbl [2]> <dbl [2]> <dbl [2]>
我想取消嵌套列表,可以使用 pmap_dfr 进行。
# Expand rows
df %>% purrr::pmap_dfr(function(...)data.frame(...))
#> ID A B C D
#> 1 1 9 3 6 5
#> 2 1 8 5 5 3
#> 3 2 7 2 7 4
#> 4 2 6 6 6 1
#> 5 3 6 1 8 6
#> 6 3 9 5 7 5
由reprex package (v0.3.0) 于 2019 年 6 月 28 日创建
这是预期的结果,但似乎是在重新发明轮子,因为 tidyr::unnest 旨在将列表列展平为常规列。但是,使用 tidyr::unnest 会产生以下错误:
df %>% unnest(cols = c(A, B, C, D))
#Error: No common type for `x` <tbl_df<A:double>> and `y` <double>.
#Call `rlang::last_error()` to see a backtrace
在这种情况下,我如何应用 unnest 来用列表列展平我的数据框?
版本信息
> packageVersion("tidyr")
[1] ‘0.8.3.9000’
【问题讨论】:
-
我认为
unnest(df)和pmap_dfr(df, data.frame)之间没有区别,两者都是您的预期输出(尽管后者不是tbl_df)。 -
@r2evans 很奇怪。
unnest为我抛出错误。再说一次,我用的是tidyr的开发版... -
我在 tidyr 开发版本中遇到了同样的问题。将您的列变成普通列表为我解决了这个问题:
df %>% mutate_at(.vars = vars(A:D), as.list) %>% unnest(cols = A:D) -
我认为暂时保留在这里实际上是相关的,因为其他人可能有类似的问题,并且看到这些 cmets 将非常有用。根据 github 上的响应时间(不确定开发人员的注意力何时会回滚到
tidyr),您可能会在此处发布一个答案,说明(1)这是一个当前的错误,并且(2)这里有一个或两个暂时的解决方法。然后稍后您可以 (3) 在 github/CRAN 版本修复后进行更新。谢谢,很好的发现! -
玩了一会儿后,我得出的结论是,可能没有任何问题,我认为
nest刚刚变得更加专注,chop已经接管了它的一些职责。请在下面查看我的回答,让我知道您的想法。