Domanda Aggregare i dati giornalieri a intervalli mese / anno


Non devo spesso lavorare con le date in R, ma immagino che sia abbastanza facile. Ho una colonna che rappresenta una data in un dataframe. Voglio semplicemente creare un nuovo dataframe che riepiloghi una seconda colonna per mese / anno utilizzando la data. Qual è l'approccio migliore?

Voglio un secondo dataframe in modo da poterlo alimentare ad una trama.

Qualsiasi aiuto tu possa fornire sarà molto apprezzato!

EDIT: Per riferimento:

> str(temp)
'data.frame':   215746 obs. of  2 variables:
 $ date  : POSIXct, format: "2011-02-01" "2011-02-01" "2011-02-01" ...
 $ amount: num  1.67 83.55 24.4 21.99 98.88 ...

> head(temp)
        date amount
1 2011-02-01  1.670
2 2011-02-01 83.550
3 2011-02-01 24.400
4 2011-02-01 21.990
5 2011-02-03 98.882
6 2011-02-03 24.900

44
2018-05-19 00:48


origine


risposte:


Probabilmente esiste una soluzione più elegante, ma con cui dividere in mesi e anni strftime() e poi aggregate()dovrebbe farlo Quindi riassemblare la data per la stampa.

x <- as.POSIXct(c("2011-02-01", "2011-02-01", "2011-02-01"))
mo <- strftime(x, "%m")
yr <- strftime(x, "%Y")
amt <- runif(3)
dd <- data.frame(mo, yr, amt)

dd.agg <- aggregate(amt ~ mo + yr, dd, FUN = sum)
dd.agg$date <- as.POSIXct(paste(dd.agg$yr, dd.agg$mo, "01", sep = "-"))

31
2018-05-19 01:42



Lo farei con lubridate e plyrarrotondando le date al mese più vicino per renderle più facili da tracciare:

library(lubridate)
df <- data.frame(
  date = today() + days(1:300),
  x = runif(300)
)
df$my <- floor_date(df$date, "month")

library(plyr)
ddply(df, "my", summarise, x = mean(x))

45
2018-05-21 15:42



Un po 'tardi per il gioco, ma un'altra opzione potrebbe essere utilizzata data.table:

library(data.table)
setDT(temp)[, .(mn_amt = mean(amount)), by = .(yr = year(date), mon = months(date))]

# or if you want to apply the 'mean' function to several columns:
# setDT(temp)[, lapply(.SD, mean), by=.(year(date), month(date))]

questo da:

     yr      mon mn_amt
1: 2011 februari 42.610
2: 2011    maart 23.195
3: 2011    april 61.891

Se desideri i nomi anziché i numeri per i mesi, puoi utilizzare:

setDT(temp)[, date := as.IDate(date)
            ][, .(mn_amt = mean(amount)), by = .(yr = year(date), mon = months(date))]

questo da:

     yr      mon mn_amt
1: 2011 februari 42.610
2: 2011    maart 23.195
3: 2011    april 61.891

Come vedi, questo darà i nomi dei mesi nella tua lingua di sistema (che è olandese nel mio caso).


O usando una combinazione di lubridate e dplyr:

temp %>% 
  group_by(yr = year(date), mon = month(date)) %>% 
  summarise(mn_amt = mean(amount))

Dati usati:

# example data (modified the OP's data a bit)
temp <- structure(list(date = structure(1:6, .Label = c("2011-02-01", "2011-02-02", "2011-03-03", "2011-03-04", "2011-04-05", "2011-04-06"), class = "factor"), 
                       amount = c(1.67, 83.55, 24.4, 21.99, 98.882, 24.9)), 
                  .Names = c("date", "amount"), class = c("data.frame"), row.names = c(NA, -6L))

13
2017-08-10 19:49



Basta usare il pacchetto xts per questo.

library(xts)
ts <- xts(temp$amount, as.Date(temp$date, "%Y-%m-%d"))

# convert daily data
ts_m = apply.monthly(ts, FUN)
ts_y = apply.yearly(ts, FUN)
ts_q = apply.quarterly(ts, FUN)

dove FUN è una funzione con cui si aggregano i dati (ad esempio somma)


8
2017-09-25 15:44



Puoi farlo come:

short.date = strftime(temp$date, "%Y/%m")
aggr.stat = aggregate(temp$amount ~ short.date, FUN = sum)

4
2017-11-24 15:07



Ho una funzione monyr che uso per questo tipo di cose:

monyr <- function(x)
{
    x <- as.POSIXlt(x)
    x$mday <- 1
    as.Date(x)
}

n <- as.Date(1:500, "1970-01-01")
nn <- monyr(n)

Puoi cambiare il as.Date alla fine di as.POSIXct per abbinare il formato della data nei tuoi dati. Riassumere per mese è quindi solo questione di usare aggregato / per / etc.


3
2018-05-19 01:20



Inoltre, dato che le tue serie temporali sembrano essere in formato xts, puoi aggregare le serie temporali giornaliere a serie temporali mensili usando la funzione media come questa:

d2m <- function(x) {
  aggregate(x, format(as.Date(zoo::index(x)), "%Y-%m"), FUN=mean)
}

1
2018-03-15 10:23