SAS:如何使用索引来挑选宏数组变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SAS:如何使用索引来挑选宏数组变量相关的知识,希望对你有一定的参考价值。

我用以下方法创建一个宏数组:

proc sql;
select distinct variable into:numVarList separated by ' ' from Map_num;

我用了:

%put &numVarList{1};

它给了我所有变量:var1 var2 var3{1}

如何使用索引来挑选宏数组变量?


更新20180305很奇怪

%put &numVarList.;

然后我得到了:年龄agenc_non_ccbt_fnd_bal chmtpd_tmpnt_bal crnyr_cnter_tdnum

%put %sysnc(scan(&numVarList.,1,str( )));

我得到了:年龄agnc_non_ccb

为什么?以及如何解决它?

答案

您没有使用select创建数组。结果只是一个字符串:var1 var2 var3

但是,您可以使用scan函数访问每个元素:

%let first_ele = %scan(&numVarList.,1,%str( ));

结果是:var1

你也可以像这样循环你的字符串:

%do i=1 %to %sysfunc(countw(&numVarList.,%str( )));
   %put %scan(&numVarList.,&i.,%str( ));
%end;
另一答案

Concatenation of values

proc sql;
select distinct variable into:numVarList separated by ' ' from Map_num;

使用值填充单个宏变量,该值可以解释为列表,该列表是名为“variable”的列中的不同值的串联。

对于这样的列表,您将扫描出@zuluk所示的各个项目。

在原始值是变量名称的情况下,串联的解析可以直接用作接受变量名称列表的SAS语句的一部分,例如Proc PRINT; VAR &numVarListDATA _NULL_; ARRAY v &numVarList

Macro array

概念宏数组只是一组宏变量(当太多'变量'想法发生碰撞时可以被认为是'符号')具有公共基名和增加数字后缀。通过在Proc SQL中使用稍微不同的语法来创建这样的一组宏变量。

select distinct variable
into :symbol1-:symbol9999
from Map_num

9999表示您不希望超过的大数字。如果数据具有N <= 9999行,则将仅创建N宏变量。如果N> 9999行,则仅创建9999个宏变量。警告:太多宏变量可能会填满宏符号表并导致SAS出错。对我来说,宏数组更像是编程概念而不是编程结构。

例如

Proc SQL noprint;
  select name into :name1-:name9999 from sashelp.class;
  %let name_count = &sqlobs;
quit;

%put NOTE: &=name1;
%put NOTE: &=name2;
%put NOTE: name&name_count=%superq(name&name_count);  * almost same as next;
%put NOTE: name&name_count=&&name&name_count;    * almost same as prev;

当以一级抽象方式处理宏数组的“名称”时,通过编写“棘手的三重帽”&&&来实现完整的分辨率

%macro log_macroArray (basename);
   %local i count_symbol value_symbol;
   %let count_symbol = &basename._count;

   %do i = 1 %to &&&count_symbol;
     %let value_symbol = &basename.&i;
     %put NOTE: &value_symbol=&&&value_symbol;
   %end;
%mend;

%log_macroArray(name);

SAS宏系统在其值解析阶段内部“循环”,并在其内部评估的每一步中将存在折叠到&&&

另一答案

基于@ zuluk的答案,你不能使用运算符(如{ })来访问宏“数组”,因为它不是语言的一部分,并且不可能使SAS中的运算符超载......主要是......但是你可以做一个功能风格的宏很容易。

proc sql;
  select name into :namelist separated by ' '
  from sashelp.class;
quit;
%macro marray(list, n);
  %scan(&list.,&n.)
%mend marray;

%put %marray(&namelist,2);

这与您正在寻找的非常接近,只是语法不完全相同。如果你想构建新的变量/ etc,你也可以通过宏来实现,尽管编写一般宏可能会更复杂,因为有很多方法你可能想要这样做。这是一个非功能风格的版本。

%macro m_to_array(list, n);
  *optionally - if you want to not specify n;
  %let n = %sysfunc(countw(&&&list));
  %do _i = 1 %to &n;
    %global &list.&_i.;
    %let &list.&_i. = %scan(&&&list.,&_i.);
  %end;
%mend m_to_array;

%m_to_array(namelist);
%put _global_;

以上是关于SAS:如何使用索引来挑选宏数组变量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用select创建一个数值降序的宏数组

使用文件中的代码作为 SAS 宏变量的内容

falcor:使用路径中的索引来设置项目值

SAS宏变量如何使用循环读取不同变量名?

SAS Proc Datasets - 使用宏变量更改数据集名称

SAS中如何分组计数,并将值保存到宏变量