【发布时间】:2020-06-09 10:31:55
【问题描述】:
我有一个包含两个 id 变量和多个变量的数据框。在这些变量中,有些变量仅取决于id1,而其他变量则取决于id1 和id2。现在,我想使用tidyr::pivot_wider() 更宽地重塑数据框。以下是一个reprex,实际数据集包含更多变量。
样本数据
library(tidyverse)
set.seed(42)
(d <- tibble(
id1 = rep(LETTERS[1:4], each = 3),
id2 = rep(letters[1:3], length.out = 12),
x = rpois(12, 3),
y = rep(rpois(4, 5), each = 3)
))
#> # A tibble: 12 x 4
#> id1 id2 x y
#> <chr> <chr> <int> <int>
#> 1 A a 5 9
#> 2 A b 6 9
#> 3 A c 2 9
#> 4 B a 5 3
#> 5 B b 3 3
#> 6 B c 3 3
#> 7 C a 4 5
#> 8 C b 1 5
#> 9 C c 4 5
#> 10 D a 4 9
#> 11 D b 3 9
#> 12 D c 4 9
输出
旋转示例框架将产生以下框架:
(d <- pivot_wider(d, names_from = id2, values_from = x:y))
#> # A tibble: 4 x 7
#> id1 x_a x_b x_c y_a y_b y_c
#> <chr> <int> <int> <int> <int> <int> <int>
#> 1 A 5 6 2 9 9 9
#> 2 B 5 3 3 3 3 3
#> 3 C 4 1 4 5 5 5
#> 4 D 4 3 4 9 9 9
从输出中可以看出,y_a、y_b 和 y_c 都是相同的,因此是重复的。
期望的输出
我想要的是一个没有冗余的数据框:
d %>%
rename(y = y_a) %>%
select(-y_b, -y_c)
#> # A tibble: 4 x 5
#> id1 x_a x_b x_c y
#> <chr> <int> <int> <int> <int>
#> 1 A 5 6 2 9
#> 2 B 5 3 3 3
#> 3 C 4 1 4 5
#> 4 D 4 3 4 9
该解决方案应生成一个没有重复列的数据框,并且无需用户输入哪些列会变成冗余列。一个 tidyverse 解决方案会很好,但也欢迎其他解决方案。
到目前为止,尝试自己解决这个问题,我能想出的唯一方法是编写一个函数,根据前缀识别列组,然后检查组中的列是否相同,删除冗余列并重命名剩下的变量去掉后缀。我觉得必须是一种更简洁的方式来做到这一点。
我也用谷歌搜索了这个问题,但结果往往是关于重复的列名或重复的行,并且没有为手头的问题找到任何解决方案。
【问题讨论】: