楼主: luyoung
3006 10

[问答] 宏变量不能作为参数被调用 [推广有奖]

  • 2关注
  • 0粉丝

本科生

50%

还不是VIP/贵宾

-

威望
0
论坛币
1073 个
通用积分
36.0396
学术水平
0 点
热心指数
5 点
信用等级
0 点
经验
847 点
帖子
35
精华
0
在线时间
120 小时
注册时间
2016-1-21
最后登录
2024-1-31

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
  1. %macro nation(inDS=,outDS=);
  2.         %do i=1 %to &n_nation.;
  3.                 %let nt=%scan(&nation.,&i.);
  4.                 data &outDS.;
  5.                         set &inDS.;
  6.                         id_addr=%sysfunc(tranwrd(id_addr,&nt.,%str()));
  7.                         now_addr=%sysfunc(tranwrd(now_addr,&nt.,%str()));
  8.                         company_addr=%sysfunc(tranwrd(company_addr,&nt.,%str()));
  9.                 run;
  10.         %end;
  11. %mend nation;
复制代码
当前要清洗一批地址类数据----去掉所有的民族信息。
&n_nation.为民族码表的条数
&nation.为全部民族名称合并的字符串,以空格隔开
现在遇到的问题是%sysfunc(tranwrd(id_addr,&nt.,%str()))不能获取&nt.的值,代码跑完并不能实现删除相应关键字功能。


请问要怎么改才好,之前有通过将id_addr逐条赋为宏变量值,然后替换,代码可实现。
二维码

扫码加我 拉你入群

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

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

关键词:sysfunc company Nation compan ATION

沙发
Tigflanker 发表于 2018-4-19 15:54:34 |只看作者 |坛友微信交流群
哥们,你混淆概念了。

宏里面的data步如果掺杂了宏变量/宏参数、宏函数(如%scan)、%sysfunc,是在这个data步执行之前先行编译的;
就说先要把你data步中的所有%和&要解析成“文本”,再接着执行整个data步。

所以你%sysfunc(tranwrd(id_addr,&nt.,%str())),这一步的意思是:把id_addr这几个字符中的民族内容替换,那当然无效了。

使用道具

藤椅
luyoung 发表于 2018-4-19 16:02:40 |只看作者 |坛友微信交流群
Tigflanker 发表于 2018-4-19 15:54
哥们,你混淆概念了。

宏里面的data步如果掺杂了宏变量/宏参数、宏函数(如%scan)、%sysfunc,是在这个 ...
是不是说只能分步实现?
1.把id_addr赋为宏变量,但是鉴于宏变量长度要求,需要分批实现。
2.对宏变量&id_addr进行函数操作。
3.合并操作结果。

使用道具

板凳
Tigflanker 发表于 2018-4-19 16:12:24 |只看作者 |坛友微信交流群
  1. data ex;
  2.   str = 'asdf汉族、回族123、777维吾尔族fdsa';
  3. run;

  4. %macro x(nation);
  5. data ex;
  6.   set ex;

  7.   str1 = str;

  8.   do i = 1 to %sysfunc(countw(&nation.));  * 解析为3;
  9.     str1 = compress(str1, scan("&nation.", i, ' '));
  10.   end;
  11. run;
  12. %mend;
  13. %x(汉族 回族 维吾尔族);
复制代码
Bye SAS.
若有缘,能重聚。

使用道具

报纸
Tigflanker 发表于 2018-4-19 16:19:19 |只看作者 |坛友微信交流群
  1. %let nation = 汉族 回族 维吾尔族;

  2. data ex;
  3.   set ex;

  4.   str2 = prxchange("s/%sysfunc(tranwrd(&nation.,%str( ),|))//",-1,str); * %sysfunc(tranwrd(&nation.,%str( ),|)) 解析为 汉族|回族|维吾尔族;
  5. run;
复制代码

使用道具

地板
Tigflanker 发表于 2018-4-19 16:31:11 |只看作者 |坛友微信交流群
luyoung 发表于 2018-4-19 16:02
是不是说只能分步实现?
1.把id_addr赋为宏变量,但是鉴于宏变量长度要求,需要分批实现。
2.对宏变量& ...
你有些过度用宏啦,一般如果你涉及到数据集层面的重复,建议用宏,另一个就是你的语句中出现%do,那也是必须用宏;
除此以外,data步也有三级循环的,PDV、array或prxchange、hash,已经挺灵活的;
你的id_addr是在数据集中,所以不用引出来哈。

使用道具

7
luyoung 发表于 2018-4-19 16:37:30 |只看作者 |坛友微信交流群
Tigflanker 发表于 2018-4-19 16:31
你有些过度用宏啦,一般如果你涉及到数据集层面的重复,建议用宏,另一个就是你的语句中出现%do,那也是必 ...
好的,谢谢,之前用普通代码实现过这个功能,因为涉及到民族,省,市,县等多个码表,所以代码量最终非常庞大,想使用宏来实现。
昨天已经用将id_addr赋为宏变量的方式实现了功能,但是是逐条实现的,循环量非常大,又想再改一下。

使用道具

8
luyoung 发表于 2018-4-19 16:45:52 |只看作者 |坛友微信交流群
  1. %macro nation(inDS=,outDS=);
  2.         %do i=1 %to &n_nation.;
  3.                 %let nt=%scan(&nation.,&i.);
  4.                 data &outDS.;
  5.                         set &inDS.;
  6.                         id_addr=compress(tranwrd(id_addr,"&nt.",""));
  7.                         now_addr=compress(tranwrd(now_addr,"&nt.",""));
  8.                         company_addr=compress(tranwrd(company_addr,"&nt.",""));
  9.                 run;
  10.         %end;
  11. %mend nation;
复制代码

这个代码不能实现功能

  1. %macro nation(inDS=,outDS=);
  2.         %let nt=苗族;
  3.         data &outDS.;
  4.                 set &inDS.;
  5.                 id_addr=compress(tranwrd(id_addr,"&nt.",""));
  6.                 now_addr=compress(tranwrd(now_addr,"&nt.",""));
  7.                 company_addr=compress(tranwrd(company_addr,"&nt.",""));
  8.         run;
  9. %mend nation;
复制代码

这个代码又可以实现。

表示难以理解

使用道具

9
luyoung 发表于 2018-4-19 16:50:16 |只看作者 |坛友微信交流群
  1. /*====  民族  ====*/
  2. %macro nation(inDS=,outDS=);
  3.         data &outDS.;
  4.                 set &inDS.;
  5.         run;
  6.         %do i=1 %to &n_nation.;
  7.                 %let nt=%scan(&nation.,&i.);
  8.                 data &outDS.;
  9.                         set &outDS.;
  10.                         id_addr=compress(tranwrd(id_addr,"&nt.",""));
  11.                         now_addr=compress(tranwrd(now_addr,"&nt.",""));
  12.                         company_addr=compress(tranwrd(company_addr,"&nt.",""));
  13.                 run;
  14.         %end;
  15. %mend nation;

  16. 实现
复制代码
已有 1 人评分论坛币 收起 理由
Tigflanker + 1 看起来没问题,跑成功了吗?

总评分: 论坛币 + 1   查看全部评分

使用道具

10
Tigflanker 发表于 2018-4-19 20:22:01 |只看作者 |坛友微信交流群
luyoung 发表于 2018-4-19 16:45
这个代码不能实现功能
我能看到的一个问题是,你上面那段code;set的永远是&inDS,data的永远是&outDS;可能未形成循环。
你可以在%scan句下面加上%put句看看你nt是否分割正确。

使用道具

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

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

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

GMT+8, 2024-4-27 12:17