楼主: crackman
2582 1

[原创博文] 跟crackman读SAS程序(5) [推广有奖]

已卖:401份资源

院士

83%

还不是VIP/贵宾

-

威望
6
论坛币
91928 个
通用积分
23.5045
学术水平
424 点
热心指数
505 点
信用等级
256 点
经验
112978 点
帖子
2940
精华
0
在线时间
2532 小时
注册时间
2007-4-26
最后登录
2025-6-25

初级热心勋章 中级热心勋章 初级学术勋章 初级信用勋章

楼主
crackman 发表于 2010-8-20 13:16:09 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
原问题在:http://www.pinggu.org/bbs/thread-883926-1-1.html
HOPEWELL的解答:
data one;
input x @@;
datalines;
1 1 1
;
data two;
input x y @@;
datalines;
2 3 2 3 2 3
;
data three;
input x y z @@;
datalines;
4 5 6 4 5 6 4 5 6
;
%macro test/parmbuff;
options mcompilenote=none nomprint nosymbolgen nomlogic;
data %scan(&syspbuff,1); run;
%let n=2;
%let dsname=%scan(&syspbuff,&n);
%do %while(&dsname ne);
  %let dsid=%sysfunc(open(&dsname,i));
  %let varname=%sysfunc(varname(&dsid,%sysfunc(attrn(&dsid,nvars))));
  %let rc=%sysfunc(close(&dsid));
  %put &dsname &varname;
  data out;
   merge out &dsname(keep=&varname);
  run;
  %let n=%eval(&n+1);
  %let dsname=%scan(&syspbuff,&n);
%end;
%mend;
%test(out one two three)

这个解答很精彩,也很难让一般人看的清楚明白,我来解释一下:
思路:首选用一个自动宏变量syspbuff获取%test(out one two three)宏中的文本参数 (out one two three),至于像了解syspbuff这个宏变量的含义,去找SAS官网看看。
用一个%scan截取文本参数的字符串,作为后面的数据集的名称。这里有段解释也许有用:
SYSPBUFF resolves to the text supplied as parameter values in the invocation of a macro that is defined with the PARMBUFF option. For name-style invocations, this text includes the parentheses and commas. Using the PARMBUFF option and SYSPBUFF, you can define a macro that accepts a varying number of parameters at each invocation. If the macro definition includes both a set of parameters and the PARMBUFF option, the macro invocation causes the parameters to receive values and the entire invocation list of values to be assigned to SYSPBUFF.
这里有个难点就是%do %while(&dsname ne);其实应该晓得&dsname ne的返回结果要么是true,要么是false.那么NE是比较什么呢?这里其实就是确定不同N下,通过%SCAN得到的DSNAME宏变量是否存在,也就是后面的DSNAME对应的数据集是否存在,读者可以做一个测试,第一:将数据集TWO去掉看看是提示LOG;第二:在文本参数中后面加一个four,看看错误提示,这个是我的理解。
在这个里面还涉及到三个函数,一个OPEN,一个是VARNAME, 一个ATTRN,OPEN函数其实就是打开制定的数据集DSNAME,ATTRN其实是获得当前活动状态下数据集DSNAME的变量数这一属性值,然后VARNAME获得在当前活动状态下数据集DSNAME里面的最后一个变量(加入变量数这属性值为3,那么就是获得第三个变量,及最后一个变量)。然后关闭活动状态下的数据集DSNAME。N自动加1,继续循环。知道(&dsname ne)为false。
不知道解释清楚没得,这个程序很经典,很多宏书上都有这个示例,大家可以琢磨一下。(多谢soporaeternus 提出来)
二维码

扫码加我 拉你入群

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

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

关键词:crackman Ackman CRACK sas程序 CRA 程序

已有 6 人评分学术水平 热心指数 信用等级 收起 理由
yatming + 1 精彩帖子
醉_清风 + 1 + 1 + 1 很精彩 可惜我现在上班不能经常上来看了
peijiamei + 3 + 3 对论坛有贡献
pobel + 1 + 1 精彩帖子
hopewell + 1 + 1 + 1 精彩帖子
soporaeternus + 1 + 1 5了,一如既往的支持......

总评分: 学术水平 + 7  热心指数 + 8  信用等级 + 2   查看全部评分

沙发
soporaeternus 发表于 2010-8-20 13:56:58
&syspbuff回来的参数带括号的,是(out one two three)
%scan截断的时候(和_blank_都是默认分隔符
效果就是 out one two three
附:
SAS Help:SYSPBUFF resolves to the text supplied as parameter values in the invocation of a macro that is defined with the PARMBUFF option. For name-style invocations, this text includes the parentheses and commas.
已有 1 人评分学术水平 热心指数 收起 理由
pobel + 1 + 1 我很赞同

总评分: 学术水平 + 1  热心指数 + 1   查看全部评分

Let them be hard, but never unjust

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-29 17:29