我有一个数据集,其中包含客户余额和付款时间详细信息的时间序列(延迟/准时)。我想确定给定客户的时间何时发生变化(从迟到时间和相反时间切换)的每个实例,并在发生变化时记录相关的余额。
我已经搜索了几个小时的解决方案而且我真的很难接受这个,所以非常感谢你的建议。
data have;
input customer date payment_status $ balance;
cards;
1 201601 on_time 80
1 201602 on_time 70
1 201603 late 60
1 201604 late 60
1 201605 on_time 50
1 201606 on_time 40
1 201607 late 40
2 201603 late 120
2 201604 on_time 100
2 201605 on_time 80
2 201606 late 60
3 201606 late 200
3 201607 late 190
3 201608 late 180
3 201609 on_time 170
3 201610 on_time 160
3 201611 on_time 150
3 201612 on_time 140
4 201603 late 80
4 201604 late 50
4 201605 late 20
;run;
最终我希望输出看起来如下所示,因此每个客户的余额以及payment_status的更改都会记录在新列中。
请注意,客户的第一个实例未记录在新变量(VAR1_STATUS_CHANGE& VAR2_BAL_AT_CHANGE)中 - 仅当原始状态与将输入新变量的原始值相比发生变化时才会记录。
customer date payment_status balance VAR1_STATUS_CHANGE VAR2_BAL_AT_CHANGE
1 201601 on_time 80 .
1 201602 on_time 70 .
1 201603 late 60 late 60
1 201604 late 60 .
1 201605 on_time 50 on_time 50
1 201606 on_time 40 .
1 201607 late 40 late 40
2 201603 late 120 .
2 201604 on_time 100 on_time 100
2 201605 on_time 80 .
2 201606 late 60 late 60
3 201606 late 200 .
3 201607 late 190 .
3 201608 late 180 .
3 201609 on_time 170 on_time 170
3 201610 on_time 160 .
3 201611 on_time 150 .
3 201612 on_time 140 .
4 201603 late 80 .
4 201604 late 50 .
4 201605 late 20 .
我先尝试过使用过。方法,但不能按照提供我正在寻找的答案的顺序得到我的'by'分组。它可能需要预先单独的数据步骤。
proc sort data=have;
by customer payment_status;
run;
data want;
set have;
by customer payment_status;
if first.payment_status then VAR1_STATUS_CHANGE = payment_status;
if first.payment_status then VAR2_BAL_AT_CHANGE = balance;
run;
proc sort data=want;
by customer date payment_status;
run;
我想知道是否有快速解决问题的方法。非常感谢。
答案 0 :(得分:1)
你的答案非常接近,但需要进行一些调整。
首先,按客户和日期排序,以正确的顺序获取数据。后续数据步骤具有正确的by
变量,但您需要添加notsorted
选项以避免在payment_status未排序时出错。
我已将条件and not first.customer
添加到if
语句中,以便它不会填充给定客户的第一条记录。
我使用了do
语句,避免了重复if
条件。
您现在不需要第二个proc sort
,因为数据的顺序正确。
data have;
input customer date payment_status $ balance;
cards;
1 201601 on_time 80
1 201602 on_time 70
1 201603 late 60
1 201604 late 60
1 201605 on_time 50
1 201606 on_time 40
1 201607 late 40
2 201603 late 120
2 201604 on_time 100
2 201605 on_time 80
2 201606 late 60
3 201606 late 200
3 201607 late 190
3 201608 late 180
3 201609 on_time 170
3 201610 on_time 160
3 201611 on_time 150
3 201612 on_time 140
4 201603 late 80
4 201604 late 50
4 201605 late 20
;
run;
proc sort data=have;
by customer date;
run;
data want;
set have;
by customer payment_status notsorted;
if first.payment_status and not first.customer then do;
VAR1_STATUS_CHANGE = payment_status;
VAR2_BAL_AT_CHANGE = balance;
end;
run;
答案 1 :(得分:0)
这是Longfish的完美答案。 notsorted
选项完成了这项工作!