R循环/拉普拉,按分组的累积总计

R循环/拉普拉,按分组的累积总计,r,data.table,lapply,cumsum,cumulative-sum,R,Data.table,Lapply,Cumsum,Cumulative Sum,我正在尝试在我的数据集中创建新的变量,这些变量是累积总计,使用group by基于其他变量重新启动…我希望这些是数据集中的新列,这是我正在努力解决的部分 使用下面的数据,我想创建累积销售和利润列,这些列将为每个产品和产品类别重新启动 下面的代码部分给出了我需要的内容,但这些变量不是新变量,而是覆盖了现有的销售/利润。。。我做错了什么?我想这很简单,我什么也没发现 注意:我使用Lappy,因为我的真实数据集有40多个VARB,我需要为这些VARB创建计算 DT <- setDT(Data)[

我正在尝试在我的数据集中创建新的变量,这些变量是累积总计,使用group by基于其他变量重新启动…我希望这些是数据集中的新列,这是我正在努力解决的部分

使用下面的数据,我想创建累积销售和利润列,这些列将为每个产品和产品类别重新启动

下面的代码部分给出了我需要的内容,但这些变量不是新变量,而是覆盖了现有的销售/利润。。。我做错了什么?我想这很简单,我什么也没发现

注意:我使用Lappy,因为我的真实数据集有40多个VARB,我需要为这些VARB创建计算

DT <- setDT(Data)[,lapply(.SD, cumsum), by = .(Product,Product_Cat) ]
数据,例如:

Product <- c('A','A','A','B','B','B','C','C','C')
Product_Cat <- c('S1','S1','S2','C1','C1','C1','D1','E1','F1')
Sale <- c(10,15,5,20,15,10,5,5,5)
Profit <- c(2,4,2,6,8,2,4,6,8)
Sale_Cum <- c(10,25,5,20,35,45,5,5,5)
Profit_Cum <- c(2,6,2,6,14,16,4,6,8)

Data <- data.frame(Product,Product_Cat,Sale,Profit)
Desired_Data <- data.frame(Product,Product_Cat,Sale,Profit,Sale_Cum,Profit_Cum)

这本身并没有使用组,但我认为它实现了您想要的功能,因为它很容易扩展到许多列:

D2 <- data.frame(lapply(Data[,c(3,4)], cumsum))
names(D2) <- gsub("$", "_cum", names(Data[,c(3,4)]))
Data <- cbind(Data, D2)
如果您有40多列,只需将c3,4更改为包含您要查找的所有列

编辑:

我忘了OP希望为每个类别重置它。在这种情况下,您可以修改原始代码:

DT <- setDT(Data)[,lapply(.SD, cumsum), by = .(Product,Product_Cat) ]
names(D2)[c(-1,-2)] <- gsub("$", "_cum", names(Data)[c(-1,-2)])
cbind(Data, D2[,c(-1,-2)])
数据:

我们可以根据Product和Product_Cat对数据帧进行迭代切片,对于每次迭代,将cumsum产生的输出分配给Sale_Cum和Product_Cum:


下面是一些非常糟糕的代码,它一步一步地完成所有事情

#sample data
d<-sample(1:10)
f<-sample(1:10)
p<-c("f","f","f","f","q","q","q","w","w","w")
pc<-c("c","c","d","d","d","v","v","v","b","b")
cc<-data.table(p,pc,d,f)

#storing the values that are overwritten first.
three<-cc[,3]
four<- cc[,4]
#applying your function 
dt<-setDT(c)[,lapply(.SD,cumsum), by=.(p,pc)]

#binding the stored values to your function and renaming everything.
x<-cbind(dt,three,four)
colnames(x)[5]<-"sale"
colnames(x)[6]<-"profit"
colnames(x)[4]<-"CumSale"
colnames(x)[3]<-"CumProfit"

#reordering the columns
xx<-x[,c("p","pc","profit","sale","CumSale","CumProfit")]
xx

我只想说,这个标题有节奏的轻快让我很高兴这可能会奏效,但我尽量避免为每个变量写一个计算。。。我的真实数据集有40多个变量,我需要计算累积总数,这就是为什么我使用lappy方法。三重嵌套for循环不能解决任何问题!似乎并不是每种新产品都会重新启动,前三个销售值是10、25、30,它们应该是10、25、5你说得对!请参阅修改后的解决方案,其中使用了原始问题中的一些代码。谢谢-这很简单,正是我所寻找的-也很容易在40多个列中重复。非常感谢。对不起,也许这是一个单独的帖子。。。但是如果我想让累计总和减去当前值呢?在这种情况下,每个值的第一个总和为0。。。第6b、C1行的销售额为35,而不是45。这有意义吗?可以做到吗?将lappy.SD、cumsum更改为lappy.SD、functionx cumsumx-x在这种情况下完美-这起作用了。我真是太感谢你了!节省了我很多时间!
cols <- c('Sale', 'Profit')

for (column in cols){
  x[, paste0(column, '_Cum')] <- 0
  for(p in unique(x$Product)){
    for (pc in unique(x$Product_Cat)){
      x[x$Product == p & x$Product_Cat == pc, paste0(column, '_Cum')] <- cumsum(x[x$Product == p & x$Product_Cat == pc, column])
    }
  }
}
print(x)
# Product Product_Cat Sale Profit Sale_Cum Profit_Cum
# 1       A          S1   10      2       10          2
# 2       A          S1   15      4       25          6
# 3       A          S2    5      2        5          2
# 4       B          C1   20      6       20          6
# 5       B          C1   15      8       35         14
# 6       B          C1   10      2       45         16
# 7       C          D1    5      4        5          4
# 8       C          E1    5      6        5          6
# 9       C          F1    5      8        5          8
library(data.table)
setDT(Data)

cols <- names(Data)[3:4]

Data[, paste0(cols, '_cumsum') := lapply(.SD, cumsum)
     , by = .(Product, Product_Cat) 
     , .SDcols = cols]
#sample data
d<-sample(1:10)
f<-sample(1:10)
p<-c("f","f","f","f","q","q","q","w","w","w")
pc<-c("c","c","d","d","d","v","v","v","b","b")
cc<-data.table(p,pc,d,f)

#storing the values that are overwritten first.
three<-cc[,3]
four<- cc[,4]
#applying your function 
dt<-setDT(c)[,lapply(.SD,cumsum), by=.(p,pc)]

#binding the stored values to your function and renaming everything.
x<-cbind(dt,three,four)
colnames(x)[5]<-"sale"
colnames(x)[6]<-"profit"
colnames(x)[4]<-"CumSale"
colnames(x)[3]<-"CumProfit"

#reordering the columns
xx<-x[,c("p","pc","profit","sale","CumSale","CumProfit")]
xx