【问题标题】:R previous week total [duplicate]R前一周总计[重复]
【发布时间】:2015-05-31 12:57:35
【问题描述】:

我有日期(B 列)和总计(A 列)变量 - 我如何在 R 中创建一个新变量来汇总前 7 天的总计值?

在 Excel 中,我有以下公式:

=SUMIFS($A:$A,$B:$B, ">="&$B20-7,$B:$B,"<"&$B20)

我只是不知道如何将其转换为在 R. 中工作。建议?

【问题讨论】:

  • 我不熟悉 Excel,但我想您可能正在寻找 zoo 包中的 rollsum 函数。
  • @AlexWoolford:好主意,但这只有在他们的数据每天都只有一个观察值时才有效。 zoo::window 可能更合适。
  • 数据每天只包含一个观察值。我正在查看rollsum 的文档,但我仍然不清楚如何包含仅对前 7 天求和的标准。

标签: r sum


【解决方案1】:

这也可以,高级但简短 - 基本上是单线。

# Initialze some data
date <- seq(as.Date("2001-01-01"),as.Date("2001-01-31"),"days")
tot <- trunc(rnorm(31,100,20))
df <- data.frame(date,tot)

# Now compute week sum by summing a subsetted df for each date
df$wktot <- sapply(df$date,function(x)sum(df[difftime(df$date,x,,"days") %in% 0:-6,]$tot))

更改了变量名称以匹配提出的问题。

它还以任何顺序处理数据,每天处理多个条目。

编辑添加 cmets 并使其适合窗口。

【讨论】:

  • 更改了变量名并修正了一个错字。
  • 很好的答案。投了赞成票
  • 一站式服务。我写了一篇将日子分组的文章,但可以如此简洁地完成它真是太好了。仍在尝试解压缩您的代码:)
  • 在实践中,子集化向量而不是整个数据帧可能会更好。对于大数据帧会更快......现在我想到了。
  • 我添加了一个分组功能。它有效,但非常罗嗦。如果我能以某种方式合并difftime,我也许可以缩短。并且您的不会为小于滚动总和组的组返回 NA。它只是将天数添加到第 i 个元素。我没有考虑到这一点。
【解决方案2】:

如果每天有一个总数,这个功能可能会有所帮助:

rollSums <- function(totals, roll) {
  res <- c()
  for(i in 1:(length(totals)-roll)) {
    res <- c(res, sum(totals[0:(roll-1)+i]))
  }
  res
}

df1
   Total       Date
1      3 2015-01-01
2      8 2015-01-01
3      4 2015-01-02
4      7 2015-01-03
5      6 2015-01-04
6      1 2015-01-04
7     10 2015-01-05
8      9 2015-01-06
9      2 2015-01-07
10     5 2015-01-08

rollSums(df1$Total, 3)
[1] 15 19 17 14 17 20 21

rollSums(df1$Total, 4)
[1] 22 25 18 24 26 22

这将需要两个参数,带有总数的向量以及您希望每个总和的天数。

数据

dput(df1)
structure(list(Total = c(3L, 8L, 4L, 7L, 6L, 1L, 10L, 9L, 2L, 
5L), Date = structure(c(16436, 16436, 16437, 16438, 16439, 16439, 
16440, 16441, 16442, 16443), class = "Date")), .Names = c("Total", 
"Date"), row.names = c(NA, -10L), class = "data.frame")

更新

如果您在同一天遇到多个值的情况,这里有一个解决方案。令人惊讶的是,@MikeWise 有一个可以做到所有这些的单线。查看其他答案。

grouped.roll <- function(DF, Values, Group, roll) {
  totals <- eval(substitute(with(DF, tapply(Values, Group, sum))))
  newsums <- rollSums(totals, roll)
  data.frame(Group=names(totals), Sums=c(rep(NA, roll), newsums))
}

它使用我之前使用的rollSums。它会吐出 NA,直到所需的日期分组开始。这可能是与其他答案相比的唯一优势。但我敢肯定,他们可以轻松地对其进行编辑。只是提供更多选项供参考。

grouped.roll(df1, Total, Date, 3)
       Group Sums
1 2015-01-01   NA
2 2015-01-02   NA
3 2015-01-03   NA
4 2015-01-04   22
5 2015-01-05   18
6 2015-01-06   24
7 2015-01-07   26
8 2015-01-08   21

【讨论】:

  • 我也从中学到了一些东西。
猜你喜欢
  • 2013-10-02
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2020-11-22
  • 2017-09-09
  • 1970-01-01
相关资源
最近更新 更多