【问题标题】:SAS syntax error 22 and 200 when using variable inside dataset name inside macroSAS 语法错误 22 和 200 在宏内使用数据集名称内的变量时
【发布时间】:2017-12-28 10:52:14
【问题描述】:

我正在尝试使用宏中的循环对 SAS 中的多个数据集进行排序,使用数据集名称中的数字列表(其中一些具有前导零)(例如,在示例代码中,01,02 的列表),并且此代码还将指导我想构建的其他一些循环。

我使用 SAS 指南来循环使用宏 DO 循环代码作为起点的非顺序值列表:http://support.sas.com/kb/26/155.html

data dir1201;
   input compid directorid X;
   format ;
   datalines;
01 12 11  
02 15 5  
;
run;

data dir1202;
   input compid directorid X;
   format ;
   datalines;
01 12 1  
03 18 8  
;
run;

%macro loops1(values);                                                                                                         
     /* Count the number of values in the string */                                                                                                                                   
     %let count=%sysfunc(countw(&values)); 
     /* Loop through the total number of values */                                                                                         
     %do i = 1 %to &count;
      %let value=%qscan(&values,&i,%str(,)); 
      proc sort data=dir12&value out=dir12sorted&value nodupkey;
      by directorid compid;
      run;
      %end;
%mend;
options mprint mlogic;
%loops1(%str(01,02))  

我假设非顺序列表需要str,但当我想保留前导零时这也很有用;

我看到宏变量似乎在日志中包含 01 或 02,但随后我立即收到错误 22 和 200。这是使用此示例代码的日志错误的 sn-p:

339  %macro loops1(values);
340       /* Count the number of values in the string */
341       %let count=%sysfunc(countw(&values));
342       /* Loop through the total number of values */
343       %do i = 1 %to &count;
344        %let value=%qscan(&values,&i,%str(,));
345        proc sort data=dir12&value out=dir12sorted&value nodupkey;
346        by directorid compid;
347        run;
348        %end;
349  %mend;
350  options mprint mlogic;
351  %loops1(%str(01,02))
MLOGIC(LOOPS1):  Beginning execution.
MLOGIC(LOOPS1):  Parameter VALUES has value 0102
MLOGIC(LOOPS1):  %LET (variable name is COUNT)
MLOGIC(LOOPS1):  %DO loop beginning; index variable I; start value is 1; stop value is 2; by
      value is 1.
MLOGIC(LOOPS1):  %LET (variable name is VALUE)
NOTE: Line generated by the macro variable "VALUE".
1    dir1201
          --
          22
           --
           200
ERROR: File WORK.DIR12.DATA does not exist.

我不明白为什么会显示dir1201,但是错误是引用数据集work.dir12(忽略01

【问题讨论】:

  • 您熟悉 CALL EXECUTE 吗?我觉得它在这里可能会更好。我也想知道你是否在这里循环日期,如果你是,那么这个例子可能会有所帮助。 documentation.sas.com/…
  • 我见过 CALL EXECUTE,但我不记得使用过它或阅读过很多关于它的内容。我会调查的。我正在遍历代表一年数据的数据集,但我没有看到在 SAS 中使用两位数独立年份格式。我认为以下答案可以让我使用我所拥有的。

标签: macros sas sas-macro


【解决方案1】:

宏引用使解析器误以为宏引用表示新标记的开始。您可以添加 %unquote() 以删除宏引用。

proc sort data=%unquote(dir12&value) out=%unquote(dir12sorted&value) nodupkey;

或者只是不要在开头添加宏引用。

%let value=%scan(&values,&i,%str(,));

如果您将宏设计为使用空格分隔的值而不是逗号分隔的值,那么使用宏会容易得多。那么也不需要在调用中添加宏引用。

%macro loops1(values);
%local i value ;
%do i = 1 %to %sysfunc(countw(&values,%str( )));
  %let value=%scan(&values,&i,%str( ));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
  by directorid compid;
run;
%end;
%mend loops1;
%loops1(values=01 02)

【讨论】:

  • 你打败了我。
【解决方案2】:

宏声明选项/PARMBUFF 用于使自动宏变量SYSPBUFF 可用于扫描作为参数传递的任意数量的逗号分隔值。

%macro loops1/parmbuff;
  %local index token;
  %do index = 1 %to %length(&syspbuff);
    %let token=%scan(&syspbuff,&index);
    %if %Length(&token) = 0 %then %goto leave1;
    proc sort data=dir12&token out=dir12sorted&token nodupkey;
    by directorid compid;
    run;
  %end;
  %leave1:
%mend;
options mprint nomlogic;
%loops1(01,02)

SYSPBUFF
MACRO / PARMBUFF

【讨论】:

  • 谢谢。当我运行它时,这引发了一个错误,我认为如果 cancel 被删除它可以工作。
【解决方案3】:

由于您正在循环日期,我认为从长远来看,这样的事情可能会更有帮助:

%macro date_loop(start, end);
    %let start=%sysfunc(inputn(&start, anydtdte9.));
    %let end=%sysfunc(inputn(&end, anydtdte9.));
    %let dif=%sysfunc(intck(month, &start, &end));

    %do i=0 %to &dif;
        %let date=%sysfunc(intnx(month, &start, &i, b), yymmdd4.);
        %put &date;
    %end;
%mend date_loop;

%date_loop(01Jan2012, 01Jan2015);

这是对 SAS 文档(宏附录,示例 11)中的版本稍作修改的版本。

http://documentation.sas.com/?docsetId=mcrolref&docsetTarget=n01vuhy8h909xgn16p0x6rddpoj9.htm&docsetVersion=9.4&locale=en

【讨论】:

  • 谢谢。我不会遍历实际日期,除非您将两位数的年份格式视为日期(我没有看到两位数的年份格式)。我用两位数的年份指标命名了一组数据集。回想起来,我应该使用四位数。
  • 输出当前为 YYMM 格式。但是第 2 年。将生成一个两位数的年份,将YYMMDD4 更改为YEAR2 并将INTCK 中的month 更改为year
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2021-03-23
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多