从数据框中选择多个行,其值等于组中的最高值

时间:2017-10-20 22:25:44

标签: r dataframe dplyr tidyverse

我有一个如下所示的数据框:

query <- c('a','a','a','b','b','b','c','c','c')
hit <- c(1,2,3,4,5,6,7,8,9)
score <- c(97,97,96,98,97,96,99,99,98)
df <- data.frame(query,hit,score)
df

  query hit score
1     a   1    97
2     a   2    97
3     a   3    96
4     b   4    98
5     b   5    97
6     b   6    96
7     c   7    99
8     c   8    99
9     c   9    98

我想对第一列进行分组,并选择分数等于该组最高分数的所有行。关于我能想出的最接近的是使用这样的top_n:

df %>%
+ group_by(query) %>%
+ top_n(2,score)

A tibble:6 x 3

组:查询[3]

   query   hit score
  <fctr> <dbl> <dbl>
1      a     1    97
2      a     2    97
3      b     4    98
4      b     5    97
5      c     7    99
6      c     8    99

但显然所有人都在给我前两名(或我指定的任何内容)。我想最终得到的结果看起来更像是这样:

   query   hit score
  <fctr> <dbl> <dbl>
1      a     1    97
2      a     2    97
3      b     4    98
5      c     7    99
6      c     8    99

像往常一样,我认为我错过了一些非常简单的事情。

2 个答案:

答案 0 :(得分:4)

dplyr 中,只需过滤score == max(score)

group_by(df, query) %>%
    filter(score == max(score))
# A tibble: 5 x 3
# Groups:   query [3]
#    query   hit score
#   <fctr> <dbl> <dbl>
# 1      a     1    97
# 2      a     2    97
# 3      b     4    98
# 4      c     7    99
# 5      c     8    99

您还可以使用ave()

在基础R中轻松完成此操作
df[with(df, ave(score, query, FUN = max) == score), ]
#   query hit score
# 1     a   1    97
# 2     a   2    97
# 4     b   4    98
# 7     c   7    99
# 8     c   8    99

答案 1 :(得分:4)

您的语法基本上是正确的,只需在n = 1中指定n = 2而不是top_n

query <- c('a','a','a','b','b','b','c','c','c')
hit <- c(1,2,3,4,5,6,7,8,9)
score <- c(97,97,96,98,97,96,99,99,98)
df <- data.frame(query,hit,score)

df %>%
  group_by(query) %>%
  top_n(n = 1, wt = score)
#> # A tibble: 5 x 3
#> # Groups:   query [3]
#>    query   hit score
#>   <fctr> <dbl> <dbl>
#> 1      a     1    97
#> 2      a     2    97
#> 3      b     4    98
#> 4      c     7    99
#> 5      c     8    99

使用top_n时,如果存在平局,将返回包含该分数的所有观察结果。因此,您可以指定要获得1个最高分(n = 1),然后返回每个组中所有具有该分数的观察结果。