2015-05-30 15 views
7

Quindi ho un frame di dati che ha una colonna di data, una colonna di un'ora e una serie di altre colonne numeriche. Ogni riga nel frame di dati è 1 ora di 1 giorno per un anno intero.Sommando le righe per mese in R

telaio I dati appare così:

  Date Hour Melbourne Southern Flagstaff 
1 2009-05-01  0   0   5   17 
2 2009-05-01  2   0   2   1 
3 2009-05-01  1   0  11   0 
4 2009-05-01  3   0   3   8 
5 2009-05-01  4   0   1   0 
6 2009-05-01  5   0  49   79 
7 2009-05-01  6   0  425  610 

Le ore sono in ordine perché questo è subsetted da un altro frame di dati.

Vorrei riassumere i valori nelle colonne numeriche per mese e possibilmente per giorno. Qualcuno sa come posso fare questo?

risposta

7

ho creare il set di dati da

data <- read.table(text=" Date Hour Melbourne Southern Flagstaff 
         1 2009-05-01 0 0 5 17 
         2 2009-05-01 2 0 2 1 
         3 2009-05-01 1 0 11 0 
         4 2009-05-01 3 0 3 8 
         5 2009-05-01 4 0 1 0 
         6 2009-05-01 5 0 49 79 
         7 2009-05-01 6 0 425 610", 
        header=TRUE,stringsAsFactors=FALSE) 

Si può fare la somma con la funzione aggregate:

byday <- aggregate(cbind(Melbourne,Southern,Flagstaff)~Date, 
      data=data,FUN=sum) 
library(lubridate) 
bymonth <- aggregate(cbind(Melbourne,Southern,Flagstaff)~month(Date), 
      data=data,FUN=sum) 

Guardate ?aggregate per capire la funzione di meglio. A partire con l'ultimo argomento (perché questo rende più facile spiegare) gli argomenti effettuare le seguenti operazioni:

  • FUN è la funzione che deve essere utilizzato per l'aggregazione. Io uso sum per riassumere i valori, ma potrei anche essere mean, max o qualche funzione che hai scritto tu stesso.
  • data viene utilizzato per indicare il frame di dati che desidero aggregare.
  • Il primo argomento indica alla funzione che cosa esattamente voglio aggregare. Sul lato sinistro di ~, indico le variabili che voglio aggregare. Se ce n'è più di uno, vengono combinati con cbind. Sul lato destro è la variabile in base alla quale i dati devono essere divisi. Mettendo Date significa che l'aggregato somma le variabili per ciascun valore distinto di Date.

Per l'aggregazione per mese, ho utilizzato la funzione month dal pacchetto lubridate. Fa ciò che ci si aspetta: restituisce un valore numerico che indica il mese per una determinata data. Forse è necessario prima installare il pacchetto entro il install.packages("lubridate").

Se si preferisce non utilizzare lubridate, si potrebbe fare la seguente invece:

data <- transform(data,month=as.numeric(format(as.Date(Date),"%m"))) 
bymonth <- aggregate(cbind(Melbourne,Southern,Flagstaff)~month, 
        data=data,FUN=sum) 

Qui ho aggiunto una nuova colonna di dati che contiene il mese e poi aggregate per quella colonna.

+0

Ricevo un errore sul libreria (lubridate) line. Doi è necessario importare manualmente il pacchetto? – user2787386

+1

L'hai installato per primo? 'Installazione.pacchetti ("lubridate") ' –

+0

Ci scusiamo per ... Sì, è necessario installare il pacchetto come descritto da @Marta Cz-C. – Stibu

7

Questo potrebbe essere un altro modo per farlo utilizzando data.table

library(data.table) 
# Edited as per Arun's comment 
out = setDT(data)[, lapply(.SD, sum), by=Date] 

#>out 
#   Date Hour Melbourne Southern Flagstaff 
#1: 2009-05-01 21   0  496  715 

o utilizzando dplyr

library(dplyr) 
out = data %>% group_by(Date) %>% summarise_each(funs(sum)) 

#>out 
#Source: local data frame [1 x 5] 
#  Date Hour Melbourne Southern Flagstaff 
#1 2009-05-01 21   0  496  715 
+3

L'equivalente della tua soluzione dplyr in data.table è semplicemente: 'setDT (data) [, lapply (.SD, sum), per = Date]' – Arun

+0

Sì, certo !, grazie Arun. Farò i cambiamenti ora. –

4

Un'altra soluzione di base R

# to sum by date 
rowsum(dat[-1], dat$Date) 
#   Hour Melbourne Southern Flagstaff 
#2009-05-01 21   0  496  715 

# or by month and year 
rowsum(dat[-1], format(dat$Date, "%b-%y")) 
#  Hour Melbourne Southern Flagstaff 
#May-09 21   0  496  715