SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 1784|回复: 12
打印 上一主题 下一主题

菜鸟请教 -- 如何循环?

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2008-10-12 23:10:20 | 只看该作者

菜鸟请教 -- 如何循环?

有个 Temp 表,其中含有 Office 字段,希望历遍所有记录,并将 office 的值作为变量来传递,调用另一个 Macro
应该怎么做?谢谢各位。

[color=#4040FF:3fsxxt29]Data;
   set in.temp;   
   Do until(EndoFile);
        x = office;
        %region(x);          /*  这行出错。。。。*/
    End;
run;
[/color:3fsxxt29]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2008-10-13 08:04:26 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

from another rookie:
/*
%let dsid=%sysfunc(open(in.temp, is));
%syscall set(dsid);
%let rc = %sysfunc(fetch(&dsid));
%do %while(&rc  EQ 0);
%region(&office);
%let rc = %sysfunc(fetch(&dsid));
%end;
%let rc=%sysfunc(close(&dsid));
*/
or use /*CALL EXECUTE('%region(' || x || ')');*/ to replace your %region(x).
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2008-10-13 11:40:50 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

Thanks a lot , Urchin,

But I do not quite understand your codes. 不很明白您的codes.
Little SAS Book 也没有答案。

%let dsid=%sysfunc(open(in.temp, is));
%syscall set(dsid);                                 
%let rc = %sysfunc(fetch(&dsid));        /* 这行是找出 in.temp 的长度吗?*/
%do %while(&rc EQ 0);
%region(&office)                                        /*这行似乎并没有执行,因 Output 窗口没有内容。*/
%let rc = %sysfunc(fetch(&dsid));
%end;                                              /* 这行出错*/
%let rc=%sysfunc(close(&dsid));

插入这行,结果运行不断,只能强行终止。
  CALL EXECUTE('%region('|| x ||')');
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2008-10-13 13:32:13 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

#1. I forgot a semicolon after '%region(&amp;office)'. For reference, please read <!-- m --><a class="postlink" href="http://support.sas.com/onlinedoc/913/getDoc/zh/lrdict.hlp/a000127856.htm">http://support.sas.com/onlinedoc/913/ge ... 127856.htm</a><!-- m --> or <!-- m --><a class="postlink" href="http://www2.sas.com/proceedings/forum2007/050-2007.pdf">http://www2.sas.com/proceedings/forum2007/050-2007.pdf</a><!-- m -->

#2. your DATA Step needs a couple of minor changes to avoid endless loop.
/*
Data _NULL_;
Do until(EndoFile);
set in.temp END=EndOFile;
x = office;
CALL EXECUTE('%region(' || x || ')');
End;
run;
*/

#3. the Little SAS book are not written from a programmer's point of view, and its intended audience are PhD's, researchers, but unfortunately does no good and are sometimes even misleading to bottom-level computer slaves.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2008-10-13 16:28:35 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

一个相似的例子。
[code:3l441zzd]data temp;
     input office ;
         num=ceil(ranuni(0)*8);
         cards;
1
2
3
4
5
6
7
8
;
run;
options symbolgen mprint mlogic;
%macro just(x);
       data _null_;
                if &amp;x&gt;=5 then put 'big';
                        else put 'small';
           run;      
%mend;

Data aa;
     set temp;
     if _n_ &gt;=1 then call execute(&quot;%just(&quot;||office||&quot;)&quot;);
run;
[/code:3l441zzd]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2008-10-14 10:11:39 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

谢谢 horse1,

我希望的效果正是,
Office   Size
1          small
2          small
3          small
4          small
5          big
6          big
7          big
8          big

为测试方便,我将您的 Macro 改为

%macro just(x);
      * data _null_;
                data test;
                set temp(keep=office);
                 if &amp;x&gt;=5 then size= 'Big';
                          else size='Small';
      run;      
%mend;

data aa;
     set temp;
     if _n_ &gt;=1 then call execute(&quot;%just(&quot;||office||&quot;)&quot;);
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2008-10-15 10:43:47 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

谢谢两位老师指点,我最后对付成这样

%Macro Region(Office);

%Let Office=&amp;Office;                       /*I found I have to add this line here. */

Data in.One_Office;     
    set in.Products;
    If  _Office='&amp;Office' ;                     /* I have to put quotes here.*/
Run;

Proc Freq data=in.One_Office Order = Freq NoPrint;  
    Table Product   / out = in.NewFreq ;
Run;

Proc Sort Data=in.One_Office Out=in.Unique&amp;Office  Nodupkey;     
     By client_no;
Run;

%Mend ;

Data _NULL_;
        Do until(EndoFile);                            /* Not sure if we can us do while loop here. */
                set in.temp END=EndOFile ;
                x = Office;
                call Execute(&quot;%region(&quot;|| x ||&quot;)&quot;);   
        End;
Run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2008-10-15 21:03:32 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

No &quot;老师&quot;, I'm just nobody.
(1) the %let statement is unnecessary. As a parameter, &amp;office should exist in the local symbol table already. The %let statement only trims the leading and trailing blanks. This can be done with CALL EXECUTE(&quot;%regin(&quot; || left(office) || &quot;)&quot;);
(2) there's no need of subsetting dataset 'in.products' unless the subset is used many times. A WHERE statement or WHERE= option in PROC FREQ / PROC SORT is what people usually do.
(3) use double quotes --- &quot;&amp;office&quot;
(4) either do...while... or do...until... will work as long as your dataset is non-empty (slightly more work to cover the case of empty).
/*
Data _NULL_;
EndoFile=0;
Do while(NOT EndoFile);
set in.temp END=EndOFile ;
call Execute(&quot;%region(&quot;|| office ||&quot;)&quot;);
End;
Run;
*/
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2008-10-16 06:01:59 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

You're the man, urchin,

Thanks a lot for your detailed explanation.

However, it does not work if I

1. remove the %let .... line.  
2. change the double quotes to single quotes,

    it became:     [color=#4040FF:kpszkujj]If _office=&quot;|| office ||&quot; [/color:kpszkujj];      instead of     [color=#4040FF:kpszkujj] if  _office='Z';[/color:kpszkujj]

How can I add a where statement in Proc Freq  or Proc Sort.... so that I can save the trouble of creating the in.One_office dataset?

Your  &quot;Do while&quot;  works great !  That's really what I want to know.
In SAS, do we have a similar loop like Scan .......End ?

Thanks again.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2008-10-16 23:31:16 | 只看该作者

Re: 菜鸟请教 -- 如何循环?

(1) my bad, it seems that the CALL EXECUTE routine doesn't like double quotes, so I should have used [u:1ez4pmu5]CALL EXECUTE('%region(' || compress(office) || ')');[/u:1ez4pmu5] instead.
(2) never heard of scan...end... maybe just because I don't know much.
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-5 03:24 , Processed in 0.094394 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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