SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 742|回复: 9
打印 上一主题 下一主题

关于一个宏的应用问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2004-8-19 21:54:16 | 只看该作者

关于一个宏的应用问题

有一数据集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;

请指教!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2004-8-20 10:52:39 | 只看该作者

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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2004-8-20 18:02:10 | 只看该作者

re

macro中嵌套的data step中是不能用%do,%if,%then之类的,它就是一个简单的data step。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2004-8-21 09:50:13 | 只看该作者

Re: re

这个观点不完全对,宏语句可以出现在几乎所有的场合,但必须正确使用,宏语句和宏变量有其特定的规则和使用方式,有时候容易和别的语句规则相混淆,因此容易出错。

我的经验是记住一点,宏语句的功能从根本上讲就是一个字符串替代的过程。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2004-8-22 20:43:02 | 只看该作者

good!

谢谢各位的帮助!

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

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

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

data t2;
set t1;
if %test then delete;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2004-8-23 20:49:43 | 只看该作者

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是一个预先定义的宏程序,我还未曾见过这样的应用方式,并且认为这样是行不通的。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2004-8-24 17:19:35 | 只看该作者

RE

能否举个例子说一下%if %then。。。在data步中的使用,我试了不行。


多谢。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2004-8-24 22:43:49 | 只看该作者

应用在宏中!

我想你可能将该宏语句直接使用在开放的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;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2004-8-25 22:34:28 | 只看该作者

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;
运行成功过!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2004-8-25 23:46:55 | 只看该作者

correct indeed.

这样使用是可以的,但必须保证宏程序所产生的代码符合data步的语句规则以及和其中所引用数据集的内容相符合。

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

使用道具 举报

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

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2025-1-10 23:12 , Processed in 0.195051 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表