我有这种格式的数据框:
pair_id group_id value
<int> <int> <dbl>
1 1 0.600
1 2 0.400
2 3 0.500
2 4 0.500
3 5 0.200
3 6 0.800
4 7 0.300
4 8 0.700
5 9 0.500
5 10 0.500
使用以下代码段生成:
library(tidyverse)
df <- tibble(pair_id = rep(1:5, each = 2),
group_id = seq(1:10),
value = c(0.6, 0.4, 0.5, 0.5, 0.2, 0.8, 0.3, 0.7, 0.5, 0.5))
我的目标是确定每个pair_id中的哪个group_id具有更高的值,哪个具有更低的值。一旦确定,我想分配&#34;更高&#34;到具有较高值的group_id和&#34;较低的&#34;到具有较低值的group_id。
然而,需要注意的是,如果两个组具有相等的值(例如,两个组的值都为0.5,如在示例中的对2和对5中),则分配&#34;更高的&#34;或&#34;降低&#34;应该随机确定。
目标是生成一个包含新列的数据框,让我们说group_rank,它应该如下所示:
pair_id group_id value group_rank
<int> <int> <dbl> <chr>
1 1 0.600 higher
1 2 0.400 lower
2 3 0.500 higher
2 4 0.500 lower
3 6 0.800 higher
3 5 0.200 lower
4 8 0.700 higher
4 7 0.300 lower
5 9 0.500 lower
5 10 0.500 higher
在tidyverse框架内有没有一种简单的方法可以实现这一目标?
答案 0 :(得分:1)
按&#39; pair_id&#39;分组后,在&#39;值&#39;上使用which.min
和which.max
列,以获取用于对相应的&#39; group_id&#39;
df %>%
group_by(pair_id) %>%
summarise(groupMin = group_id[which.min(value)], groupMax = group_id[which.max(value)])
注意:如果&#39; pair_id&#39;有多个min
或max
值,which.min
或which.max
只会获得第一个索引< / p>
如果有多个min
或max
值,则使用==
和sample
获取random
&#39; group_id&#39;
df %>%
group_by(pair_id) %>%
summarise(groupMin = sample(group_id[value == min(value)], 1),
groupMax = sample(group_id[value == max(value)], 1) )
根据OP的评论,我们arrange
通过&#39; pair_id&#39;和&#39;价值&#39;按降序排列,按&#39; pair_id&#39;分组,如果&#39;值&#39;中的不同元素的数量等于1,然后分配&#34;更高&#34;,&#34;更低&#34;值sample
或else
按照&#34;更高&#34;的顺序分配值然后是&#34;降低&#34;
df %>%
arrange(pair_id, desc(value)) %>%
group_by(pair_id) %>%
mutate(group_rank = case_when(n_distinct(value) == 1 ~ sample(c("higher", "lower")),
TRUE ~ c("higher", "lower")))
# A tibble: 10 x 4
# Groups: pair_id [5]
# pair_id group_id value group_rank
# <int> <int> <dbl> <chr>
# 1 1 1 0.600 higher
# 2 1 2 0.400 lower
# 3 2 3 0.500 higher
# 4 2 4 0.500 lower
# 5 3 6 0.800 higher
# 6 3 5 0.200 lower
# 7 4 8 0.700 higher
# 8 4 7 0.300 lower
# 9 5 9 0.500 lower
#10 5 10 0.500 higher