2011-03-04 13 views
13

Ho un dati meteo orarie nel seguente formato:Aggregare dati orari in aggregati quotidiani

Date,DBT 
01/01/2000 01:00,30 
01/01/2000 02:00,31 
01/01/2000 03:00,33 
... 
... 
12/31/2000 23:00,25 

cosa ho bisogno è un aggregato giornaliera di max, min, ave in questo modo:

Date,MaxDBT,MinDBT,AveDBT 
01/01/2000,36,23,28 
01/02/2000,34,22,29 
01/03/2000,32,25,30 
... 
... 
12/31/2000,35,9,20 

Come fare questo in R?

+7

prossima volta, forniscono le tabelle di dati in un formato readible, ad esempio utilizzando dput() o dare il codice eseguibile che fornisce i dati come ho mostrato nella mia risposta. –

+0

Dopo aver letto le risposte proposte, mi chiedo se non può essere fatto usando solo la base R. –

risposta

18

1) Questo può essere fatto in modo compatto utilizzando zoo:

L <- "Date,DBT 
01/01/2000 01:00,30 
01/01/2000 02:00,31 
01/01/2000 03:00,33 
12/31/2000 23:00,25" 

library(zoo) 
stat <- function(x) c(min = min(x), max = max(x), mean = mean(x)) 
z <- read.zoo(text = L, header = TRUE, sep = ",", format = "%m/%d/%Y", aggregate = stat) 

Questo dà:

> z 
      min max  mean 
2000-01-01 30 33 31.33333 
2000-12-31 25 25 25.00000 

2) qui è una soluzione che utilizza solo nucleo R:

DF <- read.csv(text = L) 
DF$Date <- as.Date(DF$Date, "%m/%d/%Y") 
ag <- aggregate(DBT ~ Date, DF, stat) # same stat as in zoo solution 

L'ultima riga indica:

> ag 
     Date DBT.min DBT.max DBT.mean 
1 2000-01-01 30.00000 33.00000 31.33333 
2 2000-12-31 25.00000 25.00000 25.00000 

MODIFICA: (1) Da quando è comparso per la prima volta l'argomento text= a read.zoo è stato aggiunto nel pacchetto zoo. (2) miglioramenti minori.

+0

@Grothendieck: +1 Non mi ero mai reso conto che potevi semplicemente rilasciare le informazioni orarie non specificandolo in as.Date(). –

+0

Sto guardando questo dal telefono, ma Id scommetto che la soluzione 'aggregata' fornisce una colonna di lista che non puoi usare per niente a meno che non avanzi l'intero contenuto in' do.call (cbind.data.frame, aggregate ... ' –

+0

Produce un data.frame la cui prima colonna è' ag $ Date. E la cui seconda colonna è la matrice 'ag $ DBT', le cui colonne sono' "min" ',' "max" 'e' "significano" '. Si converte facilmente in una serie di zoo usando 'read.zoo (ag)'. –

5

Utilizzando strptime(), trunc() e ddply() dal pacchetto plyr:

#Make the data 
ZZ <- textConnection("Date,DBT 
01/01/2000 01:00,30 
01/01/2000 02:00,31 
01/01/2000 03:00,33 
12/31/2000 23:00,25") 
dataframe <- read.csv(ZZ,header=T) 
close(ZZ) 

# Do the calculations 
dataframe$Date <- strptime(dataframe$Date,format="%m/%d/%Y %H:%M") 
dataframe$day <- trunc(dataframe$Date,"day") 

require(plyr) 

ddply(dataframe,.(day), 
     summarize, 
     aveDBT=mean(DBT), 
     maxDBT=max(DBT), 
     minDBT=min(DBT) 
) 

  day aveDBT maxDBT minDBT 
1 2000-01-01 31.33333  33  30 
2 2000-12-31 25.00000  25  25 

per chiarire:

strptime converte il carattere di date in base al formato. Per vedere come è possibile specificare il formato, vedere ?strptime. trunc quindi troncherà queste date per l'unità specificata, che in questo caso è giorno.

ddply valuterà la funzione summarize all'interno del dataframe dopo averlo diviso in base a day. tutto dopo summarize sono argomenti passati alla funzione summarize.

+1

Hai veramente bisogno del wrapper per "riassumere"? –

+0

@Sacha: anzi, non ce n'è bisogno, grazie per la correzione. Si sta facendo tardi qui ... –

2

C'è anche un bel pacchetto chiamato HydroTSM. Esso utilizza oggetti zoo e può convertire in altri aggregati in tempo

La funzione nel tuo caso è subdaily2daily. È possibile scegliere se l'aggregazione dovrebbe essere basata su min/max/media ...

0

È possibile utilizzare il pacchetto tidyquant per questo. Il processo prevede l'uso della funzione tq_transmute per restituire un frame di dati che viene modificato utilizzando la funzione di aggregazione xts, apply.daily. Applicheremo un numero personalizzato stat_fun, che restituisce il valore min, max e medio. Tuttavia, puoi applicare qualsiasi funzione vettoriale che desideri, ad esempio quantile.

library(tidyquant) 

df 
#> # A tibble: 4 x 2 
#>     Date DBT 
#>    <dttm> <dbl> 
#> 1 2000-01-01 01:00:00 30 
#> 2 2000-01-01 02:00:00 31 
#> 3 2000-01-01 03:00:00 33 
#> 4 2000-12-31 23:00:00 25 

stat_fun <- function(x) c(min = min(x), max = max(x), mean = mean(x)) 

df %>% 
    tq_transmute(select  = DBT, 
       mutate_fun = apply.daily, 
       FUN  = stat_fun) 
# A tibble: 2 x 4 
#>     Date min max  mean 
#>    <dttm> <dbl> <dbl> <dbl> 
#> 1 2000-01-01 03:00:00 30 33 31.33333 
#> 2 2000-12-31 23:00:00 25 25 25.00000 
Problemi correlati