Intervalos diarios agregados al mes / año

A menudo no tengo que trabajar con fechas en R, pero me imagino que esto es bastante fácil. Tengo una columna que representa una fecha en un dataframe. Simplemente quiero crear un nuevo dataframe que resum una 2da columna por Mes / Año usando la fecha. ¿Cuál es el mejor enfoque?

Quiero un segundo dataframe para poder alimentarlo a una ttwig.

¡Cualquier ayuda que puede proporcionar será muy apreciada!

EDITAR: Para referencia:

> 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 

Probablemente strftime() una solución más elegante, pero dividida en meses y años con strftime() y luego aggregate() ing debería hacerlo. Luego vuelva a armar la fecha para trazar.

 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 = "-")) 

Lo haría con lubridate y plyr , redondeando las fechas al mes más cercano para que sean más fáciles de trazar:

 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)) 

Un poco tarde para el juego, pero otra opción sería usar 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))] 

esto da:

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

Si desea nombres en lugar de números para los meses, puede usar:

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

esto da:

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

Como verá, dará los nombres de los meses en el idioma de su sistema (que es holandés en mi caso).


O usando una combinación de lubridate y dplyr :

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

Datos usados:

 # 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)) 

Solo usa el paquete xts para esto.

 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) 

donde FUN es una función con la que agregas datos (por ejemplo, sum)

Puedes hacerlo como:

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

Tengo un monyr función que uso para este tipo de cosas:

 monyr <- function(x) { x <- as.POSIXlt(x) x$mday <- 1 as.Date(x) } n <- as.Date(1:500, "1970-01-01") nn <- monyr(n) 

Puede cambiar el as.Date al final como. as.POSIXct para que coincida con el formato de fecha en sus datos. Resumir por mes es simplemente una cuestión de usar agregado / por / etc.

Además, dado que sus series de tiempo parecen estar en formato xts, puede agregar su serie de tiempo diaria a una serie de tiempo mensual utilizando la función de la media de esta manera:

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

Una solución más:

  rowsum(temp$amount, format(temp$date,"%Y-%m")) 

Para la ttwig, puedes usar el barplot :

 barplot(t(rowsum(temp$amount, format(temp$date,"%Y-%m"))), las=2)