楼主: guanf1986
3951 3

[原创博文] 一个与select into :macroname生成的宏相关的问题 [推广有奖]

  • 0关注
  • 0粉丝

硕士生

13%

还不是VIP/贵宾

-

威望
0
论坛币
461 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
1617 点
帖子
110
精华
0
在线时间
128 小时
注册时间
2009-3-7
最后登录
2020-4-9

50论坛币
这个问题困扰我一天多了,一直很无奈。换了9.1.3和9.2,都有这样的问题。

我的任务是:
一大堆数据库,data(i,j),但是数据库里已知的变量只有两个,一个是日期date,一个是回归因变量比如growth(i,j),剩下的用于回归的自变量除一个以外都是未知的比如growth(x,y),其中x^=i。
我要做的第一步,将所有的自变量全部扩展成lag1-lag5,也就是将growth(x,y)变成变量growth(x,y,t-5),growth(x,y,t-4),growth(x,y,t-3)……growth(x,y,t);
第二步就是将所有的自变量对growth(i,j)回归。

程序如下:
  1. %global vlist;

  2. %macro processing(i, j);

  3. proc contents data=data&i._&j out=content1 noprint;
  4. /*vlist装着表格里的变量名称*/
  5. proc sql noprint;
  6.     select name
  7.     into :vlist separated by '  '
  8.     from content1
  9.     where varnum>2;
  10. quit;

  11. %put vlist===============================&vlist;

  12. /*下面段程序用于扩展数据,将growth(x,y)变成growth(x,y,t-5),growth(x,y,t-4),growth(x,y,t-3)……growth(x,y,t)*/
  13. proc expand data=data&i._&j out=rexpand.data&i._&j;
  14.     %do s=1 %to 99;
  15.         %let string=%scan(&vlist, &s);
  16.         %if %length(&string) ne 0 %then
  17.             %do t=1 %to 5;
  18.                 convert &string=lag&t._&string / transformout= (lag &t);
  19.             %end;
  20.         %else %goto done;
  21.     %end;
  22.     %done: run;
  23. quit;


  24. data rexpand.data&i._&j;
  25. /*下面这2行程序确保这2个变量不在自变量列表的行列里。*/
  26.     format date yymmdd10.;
  27.     format growth&i._&j 15.12;

  28.     set rexpand.data&i._&j;
  29. /*下面这一行只是为了删除lag5为空的行*/
  30.     if lag5_var&i._&j=. then delete;

  31.     drop time;
  32. run;
  33. /*下面这段程序是为了获取最新的自变量列表,包括原列表里所有的lag1-lag5项*/
  34. proc contents data=rexpand.data&i._&j  noprint out= content2;
  35. run;

  36. proc sql noprint;
  37.     select name
  38.     into :vlist separated by '  '
  39.     from content2
  40.     where varnum>2;/*varnum>2确保date和growth(i,j)变量没被列入自变量列表中*/
  41. quit;

  42. %put vlist=================================&vlist;

  43. proc reg data=rexpand.data&i._&j outest=outest.data&i._&j;
  44.     model growth&i._&j=&vlist / selection=stepwise aic ADJRSQ;
  45.     output out=out.data&i._&j p=p r=r;
  46.     run;
  47. quit;

  48. %mend;
复制代码
这段程序如果放在几百行的复杂程序里跑时,
第一次,vlist的值输出显示为空
第二次,vlist的值输出显示不为空,但是也不对。
第三次,vlist的值显示正常了。然后程序运行就正常了。

但是如果这段程序变成不用宏%macro processing,单独copy出来到一个新文件里,把i和j分别替换成具体的数值,程序完全能够一次性正常运行。vlist的显示也正确。

说实话这个问题我目前的解决方案感觉就像电视机不好使唤的时候,拍两下就会好一阵子的。

另外我将程序
  1. proc sql noprint;
  2.     select name
  3.     into :vlist separated by '  '
  4.     from content1
  5.     where varnum>2;
  6. quit;
复制代码
换成过call symput()的形式,结果还是一样的。


我对问题的感觉是,程序大了或宏变量多了以后,正常的宏运算就会遇到一定的问题,不知道谁有这样的经验?

关键词:macroname Select Elect Macro name growth 数据库 因变量 自变量 程序
沙发
guanf1986 发表于 2011-3-13 11:09:47 |只看作者 |坛友微信交流群
我将下面这段程序
  1. proc sql noprint;
  2.     select name
  3.     into :vlist separated by '  '
  4.     from content
  5.     where varnum>3;
  6. quit;
复制代码

换成了
  1. data _null_;
  2.     length list $2000;
  3.     retain list ' ';
  4.     set content end=last;
  5.     if _n_=1 then sp=' ';
  6.     else sp=' '; /* sp separates macro variables */
  7.     if varnum>3 then list=trim(list)||sp||trim(name);
  8.     if last then call symput('vlist',list);  
  9. run;
复制代码

问题依旧。。。。
讲究 但不将就!

使用道具

藤椅
一米酱 学生认证  发表于 2017-9-28 23:31:26 |只看作者 |坛友微信交流群
我也遇到了相似的问题
  1. %let dsname=infor;
  2. proc sql noprint;
  3. select name into :&dsname._var separated by ' ' from &dsname._contents;
  4. quit;
复制代码
上面的代码运行无误,可以把变量名提取出来。

  1. %macro inputcsv(file=,dsname=);
  2. filename mycsv &file;
  3. proc import out=&dsname datafile=mycsv dbms=csv replace;
  4.          getnames= yes;
  5. run;

  6. proc contents data=&dsname out=&dsname._contents noprint;
  7. run;

  8. proc sql noprint;
  9. select name into :&dsname._var separated by ' ' from &dsname._contents;
  10. quit;

  11. %mend;
复制代码
完全一样的代码放在macro函数中就不行
%put _user_找不到infor_var

放弃了。。。。。决定不把into套在macro里面了

使用道具

板凳
一米酱 学生认证  发表于 2017-9-29 01:12:15 |只看作者 |坛友微信交流群
开心,终于debug出来了~~

  1. data a;
  2. input x y ;
  3. cards;
  4. 1  3
  5. 2  4
  6. 5  7
  7. ;

  8. %macro var(dsname);
  9. %global &dsname._num1;
  10. proc sql noprint;
  11. select x into :&dsname._num1 separated by ',' from &dsname;
  12. quit;
  13. %mend;

  14. %var(a)

  15. %put &a_num1;
复制代码


这个是示范代码~
最重要的一句是在macro里面建立全局宏变量。

哈哈哈哈哈
已有 1 人评分经验 论坛币 收起 理由
admin_kefu + 40 + 30 热心帮助其他会员

总评分: 经验 + 40  论坛币 + 30   查看全部评分

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-20 11:39