2013-01-23 5 views
8

Utilizzando il pacchetto data.table, è possibile riepilogare i dati preservando combinazioni di variabili che non compaiono nell'input?Come conservare combinazioni di variabili che non appaiono nei dati di input quando si raggruppa con data.table?

Con plyr pacchetto So come fare questo con l'argomento .Drop, ad esempio:

require(plyr) 
df <- data.frame(categories = c(rep("A",3), rep("B",3), rep("C",3)), groups = c(rep(c("X", "Y"),4), "Z"), values = rep(1, 9)) 

df1 <- ddply(df, c("categories","groups"), .drop = F, summarise, sum = sum(values)) 

uscita:

categories groups sum 
1   A  X 2 
2   A  Y 1 
3   A  Z 0 
4   B  X 1 
5   B  Y 2 
6   B  Z 0 
7   C  X 1 
8   C  Y 1 
9   C  Z 1 

In questo caso io conservo tutti i gruppi/categorie, anche se le combinazioni la sua somma è 0.

risposta

8

Grande domanda. Qui ci sono due modi. Entrambi usano by-without-by.

DT = as.data.table(df) 
setkey(DT,categories,groups) 
DT[CJ(unique(categories),unique(groups)), sum(values,na.rm=TRUE)] 

    categories groups V1 
1:   A  X 2 
2:   A  Y 1 
3:   A  Z 0 
4:   B  X 1 
5:   B  Y 2 
6:   B  Z 0 
7:   C  X 1 
8:   C  Y 1 
9:   C  Z 1 

dove CJ sta per cross join, vedere ?CJ. by-without-by significa semplicemente che j viene eseguito su ciascun gruppo a cui ogni riga di i si unisce.

Ammetto che a prima vista sembra difficile. L'idea è che se si dispone di un sottoinsieme noto di gruppi, questa sintassi è più veloce di raggruppare tutto e quindi selezionare solo i risultati da ciò che è necessario. Ma in questo caso ti piacerebbe tutto comunque, quindi non c'è molto vantaggio, oltre alla possibilità di cercare gruppi che non esistono nei dati (cosa che non puoi fare con by).

Un altro modo è quello di by prima come normale, quindi unire il risultato CJ() a che:

DT[,sum(values),keyby='categories,groups'][CJ(unique(categories),unique(groups))] 
    categories groups V1 
1:   A  X 2 
2:   A  Y 1 
3:   A  Z NA 
4:   B  X 1 
5:   B  Y 2 
6:   B  Z NA 
7:   C  X 1 
8:   C  Y 1 
9:   C  Z 1 

ma poi si ottiene NA invece del desiderato 0. Coloro potrebbe essere sostituito con set() se necessario. Il secondo modo potrebbe essere più veloce perché le due chiamate unique hanno un input molto più piccolo.

Entrambi i metodi possono essere racchiusi in piccole funzioni di supporto se lo si fa molto.

Problemi correlati