0
votes

Rang sur deux colonnes, r

J'essaie de créer une colonne qui classera x, regroupée par noms.

names    x     rank
<chr>  <int>  <list>
Ben      3      1
Joe      4      2
Karen    6      2
Joan    10      4
Ben      3      2
Joe      9      4
Karen   10      4
Joan     7      3    
Ben      7      3
Joe      1      1

J'ai utilisé la fonction tapply:

learnrank$rank <- 
tapply(learnrank$x, learnrank$names, 
rank, ties.method = "first")

learnrank

names    x     rank
<chr>  <int>  <list>
Ben      3  <int [4]>
Joe      4  <int [4]>
Karen    6  <int [4]>
Joan    10  <int [4]>
Ben      3  <int [4]>
Joe      9  <int [4]>
Karen   10  <int [4]>
Joan     7  <int [4]>
Ben      7  <int [4]>
Joe      1  <int [4]>

Ce que je voudrais, c'est ci-dessous, où nous classons tous les scores de Ben à partir de 1: 4, les scores de Joe de 1: 4, etc.

names <- rep(c("Ben", "Joe", "Karen", "Joan"), times = 4)
set.seed(1)
x <- sample((1:10), 16, replace = TRUE)
learnrank <- data.frame(names,x)

Quelqu'un a-t-il des suggestions?

Cordialement

Kevin p>


1 commentaires

4 Réponses :


2
votes

Voici une solution dplyr:

library(dplyr)

learnrank %>% 
  group_by(names) %>% 
  mutate(x = sort(x), rank = order(-x)) %>%
  arrange(names)
#> # A tibble: 16 x 3
#> # Groups:   names [4]
#>    names     x  rank
#>    <fct> <int> <int>
#>  1 Ben       1     4
#>  2 Ben       2     3
#>  3 Ben       6     2
#>  4 Ben       9     1
#>  5 Joan      1     4
#>  6 Joan      3     3
#>  7 Joan      9     2
#>  8 Joan     10     1
#>  9 Joe       4     4
#> 10 Joe       5     3
#> 11 Joe       7     2
#> 12 Joe      10     1
#> 13 Karen     2     3
#> 14 Karen     5     4
#> 15 Karen     7     2
#> 16 Karen     7     1


0 commentaires

2
votes

Vous pouvez utiliser ave au lieu de tapply comme:

learnrank$rank <- ave(learnrank$x, learnrank$names,
 FUN=function(x) rank(x, ties.method = "first"))
learnrank
#   names  x rank
#1    Ben  9    4
#2    Joe  4    1
#3  Karen  7    3
#4   Joan  1    1
#5    Ben  2    2
#6    Joe  7    3
#7  Karen  2    1
#8   Joan  3    2
#9    Ben  1    1
#10   Joe  5    2
#11 Karen  5    2
#12  Joan 10    4
#13   Ben  6    3
#14   Joe 10    4
#15 Karen  7    4
#16  Joan  9    3


2 commentaires

Merci beaucoup. Avec cette méthode, pouvez-vous utiliser l'argument tie.method?


Oui. Je l'ai ajouté maintenant.



1
votes

Utiliser dplyr:

learnrank %>%
  group_by(names) %>%
  mutate(rank=row_number(x))

vous donne

# A tibble: 16 x 3
# Groups:   names [4]
   names     x  rank
   <fct> <int> <dbl>
 1 Ben       9   4  
 2 Joe       4   1  
 3 Karen     7   3.5
 4 Joan      1   1  
 5 Ben       2   2  
 6 Joe       7   3  
 7 Karen     2   1  
 8 Joan      3   2  
 9 Ben       1   1  
10 Joe       5   2  
11 Karen     5   2  
12 Joan     10   4  
13 Ben       6   3  
14 Joe      10   4  
15 Karen     7   3.5
16 Joan      9   3 

Avec l'argument tie.method vous pouvez gérer l'égalité des rangs. Choisir tie.method = "first" équivaut à

learnrank %>%
  group_by(names) %>%
  mutate(rank=rank(x))


1 commentaires

Merci, c'est génial



2
votes

Vous pouvez classer les données et attribuer un numéro de ligne à chaque nom .

Cela peut être fait dans la base R:

library(dplyr)
learnrank %>%
  arrange_all() %>%
  group_by(names) %>%
  mutate(row = row_number())

Ou en utilisant dplyr :

learnrank <- learnrank[do.call(order, learnrank), ]
learnrank$rank <- with(learnrank, ave(x, names, FUN = seq_along))


1 commentaires

Merci, c'est une aide précieuse