dplyr:计算产品补货的天数

dplyr:计算产品补货的天数,r,dplyr,tidyverse,duration,R,Dplyr,Tidyverse,Duration,我正在处理一个数据集,其中我需要计算零售店需要多长时间才能从短缺中补充一些产品,以下是以最简单的形式快速查看数据集: Date我希望其他人能找到更干净的解决方案。但这会产生diffDate,它指定负数变为正/零时的日期差 sample_df %>% mutate(sign = ifelse(Net_Available_Qty > 0, "pos", ifelse(Net_Available_Qty < 0, "neg", "zero")), sign_l

我正在处理一个数据集,其中我需要计算零售店需要多长时间才能从短缺中补充一些产品,以下是以最简单的形式快速查看数据集:


Date我希望其他人能找到更干净的解决方案。但这会产生
diffDate
,它指定负数变为正/零时的日期差

sample_df %>%
  mutate(sign = ifelse(Net_Available_Qty > 0, "pos", ifelse(Net_Available_Qty < 0, "neg", "zero")),
         sign_lag = lag(sign, default = sign[1]),       # get previous value (exception in the first place)
         change = ifelse(sign != sign_lag, 1 , 0),      # check if there's a change
         sequence=sequence(rle(as.character(sign))$lengths)) %>%
  group_by(sequence) %>%
  mutate(diffDate = as.numeric(difftime(Date, lag(Date,1))),
         diffDate=ifelse(Net_Available_Qty <0, NA, ifelse((sign=='pos'| sign=='zero') & sequence==1, diffDate, NA))) %>% 
  ungroup() %>%
  select(Date, Product, Net_Available_Qty, diffDate)
sample_df%>%
变异(符号=ifelse(净可用数量>0,“pos”,ifelse(净可用数量<0,“负”,“零”)),
sign_lag=lag(sign,default=sign[1]),#获取上一个值(第一个异常)
change=ifelse(sign!=sign_lag,1,0),#检查是否有更改
序列=序列(rle(作为字符(符号))$长度))%>%
分组依据(顺序)%>%
mutate(diffDate=as.numeric(difftime(日期,滞后(日期,1))),
diffDate=ifelse(净可用数量%
解组()%>%
选择(日期、产品、净可用数量、日期)

@Schilker使用
rle
有一个很好的主意。我在他的答案的基础上,提供了一个略短的版本,包括使用
cumsum

日期%
变异(n_天=最大值(累积值(差异日期)))
#>#A tibble:8 x 7
#>#组:组[4]
#>日期产品净可用数量差异日期序列组n天
#>                                   
#>1 2019-1-1产品A-2 1 0 2
#>2 2019-1-2产品A-2 1 2 0 2
#>3 2019-1-3产品A 10 1 2
#>4 2019-1-4产品A 8 1 2
#>5 2019-1-5产品A-5 1 2 3
#>6 2019-1-6产品A-6 1 2 3
#>7 2019-1-7产品A-7 1 2 3
#>8 2019-1-8产品A 0 1 1 3 1

由(v0.3.0)于2020-02-23创建

非常感谢Schilker的快速回复。我需要花一些时间来理解您的代码。最让人困惑的是:sequence=sequence(rle(as.character(sign))$length的变异列,您能帮我理解一下吗?@FelixZhao,序列变量的创建目的是:统计变量符号的连续出现次数。符号是一个创建的因子,用于显示净可用数量的负值、正值或零值。如果您想查看完整的数据集,请删除“Select()”在上面的代码中。它可能会让你更好地理解。然后我们按顺序分组,因为这是新的正、负或零的第一次出现:计算第一次出现之间的日期差Shi Schilker,你救了我一天!我对你的代码做了一些修改以适应我的问题,它工作得很好。非常感谢你ch!不客气@felixZhao,如果你觉得我的答案对你有帮助并解决了你的问题,请在帖子上标记为正确答案。干杯!
sample_df %>%
  mutate(sign = ifelse(Net_Available_Qty > 0, "pos", ifelse(Net_Available_Qty < 0, "neg", "zero")),
         sign_lag = lag(sign, default = sign[1]),       # get previous value (exception in the first place)
         change = ifelse(sign != sign_lag, 1 , 0),      # check if there's a change
         sequence=sequence(rle(as.character(sign))$lengths)) %>%
  group_by(sequence) %>%
  mutate(diffDate = as.numeric(difftime(Date, lag(Date,1))),
         diffDate=ifelse(Net_Available_Qty <0, NA, ifelse((sign=='pos'| sign=='zero') & sequence==1, diffDate, NA))) %>% 
  ungroup() %>%
  select(Date, Product, Net_Available_Qty, diffDate)