Как быстро агрегировать и обобщать данные?
У меня есть набор данных, чьи заголовки выглядят так:
PID Time Site Rep Count
Я хочу суммировать Count
на Rep
для каждого PID x Time x Site combo
в результирующем файле data.frame, я хочу получить среднее значение Count
для PID x Time x Site
комбо.
Текущая функция следующая:
dummy <- function (data)
{
A<-aggregate(Count~PID+Time+Site+Rep,data=data,function(x){sum(na.omit(x))})
B<-aggregate(Count~PID+Time+Site,data=A,mean)
return (B)
}
Это очень медленно (исходный data.frame 510000 20)
. Есть ли способ ускорить это с помощью plyr?
Ответы
Ответ 1
Вы должны посмотреть на пакет data.table
для более быстрой работы агрегации на больших кадрах данных. Для вашей проблемы решение будет выглядеть так:
library(data.table)
data_t = data.table(data_tab)
ans = data_t[,list(A = sum(count), B = mean(count)), by = 'PID,Time,Site']
Ответ 2
Посмотрим, насколько быстро data.table
сравнивается с dplyr
. Тиши был бы примерно таким, как это сделать в dplyr
.
data %>% group_by(PID, Time, Site, Rep) %>%
summarise(totalCount = sum(Count)) %>%
group_by(PID, Time, Site) %>%
summarise(mean(totalCount))
Или, возможно, это, в зависимости от того, как именно интерпретируется вопрос:
data %>% group_by(PID, Time, Site) %>%
summarise(totalCount = sum(Count), meanCount = mean(Count)
Вот полный пример этих альтернатив по сравнению с предложенным нами предложением @Ramnath, и тот, который @David Arenburg предложил в комментариях, который, я думаю, эквивалентен второму dplyr
.
nrow <- 510000
data <- data.frame(PID = sample(letters, nrow, replace = TRUE),
Time = sample(letters, nrow, replace = TRUE),
Site = sample(letters, nrow, replace = TRUE),
Rep = rnorm(nrow),
Count = rpois(nrow, 100))
library(dplyr)
library(data.table)
Rprof(tf1 <- tempfile())
ans <- data %>% group_by(PID, Time, Site, Rep) %>%
summarise(totalCount = sum(Count)) %>%
group_by(PID, Time, Site) %>%
summarise(mean(totalCount))
Rprof()
summaryRprof(tf1) #reports 1.68 sec sampling time
Rprof(tf2 <- tempfile())
ans <- data %>% group_by(PID, Time, Site, Rep) %>%
summarise(total = sum(Count), meanCount = mean(Count))
Rprof()
summaryRprof(tf2) # reports 1.60 seconds
Rprof(tf3 <- tempfile())
data_t = data.table(data)
ans = data_t[,list(A = sum(Count), B = mean(Count)), by = 'PID,Time,Site']
Rprof()
summaryRprof(tf3) #reports 0.06 seconds
Rprof(tf4 <- tempfile())
ans <- setDT(data)[,.(A = sum(Count), B = mean(Count)), by = 'PID,Time,Site']
Rprof()
summaryRprof(tf4) #reports 0.02 seconds
Метод таблицы данных намного быстрее, а setDT
еще быстрее!