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)
È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top