宏数值比较

时间:2019-01-09 20:48:27

标签: macros sas

我正在尝试比较宏中的两个数字值。 但我不断收到以下消息:

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 0.2
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 0.05
ERROR: The %BY value of the %DO I loop is invalid.
ERROR: The macro FAIL will stop executing.

我的代码如下:

%macro fail;
      %do i=0 %to 0.2 %by 0.05;
          data failcrs;
              set fail;
              if f_p>=input(&i, 8.) then output;
          run;
      %end;
%mend failcrs;

f_p是一个数字变量。

我的代码有什么问题?请帮忙。

非常感谢您!

5 个答案:

答案 0 :(得分:0)

尝试使用best32。但是当每个循环的数据集都被覆盖时,为什么要循环。请检查以下每个步骤的日志。就像@Reeza在评论中解释的那样,您甚至无需输入语句     选项mprint;

   /* do this*/
    %macro fail;
   %let i =15;
    data failcrs;
          set sashelp.class;

          if age lt input(&i, best32.)  then output;
      run;
   %mend fail;

  %fail

   /* dataset overwritten every time to finally pick up 15 as value check in the log*/
   %macro fail1;
   %do i = 1 %to 15;
    data failcrs1;
          set sashelp.class;

          if age lt input(i, best32.) then output;
      run;
  %end;
 %mend fail1;

%fail1

答案 1 :(得分:0)

You have a couple of issues. Macro loops work better with integers, but an easy workaround is a %DO %UNTIL loop instead.

  1. Name on %MEND is different than on %MACRO
  2. Invalid values for %DO %I loop.
  3. Non-unique data set name, which means the output overwrites itself.

    *fake data to work with;  
    data fail;
        do f_p=0 to 0.2 by 0.01;
            output;
        end;
    run;
    
    %macro fail;
        %let i=0;
          %do %until(&i = 0.2); /*2*/
              data failcrs_%sysevalf(&i*100); /*3*/
                  set fail;
                  if f_p>=&i then output;
              run;
              %let i = %sysevalf(&i + 0.05);
          %end;
    %mend fail; /*3*/
    
    *test macro;
    %fail;
    

The numbers in the comments align with the issues identified.

答案 2 :(得分:0)

%macro fail;
        %let i=0;
        %do %until(&i = 0.2);
            data failcrs; 
                set crse_grade_dist_fail;
                if f_p>=&i then output;
                run;

        proc sql;
            create table count_failclass as
            select strm, count(class_nbr) as numfclass_%sysevalf(&i*100)
            from failcrs
            group by strm;
        quit;

        proc sql;
            create table failfaculty as
            select strm, instructor_id, instructor, count(class_nbr) as numfclass
            from failcrs
            group by strm, instructor_id, instructor;
        quit;

        proc sql;
            create table count_failfaculty as
            select strm, count(instructor) as numffaculty_%sysevalf(&i*100)
            from failfaculty
        group by strm;
        quit;

        data count_class_faculty;
            set count_class_faculty;
            set count_failclass;
            set count_failfaculty;
        run;

        %let i = %sysevalf(&i + 0.05);
    %end;
%mend fail;

好消息是我的数据没有f_p = 0,它们都大于零。因为我只想计算失败的课程。

答案 3 :(得分:0)

使用宏代码(%if%until%while等)进行的条件测试使用的%eval()宏函数仅执行整数运算。这包括在%do-%to-%by循环中完成的增量和测试。

要使用浮点算术,您需要使用%sysvalf()宏函数。

您可以将自己的增量编码到循环计数器中。

%let i=0;
%do %while( %sysevalf( &I <= 0.2 ) );
   ...
   %let i=%sysevalf(&i + 0.05);
%end;

或者将循环计数器设为整数,然后使用另一个宏变量保存分数。

%do j=0 %to 20 %by 5 ;
   %let i=%sysevalf(&j/100);
   ...
%end;

答案 4 :(得分:0)

文档被编写为可读取,对“ SAS 9.4 Macro Do”的简单搜索应能解释所有内容-起始,终止并按整数表示-整数,即无论其位置上的任何宏源表达式都隐式求值或在需要的时间明确地转换为整数。

您编码的宏有点奇怪。它将生成多个数据步骤,全部覆盖同一数据集。您可能要集中精力于不首先编写宏代码,而在需要提交重复的样板代码时转到它。编写好的宏代码意味着您必须考虑“这将生成合适的源代码,以及这些宏语句在其解析范围内将产生什么副作用”

%DO, Iterative Statement

  

语法

     

%DO 宏变量 = 开始%TO 停止 <%BY 增量>;

     

文本和宏语言声明

     

%END;

     

必需参数

     

宏变量

  •   

    为宏变量或生成宏的文本表达式命名   变量名。其值用作确定   %DO循环迭代的次数。如果指定了宏变量   由于索引不存在,因此宏处理器会在   本地符号表。

  •   

    您可以更改   处理期间的索引变量。例如,使用条件   处理以将索引变量的值设置为超出停止点   满足特定条件时的值结束循环的处理。

  

开始停止

  •   

    指定整数或生成整数的宏表达式   控制宏部分之间的次数   迭代的%DO和%END语句已处理。

  •   

    第一次   %DO组迭代,宏变量等于start。作为加工   继续,宏变量的值会随着   递增,直到宏变量的值超出以下范围:   开始和停止处包含的整数。

  

增量

  •   

    指定一个整数   (非0)或产生整数的宏表达式   在每次的迭代中添加到index变量的值   环。默认情况下,增量为1。   循环的第一次迭代。因此,您不能将其更改为   循环迭代。