SAS 计算连续时间段之间的变化次数
SAS Count number of changes between consecutive time periods
Proc SQL 版本=9.4。没有 windows 个函数可以使用。
有client id, time period(month), amount 对应class.
client_id data_period amount class
1 200801 30000 2
2 200801 17000 1
3 200801 9000 1
1 200802 30000 2
2 200802 55555 2
3 200802 11000 2
门槛金额 = 20 000。
数量 > 20k 得到 class = 2, 数量 <= 20k 得到 class = 1
client_id = 1,金额和class对于200801和200802是一样的。
client_id = 2,数量从 17k 增加到 55.5k,class 变化是正确的,从 1 到 2。
client_id =3,同样在class 1 (<20K) 内更改了数量,但class 更改不正确。
想要的结果是
client_id oldDate newDate AmtOld AmtNew ClassOld ClassNew Good Bad
2 200801 200802 17000 55555 1 2 1 0
3 200801 200802 9000 11000 1 1 0 1
我尝试应用自连接来获取数据周期的所有差异,但输出中的行太多。下面的数据不是来自上面的例子,实数。
client_id oldDate newDate AmtOld AmtNew ClassOld ClassNew
A001687463 200808 200802 -5613 1690386 I03 I04
A001687463 200807 200802 -5613 1690386 I03 I04
A001687463 200806 200802 -5613 1690386 I03 I04
A001687463 200805 200802 -5613 1690386 I03 I04
PROC SQL;
CREATE TABLE WORK.'Q'n AS
SELECT distinct
t1.client_id, t1.data_period as oldDate, t2.data_period as newDate, t1.amount as expAmtOld, t2.amount as expAmtNew, t1.class as classOld, t2.class as classNew
FROM WORK.'E'n t1, WORK.'E'n t2
where
t1.client_id = t2.client_id and
t1.amount <> t2.amount
order by t1.client_id;
不要尝试使用 SQL 进行顺序处理。它不是为此而构建的。
一个数据步骤应该很容易做到。例如,让我们将您的打印输出转换为实际的 SAS 数据集,以便我们编写代码。
data have ;
input client_id data_period amount class ;
cards;
1 200801 30000 2
2 200801 17000 1
3 200801 9000 1
1 200802 30000 2
2 200802 55555 2
3 200802 11000 2
;
让我们按客户和时期排序。
proc sort data=have ;
by client_id data_period ;
run;
现在只需设置数据并使用 LAG() 函数获取以前的值。
不确定你对好和坏的定义是什么,所以我只是根据你的 20K 规则创建了新的 class 变量。
data want ;
set have ;
by client_id;
old_period = lag(data_period);
old_class = lag(class);
newclass = 1 + (amount > 20000) ;
old_newclass = lag(newclass);
if first.client_id then call missing(of old_:);
bad = (class ne newclass) or (old_newclass ne old_class) ;
run;
结果如下。
client_ data_ old_ old_ old_
id period amount class period class newclass newclass bad
1 200801 30000 2 . . 2 . 0
1 200802 30000 2 200801 2 2 2 0
2 200801 17000 1 . . 1 . 0
2 200802 55555 2 200801 1 2 1 0
3 200801 9000 1 . . 1 . 0
3 200802 11000 2 200801 1 1 1 1
Proc SQL 版本=9.4。没有 windows 个函数可以使用。
有client id, time period(month), amount 对应class.
client_id data_period amount class
1 200801 30000 2
2 200801 17000 1
3 200801 9000 1
1 200802 30000 2
2 200802 55555 2
3 200802 11000 2
门槛金额 = 20 000。
数量 > 20k 得到 class = 2, 数量 <= 20k 得到 class = 1
client_id = 1,金额和class对于200801和200802是一样的。 client_id = 2,数量从 17k 增加到 55.5k,class 变化是正确的,从 1 到 2。 client_id =3,同样在class 1 (<20K) 内更改了数量,但class 更改不正确。
想要的结果是
client_id oldDate newDate AmtOld AmtNew ClassOld ClassNew Good Bad
2 200801 200802 17000 55555 1 2 1 0
3 200801 200802 9000 11000 1 1 0 1
我尝试应用自连接来获取数据周期的所有差异,但输出中的行太多。下面的数据不是来自上面的例子,实数。
client_id oldDate newDate AmtOld AmtNew ClassOld ClassNew
A001687463 200808 200802 -5613 1690386 I03 I04
A001687463 200807 200802 -5613 1690386 I03 I04
A001687463 200806 200802 -5613 1690386 I03 I04
A001687463 200805 200802 -5613 1690386 I03 I04
PROC SQL;
CREATE TABLE WORK.'Q'n AS
SELECT distinct
t1.client_id, t1.data_period as oldDate, t2.data_period as newDate, t1.amount as expAmtOld, t2.amount as expAmtNew, t1.class as classOld, t2.class as classNew
FROM WORK.'E'n t1, WORK.'E'n t2
where
t1.client_id = t2.client_id and
t1.amount <> t2.amount
order by t1.client_id;
不要尝试使用 SQL 进行顺序处理。它不是为此而构建的。
一个数据步骤应该很容易做到。例如,让我们将您的打印输出转换为实际的 SAS 数据集,以便我们编写代码。
data have ;
input client_id data_period amount class ;
cards;
1 200801 30000 2
2 200801 17000 1
3 200801 9000 1
1 200802 30000 2
2 200802 55555 2
3 200802 11000 2
;
让我们按客户和时期排序。
proc sort data=have ;
by client_id data_period ;
run;
现在只需设置数据并使用 LAG() 函数获取以前的值。 不确定你对好和坏的定义是什么,所以我只是根据你的 20K 规则创建了新的 class 变量。
data want ;
set have ;
by client_id;
old_period = lag(data_period);
old_class = lag(class);
newclass = 1 + (amount > 20000) ;
old_newclass = lag(newclass);
if first.client_id then call missing(of old_:);
bad = (class ne newclass) or (old_newclass ne old_class) ;
run;
结果如下。
client_ data_ old_ old_ old_
id period amount class period class newclass newclass bad
1 200801 30000 2 . . 2 . 0
1 200802 30000 2 200801 2 2 2 0
2 200801 17000 1 . . 1 . 0
2 200802 55555 2 200801 1 2 1 0
3 200801 9000 1 . . 1 . 0
3 200802 11000 2 200801 1 1 1 1