Loops SAS中带有两个Set语句的嵌入式隐式循环
我有下面的代码来跟踪特定的制造商优惠券发行。每期可以在赎回、过期和剩余字段中包含美元。我有一个发行表,给出所有发行和金额,赎回表是赎回或到期金额的会计。目标是通过在每个类别中放入适当的金额来跟踪每个发行的所有息票美元 该代码应该在ISSUE表中循环,并将赎回表中的匹配记录绑定到ISSUE表中的每条记录Loops SAS中带有两个Set语句的嵌入式隐式循环,loops,sas,Loops,Sas,我有下面的代码来跟踪特定的制造商优惠券发行。每期可以在赎回、过期和剩余字段中包含美元。我有一个发行表,给出所有发行和金额,赎回表是赎回或到期金额的会计。目标是通过在每个类别中放入适当的金额来跟踪每个发行的所有息票美元 该代码应该在ISSUE表中循环,并将赎回表中的匹配记录绑定到ISSUE表中的每条记录 /*create sample tables*/ data ISSUE; input Coupon_NBR $ AMOUNT REDEEMED EXPIRED RE
/*create sample tables*/
data ISSUE; input
Coupon_NBR $ AMOUNT REDEEMED EXPIRED REMAINING; datalines;
A 500 0 0 500
A 500 0 0 500
B 500 0 0 500
B 500 0 0 500
B 500 0 0 500
B 1250 0 0 1250
B 750 0 0 750
C 500 0 0 500
C 500 0 0 500
C 500 0 0 500
C 500 0 0 500
C 500 0 0 500
run;
data REDEMPTIONS; input
Redemp_coupon_NBR $ TRANS_AMOUNT TYPE $16.; datalines;
A -150 REDEMPTION
A -350 REDEMPTION
A -200 EXPIRATION
B -300 REDEMPTION
B -200 EXPIRATION
B -1000 REDEMPTION
C -1500 REDEMPTION
C -500 EXPIRATION
run;
/*begin looping code*/
data Tracking;
if _n_ = 1 then Link get_redemptions;
set issue;
if (remaining > 0) and (Coupon_NBR = Redemp_coupon_NBR) then do;
if trans_amount = 0 then
link get_redemptions;
if trans_amount + remaining >=0 then do;
remaining = remaining + trans_amount;
if type = 'EXPIRATION' then;
expired = expired - trans_amount;
if type = 'REDEMPTION' then;
redeemed = redeemed - trans_amount;
link get_redemptions;
end;
else do;
remaining = 0;
if type = 'EXPIRATION' then do;
expired = expired - trans_amount;
end;
else do;
redeemed = redeemed - trans_amount;
trans_amount = trans_amount + remaining;
remaining = 0;
end;
end;
end;
else do;
link get_redemptions;
end;
return;
get_redemptions:
set redemptions;
return;
run;
这是我得到的输出:
Coupon_NBR AMOUNT REDEEMED EXPIRED REMAINING redemp_coupon_nbr trans_amount type
A 500 150 150 350 A -350 REDEMPTION
A 500 350 350 150 A -200 EXPIRATION
B 500 0 0 500 B -300 REDEMPTION
B 500 300 300 200 B -200 EXPIRATION
B 500 200 200 300 B -1000 REDEMPTION
B 1250 1000 1000 250 C -1500 REDEMPTION
B 750 0 0 750 C -500 EXPIRATION
在本例中,正确的输出为:
redemp_coupon_nbr AMOUNT REDEEMED EXPIRED REMAINING
A 500 500 0 0
A 500 0 200 300
B 500 300 200 0
B 500 500 0 0
B 500 500 0 0
B 1250 0 0 1250
B 750 0 0 750
C 500 500 0 0
C 500 500 0 0
C 500 500 0 0
C 500 0 500 0
C 500 0 0 500
显然,我的结果离我想要的还很远。然而,我主要关心的是,当我希望它跟踪每个优惠券发行时,输出只有七行,这意味着我需要它有12行(发行表中每行一行)。我认为我的循环存在某种问题,具体表现在Get retemptions
定义中。我已经调试了一段时间,但没有成功。Jarom:
一个健壮的解决方案需要一种事务性分类账方法,以便正确处理以下备选方案:获取每张优惠券的多次赎回并跟踪超额,以及在获取额外赎回之前将超额应用于优惠券
下面的示例代码有许多put语句,因此您可以观察日志中的算法决策点。余额
的目标是在每次交易对账时接近零(从上方或下方),并跟踪超出目标的任何部分
对于示例,这些变量名替换是针对您的数据进行的
- 优惠券编号->G
- 重新设计优惠券编号->XG
- 运输量->装载量
链接
来获取赎回是正确的。通过XG和
END=
添加,进一步简化了分组处理
对REDUCTIONS end=变量的测试可防止过早停止数据步骤(如果在读取数据集最后一条记录后达到后续无条件集,则会发生这种情况)
下面是一些附加的示例数据
- 非匹配赎回
- B组有一个首次赎回,这是一个跨越两张优惠券的巨大超额
- 无赎回的优惠券组
棘手的数据
data ISSUE; input
G $ AMOUNT;
A 500
A 500
B 500
B 500
B 500
B 1250
B 750
B2 100
B2 200
C 500
C 500
C 500
C 500
C 500
run;
data REDEMPTIONS; input
XG $ XAMOUNT TYPE $16.; datalines;
! -1000 REDEMPTION
A -150 REDEMPTION
A -350 REDEMPTION
A -200 EXPIRATION
B -1100 REDEMPTION was -300
B -200 EXPIRATION
B -1000 REDEMPTION
C -1500 REDEMPTION
C -500 EXPIRATION
run;
如果没有任何output
语句,则SAS将在数据步骤迭代结束时输出。听起来您的数据步骤只重复了7次。您只需要在准备就绪时显式输出观察值。大多数数据步骤在读取超过输入末尾时停止。在处理完发行
中的所有记录之前,您不需要阅读超过赎回结束时间的内容。您的输出不会反映整个情况,尤其是在第三个B,其中1000次赎回应用于500张优惠券,这意味着赎回余额为500(在以后的优惠券中使用)。我认为,一般来说,你不希望允许赎回超过票面金额。你将需要一个相当数量的脚手架,以允许旋转超过赎回或耦合。“脚手架”将是当前余额、赎回金额、到期金额、赎回余额和到期余额的变量谢谢你的回答。我发现我过分简化了这个过程。你的解决方案有效。非常感谢你!
data ISSUE; input
G $ AMOUNT;
A 500
A 500
B 500
B 500
B 500
B 1250
B 750
B2 100
B2 200
C 500
C 500
C 500
C 500
C 500
run;
data REDEMPTIONS; input
XG $ XAMOUNT TYPE $16.; datalines;
! -1000 REDEMPTION
A -150 REDEMPTION
A -350 REDEMPTION
A -200 EXPIRATION
B -1100 REDEMPTION was -300
B -200 EXPIRATION
B -1000 REDEMPTION
C -1500 REDEMPTION
C -500 EXPIRATION
run;