SAS确定价值何时发生变化(在组内)并记录每次变更的余额

时间:2017-04-25 21:22:52

标签: sas grouping

我有一个数据集,其中包含客户余额和付款时间详细信息的时间序列(延迟/准时)。我想确定给定客户的时间何时发生变化(从迟到时间和相反时间切换)的每个实例,并在发生变化时记录相关的余额。

我已经搜索了几个小时的解决方案而且我真的很难接受这个,所以非常感谢你的建议。

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)中 - 仅当原始状态与将输入新变量的原始值相比发生变化时才会记录。

output_dataset

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;

我想知道是否有快速解决问题的方法。非常感谢。

2 个答案:

答案 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选项完成了这项工作!