作者bugle (低点)
看板Statistics
标题Re: [程式] SAS MACRO问题
时间Sun Feb 21 04:52:56 2016
※ 引述《yonny (悠逆)》之铭言:
: [软体程式类别]: SAS
: [程式问题]: MARCRO Multiple ampersands(&)
: [软体熟悉度]: 熟悉
: [问题叙述]:
: 今天在看 SAS advanced MACRO的部分
: 里面有讲到Re-Scan Rule的部分
: the macro processor resolves two ampersand(&&) to one ampersand(&)
: 在部分我有些疑惑的地方
: [程式范例]:
: 例如:
: %let A = C; %let B = A; %put &&B/*答案是A*/;
: &B = A
: &&B -> &B = A (所以&B和&&B的值其实一样的)
: 虽然知道SAS规定的原则就是这样
: 但不知道这样的规定是有什麽好处吗?为什麽要这样定?
: 既然&B和&&B的值相同 那为什麽还要有&&B ?
: 直觉上会觉得
: &B=A 那&&B会等於&A又等於C 这样比较合理
: SAS为什麽不这麽设定?
因为SAS不是这样设计的
控制巨集变数的&符号,其连续次数n,并不代表变数是第n层叠代...
: 另外还有一个问题 例如:
: %let var1 = one;
: %let var2 = two;
: %let var3 = three;
: %let crs=3;
: 当
: %PUT &&var&crs;
: 答案是three, 因为会变成&var3 = three
: 但当
: %PUT &var&crs;
: 就会跑出
: WARNING: Apparent symbolic reference VAR not resolved.
: &var3
: 心理觉得很疑惑
: %PUT &&var&crs; 就会跑出正确的答案
: 而%PUT &var&crs; 不是也是&var3 为什麽不会跑出three?
: 内心真的非常疑惑
: 十分感谢大家解答!!!
先解说你的第一个疑问:SAS为什麽要设计multi-ampersands(&)
但要回答这个问题之前,请先建立SAS在处理巨集变数叠代,非常重要的两个概念
1.
将 double ampersands(&&) 转换为 single ampersand (&)
2.
若 &xxxx 可以代表任意已经建立的巨集变数,&xxxx就会叠代为该巨集变数
就这两个逻辑,没有第三
任何一行SAS程式码 (至分号为止),都会对上面两个逻辑进行巨集变数的叠代
直到都不成立为止,才会解译为即将被执行的程式码,送进编译器执行
以你的例子为例:
%LET A = C; %LET B = A; %PUT &&B;
前两个%LET不解释,真正要被叠代的是这行:%PUT &&B;
SAS其实是经过以下逻辑去推演的
(SAS侦测到巨集) %PUT &&B;
(第一次叠代後) %PUT &B; /* 符合条件1,因此&&转换为& */
(第二次叠代後) %PUT A; /* 符合条件2,因此&B转换为A */
因此最终,SAS真正执行的程式码是:%PUT A;
於是我们在log看到一个英文字母A被丢出来
SAS为什麽要这样设计多层的ampersand?
这是因为,SAS希望设计出,
巨集变数能够被其他巨集变数来组合(计算)
例如,我手上有n个巨集变数,来标示我观察到特定时间
%LET YYMM1 = 1308;
%LET YYMM2 = 1502;
......
%LET YYMMn = 1412; /*请注意不是连续*/
假设我要取某个变数&YYMMp,其中p可能是被计算才得知的
此时就要考虑到巨集变数的叠代
/* 假设经过一番计算,得出&p为2 */
(原始程式码) %PUT &&YYMM&P;
(第一次叠代) %PUT &YYMM2;
(第二次叠代) %PUT 1502;
1502才会因此被引用,因为&P是需要被计算的
再看你的第二例子
%let var1 = one;
%let var2 = two;
%let var3 = three;
%let crs = 3;
%PUT &&VAR&CRS; 为何没有问题? 因为...
(第一次叠代) %PUT &VAR3; /* &&叠代为&,&CRS叠代为3 */
(第二次叠代) %PUT three; /* 最後执行的结果,three被丢到log */
%PUT &VAR&CRS; 哪里出问题?
因为在第一次要叠代时,程式先判断到&VAR(还没到&CRS)时
就先发生了解译不出&VAR的状况
解译不出,但却为巨集变数的格式,SAS会以程式码的方式处理,因此丢出&VAR3
以上
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.231.102.90
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Statistics/M.1456001578.A.226.html
※ 编辑: bugle (36.231.102.90), 02/21/2016 04:56:40
1F:推 yonny: 哇! 神人~ 非常感谢您~~~~ 02/21 11:12
2F:推 yonny: 真的解释得很清楚!!!!! 02/21 11:21
3F:推 ghd123483: 获益良多 02/21 15:17
4F:推 h14753951: 一个字,屌!!!!!,又学到一个技巧了 02/22 12:16
5F:推 BugEater: 感谢,以前知其然不知其所以然,现在明白了。 03/03 11:14