- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题:
我有赚取和兑换代金券的时间序列数据。优惠券只限一次 3天固定窗口包括他们获得的那一天,例如。 1 月 1 日获得的代金券将在 1 日、2 日和 3 日有效。
我需要做出一个假设,即当涉及到针对他们赚取的赎回时,它是先到先得的。例如。如果我们有数据
Date VouchersEarned VouchersRedeemed
01/01/2020 10 0
02/01/2020 8 9
03/01/2020 4 4
04/01/2020 2 4
05/01/2020 1 4
然后在 2 日,那 9 张代金券来自第 1 次,即我们还有剩余的代金券
Date VouchersEarned VouchersRedeemed RemainingVouchers
01/01/2020 10 0 1
02/01/2020 8 9 8
然后在 3 日,这 4 次赎回将是第 1 次的剩余 1 次和第 2 次的 3 次
Date VouchersEarned VouchersRedeemed RemainingVouchers
01/01/2020 10 0 0
02/01/2020 8 9 5
03/01/2020 4 4 0
第四:
Date VouchersEarned VouchersRedeemed RemainingVouchers
01/01/2020 10 0 0
02/01/2020 8 9 1
03/01/2020 4 4 4
04/01/2020 2 4 2
第5个:
Date VouchersEarned VouchersRedeemed RemainingVouchers
01/01/2020 10 0 0
02/01/2020 8 9 1**
03/01/2020 4 4 0
04/01/2020 2 4 2
05/01/2020 1 4 1
所以在 5 日,我们拿到了第一张过期的优惠券,因为 ** 一张在 3 天内没有用完。
R dput
最后但这是它的样子
Date VouchersEarned VouchersRedeemed ActualActive ActualExpired CumulativeEarned
1 01/01/2020 10 0 10 0 10
2 02/01/2020 8 9 9 0 18
3 03/01/2020 4 4 9 0 22
4 04/01/2020 2 4 7 0 24
5 05/01/2020 1 4 3 1 25
6 06/01/2020 0 1 2 0 25
7 07/01/2020 0 1 0 1 25
8 08/01/2020 0 0 0 0 25
CumulativeRedeemed CumulativeDiff
1 0 10
2 9 9
3 13 9
4 17 7
5 21 4
6 22 3
7 23 2
8 23 2
ActualActive
&
ActualExpired
是我用笔和纸得出的数字。请注意,我将它们放在它们到期的日期上,而不是根据它们获得的日期。要么对我有用,只是改变报告 View 。我可以通过查看
CumulativeEarned
来获得总代金券。 &
CumulativeRedeemed
然后取差额。我想如果我能得到过期的,那么计算活跃的就很简单了。
df <- structure(list(Date = c("01/01/2020", "02/01/2020", "03/01/2020",
"04/01/2020", "05/01/2020", "06/01/2020", "07/01/2020", "08/01/2020"
), VouchersEarned = c(10L, 8L, 4L, 2L, 1L, 0L, 0L, 0L), VouchersRedeemed = c(0L,
9L, 4L, 4L, 4L, 1L, 1L, 0L), ActualActive = c(10L, 9L, 9L, 7L,
3L, 2L, 0L, 0L), ActualExpired = c(0L, 0L, 0L, 0L, 1L, 0L, 1L,
0L), CumulativeEarned = c(10L, 18L, 22L, 24L, 25L, 25L, 25L,
25L), CumulativeRedeemed = c(0L, 9L, 13L, 17L, 21L, 22L, 23L,
23L), CumulativeDiff = c(10L, 9L, 9L, 7L, 4L, 3L, 2L, 2L)), class = "data.frame", row.names = c(NA,
-8L))
编辑 2:
我最近在 R 中的尝试 .虽然有些问题,但我觉得滞后列的正确组合并非不可能
library(data.table)
dt <- as.data.table(df)
dt[, Date := lubridate::dmy(Date)]
# functional form
findExpiredVouchers <- function(dt, period=3){
# generation of cumulative data
dt[, CumulativeEarned := cumsum(VouchersEarned)]
dt[, CumulativeRedeemed := cumsum(VouchersRedeemed)]
dt[, CumulativeDiff := CumulativeEarned-CumulativeRedeemed]
# I think if we look at the cumulative earned against the cumulative redeemed,
# plus it's lag period from that point, ie the cumulative redeemed in 2 days,
# then we can see for data prior to last 3 which have expired
dt[, LaggedCumulativeRedeemed := shift(CumulativeRedeemed, period-1, type="lead")]
dt[, ExpiredCumulative := CumulativeEarned - LaggedCumulativeRedeemed]
# Now this creates negative values though for eg the first case, I'm not 100%
# if I need to worry about these
dt[ExpiredCumulative < 0, ExpiredCumulative := 0]
# so now it should be the difference in this series that captures the origin
# of an expiration
dt[, Expired := c(NA, diff(ExpiredCumulative))]
dt[1, Expired := ExpiredCumulative]
# and I can shift this by the lag period to get the end result
dt[, OutputExpired := shift(Expired, period, type="lag")]
dt[is.na(OutputExpired), OutputExpired := 0]
# and active
dt[, CumulativeExpired := cumsum(OutputExpired)]
dt[, OutputActive := CumulativeDiff-CumulativeExpired]
}
dt <- findExpiredVouchers(dt, 3)
dt[] # OutputExpired & OutputActive
有了一些新的虚假数据,随着负到期时间的出现,缺陷就会暴露出来:(
set.seed(1)
p = 0.2
new_dt <- data.table(
Date = 1:10,
VouchersEarned = sample(0:15, 10, replace=TRUE)
)
new_dt[, CumulativeEarned := cumsum(VouchersEarned)]
# fake VouchersRedeemed
new_dt[, VouchersRedeemed := as.integer(NA)]
new_dt[, CumulativeDiff := CumulativeEarned]
for(i in 1:nrow(new_dt)){
new_value <- sum(rbinom(new_dt$CumulativeDiff[i], 1, p))
new_dt[i, VouchersRedeemed := new_value]
new_dt[i:.N, CumulativeDiff := CumulativeDiff - new_value]
}
new_dt <- findExpiredVouchers(dt=new_dt, 3)
new_dt[] # OutputExpired < 0
新例子
Date VouchersEarned VouchersRedeemed OutputExpired
1: 1 8 1 0
2: 2 3 1 0
3: 3 6 3 0
4: 4 0 1 3
5: 5 1 1 2
6: 6 12 5 5
7: 7 6 5 -5
8: 8 10 3 -4
9: 9 13 7 9
10: 10 1 8 -1
运行
Waldi 的 循环显示了类似的结果,但 -5、-4 和 9 取消为 0(它们应该如此!)
最佳答案
使用 tidyverse 库,特别是 dplyr , 和 magrittr ,你可以写这个代码
df %<>%
mutate(VouchersEarnedCumsum = cumsum(VouchersEarned),
VouchersRedeemedCumsum = cumsum(VouchersRedeemed),
VouchersCumsumDifference = VouchersEarnedCumsum - lead(VouchersRedeemedCumsum, 2, default = max(VouchersRedeemedCumsum)),
VouchersCumsumDifference = as.numeric(VouchersCumsumDifference),
VouchersCumsumDifference = case_when(VouchersCumsumDifference < 0 ~ 0, T ~ VouchersCumsumDifference),
ExpiredVouchers = VouchersCumsumDifference - lag(VouchersCumsumDifference, default = 0),
ExpiredVouchersInDate = lag(ExpiredVouchers, 3, default = 0))
结果表,从你的数据帧 df 开始,是
# A tibble: 8 x 8
Date VouchersEarned VouchersRedeemed VouchersEarnedCumsum VouchersRedeemedCumsum VouchersCumsumDifference ExpiredVouchers ExpiredVouchersInDate
<chr> <int> <int> <int> <int> <dbl> <dbl> <dbl>
1 01/01/2020 10 0 10 0 0 0 0
2 02/01/2020 8 9 18 9 1 1 0
3 03/01/2020 4 4 22 13 1 0 0
4 04/01/2020 2 4 24 17 2 1 0
5 05/01/2020 1 4 25 21 2 0 1
6 06/01/2020 0 1 25 22 2 0 0
7 07/01/2020 0 1 25 23 2 0 1
8 08/01/2020 0 0 25 23 2 0 0
然后,很容易使用 dbplyr 翻译相应 SQL 查询中的每个函数,使用
translate_sql .
df %<>%
mutate(VouchersEarnedCumsum = cumsum(VouchersEarned),
VouchersRedeemedCumsum = cumsum(VouchersRedeemed),
VouchersCumsumDifference = VouchersEarnedCumsum - lead(VouchersRedeemedCumsum, 2, default = max(VouchersRedeemedCumsum)),
VouchersCumsumDifference = as.numeric(VouchersCumsumDifference),
VouchersCumsumDifference = case_when(VouchersCumsumDifference < 0 ~ 0, T ~ VouchersCumsumDifference),
VouchersCumsumDifference = accumulate(VouchersCumsumDifference, max),
ExpiredVouchers = VouchersCumsumDifference - lag(VouchersCumsumDifference, default = 0),
ExpiredVouchersInDate = lag(ExpiredVouchers, 3, default = 0))
关于sql - 计算过期的凭证,给定一个固定的窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65718399/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!