确定分组数据帧中的较低和较高值

时间:2018-04-26 09:48:25

标签: r tidyverse

我有这种格式的数据框:

 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框架内有没有一种简单的方法可以实现这一目标?

1 个答案:

答案 0 :(得分:1)

按&#39; pair_id&#39;分组后,在&#39;值&#39;上使用which.minwhich.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;有多个minmax值,which.minwhich.max只会获得第一个索引< / p>

如果有多个minmax值,则使用==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;值sampleelse按照&#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