a***r 发帖数: 420 | 1 很简单的一段
%macro multi;
%do i=1 %to 75;
%pearson(X,&i);
%end;
%mend;
%multi;
昨天还可以用,今天莫名就只跑第一个值就退出循环了。。。
单独%pearson(X,1);%pearson(X,2);。。。还是可以跑的
很莫名。。。
达人点解?
谢谢:) |
d*******o 发帖数: 493 | 2 用一个macro不行吗?
%pearson(X, cycle = 1);
%do i=1 %to &cycle;
/**/
%end;
%mend;
nested macro涉及变量scope的问题。 |
A*******s 发帖数: 3942 | 3 嗯,我也猜有可能是这个原因。
比较好的风格是macro里定义的所有macro variabe都应该尽量是local的,最好避免用
太短的命名以免冲突。
【在 d*******o 的大作中提到】 : 用一个macro不行吗? : %pearson(X, cycle = 1); : %do i=1 %to &cycle; : /**/ : %end; : %mend; : nested macro涉及变量scope的问题。
|
b*****e 发帖数: 223 | 4 nested macro 的问题具体怎么说?这些是不是只有自己写过用过才清楚
我们有个 standard macro,不能用 do i=1 to n 去 call 它,用 do j=1 to n 或者
随便非 i 就可以了。这是为什么?standard macro 把 i 定义成 global 变量了?
【在 A*******s 的大作中提到】 : 嗯,我也猜有可能是这个原因。 : 比较好的风格是macro里定义的所有macro variabe都应该尽量是local的,最好避免用 : 太短的命名以免冲突。
|
D******n 发帖数: 2836 | 5 SAS Macro is different from function that is common in many other language.
Macros encapsulation is very bad.
【在 b*****e 的大作中提到】 : nested macro 的问题具体怎么说?这些是不是只有自己写过用过才清楚 : 我们有个 standard macro,不能用 do i=1 to n 去 call 它,用 do j=1 to n 或者 : 随便非 i 就可以了。这是为什么?standard macro 把 i 定义成 global 变量了?
|
A*******s 发帖数: 3942 | 6 我猜那个macro里面有类似于 %let i=n+1; 之类的语句,然后执行完这个macro之后,&
i的值改变了就跳出循环了。
试着运行下面的code
%macro layer2();
%local i;
%let i=10;
%put i = &i in the nested macro;
%mend;
%macro layer1();
%do i=1 %to 5;
%put i = &i before calling macro;
%layer2;
%put i = &i after calling macro;
%end;
%mend;
%layer1;
然后把layer2里面的%local去掉就知道了。
【在 b*****e 的大作中提到】 : nested macro 的问题具体怎么说?这些是不是只有自己写过用过才清楚 : 我们有个 standard macro,不能用 do i=1 to n 去 call 它,用 do j=1 to n 或者 : 随便非 i 就可以了。这是为什么?standard macro 把 i 定义成 global 变量了?
|
A*******s 发帖数: 3942 | 7 macro variable至少还有不同的scope,macro里创建的temp datasets的命名冲突就更
麻烦了...以前写了个recursive macro,差点没把我整疯掉...
.
【在 D******n 的大作中提到】 : SAS Macro is different from function that is common in many other language. : Macros encapsulation is very bad.
|
D******n 发帖数: 2836 | 8 所以macro里面大多用 _temp_ ,_dataset1_
之类的命名方法。
跟oloolo学的。
【在 A*******s 的大作中提到】 : macro variable至少还有不同的scope,macro里创建的temp datasets的命名冲突就更 : 麻烦了...以前写了个recursive macro,差点没把我整疯掉... : : .
|
A*******s 发帖数: 3942 | 9 对,最好要加一个和macro name相关的prefix
如果是recursion,还得按照情况加不同的prefix
【在 D******n 的大作中提到】 : 所以macro里面大多用 _temp_ ,_dataset1_ : 之类的命名方法。 : 跟oloolo学的。
|
b*****e 发帖数: 223 | 10 哦,没好好学 sas 啊 //headdown |
|
|
b*****e 发帖数: 223 | 11 我们那个一用 do i 去 call 就死掉结束不了了.....
【在 A*******s 的大作中提到】 : macro variable至少还有不同的scope,macro里创建的temp datasets的命名冲突就更 : 麻烦了...以前写了个recursive macro,差点没把我整疯掉... : : .
|
A*******s 发帖数: 3942 | 12 那几乎可以肯定是因为这个
%macro layer2();
%let i=1;
%put i = &i in the nested macro;
%mend;
%macro layer1();
%do i=1 %to 5;
%put i = &i before calling macro;
%layer2;
%put i = &i after calling macro;
%end;
%mend;
%layer1;
【在 b*****e 的大作中提到】 : 我们那个一用 do i 去 call 就死掉结束不了了.....
|
b*****e 发帖数: 223 | 13 macro 这些是不是只有自己写过一些才了解细节?好像没看书里有说啊。我们平常胡乱
写的我觉得都好简单啊
【在 A*******s 的大作中提到】 : 那几乎可以肯定是因为这个 : %macro layer2(); : %let i=1; : %put i = &i in the nested macro; : %mend; : %macro layer1(); : %do i=1 %to 5; : %put i = &i before calling macro; : %layer2; : %put i = &i after calling macro;
|
A*******s 发帖数: 3942 | 14 scopes of macro variables在advanced certificate就有说吧。有些细节要是自己没
用过肯定记不住。
我觉得,SAS这么笨的东西,就应该写的简单,写的复杂的都不可避免地要出错。而且想
想,比你水平差的同事都用了最笨的方法写完了,你还在辛辛苦苦殚精竭虑地debug一
个复杂的macro,划不来啊...
【在 b*****e 的大作中提到】 : macro 这些是不是只有自己写过一些才了解细节?好像没看书里有说啊。我们平常胡乱 : 写的我觉得都好简单啊
|
b*****e 发帖数: 223 | 15 。。。汗。。。其实我很少殚精竭虑,我都很少看 log 去 debug 那种好些层的 macro
,除非那种一眼看就知道什么问题的
btw,你中文真好啊,殚精竭虑,咳咳
【在 A*******s 的大作中提到】 : scopes of macro variables在advanced certificate就有说吧。有些细节要是自己没 : 用过肯定记不住。 : 我觉得,SAS这么笨的东西,就应该写的简单,写的复杂的都不可避免地要出错。而且想 : 想,比你水平差的同事都用了最笨的方法写完了,你还在辛辛苦苦殚精竭虑地debug一 : 个复杂的macro,划不来啊...
|
f*****k 发帖数: 110 | 16 对第一个macro有疑问,特请教Actuaries。
这个macro少了‘%local i;’那么这个i就是在global symbol table 里了么?我记得
如果%let出现在macro里面时,其所定义的macro variable 仍然是在local symbol
table里。如果我是对的话,‘%local i;’语句用不用都无所谓啊。
另外,如何查看global symbol table 和 local symbol table 啊?
【在 A*******s 的大作中提到】 : 那几乎可以肯定是因为这个 : %macro layer2(); : %let i=1; : %put i = &i in the nested macro; : %mend; : %macro layer1(); : %do i=1 %to 5; : %put i = &i before calling macro; : %layer2; : %put i = &i after calling macro;
|
f*****k 发帖数: 110 | 17 Actuaries的意思是外层macro中的i和内层macro中i被放到了一个symbol table里,所
以内层i的值影响了外层i的值?但外层macro和内层macro应该有不同的symbol table啊
(即使都是local的),那怎么还会有干扰呢?
我正在学习macro,但很多概念和细节都不清楚,所以想借此机会打破沙锅问到底。多
谢!
,&
【在 A*******s 的大作中提到】 : 我猜那个macro里面有类似于 %let i=n+1; 之类的语句,然后执行完这个macro之后,& : i的值改变了就跳出循环了。 : 试着运行下面的code : %macro layer2(); : %local i; : %let i=10; : %put i = &i in the nested macro; : %mend; : %macro layer1(); : %do i=1 %to 5;
|
A*******s 发帖数: 3942 | 18 我一时半刻说不明白,看这个
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML
【在 f*****k 的大作中提到】 : Actuaries的意思是外层macro中的i和内层macro中i被放到了一个symbol table里,所 : 以内层i的值影响了外层i的值?但外层macro和内层macro应该有不同的symbol table啊 : (即使都是local的),那怎么还会有干扰呢? : 我正在学习macro,但很多概念和细节都不清楚,所以想借此机会打破沙锅问到底。多 : 谢! : : ,&
|
d******9 发帖数: 404 | 19 呵呵,这叫做保险起见 !!!以确保 I 是 local .
"如果%let出现在macro里面时,其所定义的macro variable 仍然是在local symbol
table里。"
Usually, this is correct. However, in special case, it is not.
If you already have a same named macro variable I outside the macro
definition, then this "%let I=10" will only overwrite the global macro
variable, rather than creating a new local macro variable.
So, that is why we use %local I. It will ensure SAS to create a local macro
variable I in the local symbol table, even we already have a global macro
variable I.
【在 f*****k 的大作中提到】 : 对第一个macro有疑问,特请教Actuaries。 : 这个macro少了‘%local i;’那么这个i就是在global symbol table 里了么?我记得 : 如果%let出现在macro里面时,其所定义的macro variable 仍然是在local symbol : table里。如果我是对的话,‘%local i;’语句用不用都无所谓啊。 : 另外,如何查看global symbol table 和 local symbol table 啊?
|
f*****k 发帖数: 110 | 20 I studied dido2009's explanation and Actuaries' link. Now I am kind of
understand aquar's issue, where he macro rv i exists only in the local table
of the out-layer macro, so that the macro rv i appears in the inner-layer
macro still can affect the value of i in the out-layer macro.
Before the 1st run of execution of the inner-layer macro, the value of i in
the local table of the out-layer macro is 1 so that the DO loop can work and
the inner-layer macro is executed for 1st time. After the 1st run of
execution of the inner-layer macro, however, the value of i in the local
table of the out-layer macro is changed to beyond the range of 75. So,the
2nd iteration of the DO loop can not happen.
To solve this issue, use %local statement in the inner-layer macro to force
its i to be in this macro's local table. Now, the two i's will not affect
each other anymore so that the DO loop can go through the whole range of 75.
Right?
macro
【在 d******9 的大作中提到】 : 呵呵,这叫做保险起见 !!!以确保 I 是 local . : "如果%let出现在macro里面时,其所定义的macro variable 仍然是在local symbol : table里。" : Usually, this is correct. However, in special case, it is not. : If you already have a same named macro variable I outside the macro : definition, then this "%let I=10" will only overwrite the global macro : variable, rather than creating a new local macro variable. : So, that is why we use %local I. It will ensure SAS to create a local macro : variable I in the local symbol table, even we already have a global macro : variable I.
|
d******9 发帖数: 404 | 21 It could be,however, not sure.
table
in
and
【在 f*****k 的大作中提到】 : I studied dido2009's explanation and Actuaries' link. Now I am kind of : understand aquar's issue, where he macro rv i exists only in the local table : of the out-layer macro, so that the macro rv i appears in the inner-layer : macro still can affect the value of i in the out-layer macro. : Before the 1st run of execution of the inner-layer macro, the value of i in : the local table of the out-layer macro is 1 so that the DO loop can work and : the inner-layer macro is executed for 1st time. After the 1st run of : execution of the inner-layer macro, however, the value of i in the local : table of the out-layer macro is changed to beyond the range of 75. So,the : 2nd iteration of the DO loop can not happen.
|