R - расчеты по группам - data.table и aggregate () - PullRequest
3 голосов
/ 12 апреля 2019

Я хочу делать простые вычисления по группам.Как часто я использовал aggregate.Чтобы вычислить sum моего var по группам gp1, gp2 и gp3, я сделал:

m.temp  <- aggregate(var ~ gp1 + gp2 + gp3, df, sum)

Это работает хорошо, но было очень медленно.Прежде чем сделать это в datatable, я хотел попытаться изменить синтаксис функции, чтобы ускорить процесс.Затем я сделал:

m.temp2 <- aggregate(df$var, 
                     list(df$gp1, df$gp2, df$gp3), 
                     sum)

К сожалению для меня, простая проверка показала, что эти вычисления не эквивалентны.

> identical(m.temp, m.temp2)
[1] FALSE

Имена переменных разные, но, что еще хуже, есть разницаиз 19 477 наблюдений (строк) между этими двумя результатами, и это не из-за некоторого присутствия NAs ...

Тогда возникает мой первый вопрос: как получилось?В чем разница между этими двумя синтаксисами?

Чтобы понять, какой синтаксис является хорошим, я попытался сделать это, используя простой процесс data.table.К сожалению, я не смог получить никакого результата, так как мой синтаксис неверен, но я не понимаю, что я пропустил.Я связал:

m.temp4 <- df[, list(sum = sum(df$var)), 
                      by = list(gp1, gp2, gp3)]

наконец, я также попытался напрямую агрегировать новый столбец с тем же отсутствием результатов ...

df[, new.col := sum(var), by = list(gp1, gp2, gp3)] 

Что я сделал не так?

1 Ответ

2 голосов
/ 12 апреля 2019

Если предположить, что набор данных равен data.table или преобразовать в набор данных с setDT

library(data.table)
setDT(df)[, new_col := sum(var), by = .(gp1, gp2, gp3)]

В посте ОП sum было сделано вместо всего столбца df$varэлементов 'var' внутри группы, в результате чего получается одно значение sum.Удалите df$ и используйте имя столбца без кавычек.

ПРИМЕЧАНИЕ. := создает новый столбец.Если целью является суммирование, поместите его в list или .()

setDT(df)[, .(new_col =  sum(var)), by = .(gp1, gp2, gp3)]

Другой вариант - tidyverse

library(tidyverse)
df %>%
    group_by(gp1, gp2, gp3) %>%
    summarise(new_col = sum(var))

для создания нового столбца,заменить summarise на mutate

...