我对 R 相当陌生,并且花了很长时间寻找更好的方法来解决下面的问题,但没有成功。我能够使用有效的for
循环开发解决方案;但是,我违反了此 GitHub 教程中描述的规则,该教程讨论了编写循环时应避免的内容。
我正在处理销售数据。我的特定数据框包括产品类别(“CAT_NO”)、客户十分位数(“CUST_DECILE”)(客户被放入从 1 到 10 的十分位数组,其中 1 是“最佳”客户)和地板毛利率(“floorGM” ) 对于该产品类别,客户十分位组合。可能值得注意的是,并非每个产品类别都代表所有客户十分位(例如,样本类别“A”可能只有客户十分位 4、7 和 9。为简单起见,下面的可重现示例确保每个产品类别都有所有 10 个客户十分位)。我的数据集可以表示为:
df <- data.frame(CAT_NO = c(rep(c("A"), times = 10), rep(c("B"), times = 10),
rep(c("C"), times = 10), rep(c("D"), times = 10))
, CUST_DECILE = rep(c(1:10), times = 4), floorGM = runif(40, 0.2, 0.8))
df
我的目标是查看每个产品类别并比较每个客户十分位的底毛利率;如果处于较低十分位的客户的 floorGM 高于处于较高十分位的客户,则较高十分位的客户应采用较低十分位的 floorGM。
我使用的逻辑按每个 CAT_NO 对数据进行了子集化,然后应用循环来比较该 CAT_NO 中每个 CUST_DECILE 的 floorGM。我的代码是:
Product_Categories <- as.character(unique(df$CAT_NO))
for(k in seq_along(Product_Categories)) {
subdata <- subset(df, CAT_NO == Product_Categories[k])
deciles <- sort(unique(subdata$CUST_DECILE))
for(k in 2:length(deciles)) {
if(subdata[subdata$CUST_DECILE == subdata$CUST_DECILE[k], "floorGM"< subdata[subdata$CUST_DECILE == subdata$CUST_DECILE[k-1], "floorGM"]) {
subdata[subdata$CUST_DECILE == subdata$CUST_DECILE[k], "floorGM"] <- subdata[subdata$CUST_DECILE == subdata$CUST_DECILE[k-1], "floorGM"]
}
}
if (!exists("temp")) {
temp <- subdata
} else {
temp <- rbind(temp, subdata)
}
}
虽然这可行,但我确信有一种更快的方法来执行此操作,特别是当rbind()
我在数百万个事务中扩展此解决方案时,在循环期间增长我的数据集会阻碍性能。
感谢您的任何意见和/或其他参考!