2017-10-20 41 views
2

J'ai une trame de données qui ressemble à ceci:sélectionner plusieurs lignes à partir d'une trame de données d'une valeur égale à la valeur la plus élevée par groupe

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 

Je veux groupe sur la première colonne, et sélectionnez toutes les lignes avec un score égal au score le plus élevé pour ce groupe. A propos de la plus proche, je peux comprendre est d'utiliser top_n comme ceci:

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

A Tibble: 6 x 3

Groupes: requête [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 

Mais évidemment, tout ce qui est fait est en me donnant les deux premiers (ou tout ce que je spécifie). Le résultat que je veux finir avec regarderait plus comme ceci:

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 

Comme d'habitude, je suppose que je manque quelque chose assez simple.

Répondre

5

Dans dplyr, filtrez simplement sur 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 

Vous pouvez aussi le faire facilement dans la base R, avec 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

Votre syntaxe est fondamentalement correcte, il suffit de spécifier n = 1 au lieu de n = 2 dans 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 

Lorsque vous utilisez top_n, s'il y a égalité, toutes les observations avec ce score sera retourné. Vous pouvez donc spécifier que vous voulez le score 1 le plus élevé (n = 1), puis toutes les observations avec ce score, au sein de chaque groupe, seront renvoyées.