【问题标题】:Aggregate Weekly Data in R在 R 中聚合每周数据
【发布时间】:2010-12-04 00:55:17
【问题描述】:

我确信这是直截了当的,但我似乎无法让它发挥作用。我有一个代表每日总数的数据框。我只想按周对总数求和,如果没有表示一周,则保留零。 R中最好的方法是什么?万一这很重要,我从 CSV 中读取数据并在 R 中将其转换为日期。

这是我的数据框 p1 的结构:

'data.frame':   407 obs. of  2 variables:
 $ date:Class 'Date'  num [1:407] 14335 14336 14337 14340 14341 ...
 $ amt : num  45 150 165 165 45 45 150 150 15 165 ...

还有前几个……

> head(p1)
        date amt
1 2009-04-01  45
2 2009-04-02 150
3 2009-04-03 165
4 2009-04-06 165
5 2009-04-07  45
6 2009-04-08  45

提前非常感谢。

备注:我之前看到过post,但无法使用

【问题讨论】:

  • 尝试将您的数据转换为zooxts。另外,请发布您正在尝试的命令及其给出的错误输出。我认为,如果您遵循 Shane 的指导,并在 "sum" 之后设置 na.rm=T,那么它应该在 NA 的几周内回吐 NaN

标签: datetime r


【解决方案1】:

lubridate 库的解决方案:

library(lubridate)
Lines <- "date,amt
2009-04-01,45
2009-04-02,150
2009-04-03,165
2009-04-13,165
2009-04-14,45
2009-04-15,45
2009-05-15,45"
df <- read.csv(textConnection(Lines))

如果您不需要 0 来缺席几周,这很简单:

weeks <- week(df$date)
sums <- tapply(df$amt, weeks, sum)
# 14  15  16  20 
#360 210  45  45 

将缺失的周数归零:

span <- min(weeks):max(weeks)
out <- array(0, dim = length(span), dimnames = list(span))
out[dimnames(sums)[[1]]] <- sums
# 14  15  16  17  18  19  20 
#360 210  45   0   0   0  45 

【讨论】:

    【解决方案2】:

    这是一个解决方案,它读取数据,按周汇总数据,然后在 3 行代码中用零填充缺失的周数。 read.zoo 在假定标题和逗号字段分隔符的情况下读取它。它将第一列转换为Date 类,然后将日期转换为下一个星期五。执行此转换的 nextfri 函数取自 zoo 包中的 zoo-quickref 小插图。 (如果您想让一周的结束成为一周中的不同日期,只需将公式中的 every 5 替换为另一个日期数。这个想法是相对于 d-4 下降的 UNIX 纪元在星期几,d=0 是星期日,d=1 是蒙达,...,d=6 是星期六,所以从那以后 7 天的任何倍数也落在星期几。)read.zoo命令还聚合具有相同索引的所有点(请记住,我们已将它们转换为一周的最后一个星期五,因此同一周中的所有点现在将具有与其索引相同的星期五)。下一个命令创建一个宽度为零的 zoo 对象,该对象具有从第一个到最后一个的周数,并使用 fill = 0 将其与读取的输出合并,以便填充的周数得到该值。

    Lines <- "date,amt
    2009-04-01,45
    2009-04-02,150
    2009-04-03,165
    2009-04-13,165
    2009-04-14,45
    2009-04-15,45"
    library(zoo)
    nextfri <- function(x) 7 * ceiling(as.numeric(x - 5 + 4)/7) + as.Date(5 - 4)
    z <- read.zoo(textConnection(Lines), header = TRUE, sep = ",", 
        FUN = as.Date, FUN2 = nextfri, aggregate = sum)
    merge(z, zoo(, seq(min(time(z)), max(time(z)), 7)), fill = 0)
    

    我们使用上面的textConnection(Lines) 使其独立,以便您可以将其复制并直接粘贴到您的会话中,但实际上textConnection(Lines) 将替换为您的文件名,例如"myfile.csv".

    对于上面的输入,输出将是以下动物园对象:

    2009-04-03 2009-04-10 2009-04-17 
           360          0        255
    

    您可能想阅读 zoo 包附带的三个小插曲。

    【讨论】:

    • 这正是我要找的!两件事:我收到一个错误,因为我怀疑 CSV 文件中的“日期”是日/月/年。我在帮助中看到我可以将其作为格式“%d/%m/%Y”传递,但我不确定这是否会导致错误。其次,我希望星期天结束,星期一开始新的一周。再次感谢!
    • 这真的是不必要的,因为 library(zoo) 已经被使用了,如果没有 zoo,后续行将无法工作。如果您想将该行脱离上下文并使其独立于 zoo,您可以明确指定 origin= 参数。
    • 如果你想让周末成为一周中的不同日期,只需将 5 替换为另一个日期数。 - 我对此有点困惑 - 实际上我认为-5+4 是一个常数(可以用 -1 代替) - ??? (请参阅我的答案,因为评论代码太多而发布)
    • 我已经在回答中澄清了必须替换 5 的两个实例。
    • 来自 G.Grothendieck 本人对我的一篇(现已删除)帖子的评论:周日用 0 替换 5 的两个实例:像这样:nextsun
    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多