2013-05-13 13 views
7

Ho il seguente frame di dati "DF", che è parte di un molto più grande:Il datagram aggregato per data e applica diverse funzioni alle colonne corrispondenti?

   X1 X2   X3 X4 X5 
4468 2010-03-24 3 1.000000e+00 1 2 
7662 2010-03-24 9 3.000000e+00 2 1 
1272 2010-03-25 8 2.000000e+00 1 1 
1273 2010-03-26 9 0.000000e+00 1 1 
1274 2010-03-27 8 0.000000e+00 1 1 
4469 2010-03-28 4 0.000000e+00 1 2 
7663 2010-03-28 4 3.000000e+00 3 1 
8734 2010-03-28 7 4.000000e+00 2 3 
1275 2010-03-29 8 0.000000e+00 1 1 

Come si può vedere la prima colonna contiene una data. Quello che voglio fare è la seguente: voglio trasformare questo dataframe ad uno nuovo "DF2" dove c'è solo 1 riga per data con i valori delle colonne corrispondenti:

X2, the average 
X3, the sum 
X4, the maximum 

di tutti i valori precedenti alla data. X5 non è rilevante e può essere rimosso. Questo sarebbe il risultato:

   X1 X2   X3 X4 
7662 2010-03-24 6 4.000000e+00 2 
1272 2010-03-25 8 2.000000e+00 1 
1273 2010-03-26 9 0.000000e+00 1 
1274 2010-03-27 8 0.000000e+00 1 
8734 2010-03-28 5 7.000000e+00 3 
1275 2010-03-29 8 0.000000e+00 1 

Qualcuno sa come eseguire questa operazione? L'aiuto sarebbe molto apprezzato!

risposta

4

È possibile utilizzare la funzione ddply dal pacchetto plyr fare aggregazioni arbitrarie o altre trasformate da qualche variabile di raggruppamento.

Per la vostra domanda il codice sarebbe simile:

library(plyr) 
result <- ddply(DF, .(X1), function(df) { 
    with(df, data.frame(X1=mean(X1), X2=sum(X2), X3=max(X3))) 
}) 

Se questo è un progetto di medio-grande, allora si può decidere di impostare l'argomento progress per mostrare una barra di avanzamento. Per un problema molto grande può essere impostato per utilizzare l'elaborazione parallela.

+1

'riepilogo 'è un'opzione alternativa alla funzione anonima. – joran

+0

Penso che la parallelizzazione servirà solo se una delle funzioni è il collo della bottiglia di velocità, il che probabilmente non sarebbe il caso di 'mean',' sum' o 'max'. – Roland

8
DF <- read.table(text="    X1 X2   X3 X4 X5 
4468 2010-03-24 3 1.000000e+00 1 2 
7662 2010-03-24 9 3.000000e+00 2 1 
1272 2010-03-25 8 2.000000e+00 1 1 
1273 2010-03-26 9 0.000000e+00 1 1 
1274 2010-03-27 8 0.000000e+00 1 1 
4469 2010-03-28 4 0.000000e+00 1 2 
7663 2010-03-28 4 3.000000e+00 3 1 
8734 2010-03-28 7 4.000000e+00 2 3 
1275 2010-03-29 8 0.000000e+00 1 1",header=TRUE) 

library(data.table) 

DT <- as.data.table(DF) 

DT[,list(X2=mean(X2),X3=sum(X3),X4=max(X4)),by=X1] 

#   X1 X2 X3 X4 
# 1: 2010-03-24 6 4 2 
# 2: 2010-03-25 8 2 1 
# 3: 2010-03-26 9 0 1 
# 4: 2010-03-27 8 0 1 
# 5: 2010-03-28 5 7 3 
# 6: 2010-03-29 8 0 1 
+0

non è sicuro se i rownames sono importanti pezzo di dati o meno. In tal caso, l'istruzione DT può essere 'DT <- data.table (DF, rowName = rownames (DF))' –

+1

Quando viene presa la media di più righe, quale rowname assegneresti? Non penso che i giochi di ruolo siano importanti qui. – Roland

+0

Scusate, avrei dovuto essere più specifico. Il mio commento era più di un genere generale se l'utente desidera continuare ad usare il 'DT' al posto del' DF' originale, oltre lo scopo di questa specifica attività –

4

Ci sono molti modi per farlo, ma qui è una soluzione sqldf:

library(sqldf) 
sqldf("select X1, avg(X2), sum(X3), max(X4) from DF group by X1") 

Il risultato è:

  X1 avg(X2) sum(X3) max(X4) 
1 2010-03-24  6  4  2 
2 2010-03-25  8  2  1 
3 2010-03-26  9  0  1 
4 2010-03-27  8  0  1 
5 2010-03-28  5  7  3 
6 2010-03-29  8  0  1 
Problemi correlati