R - 按组的累积产品和总和

Posted

技术标签:

【中文标题】R - 按组的累积产品和总和【英文标题】:R - cumulative product & sum by group 【发布时间】:2021-06-18 17:12:33 【问题描述】:

我有以下数据集并想添加一个新列“colY”。如何实现(下图为colY是如何计算的)?

GROUP   ID  colX   colY
1       1   0.8    =0.8*(1+0.7*(1+0.6))
1       2   0.7    =0.7*(1+0.6)
1       3   0.6    =0.6
2       1   1.3    =1.3*(1+1.2*(1+1.1*(1+1.0)))
2       2   1.2    =1.2*(1+1.1*(1+1.0))
2       3   1.1    =1.1*(1+1.0)
2       4   1.0    =1.0

最好采用 data.table 语法。谢谢!

【问题讨论】:

计算是0.8*(1+0.7*(1+0.6))还是0.8*((1+0.7)*(1+0.6)) @RonakShah 它是 '''0.8*(1+0.7*(1+0.6))''' @LeGeniusII,你想要计算的值作为结果还是计算字符串。 【参考方案1】:

检查一下

runsum <- function(x)
  b <- as.numeric()
  len <- length(x)
  for(i in 1:len)
    b[i] <- sum(cumprod(x[i:len]))
  
  return(b)

dt[, colY := runsum(colX),by=GROUP]

结果:

   GROUP ID colX  colY
1:     1  1  0.8 1.696
2:     1  2  0.7 1.120
3:     1  3  0.6 0.600
4:     2  1  1.3 6.292
5:     2  2  1.2 3.840
6:     2  3  1.1 2.200
7:     2  4  1.0 1.000

数据:

library(data.table)
dt <- fread("GROUP   ID  colX   
1       1   0.8    
1       2   0.7    
1       3   0.6    
2       1   1.3    
2       2   1.2    
2       3   1.1    
2       4   1.0    ")

我认为有一些更好的方法可以替换函数runsum,但我没有,这里我只是使用自定义函数来展示基本思想。欢迎任何改进。

【讨论】:

【参考方案2】:

这是一个使用Rcppdata.table 的选项:

library(Rcpp)
cppFunction('NumericVector fun(NumericVector v) 
    int n = v.size();
    NumericVector res(n);

    res[n-1] = v[n-1];
    for(int i=n-2; i>=0; i--) 
        res[i] = v[i] * (1 + res[i+1]);
    
    return res;
')
DT[, colY := fun(colX), GROUP]

输出:

   GROUP ID colX  colY
1:     1  1  0.8 1.696
2:     1  2  0.7 1.120
3:     1  3  0.6 0.600
4:     2  1  1.3 6.292
5:     2  2  1.2 3.840
6:     2  3  1.1 2.200
7:     2  4  1.0 1.000

【讨论】:

以上是关于R - 按组的累积产品和总和的主要内容,如果未能解决你的问题,请参考以下文章

如果名称按组的顺序不同,R data.table 分组操作返回错误值?

熊猫按时间和分组滚动条件总和

用 R 中的多列按组计算百分比

高效的轧制窗产品的总和

Magento 按组加载产品属性?

R/dplyr:使用循环创建滞后并根据列名计算累积总和