SAS中文论坛

标题: 关于一个宏的应用问题 [打印本页]

作者: shiyiming    时间: 2004-8-19 21:54
标题: 关于一个宏的应用问题
有一数据集t1, 假定它有10个变量x1,x2,…,x10,现要根据变量对观测进行筛选,假定条件为abs(xi)>5, 如何用简洁且效率高的宏词句实现?

我用下面的语句试了一下,不行。

%macro chuli1;
%do i=1 %to 10;
abs(x&i.)>5;
%end;
%mend;

%macro chuli2;
data t2;
set t1;
%if %chuli1  %then delete;
run;
%mend;
%chuli2;

请指教!
作者: shiyiming    时间: 2004-8-20 10:52
标题: test
[code:227d2]%macro test;
data t2;
  set t1;
  %do i=1 %to 10;
    if abs(x&i.)>5 then delete;
  %end;
run;
%mend;
%test [/code:227d2]
如用%if...%then语句,delete和abs都会有问题,不知为什么?

另外,这个问题不用宏也好解决,如下
[code:227d2]data t2;
  set t1;
  array arr x1-x10;
  do over arr;
    if abs(arr)>5 then delete;
  end;
run;[/code:227d2]
作者: shiyiming    时间: 2004-8-20 18:02
标题: re
macro中嵌套的data step中是不能用%do,%if,%then之类的,它就是一个简单的data step。
作者: shiyiming    时间: 2004-8-21 09:50
标题: Re: re
这个观点不完全对,宏语句可以出现在几乎所有的场合,但必须正确使用,宏语句和宏变量有其特定的规则和使用方式,有时候容易和别的语句规则相混淆,因此容易出错。

我的经验是记住一点,宏语句的功能从根本上讲就是一个字符串替代的过程。
作者: shiyiming    时间: 2004-8-22 20:43
标题: good!
谢谢各位的帮助!

student说的很精辟, 宏就是一个字符替换技术, 但这个替换技术的技巧却是很多.

%do %end 是可以在data步中使用的, 我理解它的功能相当于定义宏变量,
但%if %then好像不能在data步中使用.

我还有一个问题想问, 还是上面那个问题,如果我要利用下面这个data步,好么其中的%test该如何写? 请指教!

data t2;
set t1;
if %test then delete;
run;
作者: shiyiming    时间: 2004-8-23 20:49
标题: You can not do it that way!
首先申明一点,%if %then %else语句在data步中是可以使用的,但如果其中嵌套了data步语句,则必须写成如下的形式:
%if condition %then %do;
%end;
%else %do;
%end;
即必须和%do;%end;语句配合使用。

你所设计的data步程序,
data t2;
set t1;
if %test then delete;
run;
将%test作为一个宏条件来使用,而%test是一个预先定义的宏程序,我还未曾见过这样的应用方式,并且认为这样是行不通的。
作者: shiyiming    时间: 2004-8-24 17:19
标题: RE
能否举个例子说一下%if %then。。。在data步中的使用,我试了不行。


多谢。
作者: shiyiming    时间: 2004-8-24 22:43
标题: 应用在宏中!
我想你可能将该宏语句直接使用在开放的data步程序中了,%if %then %else语句以及%do;%end;语句不能以此方式使用,而是必须使用在某个宏程序中。比如以下的例子。

%macro test;
data _null_;
  %do i=1 %to 8;
    %if &i<5 %then %do;
          put 'i is less than 5';
        %end;
        %else %do;
          put 'i is greater than 5';
        %end;
  %end;
run;
%mend test;
%test;
作者: shiyiming    时间: 2004-8-25 22:34
标题: to student!
我感觉是行得通的,因为我以前这样用过,
利用宏生成一系列变量,在data步中引用宏.
如:
%macro test;
%do i=1 %to 9;
%do j=1 %to 10;
%if &i>&j %then %do;
x%eval(10*(&i-1)+1)=y%eval(10*(&i-1)+1)/z%eval(10*(&i-1)+1);
%end;
%end;
%end;
%mend;

data t2;
set t1;
%test;
run;
运行成功过!
作者: shiyiming    时间: 2004-8-25 23:46
标题: correct indeed.
这样使用是可以的,但必须保证宏程序所产生的代码符合data步的语句规则以及和其中所引用数据集的内容相符合。

我个人认为一般情况下这样使用效率不高,为什么不将整个程序写入一个完整的宏程序中?这样效率较高,而且宏程序的重复利用价值也较高。




欢迎光临 SAS中文论坛 (http://mysas.net/forum/) Powered by Discuz! X3.2