在数组中使用变量 - SAS

时间:2017-11-03 19:13:53

标签: arrays sas sas-macro

我试图根据数组中的标识符有条件地调用宏,并根据数组的值更改宏变量。这是我的代码:

data;
array file(*) $ file1-file7;
array prog(*) $ prog1-prog7;
do i=1 to dim(prog);
    if prog(i) = "Y" then
    call execute("%findit(name(file(i)))");
end;
run;

举个例子:

%let file1 = C:\file.doc
%let prog1 = Y

我希望我的代码可以为我的代码中先前定义的文件和prog变量创建数组。然后,它将开始在数组中循环。第一次迭代将有条件地执行宏语句,因为prog1变量是Y.然后,宏将使用file1(“C:\ file.doc”)的值作为宏变量执行。

条件逻辑似乎正在起作用。但是,宏在“name(file(I)))”而不是“C:\ file.doc”上执行。

有人看到我的错误吗?

2 个答案:

答案 0 :(得分:4)

您将字符串文字传递给CALL EXECUTE(),而不是使用变量的值。但是你也永远不会将变量设置为任何值。

因此,如果您有数据集中的PROG / FILE组合列表。像这样:

data have ;
  infile cards truncover ;
  input prog $1. file $100. ;
cards;
YC:\file.doc
NC:\file2.doc
;

然后您可以使用它们来生成对宏的调用:

data _null_;
  set have ;
  if prog = "Y" then call execute(cats('%nrstr(%findit)(',file,')'));
run;

所以你应该在SAS LOG中看到这一行,以显示你在DATA _NULL_步骤之后推送到堆栈上的命令。

1   + %findit(C:\file.doc)

如果您有一系列宏变量,那么使用symget()函数来检索值。您可以使用CATS()生成宏变量名称以传递给symget()函数。

%let prog1=Y;
%let file1=C:\file.doc;
%let n=1;

data _null_;
  do n=1 to &n ;
    if symget(cats('prog',n))='Y' then 
      call execute(cats('%nrstr(%findit)(&file',n,')'))
    ;
  end;
run;

答案 1 :(得分:1)

你可能会在这里混淆。

如果你有一组宏变量,可能随便称之为宏变量数组(但要注意,这不是SAS中的正式类型,技术上也不准确),如下所示:

%let file1= c:\temp\file1.txt;
%let file2= c:\temp\file2.txt;
%let prog1= Y;
%let prog2= N;

您想要调用宏%findit(&file1.),您可以执行以下操作:

%macro call_findit();
  %do i = 1 %to 2;
    %if &&prog&i. = Y %then %do;
      %findit(&&file&i.)
    %end;
  %end;
%mend call_findit;

%call_findit();

使用宏语言语法在需要时调用%findit。从&&转换为&&file&i的内容需要&file1;宏解析器传递两次,一次将&&转为&&i转为1,然后离开&file1,然后在第二次传递中转为c:\temp\file1.txt

同样,这在技术上并不是以任何方式使用'数组',但它使用SAS宏变量的方式大致类似于数组的工作方式,有时称为“SAS宏变量数组”,例如{ {3}}和this paper by Ron Fehd,两者都就此主题撰写了大量文章。

在我看来,一般来说,写这样的东西并不是一个好方法。您最好通过数据步骤使用Tom建议的方法,并让进行这些更改的人通过输入到数据步骤的文本文件来执行此操作,因为这比修改代码更好。