Macros sas宏参数的多个值

Macros sas宏参数的多个值,macros,sas,Macros,Sas,我是SAS宏编程新手,需要启用以下宏以能够处理和处理其宏参数的多个值。您好 data have; input name $ ACCOUNT_ID $ cust_id; cards; ARTHUR CC1234 1234 TOM eil1235 1235 MIKEZ tb1236 1236 MATT mb1237 1237 LIZ TB1238 1238 PIZ VB1239 1239 TAN MB1240 1240 PANDA . 1241 ; run; %MACRO algo (IN_DS=

我是SAS宏编程新手,需要启用以下宏以能够处理和处理其宏参数的多个值。您好

data have;
input name $ ACCOUNT_ID $ cust_id;
cards;
ARTHUR CC1234 1234
TOM eil1235 1235
MIKEZ tb1236 1236
MATT mb1237 1237
LIZ TB1238 1238
PIZ VB1239 1239
TAN MB1240 1240
PANDA . 1241
;
run;

%MACRO algo (IN_DS=,VAR_LIST=,DATA_TYPE_LIST=,OUT_DS=);
DATA &OUT_DS;
SET &IN_DS;

%If &data_type_LIST = num %then 
&var_LIST=sum(&VAR_LIST,2);
%else &var_LIST=cats(&var_LIST,'re');;
run;
%mend;

%algo(IN_DS=HAVE,VAR_LIST=CUST_ID,DATA_TYPE_LIST=num,OUT_DS=out1);`
我现在需要启用此宏,以便能够为宏参数传递多个值。大概是这样的:

%algo(IN\u DS=HAVE,VAR\u LIST='CUST\u ID,ACCT\u ID',DATA\u TYPE\u LIST='num,char',OUT\u DS=out1)

有人能帮我在宏代码中启用此功能吗。

如果您想传递一个变量列表,然后在上面发布的代码中使用该列表,我的建议是将&var_列表视为一个列表,并使用scan确定有多少个变量,然后循环遍历列表并相应地执行代码。

如果您希望传递一个变量列表,然后在上面发布的代码中使用该列表,我的建议是将&var_列表视为一个列表,并使用scan确定有多少个变量,然后在列表中循环并相应地执行代码。

参数参数应在宏调用中用%STR()引用

试一试


宏引用不同于用于字符文字的数据步骤引用。

参数参数应在宏调用中用%STR()进行宏引用

试一试


宏引用不同于用于字符文字的数据步引用。

确保宏可以处理多个值。一般来说,在调用宏时,在值列表中使用逗号作为分隔符不是一个好主意

通常,空格是最好的分隔符,因为您可以在生成的代码中直接使用宏值。例如,如果您的变量都是相同类型的,则可以使用数据步骤数组

%MACRO algo (IN_DS=,VAR_LIST=,DATA_TYPE_LIST=,OUT_DS=);
DATA &OUT_DS;
  SET &IN_DS;
  array list &var_list ;
  do _n_=1 to dim(list);
%if &data_type_LIST = num %then %do ;
    list(_n_)=sum(list(_n_),2);
%end;
%else %do;
    list(_n_)=cats(list(_n_),'re');
%end;
  end;
run;
%mend algo;
如果变量的类型不同,则需要为每个变量生成单独的语句。在这种情况下,如果需要,可以使用不同的分隔符,例如管道字符,以便在调用宏函数(如
%scan()
)时更容易地将其用作分隔符


确保宏可以处理多个值。一般来说,在调用宏时,在值列表中使用逗号作为分隔符不是一个好主意

通常,空格是最好的分隔符,因为您可以在生成的代码中直接使用宏值。例如,如果您的变量都是相同类型的,则可以使用数据步骤数组

%MACRO algo (IN_DS=,VAR_LIST=,DATA_TYPE_LIST=,OUT_DS=);
DATA &OUT_DS;
  SET &IN_DS;
  array list &var_list ;
  do _n_=1 to dim(list);
%if &data_type_LIST = num %then %do ;
    list(_n_)=sum(list(_n_),2);
%end;
%else %do;
    list(_n_)=cats(list(_n_),'re');
%end;
  end;
run;
%mend algo;
如果变量的类型不同,则需要为每个变量生成单独的语句。在这种情况下,如果需要,可以使用不同的分隔符,例如管道字符,以便在调用宏函数(如
%scan()
)时更容易地将其用作分隔符


您不能这样做:
&var_LIST=cats(&var_LIST,'re')var1,var2=cats(var1,var2,'re')这是无效的SAS语法。请进一步解释你在这里想做什么。一般来说,我建议不要这样做,而是使用一个没有问题的空格分隔的列表。宏的逗号分隔列表是导致问题的原因。您不能这样做:
&var_LIST=cats(&var_LIST,'re')var1,var2=cats(var1,var2,'re')这是无效的SAS语法。请进一步解释你在这里想做什么。一般来说,我建议不要这样做,而是使用一个没有问题的空格分隔的列表。宏中以逗号分隔的列表是导致问题的原因。您能否演示如何执行此操作,这正是我一直尝试实现但无法实现的。您能否演示如何执行此操作,这正是我一直尝试实现但无法实现的。我无法执行此操作,因为我需要在其上执行代码的列不是相同的数据类型。就像我上面给出的例子一样,一个是数字,另一个是字符列。这没有任何意义,请澄清。您发布的代码只有一个变量类型参数。你是说它也是一个变量类型列表吗?如果是这样,则需要使用宏
%DO
循环来分别处理每个变量,而不是数据步数组。仍然不需要在宏调用中使用逗号。是的,正如我在第一篇文章中所说的,我想对一个代码的参数的多个值进行多次处理。正如我在示例中明确给出的,我指定了我试图实现的
%algo(in_DS=HAVE,VAR_LIST='CUST\u ID,ACCT\u ID',DATA_TYPE_LIST='num,char',OUT_DS=out1)如果您看到宏parms VAR_LIST和DATA_TYPE_LIST都有多个值,并且在VAR_LIST中传递的列也是不同的数据类型,如示例数据集中所示。更新了答案以包含可以处理该问题的示例。它起作用了,我实际上尝试了相同的事情,但没有处理计数器VAR“I”作为宏变量,正在使用%scan(&var_list,i,|)而不是&i。谢谢你的帮助。我不能这样做,因为我需要执行代码的列不是相同的数据类型。就像我上面给出的例子一样,一个是数字,另一个是字符列。这没有任何意义,请澄清。您发布的代码只有一个变量类型参数。你是说它也是一个变量类型列表吗?如果是这样,则需要使用宏
%DO
循环来分别处理每个变量,而不是数据步数组。仍然不需要在宏调用中使用逗号。是的,正如我在第一篇文章中所说的,我想对一个代码的参数的多个值进行多次处理。正如我在示例中明确给出的,我指定了我试图实现的
%algo(in_DS=HAVE,VAR_LIST='CUST\u ID,ACCT\u ID',DATA_TYPE_LIST='num,char',OUT_DS=out1)如果您看到宏parms VAR_列表和DATA_TYPE_列表都有多个值,并且VAR_列表中传递的列具有不同的数据类型,如示例数据集中所示。更新了答案以包括可以处理该问题的示例。它起作用了,我
%MACRO algo (IN_DS=,VAR_LIST=,DATA_TYPE_LIST=,OUT_DS=);
%local i var;
DATA &OUT_DS;
  SET &IN_DS;
  %do i=1 %to %sysfunc(countw(&var_list,|));
    %let var=%scan(&var_list,&i,|);
    %if %scan(&data_type_LIST,&i,|) = num %then %do ;
  &var=sum(&var,2);
    %end;
    %else %do;
  &var=cats(&var,'re');
    %end;
  %end;
run;
%mend algo;
%algo(IN_DS=HAVE,VAR_LIST=CUST_ID|ACCT_ID,DATA_TYPE_LIST=num|char,OUT_DS=out1);