более быстрый способ создания переменной, которая агрегирует столбец по идентификатору
2943 просмотра
6 ответа
Есть ли более быстрый способ сделать это? Я думаю, что это не нужно медленно и что такую задачу можно выполнить с помощью базовых функций.
df <- ddply(df, "id", function(x) cbind(x, perc.total = sum(x$cand.perc)))
Я совсем новичок в R. Я смотрел by()
, aggregate()
и tapply()
, но не заставил их работать вообще или так, как я хотел. Вместо того, чтобы возвращать более короткий вектор, я хочу прикрепить сумму к исходному кадру данных. Каков наилучший способ сделать это?
Изменить: Вот сравнение скорости ответов, примененных к моим данным.
> # My original solution
> system.time( ddply(df, "id", function(x) cbind(x, perc.total = sum(x$cand.perc))) )
user system elapsed
14.405 0.000 14.479
> # Paul Hiemstra
> system.time( ddply(df, "id", transform, perc.total = sum(cand.perc)) )
user system elapsed
15.973 0.000 15.992
> # Richie Cotton
> system.time( with(df, tapply(df$cand.perc, df$id, sum))[df$id] )
user system elapsed
0.048 0.000 0.048
> # John
> system.time( with(df, ave(cand.perc, id, FUN = sum)) )
user system elapsed
0.032 0.000 0.030
> # Christoph_J
> system.time( df[ , list(perc.total = sum(cand.perc)), by="id"][df])
user system elapsed
0.028 0.000 0.028
Автор: ilprincipe
Источник
Размещён: 12.11.2019 09:34
Ответы (6)
6 плюса
Для любого вида агрегации, где вы хотите, чтобы результирующий вектор имел ту же длину, что и входной вектор с репликами, сгруппированными по вектору группировки, ave
- это то, что вам нужно.
df$perc.total <- ave(df$cand.perc, df$id, FUN = sum)
Автор: John
Размещён: 22.11.2011 12:18
12 плюса
Поскольку вы довольно плохо знакомы с R и скорость, по-видимому, является проблемой для вас, я рекомендую data.table
пакет, который действительно быстр. Один из способов решить вашу проблему в одной строке:
library(data.table)
DT <- data.table(ID = rep(c(1:3), each=3),
cand.perc = 1:9,
key="ID")
DT <- DT[ , perc.total := sum(cand.perc), by = ID]
DT
ID Perc.total cand.perc
[1,] 1 6 1
[2,] 1 6 2
[3,] 1 6 3
[4,] 2 15 4
[5,] 2 15 5
[6,] 2 15 6
[7,] 3 24 7
[8,] 3 24 8
[9,] 3 24 9
Отказ от ответственности: я не эксперт по data.table (пока ;-), так что могут быть более быстрые способы сделать это. Посетите сайт пакета, чтобы начать, если вы заинтересованы в использовании пакета: http://datatable.r-forge.r-project.org/
Автор: Christoph_J Размещён: 22.11.2011 01:033 плюса
Используйте tapply
для получения групповой статистики, затем добавьте ее обратно в набор данных.
Воспроизводимый пример:
means_by_wool <- with(warpbreaks, tapply(breaks, wool, mean))
warpbreaks$means.by.wool <- means_by_wool[warpbreaks$wool]
Непроверенное решение для вашего сценария:
sum_by_id <- with(df, tapply(cand.perc, id, sum))
df$perc.total <- sum_by_id[df$id]
Автор: Richie Cotton
Размещён: 22.11.2011 11:28
0 плюса
ilprincipe если ничего из вышеперечисленного не соответствует вашим потребностям, вы можете попробовать перенести ваши данные
dft=t(df)
затем используйте aggregate
dfta=aggregate(dft,by=list(rownames(dft)),FUN=sum)
затем вернулись ваши имена строк
rownames(dfta)=dfta[,1]
dfta=dfta[,2:ncol(dfta)]
Транспонировать обратно в исходное положение
df2=t(dfta)
и привязать к исходным данным
newdf=cbind(df,df2)
Автор: boczniak767
Размещён: 22.11.2011 12:50
0 плюса
Почему вы используете cbind (x, ...), вывод ddply будет добавлен автоматически. Это должно работать:
ddply(df, "id", transform, perc.total = sum(cand.perc))
избавление от лишнего cbind должно ускорить процесс.
Автор: Paul Hiemstra Размещён: 22.11.2011 11:320 плюса
Вы также можете загрузить свой любимый сервер foreach и попробовать аргумент .parallel = TRUE для ddply.
Автор: Zach Размещён: 23.11.2011 02:54Вопросы из категории :
- performance Как создать новый экземпляр объекта из Типа
- performance Как работает индексация базы данных?
- performance Действительно ли опечатанные классы действительно предлагают преимущества?
- performance Big O, как вы рассчитываете / приближаете это?
- performance MyISAM против InnoDB
- r Как получить доступ к последнему значению в векторе?
- r Пакеты оптимизации для R
- r Есть ли у R такие операторские операции, как Perl qw ()?
- r Библиотека / инструмент для рисования тройных / треугольных графиков
- r Участки без заголовков / надписей в R
- aggregate Как использовать GROUP BY для объединения строк в MySQL?
- aggregate Как проверить существующие агрегатные функции в Postgres?
- aggregate Группировать по нескольким столбцам
- aggregate Я нарушаю свои совокупные границы?
- aggregate Вопрос эффективности Linq - foreach против агрегатов
- plyr Объединение агрегированных значений обратно в исходный фрейм данных
- plyr Подмножество фрейма данных с топ-n строк для каждой группы и упорядочены по переменной
- plyr Агрегируйте кадр данных для данного столбца и отобразите другой столбец
- plyr Более быстрые способы вычисления частот и приведение от длинного к широкому
- plyr Группировать по нескольким столбцам и суммировать другие столбцы