将每日数据汇总到月/年间隔
我经常不需要在R中使用date,但我想这很容易。 我有一个表示数据框中的date的列。 我只是想创build一个新的数据框,使用date按月/年来总结第二列。 什么是最好的方法?
我想要第二个dataframe,所以我可以喂它到一个情节。
任何帮助,您可以提供将不胜感激!
编辑:供参考:
> 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
有可能是一个更优雅的解决scheme,但分裂成几个月和几年strftime()
然后aggregate()
ing应该做到这一点。 然后重新组装绘图的date。
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 = "-"))
我会用lubridate
和plyr
来做这些plyr
,将date舍入到最近的月份,以使它们更容易绘图:
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))
有点迟到游戏,但另一种select是使用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))]
这给了:
yr mon mn_amt 1: 2011 februari 42.610 2: 2011 maart 23.195 3: 2011 april 61.891
如果你想要的名字,而不是数字的月份,你可以使用:
setDT(temp)[, date := as.IDate(date) ][, .(mn_amt = mean(amount)), by = .(yr = year(date), mon = months(date))]
这给了:
yr mon mn_amt 1: 2011 februari 42.610 2: 2011 maart 23.195 3: 2011 april 61.891
正如你所看到的,这会给你的系统语言的月份名称(在我的情况下是荷兰语)。
或者使用lubridate
和dplyr
的组合:
temp %>% group_by(yr = year(date), mon = month(date)) %>% summarise(mn_amt = mean(amount))
使用的数据:
# 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))
只需使用xts包就可以了。
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)
其中FUN是一个函数,你聚合数据(例如总和)
你可以这样做:
short.date = strftime(temp$date, "%Y/%m") aggr.stat = aggregate(temp$amount ~ short.date, FUN = sum)
我有一个函数monyr
,我用这种东西:
monyr <- function(x) { x <- as.POSIXlt(x) x$mday <- 1 as.Date(x) } n <- as.Date(1:500, "1970-01-01") nn <- monyr(n)
您可以将as.Date
更改为as.POSIXct
以匹配数据中的date格式。 按月汇总只是使用汇总/按/等的问题。
此外,考虑到您的时间序列似乎是xt格式,您可以使用如下的平均函数将您的每日时间序列汇总为月度时间序列:
d2m <- function(x) { aggregate(x, format(as.Date(zoo::index(x)), "%Y-%m"), FUN=mean) }
另一个解决scheme:
rowsum(temp$amount, format(temp$date,"%Y-%m"))
对于情节,你可以使用barplot
:
barplot(t(rowsum(temp$amount, format(temp$date,"%Y-%m"))), las=2)