我有一个包含列表的数据框,如下所示:
# 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-06-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’
答案 0 :(得分:1)
看起来nest
更专门用于在0.8.3.9000中创建数据帧的列表列。从文档中:嵌套会创建一个数据框架的列表列;取消嵌套将其平整为常规列。。例如,尝试:
df <- tibble(x = c(1, 1, 1, 2, 2, 3), y = 1:6, z = 6:1) %>%
nest(data = c(y, z))
哪个返回:
# A tibble: 3 x 2
x data
<dbl> <list<df[,2]>>
1 1 [2]
2 2 [2]
3 3 [2]
然后查看df$data
:
<list_of<
tbl_df<
y: integer
z: integer
>
>[3]>
[[1]]
# A tibble: 3 x 2
y z
<int> <int>
1 1 6
2 2 5
3 3 4
[[2]]
# A tibble: 2 x 2
y z
<int> <int>
1 4 3
2 5 2
[[3]]
# A tibble: 1 x 2
y z
<int> <int>
1 6 1
您数据框的列是向量的列表列,它们似乎属于chop
的权限,这会在保留数据框宽度的同时缩短数据框。例如,尝试:
df <- tibble(x = c(1, 1, 1, 2, 2, 3), y = 1:6, z = 6:1) %>%
chop(c(y, z))
哪个返回:
# A tibble: 3 x 3
x y z
<dbl> <list> <list>
1 1 <int [3]> <int [3]>
2 2 <int [2]> <int [2]>
3 3 <int [1]> <int [1]>
看看df$y
:
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5
[[3]]
[1] 6
知道这一点后,chop
的对应方法unchop
就是您数据的合适方法,因此请考虑您的数据框:
# A tibble: 3 x 5
ID A B C D
<int> <list<dbl>> <list<dbl>> <list<dbl>> <list<dbl>>
1 1 [2] [2] [2] [2]
2 2 [2] [2] [2] [2]
3 3 [2] [2] [2] [2]
尝试unchop(df, c(A, B, C, D))
或unchop(df, A:D)
,它们应返回:
# A tibble: 6 x 5
ID A B C D
<int> <dbl> <dbl> <dbl> <dbl>
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