按时间段汇总的数据

时间:2013-08-04 18:31:08

标签: r lubridate

This question询问R中的时间段聚合,pandas调用重新采样。最有用的答案是使用XTS包在给定的时间段内分组,应用一些函数,如sum()或mean()。

其中一条评论表明,在lubridate中有类似的东西,但没有详细说明。有人可以使用lubridate提供一个惯用的例子吗?我已经阅读了几次相关的rubridate小插图,可以想象一下lubridate和plyr的某种组合,但是我想确保没有一种我更容易丢失的方法。

为了让这个例子更加真实,让我们说我想从这个数据集中向北行驶的每日自行车总数:

library(lubridate)
library(reshape2)

bikecounts <- read.csv(url("http://data.seattle.gov/api/views/65db-xm6k/rows.csv?accessType=DOWNLOAD"), header=TRUE, stringsAsFactors=FALSE)
names(bikecounts) <- c("Date", "Northbound", "Southbound")

数据如下所示:

> head(bikecounts)
                    Date Northbound Southbound
1 10/02/2012 12:00:00 AM          0          0
2 10/02/2012 01:00:00 AM          0          0
3 10/02/2012 02:00:00 AM          0          0
4 10/02/2012 03:00:00 AM          0          0
5 10/02/2012 04:00:00 AM          0          0
6 10/02/2012 05:00:00 AM          0          0

4 个答案:

答案 0 :(得分:7)

我不知道你为什么要使用lubridate。如果你只是想寻找比xts更糟糕的东西你可以试试这个

tapply(bikecounts$Northbound, as.Date(bikecounts$Date, format="%m/%d/%Y"), sum)

基本上,您只需按日期split,然后应用函数。


lubridate可用于为分组应用问题创建分组因子。因此,例如,如果您想要每个月的总和(忽略年份)

tapply(bikecounts$Northbound, month(mdy_hms(bikecounts$Date)), sum)

但是,它只是使用基本R函数的包装器,而在OP的情况下,我认为基本R函数as.Date是最简单的(事实证明其他Answers也忽略了你的请求)使用lubridate ;-))。


Answer与OP中链接的另一个Question未涵盖的内容为split.xtsperiod.applyxts分割endpoints并将功能应用于每个组。您可以使用endpoints函数找到对给定任务有用的端点。例如,如果您有一个xts对象x,那么endpoints(x, "months")将为您提供每个月最后一行的行号。 split.xts利用它来分割xts对象 - split(x, "months")将返回一个xts对象列表,其中每个组件的月份不同。

虽然split.xts()endpoints()主要用于xts个对象,但它们也适用于其他一些对象,包括基于简单时间的向量。即使您不想使用xts对象,您仍然可以找到endpoints()的用途,因为它的便利性或速度(在C中实现)

> split.xts(as.Date("1970-01-01") + 1:10, "weeks")
[[1]]
[1] "1970-01-02" "1970-01-03" "1970-01-04"

[[2]]
[1] "1970-01-05" "1970-01-06" "1970-01-07" "1970-01-08" "1970-01-09"
[6] "1970-01-10" "1970-01-11"

> endpoints(as.Date("1970-01-01") + 1:10, "weeks")
[1]  0  3 10

我认为lubridate在这个问题中的最佳用途是将“Date”字符串解析为POSIXct对象。即,在这种情况下mdy_hms函数。

以下是使用xts解析“日期”字符串的lubridate解决方案。

x <- xts(bikecounts[, -1], mdy_hms(bikecounts$Date))
period.apply(x, endpoints(x, "days"), sum)
apply.daily(x, sum) # identical to above

对于此特定任务,xts还具有优化的period.sum函数(用Fortran编写),速度非常快

period.sum(x, endpoints(x, "days"))

答案 1 :(得分:2)

以下是使用data.table的选项 导入csv后

library(data.table)

# convert the data.frame to data.table
bikecounts <- data.table(bikecounts)

# Calculate
bikecounts[, list(NB=sum(Northbound), SB=sum(Southbound)), by=as.Date(Date, format="%m/%d/%Y")]

        as.Date   NB   SB
  1: 2012-10-02 1165  773
  2: 2012-10-03 1761 1760
  3: 2012-10-04 1767 1708
  4: 2012-10-05 1590 1558
  5: 2012-10-06  926 1080
 ---                     
299: 2013-07-27 1212 1289
300: 2013-07-28  902 1078
301: 2013-07-29 2040 2048
302: 2013-07-30 2314 2226
303: 2013-07-31 2008 2076

注意,您还可以使用data.table包中的fread()(“快速读取”)将CSV读入一个data.table中。 唯一的缺点是你手动转换字符串的日期/时间。

eg: 
bikecounts <- fread("http://data.seattle.gov/api/views/65db-xm6k/rows.csv?accessType=DOWNLOAD", header=TRUE, stringsAsFactors=FALSE)
setnames(bikecounts, c("Date", "Northbound", "Southbound"))
bikecounts[, Date := as.POSIXct(D, format="%m/%d/%Y %I:%M:%S %p")] 

答案 2 :(得分:2)

使用plyr包中的ddply

library(plyr)
bikecounts$Date<-with(bikecounts,as.Date(Date, format = "%m/%d/%Y"))
x<-ddply(bikecounts,.(Date),summarise, sumnorth=sum(Northbound),sumsouth=sum(Southbound))


 > head(x)
        Date sumnorth sumsouth
1 2012-10-02     1165      773
2 2012-10-03     1761     1760
3 2012-10-04     1767     1708
4 2012-10-05     1590     1558
5 2012-10-06      926     1080
6 2012-10-07      951     1191


 > tail(x)
          Date sumnorth sumsouth
298 2013-07-26     1964     1999
299 2013-07-27     1212     1289
300 2013-07-28      902     1078
301 2013-07-29     2040     2048
302 2013-07-30     2314     2226
303 2013-07-31     2008     2076

答案 3 :(得分:1)

这是请求的 lubridate 解决方案,我也将其添加到链接的问题中。它使用 lubridate zoo aggregate()的组合进行这些操作:

ts.month.sum <- aggregate(zoo.ts, month, sum)

ts.daily.mean <- aggregate(zoo.ts, day, mean)

ts.mins.mean <- aggregate(zoo.ts, minutes, mean)

显然,您需要先将数据转换为zoo()对象,这很容易。您还可以使用yearmon()或yearqtr(),或者的自定义函数拆分和应用。这种方法在语法上比 pandas 更好。