2013-09-05 15 views
11

Mam dane panelu (temat/rok), dla których chciałbym tylko trzymać tematy, które pojawiają się maksymalną liczbę razy w roku. Zbiór danych jest duży, więc używam pakietu data.table. Czy istnieje bardziej eleganckie rozwiązanie niż to, które próbowałem poniżej?R data.table dane panelu zliczania

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 
+0

Tak więc, zasadniczo, potrzebujesz danych z wszystkich danych z najbardziej bogatego w dane roku dla każdego beatle? –

+0

Pomyśl o tym, byłoby miło, gdyby 'data.table' posiadało niektóre z tych samych funkcji' by' w wyrażeniu 'i', tak jak ma to miejsce w wyrażeniach' j'. –

Odpowiedz

14

nie jestem pewien, że to jako eleganckim ale jak o:

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

To w zasadzie jak stosować by do wyrażenia i jak @SenorO skomentował. Nadal będziesz potrzebował [,COUNT:=NULL], ale zamiast jednej tymczasowej kolumny zamiast dwóch.

Odradzamy jednak ze względów szybkościowych .SD, ale mamy nadzieję, że wkrótce otrzymamy tę prośbę o funkcję, aby porady mogły zostać usunięte: FR#2330 Optimize .SD[i] query to keep the elegance but make it faster unchanged..

Inne podejście jest następujące. Jest szybszy i idiomatyczny, ale można go uznać za mniej elegancki.

# 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] 

Coś podobnego jest here.