dplyr: colSums на подгруппированных (group by) фреймах данных: элегантно
у меня очень большой фрейм данных (265,874 x 30), с тремя разумными группами: возрастная категория (1-6), даты (5479 таких) и географическая местность (всего 4). Каждая запись состоит из выбора из каждого из них, а также 27 переменных count. Я хочу, чтобы группа по каждой из переменных группировку, а затем взять colSums в результате подразделе сгруппированы 27 переменных. Я пытался использовать dplyr (v0.2) сделать это, потому что делать это вручную в конечном итоге настраивает много избыточных вещей (или обращение к циклу для итерации по параметрам группировки из-за отсутствия элегантного решения).
пример кода:
countData <- sample(0:10, 2000, replace = TRUE)
dates <- sample(seq(as.Date("2010/1/1"), as.Date("2010/01/30"), "days"), 200, replace = TRUE)
locality <- sample(1:2, 2000, replace = TRUE)
ageCat <- sample(1:2, 2000, replace = TRUE)
sampleDF <- data.frame(dates, locality, ageCat, matrix(countData, nrow = 200, ncol = 10))
тогда то, что я хотел бы сделать ...
library("dplyr")
sampleDF %.% group_by(locality, ageCat, dates) %.% do(colSums(.[, -(1:3)]))
но это не совсем работает, так как результаты colSums() не являются фреймами данных. Если я бросаю его, он работает:
sampleDF %.% group_by(locality, ageCat, dates) %.% do(data.frame(matrix(colSums(.[, -(1:3)]), nrow = 1, ncol = 10)))
но окончательный сделать(...) бит кажется очень неуклюжим.
любые мысли о том, как сделать это более элегантно и эффективно? Я думаю вопрос сводится к следующему: как лучше всего использовать функцию do() и т. д. оператор для суммирования фрейма данных через colSums.
Примечание: do(.) оператор применяется только к dplyr 0.2, поэтому вам нужно захватить его из GitHub (ссылке), не от крана.
Edit: результаты из предложений
три решения:
мое предложение в сообщении: истекло, 146.765 считанные секунды.
предложение@joran ниже: 6.902 секунды
предложение@eddi в комментариях, используя данные.таблица: 6.715 секунд.
Я не потрудился воспроизвести, просто использовал систему.время (), чтобы получить грубый датчик. Судя по всему, dplyr и данные.таблица выполните примерно то же самое на моем наборе данных, и оба значительно быстрее при правильном использовании, чем решение hack I придумал вчера.
2 ответов
если я ничего не упускаю, это похоже на работу для summarise_each
(типа colwise
аналог plyr):
sampleDF %.% group_by(locality, ageCat, dates) %.% summarise_each(funs(sum))
столбец группировки по умолчанию не включен в функцию суммирования, и вы можете выбрать только подмножество столбцов, чтобы применить функции к использованию той же техники, что и при использовании select
.
(summarise_each
В версия 0.2 dplyr но не в 0.1.3, насколько я знаю.)
это был замечательный ответ @joran в 2014 году.
теперь этот метод устарел. Вместо этого используйте summarize_all()
или summarize_at()
.