#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 были более удобочитаемыми