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