SAS - 滚动 N 个月
SAS - rolling N months
我希望使用基于过去 12 个月(每月向前滚动)的静态因素列表中的 YRMON (YYYY:MM) 因素
我有一个看起来很简单的静态数据集(见下文):
我基本上需要创建一种格式,将 yrmon 更改为滚动的 13 个月,我可以根据 yrmon 在因子上标记(用于计算需要)。
yrmon facto
DATE00 1.00000
DATE01 0.99944
DATE02 0.99907
DATE03 0.99907
DATE04 0.99889
DATE05 0.99799
DATE06 0.99659
DATE07 0.99500
DATE08 0.99296
DATE09 0.99100
DATE10 0.85000
DATE11 0.78000
DATE12 0.34900
示例数据before/after:
YRMON PAYAMT PAYAMT_AFTER
2020:10 0.00 .90
2020:08 0.00 .00
这是我目前的情况:
/*Create macro dates*/
%let to_date = %sysfunc(date());
%let paydt = %sysfunc(intnx(month,&to_date, -(0)));
%let payday = %eval(&paydt. -1);
%let chirodt12 = %sysfunc(intnx(month,&payday,-0), date9.);
%let chirodt11 = %sysfunc(intnx(month,&payday,-1), date9.);
%let chirodt10 = %sysfunc(intnx(month,&payday,-2), date9.);
%let chirodt9 = %sysfunc(intnx(month,&payday,-3), date9.);
%let chirodt8 = %sysfunc(intnx(month,&payday,-4), date9.);
%let chirodt7 = %sysfunc(intnx(month,&payday,-5), date9.);
%let chirodt6 = %sysfunc(intnx(month,&payday,-6), date9.);
%let chirodt5 = %sysfunc(intnx(month,&payday,-7), date9.);
%let chirodt4 = %sysfunc(intnx(month,&payday,-8), date9.);
%let chirodt3 = %sysfunc(intnx(month,&payday,-9), date9.);
%let chirodt2 = %sysfunc(intnx(month,&payday,-10), date9.);
%let chirodt1 = %sysfunc(intnx(month,&payday,-11), date9.);
%let chirodt0 = %sysfunc(intnx(month,&payday,-12), date9.);
%put chirodt12 &chirodt12.;
%put chirodt11 &chirodt11.;
%put chirodt10 &chirodt10.;
%put chirodt9 &chirodt9.;
%put chirodt8 &chirodt8.;
%put chirodt7 &chirodt7.;
%put chirodt6 &chirodt6.;
%put chirodt5 &chirodt5.;
%put chirodt4 &chirodt4.;
%put chirodt3 &chirodt3.;
%put chirodt2 &chirodt2.;
%put chirodt1 &chirodt1.;
%put chirodt0 &chirodt0.;
filename ibnr "/path/to/file/file.txt";
data ibnr;
infile ibnr dlm='09'X dsd missover firstobs = 2;
informat month . factor 7.5;
input month factor;
run;
data ibnr;
set ibnr;
if month = 'DATE12' then yrmon = put("&chirodt12"D, yymmc7.);
else if month = 'DATE11' then yrmon = put("&chirodt11"D, yymmc7.);
else if month = 'DATE10' then yrmon = put("&chirodt10"D, yymmc7.);
else if month = 'DATE09' then yrmon = put("&chirodt9"D, yymmc7.);
else if month = 'DATE08' then yrmon = put("&chirodt8"D, yymmc7.);
else if month = 'DATE07' then yrmon = put("&chirodt7"D, yymmc7.);
else if month = 'DATE06' then yrmon = put("&chirodt6"D, yymmc7.);
else if month = 'DATE05' then yrmon = put("&chirodt5"D, yymmc7.);
else if month = 'DATE04' then yrmon = put("&chirodt4"D, yymmc7.);
else if month = 'DATE03' then yrmon = put("&chirodt3"D, yymmc7.);
else if month = 'DATE02' then yrmon = put("&chirodt2"D, yymmc7.);
else if month = 'DATE01' then yrmon = put("&chirodt1"D, yymmc7.);
else if month = 'DATE00' then yrmon = put("&chirodt0"D, yymmc7.);
run;
/*format for later use to stamp on factor for calculations*/
data chrofact (keep = fmtname label start type hlo);
retain fmtname 'chfact' type 'C';
set ibnr end = lastrec;
start=yrmon;
label = factor;
output;
if lastrec then do;
start='XXX' ;
hlo = 'O';
label = '0';
output;
end;
run;
proc format cntlin = chrofact;
run;
这给了我想要的;但我确定有更简单的方法
将文本值转换为 SAS 日期值是 INPUT 操作(即 INFORMAT),而不是 PUT 操作(即 FORMAT)。
而是考虑创建一个查找 table,将 文字 字符串 "DATE<nn>"
映射到对应于某个预定基准日期的 SAS 日期值。
示例
解码字符串文字的 <nn>
部分并将其应用于对 INTNX
的调用。使用输出作为 INFORMAT 的 CNTLIN 的基础或作为查找 table LEFT JOINED 或 HASH JOINED 到包含字符串文字“DATE”
的其他一些数据集
data have;
length yrmon facto 8.;
input yrmon facto;
basedate = today();
month = input(substr(yrmon,5),2.);
month_ago = 12-month;
ago_date = intnx('month', basedate, -month_ago);
format ago_date yymmdd10.;
datalines;
DATE00 1.00000
DATE01 0.99944
DATE02 0.99907
DATE03 0.99907
DATE04 0.99889
DATE05 0.99799
DATE06 0.99659
DATE07 0.99500
DATE08 0.99296
DATE09 0.99100
DATE10 0.85000
DATE11 0.78000
DATE12 0.34900
;
查看器中输出数据集的图像
我希望使用基于过去 12 个月(每月向前滚动)的静态因素列表中的 YRMON (YYYY:MM) 因素
我有一个看起来很简单的静态数据集(见下文): 我基本上需要创建一种格式,将 yrmon 更改为滚动的 13 个月,我可以根据 yrmon 在因子上标记(用于计算需要)。
yrmon facto
DATE00 1.00000
DATE01 0.99944
DATE02 0.99907
DATE03 0.99907
DATE04 0.99889
DATE05 0.99799
DATE06 0.99659
DATE07 0.99500
DATE08 0.99296
DATE09 0.99100
DATE10 0.85000
DATE11 0.78000
DATE12 0.34900
示例数据before/after:
YRMON PAYAMT PAYAMT_AFTER
2020:10 0.00 .90
2020:08 0.00 .00
这是我目前的情况:
/*Create macro dates*/
%let to_date = %sysfunc(date());
%let paydt = %sysfunc(intnx(month,&to_date, -(0)));
%let payday = %eval(&paydt. -1);
%let chirodt12 = %sysfunc(intnx(month,&payday,-0), date9.);
%let chirodt11 = %sysfunc(intnx(month,&payday,-1), date9.);
%let chirodt10 = %sysfunc(intnx(month,&payday,-2), date9.);
%let chirodt9 = %sysfunc(intnx(month,&payday,-3), date9.);
%let chirodt8 = %sysfunc(intnx(month,&payday,-4), date9.);
%let chirodt7 = %sysfunc(intnx(month,&payday,-5), date9.);
%let chirodt6 = %sysfunc(intnx(month,&payday,-6), date9.);
%let chirodt5 = %sysfunc(intnx(month,&payday,-7), date9.);
%let chirodt4 = %sysfunc(intnx(month,&payday,-8), date9.);
%let chirodt3 = %sysfunc(intnx(month,&payday,-9), date9.);
%let chirodt2 = %sysfunc(intnx(month,&payday,-10), date9.);
%let chirodt1 = %sysfunc(intnx(month,&payday,-11), date9.);
%let chirodt0 = %sysfunc(intnx(month,&payday,-12), date9.);
%put chirodt12 &chirodt12.;
%put chirodt11 &chirodt11.;
%put chirodt10 &chirodt10.;
%put chirodt9 &chirodt9.;
%put chirodt8 &chirodt8.;
%put chirodt7 &chirodt7.;
%put chirodt6 &chirodt6.;
%put chirodt5 &chirodt5.;
%put chirodt4 &chirodt4.;
%put chirodt3 &chirodt3.;
%put chirodt2 &chirodt2.;
%put chirodt1 &chirodt1.;
%put chirodt0 &chirodt0.;
filename ibnr "/path/to/file/file.txt";
data ibnr;
infile ibnr dlm='09'X dsd missover firstobs = 2;
informat month . factor 7.5;
input month factor;
run;
data ibnr;
set ibnr;
if month = 'DATE12' then yrmon = put("&chirodt12"D, yymmc7.);
else if month = 'DATE11' then yrmon = put("&chirodt11"D, yymmc7.);
else if month = 'DATE10' then yrmon = put("&chirodt10"D, yymmc7.);
else if month = 'DATE09' then yrmon = put("&chirodt9"D, yymmc7.);
else if month = 'DATE08' then yrmon = put("&chirodt8"D, yymmc7.);
else if month = 'DATE07' then yrmon = put("&chirodt7"D, yymmc7.);
else if month = 'DATE06' then yrmon = put("&chirodt6"D, yymmc7.);
else if month = 'DATE05' then yrmon = put("&chirodt5"D, yymmc7.);
else if month = 'DATE04' then yrmon = put("&chirodt4"D, yymmc7.);
else if month = 'DATE03' then yrmon = put("&chirodt3"D, yymmc7.);
else if month = 'DATE02' then yrmon = put("&chirodt2"D, yymmc7.);
else if month = 'DATE01' then yrmon = put("&chirodt1"D, yymmc7.);
else if month = 'DATE00' then yrmon = put("&chirodt0"D, yymmc7.);
run;
/*format for later use to stamp on factor for calculations*/
data chrofact (keep = fmtname label start type hlo);
retain fmtname 'chfact' type 'C';
set ibnr end = lastrec;
start=yrmon;
label = factor;
output;
if lastrec then do;
start='XXX' ;
hlo = 'O';
label = '0';
output;
end;
run;
proc format cntlin = chrofact;
run;
这给了我想要的;但我确定有更简单的方法
将文本值转换为 SAS 日期值是 INPUT 操作(即 INFORMAT),而不是 PUT 操作(即 FORMAT)。
而是考虑创建一个查找 table,将 文字 字符串 "DATE<nn>"
映射到对应于某个预定基准日期的 SAS 日期值。
示例
解码字符串文字的 <nn>
部分并将其应用于对 INTNX
的调用。使用输出作为 INFORMAT 的 CNTLIN 的基础或作为查找 table LEFT JOINED 或 HASH JOINED 到包含字符串文字“DATE”
data have;
length yrmon facto 8.;
input yrmon facto;
basedate = today();
month = input(substr(yrmon,5),2.);
month_ago = 12-month;
ago_date = intnx('month', basedate, -month_ago);
format ago_date yymmdd10.;
datalines;
DATE00 1.00000
DATE01 0.99944
DATE02 0.99907
DATE03 0.99907
DATE04 0.99889
DATE05 0.99799
DATE06 0.99659
DATE07 0.99500
DATE08 0.99296
DATE09 0.99100
DATE10 0.85000
DATE11 0.78000
DATE12 0.34900
;
查看器中输出数据集的图像