2014-09-10 18 views
7

Supponiamo che io ho i seguenti dati:Usa dplyr :: percent_rank() per calcolare ranghi percentili nel gruppo

id grpvar1 grpvar2 value 
1  1   3   7.6 
2  1   2   4 
... 
3  1   5   2 

Per ogni id, voglio calcolare la percent_rank() della sua value all'interno del gruppo definito dalla combinazione di grpvar1 e grpvar2.

Utilizzando data.table, vorrei andare (supponendo che il mio dati sono in un data.frame chiamato dataf:

library(data.table) 

# Make dataset into a data.table. 
dt <- data.table(dataf) 

# Calculate the percentiles. 
dt[, percrank := rank(value)/length(value), by = c("grpvar1", "grpvar2")] 

Qual è l'equivalente in dplyr

+2

Si potrebbe prova: 'dataf%>% group_by (grpvar1, grpvar2)%>% mutate (percrank = rank (valore)/lunghezza (valore))' che fornisce l'output che hai mostrato usando 'data.table' – akrun

+2

Non c'è un vero motivo per usare 'dplyr :: percent_rank()' in quanto è solo una semplice funzione che fa '(min_rank (x) - 1)/(length (x) - 1)'. È più facile scrivere 'rank (value)/length (value)' che provare ad adottare 'percent_rank' in base alle proprie esigenze –

+1

Akrun, avvolgerlo in una risposta e lo controllerò una volta che confermo che funziona come previsto! –

risposta

6

Prova:?

library(dplyr) 
dataf %>% 
group_by(grpvar1, grpvar2) %>% 
mutate(percrank=rank(value)/length(value)) 
+0

Questo sarà probabilmente molto lento se fatto un dataset esterno in un database Postgres con milioni se righe e decine di migliaia di gruppi giusto? –

+1

@Brash Equilibrio Sì, sarei d'accordo. Se il set di dati è gestibile, 'data.table' sarebbe un'opzione più veloce – akrun

+0

Il set di dati non è gestibile se eseguo tutto in una volta. Dovrò portare solo le cose di cui ho bisogno per fare la classifica, e poi estrarre la spazzatura dopo una fase di aggregazione post ranking. –

Problemi correlati