美文网首页
264:macro base(七)---宏语句之条件执行(Con

264:macro base(七)---宏语句之条件执行(Con

作者: SASPRO的打工人生活 | 来源:发表于2023-08-13 14:01 被阅读0次

先讲一个宏嵌套需要注意的地方:

就是不要把宏定义放在另一个宏中,否则的话你每次调用宏的时候,宏嵌套里面的宏定义都会被编译一次。但是并不需要这样,宏定义被编译一次就够了。

下面这段程序程序就是每次调用宏ABC的时候,宏def都会被编译一次。

%macro abc;

    XXXX;

    %macro def;

        XXXX;

    %mend def;

    %def

    XXXX

%mend abc ;

%abc

/************************/



下面这段程序程序就是每次调用的时候,宏def只会被编译一次,只要保证在d调用宏abc之前宏def编译完成既可以了。
/*********************/
%macro abc;

    XXXX;

   %def

    XXXX

%mend abc ;



 %macro def;

        XXXX;

    %mend def;

%abc

/********************/

今天讲讲宏里面的条件执行语句%if %then和 %else

宏里面的%if %then和 %else 跟data步里面的if then else 很相似,但是%if %then %else不限制于data步,且不对data步中的变量进行操作。

%macro tets;
  data test2;
  a=20;
  b=9.1;

  %if a>b %then flag="Y";  /*对data步中的变量直接进行操作是无用的*/
  run;
%mend;
%tets;

%if %then和 %else 可能出现在宏里面的任何地方,并且在一定条件下可以实现下面这些功能:
1)赋值给宏变量
2)执行其他宏
3)创建SAS代码和SAS语句

但是在写%if %then和 %else 的时候,需要注意以下几个地方:
1)它们不对data步中的变量进行操作,因为宏语句和宏定义都是在data步变量读取 之后就开始编译的!(记住这个和宏变量的解析顺序我觉得同等重要)宏表达式永远不会直接计算PDV上变量的值。

2)它们控制程序流程和代码构造,而不是DATA步骤的执行流程。

3)对文本字符串进行比较,通常不使用引号,也不需要引号。比如“X”=‘X’并不相等。

%if &city=Albany %then %let state=New York;
%else %let state=California;

在这段程序中,Albany并没有用引号括起来,在data步中,假设var="twst",通过这段程序,SAS就知道VAR是变量,“twst”是VAR变量的值,并且VAR是字符型变量,但是在宏中,宏变量的名称前总是有一个&,宏变量很容易与文本区分开来,因此,我们并不需要用引号把Albany括起来。

在data步中,我们需要注意变量的长度,但是在宏语言中,存储是根据需要动态分配的,因此截断不是问题。所以在上面的例子中,即使New York比California长度短,并且先输出New York,也不会造成截断问题,但是在data步中SAS是根据第一个输入的变量的值确定长度的(如果没有提前定义变量长度的话)。

%macro precomp(sexmain=,obs=);

data test;
  set sashelp.class(obs=&obs);
  if sex=&sexmain;
run;

/*调用precomp里的宏参数*/
%locate(sex=&sexmain,no=&obs)

data test2;
  set sashelp.cars;
run;

%ccmaro

%mend precomp;

%macro locate(sex=, no=);

  data test3;
    set sashelp.class(obs=&no);
    if sex=&sex;
  run;

%mend locate;

%macro ccmaro;

  data test4;
    set sashelp.cars;
    if _n_=7;
  run;

%mend ccmaro;

%precomp(sexmain="F",obs=7);


%macro condido(indata=,sex=,no=10);

  %if &sex ne %then %locate(sex=&sex, no=&no);
  %else %put macro locate was no called;

  %ccmaro

%mend;

%macro condido(indata=,sex=,no=10);

%if &sex ne %then %locate(sex=&sex, no=&no);

%else %put macro locate was no called;

%ccmaro

%mend;

