通过

2017-10-20 14 views
2

从等于最高值的值数据框中选择多行我有一个数据帧,看起来像这样:通过

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) 

一个tibble:6×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 

和往常一样,我假设我错过了一些非常简单的事情。

回答

5

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 

你也可以很容易地做到这一点的基础R,与ave()

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 
4

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

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),然后将返回每组中所有具有该分数的观测结果。