为SAS宏参数使用一系列值

为SAS宏参数使用一系列值,sas,Sas,我正在寻找一种方法,将一系列值用于宏参数,而不是单个值。我基本上是在连续几个月(2014年5月至2015年9月)操纵一系列文件,我编写了一个宏来利用命名约定。但是,我仍然在手动写出使用宏的月份。我用这个月的很多不同的文件做了很多次。有没有办法让参数引用一个值列表并像数组/do循环一样遍历它们?我已经研究了%数组的可能性,但这似乎不符合我的要求,除非我没有看到它的全部功能。我在下面附上了这段代码的一个示例 %MACRO memmonth(monyr=); proc freq data=work.b

我正在寻找一种方法,将一系列值用于宏参数,而不是单个值。我基本上是在连续几个月(2014年5月至2015年9月)操纵一系列文件,我编写了一个宏来利用命名约定。但是,我仍然在手动写出使用宏的月份。我用这个月的很多不同的文件做了很多次。有没有办法让参数引用一个值列表并像数组/do循环一样遍历它们?我已经研究了%数组的可能性,但这似乎不符合我的要求,除非我没有看到它的全部功能。我在下面附上了这段代码的一个示例

%MACRO memmonth(monyr=);
proc freq data=work.both_&monyr ;
    table var1/ out=work.mem_&monyr;
run;
data work.mem_&monyr;
    set work.mem_&monyr;
    count_&monyr=count;
run;

%MEND memmonth;


%memmonth(monyr=may14)
%memmonth(monyr=jun14)
%memmonth(monyr=jul14)
%memmonth(monyr=aug14)
%memmonth(monyr=sep14)
%memmonth(monyr=oct14)
%memmonth(monyr=nov14)
%memmonth(monyr=dec14)
%memmonth(monyr=jan15)
%memmonth(monyr=feb15)
%memmonth(monyr=mar15)
%memmonth(monyr=apr15)
%memmonth(monyr=may15)
%memmonth(monyr=jun15)
%memmonth(monyr=jul15)
%memmonth(monyr=aug15)
%memmonth(monyr=sep15)

一般来说,我建议将值列表作为空格分隔的列表传递,并在宏中添加循环逻辑。如果值中的空格是有效字符,则使用其他分隔符。不要使用逗号作为分隔符,因为这意味着您需要使用宏引用来调用宏

所以你的基本宏是这个

%macro memmonth(monyr);
proc freq data=work.both_&monyr ;
  table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ;
run;
%mend memmonth;
%memmonth(may14)
%memmonth(jun14)
你可以换成这个

%macro memmonth(monyrlist);
%local i monyr;
%do i=1 %to %sysfunc(countw(&monyrlist));
  %let monyr=%scan(&monyrlist,&i);
  proc freq data=work.both_&monyr ;
    table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ;
  run;
%end;
%mend memmonth;
%memmonth(may14 jun14)
如果您总是希望在一个时间间隔内处理所有月份,那么您可以只传入该时间间隔的开始月份和结束月份

%macro memmonth(start,end);
%local i monyr;
%do i=0 %to %sysfunc(intck(month,"01&start"d,"01&end"d));
  %let monyr=%sysfunc(intnx(month,"01&start"d,&i),monyy5.);
  proc freq data=work.both_&monyr ;
    table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ;
  run;
%end;
%mend memmonth;
%memmonth(may14,sep15)
如果有一个源列表,无论是文本文件还是数据集,都可以使用简单的数据步骤生成宏调用。因此,如果您有一个带有变量MONYR的输入数据集,那么您的驱动程序将如下所示:

data _null_;
   set mylist ;
   call execute(cats('%nrstr(memmonth)(',MONYR,')'));
run;

如果源是具有名称的文件,则用适当的INFLE和INPUT语句替换SET语句。如果源是目录名,请查看将目录中的文件名读入数据集的多种SAS方法之一,并使用这些方法来驱动宏调用的生成。

我将组合MMMYY数据集,并使用INDSNAME=variable SET语句选项创建一个新变量。然后,您可以通过MONYR运行PROC FREQ;这是一个完美的回答,但我应该更具体一些。我在很多不同的程序中使用了很多不同的宏。有没有办法让它引用外部源,比如文本文件或sas文件?这样,几个月过去了,我只更新了一件事。但这也很好,我可以保留一个文本文件,每次运行它时将其复制粘贴到参数提示符中,如果我们假设您的宏更复杂,您不想更改它,那么您需要创建一个驱动程序来收集信息并生成一系列宏调用。所以驱动程序可以接受一个文本文件名,一个它搜索特定模式文件或SAS数据集的目录名。让我在答案中添加这样一个选项。