Как быстро собрать и обобщить данные? - PullRequest
11 голосов
/ 11 октября 2011

У меня есть набор данных, заголовки которого выглядят так:

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?

Ответы [ 2 ]

21 голосов
/ 11 октября 2011

Вам следует взглянуть на пакет 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']
7 голосов
/ 21 сентября 2015

Давайте посмотрим, как быстро 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 еще быстрее!

...