2011-05-19 93 views
41

我并不需要在R中使用日期,但我想这很容易。我有一个表示数据框中日期的列。我只是想创建一个新的数据框,使用日期按月/年来总结第二列。什么是最好的方法?将日常数据汇总到月/年的间隔

我想要第二个数据帧,所以我可以将它馈送到一个绘图。

任何帮助,您可以提供将不胜感激!

编辑:参考:

> 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 
+0

@ Bibert3你能告诉我们你的日期格式是什么格式吗? POSIX?字符? – 2011-05-19 00:51:20

回答

29

有可能是一个更优雅的解决方案,但分成几个月和几年与strftime()然后aggregate() ing应该这样做。然后重新组装绘图的日期。

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

我有一个函数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.Dateas.POSIXct匹配数据中的日期格式。按月汇总只是使用聚合/按/等的问题。

43

我与lubridateplyr做到这一点,四舍五入日期到最近的一个月,使他们更容易绘制:

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

或者用dplyr,最后一行是'summarize(df,x = mean(my))'。 – Fato39 2016-12-16 18:51:50

0

还有一个解决办法:

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

对于您可以使用barplot

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

你可以做到这一点为:

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

末有点游戏,但另一种选择是使用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 

正如你看到的这会给你的系统语言的月份名称(这是荷兰人在我的情况)。


或使用lubridatedplyr组合:

​​

使用的数据:

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

只需使用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是一个函数,它与(例如和)

+0

为什么单独回答?最好将此添加为您之前回答的替代方法 – Jaap 2016-12-02 10:00:27

1

此外,考虑到时间序列似乎是在XTS格式,您可以聚集你每天的时间序列为每月您汇总数据时间序列使用这样的平均函数:

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