注意上面这段程序的写法,在ne后面并没有等于号,这在data步中肯定是会报错的,但是在宏语言中,宏变量可以包含一个null value(注意这跟空白是不同的),而且因为引号并不是必须的,所以这种写法是可以正确执行的而且看起来有点逼格。
还有一种有逼格的写法:
%let ccc=var;
%put &=ccc;
这段程序会输出成CCC=var,如果我们只是%put &ccc,log的输出结果只会有一个var

如果你想为了避免歧义,可以把这段程序完善一下

%if "&sex" ne "" %then %locate(sex=&sex, no=&no);

但是这样写并不推荐,一是这样写并没有完全理解%if的执行机制,另一个就是如果双引号之间有一个空格,那么这个空格也会被参与比较。当引号被包括在内时,它们就成为要比较的文本的一部分;因此,不能在右侧使用单引号,在左侧使用双引号。
通过%if语句还能够创建在实际执行之前没有完全定义的程序,顺便讲讲宏中分号的使用。

%macro dyna(num=);
  data dydat;
    set 
    %if &num=3 %then sashelp.class;  /*①*/
    %else sashelp.cars;    /*②*/
    ;     /*③*/
  run;
%mend;

通过上面这段程序,通过%if我们能灵活控制程序,读取对应的数据集。需要注意的是,初学者在位置①②③可能会犯错。

首先要知道%if 也要用分号告诉SAS我要结束一段语句了,所以位置①的分号是%if %then语句的结束,位置②是%else语句的结束;位置③是set语句的结束。
%if &num=3 %then sashelp.class;; //
%else sashelp.cars;; //
如果我在位置①②分别再加上分号,这时候SAS会报错。

image.png

原因是:
位置①:第一个分号是跟%if合在一起的,用来关闭%if语句,然后作为宏语言先一起编译;这时候第二个分号就不属于宏的一部分了,但是宏scanner知道当%else跟在%if 后面的时候,%else语句属于紧接着的第二段语句,但是你多加了一个分号,相当于把这个过程打断了。

所以当宏scanner扫描到%else的时候,它没有找到你的%if语句,这时候就报错了!所以会报红框中的错误。所以按照这个思路,如果只是在位置②多加一个分号,程序是能够正确执行的。

data df;
  set sashelp.class;
  if sex="F" then flag="Y";;
  else flag="N";
run;

这跟在data步是一样的逻辑的,SAS也会报没有匹配的if then语句。

相关文章

  • 条件语句 循环语句

    条件语句 1. if 语句 ( 只有当指定条件为 true 时,使用该语句来执行代码 ) if (con...

  • 打卡7.23:宏定义

    宏定义的三种预处理包括:宏定义、文件包含、条件编译 if是条件语句,在运行的过程中根据条件的值选择执行不同的语句。...

  • 【perl】控制结构——if控制结构

    if结构的语法 语法 单条件 if(条件)执行语句; if(条件){  执行语句1;  执行语句2;} 执行语句 ...

  • iOS开发之条件编译

    #if (条件语句) 条件符合执行的语句 #elif (条件语句) 条件符合执行的语句 #else 所有条件不符合...

  • per-course条件分支

    if语句 条件成立,执行if语句条件不成立,跳过if语句 if-else语句 当条件成立时,执行if后的语句当条件...

  • 判断语句、循环语句

    1.if条件判断语句语法:if 条件:执行语句elif 条件:执行语句...else:执行语句 猜字游戏从键盘输入...

  • 第四节: JavaScript条件分支语句

    一. 条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句。 JS中条件...

  • 第四节 JavaScript条件分支语句

    一. 条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句。 JS中条件...

  • JAVA(4)流程控制

    流程控制 条件语句之 if 如果 if 条件成立时的执行语句只有一条,是可以省略大括号滴!但如果执行语句有多条,那...

  • js判断语句

    条件判断语句:- 使用条件判断语句可以在执行某个语句之前进行判断,如果条件成立才会执行语句,条件不成立则语句不执行...

网友评论

    本文标题:264:macro base(七)---宏语句之条件执行(Con

    本文链接:https://www.haomeiwen.com/subject/oqgfmdtx.html