全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
4430 6
2014-07-22
悬赏 100 个论坛币 已解决
求助大家个问题:

是这样,我做个小宏,目的是返回一个计算好的值串,然后在存到某个data步中的某个变量中。

我初步的打算是这样:

复制代码

宏中的“&count. (%sysfunc(round(&count. * 100 / &N.,.1)))”为返回值,本来打算这样用:

复制代码

结果失败。。。。。。。

换成这样:

复制代码

然后这样用:

复制代码

依然失败。。。。。。。。。

所以我想问两个问题:

1. A计划中,reslove给我返回的是宏中的SQL过程Code,而不是我预留下来的值,我想问下为什么?

2. B计划中,我看到call execute是在data步的编译过程中执行的,所以我两个条件age < 65 and age >= 65的宏变量countx的值是一样的;我想问为什么?

谢谢。

最佳答案

pobel 查看完整内容

1. 宏执行的产品是SAS代码。楼主的宏执行后,PROC SQL语句,以及后面的 n(%) 都会作为宏的结果返回。 data test; code="%count(in=adsl,where=age < 65);"; put code=; run; 如果是需要宏只返回最后的n(%),那就需要前面的整个计算都用宏语句来完成。 2. 首先,call execute语句中对宏的调用不是在编译过程中执行的,而是: a. 其中的宏语句,如%LET语句,是在data步执行过程中为countx赋值的; b. 其中的SQL ...
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2014-7-22 10:53:42
1.
宏执行的产品是SAS代码。楼主的宏执行后,PROC SQL语句,以及后面的 n(%) 都会作为宏的结果返回。
data test;
   code="%count(in=adsl,where=age < 65);";
  put code=;
run;

如果是需要宏只返回最后的n(%),那就需要前面的整个计算都用宏语句来完成。

2.
首先,call execute语句中对宏的调用不是在编译过程中执行的,而是:
a. 其中的宏语句,如%LET语句,是在data步执行过程中为countx赋值的;
b. 其中的SQL语句,是在data out1这个data步执行完毕后才开始执行。也就是说,宏对COUNTX的“赋值”,其实是在SQL语句执行之前。

另外,%let语句为countx赋值时应该借用了已经存在的宏变量count,也就是之前的某个步骤中产生的宏变量count。楼主可以在data out;语句之前加%symdel count/nowarn; 来验证。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-7-22 12:56:48
大概改成这样的就行了,宏的思路没必要弄得很复杂,
%macro count(in=, where= );
  proc sql noprint;
  select count(distinct subjid) into: count from &in.
  where %bquote(&where)
     ;        
  quit;
%let countx= &count. (%sysfunc(round(%sysevalf(&count  * 100 / 20) ,.1)));
data out1;
   set out1 end = last;
   output;
   if last then do;
     col = symget(countx);
     output;
   end;
%mend;
%countx(in=adsl, where= age < 65)
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-7-22 13:00:26
where= age >5 因为有大于号(特殊字符),得用%bquote mark掉,然后在宏的执行阶段起作用
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-7-22 19:24:36
pobel 发表于 2014-7-22 13:53
1.
宏执行的产品是SAS代码。楼主的宏执行后,PROC SQL语句,以及后面的 n(%) 都会作为宏的结果返回。
da ...
谢谢。

换句话说,就是如果一个宏里面交杂有过程步或者data步,

那么对于返回值,他就连同其他语句作为宏编译和执行(宏语句)过后的产物;

对于execute执行就是他还是会等到所在data步的结尾来执行收集到的execute命令。

是这样么?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-7-23 07:20:47
Tigflanker 发表于 2014-7-22 19:24
谢谢。

换句话说,就是如果一个宏里面交杂有过程步或者data步,
是这样的。

宏的任务就是产生SAS语句,再交回到SAS执行。这里的SAS语句是指那些除了宏语句之外的所有字符。比如%let,%do,%if之类的宏语句,会在宏执行时“用掉”。剩下的包括过程步,data步的代码,abcdefghi之类的字符,甚至和宏语句无关的分号,都会作为宏执行的结果,一同返回。

对于call execute(),我一直把它理解成‘data步中的宏’,它可以根据变量的值来构建代码。call execute()参数中的SAS语句(data步,proc步等)都会放到其所在的data步之后依次执行。而其中如果涉及到宏的语句,包括宏的调用,其执行时间需视情况而定。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群