Данные панели данных R data.table

У меня есть панельные данные (тема/год), для которых я хотел бы сохранить только те объекты, которые появляются максимальное количество раз в год. Набор данных большой, поэтому я использую пакет data.table. Есть ли более элегантное решение, чем то, что я пробовал ниже?

library(data.table)

DT <- data.table(SUBJECT=c(rep('John',3), rep('Paul',2), 
                           rep('George',3), rep('Ringo',2), 
                           rep('John',2), rep('Paul',4), 
                           rep('George',2), rep('Ringo',4)), 
                 YEAR=c(rep(2011,10), rep(2012,12)), 
                 HEIGHT=rnorm(22), 
                 WEIGHT=rnorm(22))
DT

DT[, COUNT := .N, by='SUBJECT,YEAR']
DT[, MAXCOUNT := max(COUNT), by='YEAR']

DT <- DT[COUNT==MAXCOUNT]
DT <- DT[, c('COUNT','MAXCOUNT') := NULL]
DT

Ответ 1

Я не уверен, что вы будете рассматривать это как элегантное, но как насчет:

DT[, COUNT := .N, by='SUBJECT,YEAR']
DT[, .SD[COUNT == max(COUNT)], by='YEAR']

Это, по сути, как применить by к выражению i, как @SenorO прокомментировал. Вам все равно понадобится [,COUNT:=NULL], но для одного временного столбца, а не для двух.

Мы не поощряем .SD хотя и по соображениям скорости, но, надеюсь, скоро получим этот запрос функции, чтобы совет можно было отбросить: FR # 2330 Оптимизировать .SD [i] запрос, чтобы сохранить изящество, но сделать его более быстрым..

Другой подход заключается в следующем. Это быстрее и идиоматично, но может считаться менее элегантным.

# Create a small aggregate table first. No need to use := on the big table.
i = DT[, .N, by='SUBJECT,YEAR']

# Find the even smaller subset. (Do as much as we can on the small aggregate.)
i = i[, .SD[N==max(N)], by=YEAR]

# Finally join the small subset of key values to the big table
setkey(DT, YEAR, SUBJECT)
DT[i]

Нечто похожее на здесь.