Données quotidiennes agrégées à intervalles de mois / année

Je n’ai pas souvent à travailler avec des dates dans R, mais j’imagine que c’est assez facile. J’ai une colonne qui représente une date dans un dataframe. Je veux simplement créer un nouveau dataframe qui résume une 2ème colonne par Mois / Année en utilisant la date. Quelle est la meilleure approche?

Je veux un second dataframe pour pouvoir le nourrir sur un terrain.

Toute aide que vous pouvez apporter sera grandement appréciée!

EDIT: Pour référence:

> 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 

Il y a probablement une solution plus élégante, mais la division en mois et années avec strftime() et ensuite l’ aggregate() devrait le faire. Rassemblez ensuite la date pour le traçage.

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

Je le ferais avec du lubridate et du plyr , arrondissant les dates au mois le plus proche pour les rendre plus faciles à tracer:

 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 peu tard pour le jeu, mais une autre option serait d’utiliser 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))] 

cela donne:

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

Si vous voulez des noms plutôt que des nombres pour les mois, vous pouvez utiliser:

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

cela donne:

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

Comme vous le voyez, cela donnera les noms des mois dans la langue de votre système (qui est le néerlandais dans mon cas).


Ou en utilisant une combinaison de lubridate et de dplyr :

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

Données utilisées:

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

Utilisez simplement le package xts pour cela.

 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) 

où FUN est une fonction avec laquelle vous agrégez des données (par exemple sum)

Vous pouvez le faire comme:

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

J’ai une fonction monyr que j’utilise pour ce genre de choses:

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

Vous pouvez remplacer as.Date à la fin par as.POSIXct pour correspondre au format de date de vos données. Résumer par mois, c'est simplement utiliser l'agrégat / by / etc.

De plus, étant donné que vos séries chronologiques semblent être au format xts, vous pouvez agréger vos séries chronologiques quotidiennes à une série chronologique mensuelle en utilisant la fonction moyenne comme ceci:

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

Une solution de plus:

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

Pour l’insortinggue, vous pouvez utiliser barplot :

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