【问题标题】:R: Looping logic to calculate a moving sum over 30 daysR:循环逻辑以计算 30 天的移动总和
【发布时间】:2017-04-30 02:05:38
【问题描述】:

我有几个帐户,我正在尝试计算按帐户分组的 30 天移动存款总和。我想做这个计算的 31 次迭代。因此,每个账户将有 31 个总和,代表 30 天的总存款金额。

例如,第一次迭代是从 10/1 到 10/30 的存款,第二次迭代是 10/2 到 10/31....然后最终是 11/1 到 11/30,例如。

我的第一个想法是做两个循环,按帐户和计算分组。

这里是一些示例数据,两个账户,10 和 11。第 1 天到第 61 天的存款金额。

x <- data.frame(day = c(1:61),
                account = ifelse(runif(61) <.5, 10, 11),
                amount = rnorm(61,mean = 100, sd = 10))

numinterations<-31
numsumdays<-30

monthsums<- for(i in 1:ndays){
              for(i in 1:numsumdays){
                 sum(testloop$daily_total) group by account
              }  


}

【问题讨论】:

    标签: r loops group-by


    【解决方案1】:

    您可以使用zoo 中的rollapply 将移动窗口应用于列。根据要求,我避免使用dplyr。相反,数据框被拆分为数据框列表,并在最后重新组合。

    我不得不先在这里填写缺少的日期/帐户组合,但它才能工作;可能有更优雅的方式来做到这一点。

    library(zoo)
    
    x <- data.frame(day = c(1:61),
                account = ifelse(runif(61) <.5, 10, 11),
                amount = rnorm(61,mean = 100, sd = 10))
    
    all_combinations <- expand.grid(day=unique(x$day),account=unique(x$account))
    x <- merge(x, all_combinations, all=TRUE)
    x[is.na(x)] <- 0
    
    lx <- split(x, x$account)
    for (account in names(lx)) {
      lx[[account]][['rollingSum']] <- rollapply(lx[[account]][['amount']], width=30, FUN=sum, partial=TRUE, align='right')
    }
    names(lx) <- NULL
    x <- do.call(rbind, lx)
    

    【讨论】:

    • 笨重没关系,真实数据会被完全占用。不使用 dplyr 的解决方案怎么样?我不确定如何将该 rollapply 函数应用于其他分组函数
    • 我编辑了解决方案,因此不再需要 dplyr。如果您想使用非标准的聚合函数,只需编写您自己的函数并将其名称提供给 FUN 参数。只要它将一个值向量作为输入,并将单个值作为输出,它就可以工作。
    • 看起来总和正在倒退,所以从输出来看,账户 10 的第 1 天滚动总和应该是 117.099,而不是 1343。但我看到第 61 天,正在添加正确的总和时光倒流
    • 这些数字是随机生成的,所以我无法比较它们;您是说对于第 1 天,您希望总和包括第 1 天吗?现在它看起来比第 1 天早 30 天。当然最后它没有足够的可用天数,所以它把它们当作 0。您可以使用align='right'(我编辑了它)来扭转这种行为
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2013-02-05
    • 1970-01-01
    • 2023-01-30
    • 2020-12-04
    相关资源
    最近更新 更多