我有一个数据框,其中包含要折叠成单个条目的组,以使新行的值是每个组中的最小值或最大值,具体取决于列名。
例如,给定:
set.seed(1)
dat <- data.frame(grp = c('A', 'A', 'B', 'B'),
v1_high = rnorm(4),
v2_high = rnorm(4),
v3_low = rnorm(4))
# original
grp v1_high v2_high v3_low
1 A -0.6264538 0.3295078 0.5757814
2 A 0.1836433 -0.8204684 -0.3053884
3 B -0.8356286 0.4874291 1.5117812
4 B 1.5952808 0.7383247 0.3898432
我想生成一个新的数据帧,其中包含与组“ A”和“ B”相对应的两个条目,每列的最大值以_high
结尾,每列的最小值以{{ 1}}。
在这种情况下:
_low
最后,这些列的数目和名称事先未知。
理想情况下,汇总也可以处理没有# desired result
grp v1_high v2_high v3_low
1 A 0.1836433 0.3295078 -0.3053884
2 B 1.5952808 0.7383247 0.3898432
列且只有_min
列的情况,尽管我总是可以手动检查此情况并分别使用两种方式处理这两种情况_max
语句。
有什么建议吗?使用summarize_at()函数似乎应该可以实现,但是我还没有弄清楚如何将不同的函数应用于不同的列集。
答案 0 :(得分:1)
一种选择是按“ grp”分组,获得以“ high”(列名)结尾的max
列,也将其用作分组列并获得min
列以“低”结束
library(dplyr)
dat %>%
group_by(grp) %>%
mutate_at(vars(ends_with('high')), max) %>%
group_by_at(vars(ends_with('high')), .add = TRUE) %>%
summarise_at(vars(ends_with('low')), min)
# A tibble: 2 x 4
# Groups: grp, v1_high [2]
# grp v1_high v2_high v3_low
# <fct> <dbl> <dbl> <dbl>
#1 A 0.184 0.330 -0.305
#2 B 1.60 0.738 0.390
如果没有min
列
dat[-4] %>%
group_by(grp) %>%
mutate_at(vars(ends_with('high')), max) %>%
group_by_at(vars(ends_with('high')), .add = TRUE) %>%
summarise_at(vars(ends_with('low')), min)
# A tibble: 2 x 3
# Groups: grp, v1_high [2]
# grp v1_high v2_high
# <fct> <dbl> <dbl>
#1 A 0.184 0.330
#2 B 1.60 0.738
或者另一个选择是map2
library(purrr)
map2(list(min, max), list('low', 'high'), ~
dat %>%
select(grp, ends_with(.y)) %>%
group_by(grp) %>%
summarise_all(.x)) %>%
reduce(inner_join, by = 'grp')