SAS-如何计算某个月之前10年的观察次数
SAS-How to count the number of observation over the 10 years prior to certain month
我有一个包含两个变量的示例:ID 和 ym。 ID id 是指每个交易者的特定 ID,ym 是指年月变量。我想创建一个变量来显示前一个月 t 的 10 年期间的年数,如下图所示。
ID ym Want
1 200101 0
1 200301 1
1 200401 2
1 200501 3
1 200601 4
1 200801 5
1 201201 5
1 201501 4
2 200001 0
2 200203 1
2 200401 2
2 200506 3
我尝试使用by
函数和fisrt.id
来计算数字。
data want;
set have;
want+1;
by id;
if first.id then want=1;
run;
但是ym中的年份不是连续的。当时间间隔高于10年时,这种方法就不起作用了。虽然我假设我需要计算滚动 window(10 年)中的年数,但我不确定如何实现它。请给我一些建议。谢谢
只需在 SQL 中进行自我加入。使用 YM 的编码,很容易执行一年的倍数间隔,但很难执行其他间隔。
proc sql;
create table want as
select a.id,a.ym,count(b.ym) as want
from have a
left join have b
on a.id = b.id
and (a.ym - 1000) <= b.ym < a.ym
group by a.id,a.ym
order by a.id,a.ym
;
quit;
此方法保留每个 ID 的先前值,并直接检查当前值的 120 个月内有多少。它没有优化,但可以工作。如果您关心效率,可以将数组 m() 设置为每个 ID 的最大值数。
变量 d 是一个快速的 shorthand 我经常使用它将 years/months 转换为整数值 - 所以
200012 -> (2000*12) + 12 = 24012
200101 -> (2001*12) + 1 = 24013
time from 200012 to 200101 = 24013 - 24012 = 1 month
data have;
input id ym;
datalines;
1 200101
1 200301
1 200401
1 200501
1 200601
1 200801
1 201201
1 201501
2 200001
2 200203
2 200401
2 200506
;
proc sort data=have;
by id ym;
data want (keep=id ym want);
set have;
by id;
retain seq m1-m100;
array m(100) m1-m100;
** Convert date to comparable value **;
d = 12 * floor(ym/100) + mod(ym,10);
** Initialize number of previous records **;
want = 0;
** If first record, set retained values to missing and leave want=0 **;
if first.id then call missing(seq,of m1-m100);
** Otherwise loop through previous months and count how many were within 120 months **;
else do;
do i = 1 to seq;
if d <= (m(i) + 120) then want = want + 1;
end;
end;
** Increment variables for next iteration **;
seq + 1;
m(seq) = d;
run;
proc print data=want noobs;
我有一个包含两个变量的示例:ID 和 ym。 ID id 是指每个交易者的特定 ID,ym 是指年月变量。我想创建一个变量来显示前一个月 t 的 10 年期间的年数,如下图所示。
ID ym Want
1 200101 0
1 200301 1
1 200401 2
1 200501 3
1 200601 4
1 200801 5
1 201201 5
1 201501 4
2 200001 0
2 200203 1
2 200401 2
2 200506 3
我尝试使用by
函数和fisrt.id
来计算数字。
data want;
set have;
want+1;
by id;
if first.id then want=1;
run;
但是ym中的年份不是连续的。当时间间隔高于10年时,这种方法就不起作用了。虽然我假设我需要计算滚动 window(10 年)中的年数,但我不确定如何实现它。请给我一些建议。谢谢
只需在 SQL 中进行自我加入。使用 YM 的编码,很容易执行一年的倍数间隔,但很难执行其他间隔。
proc sql;
create table want as
select a.id,a.ym,count(b.ym) as want
from have a
left join have b
on a.id = b.id
and (a.ym - 1000) <= b.ym < a.ym
group by a.id,a.ym
order by a.id,a.ym
;
quit;
此方法保留每个 ID 的先前值,并直接检查当前值的 120 个月内有多少。它没有优化,但可以工作。如果您关心效率,可以将数组 m() 设置为每个 ID 的最大值数。
变量 d 是一个快速的 shorthand 我经常使用它将 years/months 转换为整数值 - 所以
200012 -> (2000*12) + 12 = 24012
200101 -> (2001*12) + 1 = 24013
time from 200012 to 200101 = 24013 - 24012 = 1 month
data have;
input id ym;
datalines;
1 200101
1 200301
1 200401
1 200501
1 200601
1 200801
1 201201
1 201501
2 200001
2 200203
2 200401
2 200506
;
proc sort data=have;
by id ym;
data want (keep=id ym want);
set have;
by id;
retain seq m1-m100;
array m(100) m1-m100;
** Convert date to comparable value **;
d = 12 * floor(ym/100) + mod(ym,10);
** Initialize number of previous records **;
want = 0;
** If first record, set retained values to missing and leave want=0 **;
if first.id then call missing(seq,of m1-m100);
** Otherwise loop through previous months and count how many were within 120 months **;
else do;
do i = 1 to seq;
if d <= (m(i) + 120) then want = want + 1;
end;
end;
** Increment variables for next iteration **;
seq + 1;
m(seq) = d;
run;
proc print data=want noobs;