R Plyr — упорядочивает результаты из DDPLY?

#r #plyr

#r #plyr

Вопрос:

Кто-нибудь знает простой способ упорядочить результаты, полученные в результате операции суммирования ddply?

Это то, что я делаю, чтобы получить выходные данные, упорядоченные по убыванию глубины.

   ddims <- ddply(diamonds, .(color), summarise, depth = mean(depth), table = mean(table))
  ddims <- ddims[order(-ddims$depth),]
  

С выводом…

 > 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
  

Не слишком уродливо, но я надеюсь, что это можно сделать красиво в ddply (). Кто-нибудь знает как?

В книге Хэдли ggplot2 есть этот пример для ddply и подмножества, но на самом деле это не сортировка выходных данных, а просто выбор двух наименьших бриллиантов для каждой группы.

 ddply(diamonds, .(color), subset, order(carat) <= 2)
  

Комментарии:

1. Я не уверен, что есть что-то, что вы можете сделать «на лету» — но просто случайное примечание, вместо того, ddims[order(-ddims$depth),] чтобы вы могли попробовать ddims[order(ddims$depth, decreasing=TRUE),] . Таким образом, вам не нужно создавать новый «отрицательный» векторный объект.

Ответ №1:

Я воспользуюсь этим случаем, чтобы немного прорекламировать data.table , который быстрее запускается и (на мой взгляд) по крайней мере так же элегантно написан:

 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 
  

В отличие от этого, без упорядочивания ваш ddply код уже занимает в 30 раз больше времени:

   user  system elapsed 
 0.106   0.010   0.119
  

При всем моем уважении к превосходной работе Хэдли, например, над ggplot2 , и общей потрясаемости, я должен признаться, что для меня, data.table полностью заменен ddply — по соображениям скорости.

Комментарии:

1. Спасибо, приятель. Я не знал о data.table посылке. Выглядит очень быстро, и это тоже вполне читаемо. В ближайшем будущем я буду работать с некоторыми большими наборами данных, так что спасибо за это. Я собираюсь подождать, чтобы увидеть, даст ли кто-нибудь ddply конкретный ответ.

Ответ №2:

Да, для сортировки вы можете просто вложить ddply в другое ddply . Вот как бы вы использовали ddply для сортировки по одному столбцу, например, по вашему 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
  

Комментарии:

1. Это звучит слишком нелогично и выглядит не очень приятно. Обычно это означает неправильный код. Действительно ли это правильный путь?

2. Почему бы не добавить свой собственный ответ и не показать лучший метод?

3. Я получаю ваш комментарий, и мой пост звучит более негативно, чем я предполагал. Я пришел сюда, потому что это был также мой вопрос. Я решил это, сохранив свой фрейм данных как df , а затем выполнил df[ order(df$column, ] . Итак, я сначала сохраняю его в dataframe, а затем упорядочиваю.

Ответ №3:

Если вы используете dplyr , я бы рекомендовал воспользоваться %.% оператором, который считывает более интуитивно понятный код.

 data(diamonds, package = 'ggplot2')
library(dplyr)
diamonds %.%
  group_by(color) %.%
  summarise(
    depth = mean(depth),
    table = mean(table)
  ) %.%
  arrange(desc(depth))
  

Комментарии:

1. Почему большинство ответов на R вопросов являются черной магией? Пожалуйста, объясните, где задокументирован оператор %.% и / или что он делает. Это не то, что вы можете легко найти с помощью Google.

2. help("%.%", package = 'dplyr')

Ответ №4:

Немного опоздал на вечеринку, но с dplyr все может быть немного по-другому. Заимствую решение crayola для 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"
)
  

Результаты показывают, что dplyr с tbl_dt выполняется немного медленнее, чем подход data.table. Однако dplyr с data.frame выполняется быстрее:

          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
  

Примечание: Я, очевидно, изменил имена, чтобы результаты microbenchmark были более удобочитаемыми