我所拥有的数据代表了此示例中给定商店Dist
和One
的销售额及其距离(Two
)。我想做的是,根据销售意愿来定义商店集水区。 cacthment区域定义为包含50%销售额的半径。从商店距离最小(Dist
)的订单开始,我想计算包含给定商店销售额50%的半径。
我在之前的模型中计算过以下df
。
df <- data.frame(ID = c(1,2,3,4,5,6,7,8),
Store = c('One','One','One','One','Two','Two','Two','Two'),
Dist = c(1,5,7,23,1,9,9,23),
Sales = c(10,8,4,1,11,9,4,2))
现在我想找到最小距离dist
,使得关闭数字达到Sales
的50%。所以我的输出如下:
Output <- data.frame(Store = c('One','Two'),
Dist = c(5,9),
Sales = c(18,20))
我在实际的df中有很多观察,并且我不知道我能够解决50%,所以我需要四舍五入到最近的观察。
有任何建议怎么做?
注意:我提前为可怜的头衔道歉,我试图想出一个更好的方法来制定问题,欢迎提出建议......
答案 0 :(得分:1)
以下是data.table
的一种方法:
library(data.table)
setDT(df)
df[order(Store, Dist),
.(Dist, Sales = cumsum(Sales), Pct = cumsum(Sales) / sum(Sales)),
by = "Store"][Pct >= 0.5, .SD[1,], by = "Store"]
# Store Dist Sales Pct
# 1: One 5 18 0.7826087
# 2: Two 9 20 0.7692308
setDT(df)
将df
转换为data.table
.(...)
表达式选择Dist
,并按Store
Pct >= 0.5
仅将此子集设置为累计销售额超过阈值的情况,.SD[1,]
仅将Dist
仅占最高行(即Store
的最小值),{{1} } 答案 1 :(得分:0)
我认为如果您以特定格式重新排列数据会更容易。我的逻辑是先按小组cumsum
进行。然后将组的总和合并到数据中。最后我计算百分比。现在您已经获得了数据,并且您可以以任何方式进行子集,以便从组中获得第一个障碍物。
df$cums=unlist(lapply(split(df$Sales, df$Store), cumsum), use.names = F)
zz=aggregate(df$Sales, by = list(df$Store), sum)
names(zz)=c('Store', 'TotSale')
df = merge(df, zz)
df$perc=df$cums/df$TotSale
子设置数据:
merge(aggregate(perc ~ Store,data=subset(df,perc>=0.5), min),df)
Store perc ID Dist Sales cums TotSale
1 One 0.7826087 2 5 8 18 23
2 Two 0.7692308 6 9 9 20 26