首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用宏程序返回的值计算列

使用宏程序返回的值计算列
EN

Stack Overflow用户
提问于 2019-03-11 21:37:14
回答 2查看 1K关注 0票数 3

我想将以下日期计算自动化:将(或减)X个月添加到一个给定的数值变量中,该变量表示YYYYMM格式中的日期,即201901表示2019年1月。例子: 201901 +13个月= 202002

以下宏返回所需的值(&id_mes_n)

代码语言:javascript
复制
%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中使用宏,如下所示:

代码语言:javascript
复制
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为负时)。这样的宏观政策会使我们的生活更轻松。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-12 01:21:10

听起来就像你试图把2011801这样的数字当作代表2018年第一个月的数字,然后添加一个月,并使用相同的“样式”生成一个数字。

如果要使用宏代码中的数字字符串执行此操作,可以创建如下宏:

代码语言:javascript
复制
%macro add_months_macro(date,months);
%sysfunc(intnx(month,%sysfunc(inputn(&date.01,yymmdd8)),&months),yymmn6)
%mend;

但是,您需要一个方法,您可以在普通SAS语句中使用变量值,然后根本不使用%sysfunc()。相反,只需使用宏生成SAS代码来直接调用函数。

代码语言:javascript
复制
%macro add_months_sas(date,months);
input(put(intnx('month',input(cats(&date,'01'),yymmdd8.),&months),yymmn6.),6.)
%mend;

那么WHERE子句看起来如下:

代码语言:javascript
复制
WHERE %add_months_sas(T1.old_date, T1.x_months) > 201801 

但是您实际上应该将数字转换为实际日期,然后使用INTNX() 函数来添加月份。则根本不需要宏。

代码语言:javascript
复制
WHERE intnx('month',T1.old_date, T1.x_months) > '01JAN2018'd  
票数 1
EN

Stack Overflow用户

发布于 2019-03-11 22:40:21

如果您正在运行一个相对较新的SAS版本,您应该将它作为FCMP函数而不是宏函数来共享。

proc fcmp允许您创建(并保存)用户定义的函数,这些函数可以在数据步骤和proc sql中调用(也可以通过%sysfunc()之类的东西调用)。

下面是一个fcmp函数的示例,它在指定的两个数字之间返回一个随机数:

代码语言:javascript
复制
proc fcmp outlib=work.funcs.funcs;
  function randbetween(min,max);
    return ( min + floor( ( 1 + max - min ) * rand("uniform") ) );
  endsub;
run;        

示例用法:

代码语言:javascript
复制
data example;
 do cnt=1 to 5;
   x = randbetween(1,100);
   output;
 end;
run;

结果:

代码语言:javascript
复制
Obs cnt x
1   1   8
2   2   93
3   3   98
4   4   97
5   5   12

如果您收到SAS关于它不承认您的功能的任何抱怨,您可能需要使用以下内容更新您的选项:options cmplib = (work.funcs);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55110788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档