R Plyr - Ordinare i risultati da DDPLY?
Domanda
Qualcuno conosce un modo intelligente per ordinare i risultati provenienti da un'operazione di riepilogo ddply?
Questo è ciò che sto facendo per ottenere l'output ordinato per profondità decrescente.
ddims <- ddply(diamonds, .(color), summarise, depth = mean(depth), table = mean(table))
ddims <- ddims[order(-ddims$depth),]
Con output ...
> ddims
color depth table
7 J 61.88722 57.81239
6 I 61.84639 57.57728
5 H 61.83685 57.51781
4 G 61.75711 57.28863
1 D 61.69813 57.40459
3 F 61.69458 57.43354
2 E 61.66209 57.49120
Non troppo brutto, ma spero in un modo per farlo bene all'interno di ddply ().Qualcuno sa come?
Il libro ggplot2 di Hadley contiene questo esempio per ddply e subset, ma in realtà non ordina l'output, ma seleziona solo i due diamanti più piccoli per gruppo.
ddply(diamonds, .(color), subset, order(carat) <= 2)
Soluzione
Userò questa occasione per pubblicizzare un po 'per data.table
, che è più veloce da eseguire e (nella mia percezione) almeno altrettanto elegante da scrivere:
library(data.table)
ddims <- data.table(diamonds)
system.time(ddims <- ddims[, list(depth=mean(depth), table=mean(table)), by=color][order(depth)])
user system elapsed
0.003 0.000 0.004
Al contrario, senza ordinare, il codice ddply
richiede già 30 volte più tempo:
user system elapsed
0.106 0.010 0.119
Con tutto il rispetto che ho per l'eccellente lavoro di Hadley, ad es.su ggplot2
, e in generale, devo confessare che per me data.table
ha completamente sostituito ddply
, per motivi di velocità.
Altri suggerimenti
Sì, per ordinare puoi semplicemente nidificare il ddply
in un altro ddply
.Ecco come utilizzeresti ddply
per ordinare su una colonna, ad esempio la colonna table
:
ddimsSortedTable <- ddply(ddply(diamonds, .(color),
summarise, depth = mean(depth), table = mean(table)), .(table))
color depth table
1 G 61.75711 57.28863
2 D 61.69813 57.40459
3 F 61.69458 57.43354
4 E 61.66209 57.49120
5 H 61.83685 57.51781
6 I 61.84639 57.57728
7 J 61.88722 57.81239
Se stai utilizzando dplyr
, ti consiglio di sfruttare l'operatore %.%
, che legge un codice più intuitivo.
data(diamonds, package = 'ggplot2')
library(dplyr)
diamonds %.%
group_by(color) %.%
summarise(
depth = mean(depth),
table = mean(table)
) %.%
arrange(desc(depth))
Un po 'tardi per la festa, ma le cose potrebbero essere un po' diverse con dplyr.Prendendo in prestito la soluzione di crayola per data.table:
dat1 <- microbenchmark(
dtbl<- data.table(diamonds)[, list(depth=mean(depth), table=mean(table)), by=color][order(- depth)],
dplyr_dtbl <- arrange(summarise(group_by(tbl_dt(diamonds),color), depth = mean(depth) , table = mean(table)),-depth),
dplyr_dtfr <- arrange(summarise(group_by(tbl_df(diamonds),color), depth = mean(depth) , table = mean(table)),-depth),
times = 20,
unit = "ms"
)
I risultati mostrano che dplyr con tbl_dt è un po 'più lento dell'approccio data.table.Tuttavia, dplyr con data.frame è più veloce:
expr min lq median uq max neval
data.table 9.606571 10.968881 11.958644 12.675205 14.334525 20
dplyr_data.table 13.553307 15.721261 17.494500 19.544840 79.771768 20
dplyr_data.frame 4.643799 5.148327 5.887468 6.537321 7.043286 20
Nota: ovviamente ho cambiato i nomi in modo che i risultati del microbenchmark siano più leggibili