在 SAS 中循环通过逗号分隔的宏变量
Loop through comma separated macro variable in SAS
我想像下面这样循环一个逗号分隔的宏变量,我也在 proc sql 语句的 where 条件中使用它:
%let example = (1, 2, 3, 4)
我发现以下语法几乎涵盖了我的案例:
%macro px;
%let value = 1 2 3 4;
%local i next_value;
%let i=1;
%do %while (%scan(&value, &i) ne );
%let next_value = %scan(&value, &i);
%put&=next_value;
%let i = %eval(&i + 1);
%end;
%mend;
%px;
不幸的是,我不知道如何修改该语法以使其适用于我的示例。如果我向 'value' 变量添加逗号,我会收到错误“宏函数 %SCAN 的参数太多”,这对我来说没有意义。
用户 str% 换行字符串。你可以简化代码:
%macro px;
%let value = (1, 2, 3, 4);
%let value = %sysfunc(compress(&value, %str(%(%))));
%let value = %str(%bquote(&value));
%do mvI=1 %to %sysfunc(countw(&value, %str(,)));
%let next_value = %scan(&value, &mvI, %str(,));
%put&=next_value;
%end;
%mend;
%px;
您需要保护逗号,以便 %SCAN() 不会将其视为参数之间的分隔符。如果您使用实际的 EXAMPLE 值,您现有的代码将起作用,因为用逗号分隔的数字列表括起来的括号可以做到这一点。
请注意,由于您没有告诉 %SCAN() 使用什么分隔符,所以括号、逗号和空格都被视为分隔符。
如果您的值没有括号,那么您可以用宏引用来保护逗号。
%let value=%quote(&value);
如果您将值作为实际参数传递给宏,则确保逗号受到保护的责任将落在调用宏的代码上。也不需要编写代码来增加循环计数器。 %DO 循环支持这一点,只需使用 COUNTW() 函数来确定上限。
%macro px(list);
%local i next_value;
%do i=1 %to %sysfunc(countw(&list));
%let next_value = %scan(&list, &i);
%put &=i &=next_value;
%end;
%mend;
%let example = (1, 2, 3, 4);
%px( &example );
%px( %str(1,2,3,4) );
我想像下面这样循环一个逗号分隔的宏变量,我也在 proc sql 语句的 where 条件中使用它:
%let example = (1, 2, 3, 4)
我发现以下语法几乎涵盖了我的案例:
%macro px;
%let value = 1 2 3 4;
%local i next_value;
%let i=1;
%do %while (%scan(&value, &i) ne );
%let next_value = %scan(&value, &i);
%put&=next_value;
%let i = %eval(&i + 1);
%end;
%mend;
%px;
不幸的是,我不知道如何修改该语法以使其适用于我的示例。如果我向 'value' 变量添加逗号,我会收到错误“宏函数 %SCAN 的参数太多”,这对我来说没有意义。
用户 str% 换行字符串。你可以简化代码:
%macro px;
%let value = (1, 2, 3, 4);
%let value = %sysfunc(compress(&value, %str(%(%))));
%let value = %str(%bquote(&value));
%do mvI=1 %to %sysfunc(countw(&value, %str(,)));
%let next_value = %scan(&value, &mvI, %str(,));
%put&=next_value;
%end;
%mend;
%px;
您需要保护逗号,以便 %SCAN() 不会将其视为参数之间的分隔符。如果您使用实际的 EXAMPLE 值,您现有的代码将起作用,因为用逗号分隔的数字列表括起来的括号可以做到这一点。
请注意,由于您没有告诉 %SCAN() 使用什么分隔符,所以括号、逗号和空格都被视为分隔符。
如果您的值没有括号,那么您可以用宏引用来保护逗号。
%let value=%quote(&value);
如果您将值作为实际参数传递给宏,则确保逗号受到保护的责任将落在调用宏的代码上。也不需要编写代码来增加循环计数器。 %DO 循环支持这一点,只需使用 COUNTW() 函数来确定上限。
%macro px(list);
%local i next_value;
%do i=1 %to %sysfunc(countw(&list));
%let next_value = %scan(&list, &i);
%put &=i &=next_value;
%end;
%mend;
%let example = (1, 2, 3, 4);
%px( &example );
%px( %str(1,2,3,4) );