我想将以下日期计算自动化:将(或减)X个月添加到一个给定的数值变量中,该变量表示YYYYMM格式中的日期,即201901表示2019年1月。例子: 201901 +13个月= 202002
以下宏返回所需的值(&id_mes_n)
%macro suma_meses(id_mes_ini, n_meses);
%let anio_ini = %sysfunc(floor(&id_mes_ini/100)); /*get year*/
%let mes_ini = %sysfunc(mod (&id_mes_ini,100)); /*get month*/
%let aux = %eval(12*&anio_ini + &mes_ini + &n_meses);
%let anio_n = %sysfunc(floor(&aux/12)); /*calculate new year*/
%let mes_n = %sysfunc(mod (&aux,12)); /*calculate new month*/
%if &mes_n = 0 %then %do; /*correction for month 12*/
%let id_mes_n = %eval(100*(&anio_n-1)+ 12);
%end;
%else %do;
%let id_mes_n = %eval(100*&anio_n + &mes_n);
%end;
&id_mes_n /*returned value*/
%mend;
%suma_meses(201901, 13) /*returns 202002*/我想在PROC中使用宏,如下所示:
PROC SQL;
CREATE TABLE want AS
SELECT T1.*, %suma_meses(T1.old_date, T1.x_months) AS new_date
FROM have T1
WHERE %suma_meses(T1.old_date, T1.x_months) > 201801 ;
QUIT;这能办到吗?由于这类计算对于我所在地区的人(我们不是管理员、工程师等)来说是一项非常反复的任务,所以我们的想法是与其他用户共享宏,以简化语法。换句话说,我们希望提高代码的可读性,避免复制粘贴问题,并将非高级用户从急剧的计算错误XD中解放出来(特别是在涉及子查询且X为负时)。这样的宏观政策会使我们的生活更轻松。
发布于 2019-03-12 01:21:10
听起来就像你试图把2011801这样的数字当作代表2018年第一个月的数字,然后添加一个月,并使用相同的“样式”生成一个数字。
如果要使用宏代码中的数字字符串执行此操作,可以创建如下宏:
%macro add_months_macro(date,months);
%sysfunc(intnx(month,%sysfunc(inputn(&date.01,yymmdd8)),&months),yymmn6)
%mend;但是,您需要一个方法,您可以在普通SAS语句中使用变量值,然后根本不使用%sysfunc()。相反,只需使用宏生成SAS代码来直接调用函数。
%macro add_months_sas(date,months);
input(put(intnx('month',input(cats(&date,'01'),yymmdd8.),&months),yymmn6.),6.)
%mend;那么WHERE子句看起来如下:
WHERE %add_months_sas(T1.old_date, T1.x_months) > 201801 但是您实际上应该将数字转换为实际日期,然后使用INTNX() 函数来添加月份。则根本不需要宏。
WHERE intnx('month',T1.old_date, T1.x_months) > '01JAN2018'd 发布于 2019-03-11 22:40:21
如果您正在运行一个相对较新的SAS版本,您应该将它作为FCMP函数而不是宏函数来共享。
proc fcmp允许您创建(并保存)用户定义的函数,这些函数可以在数据步骤和proc sql中调用(也可以通过%sysfunc()之类的东西调用)。
下面是一个fcmp函数的示例,它在指定的两个数字之间返回一个随机数:
proc fcmp outlib=work.funcs.funcs;
function randbetween(min,max);
return ( min + floor( ( 1 + max - min ) * rand("uniform") ) );
endsub;
run; 示例用法:
data example;
do cnt=1 to 5;
x = randbetween(1,100);
output;
end;
run;结果:
Obs cnt x
1 1 8
2 2 93
3 3 98
4 4 97
5 5 12如果您收到SAS关于它不承认您的功能的任何抱怨,您可能需要使用以下内容更新您的选项:options cmplib = (work.funcs);
https://stackoverflow.com/questions/55110788
复制相似问题