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 
;

查看器中输出数据集的图像