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

SAS:如何使用索引选择宏数组变量,sas,Sas,我使用以下方法创建marco阵列: proc sql; select distinct variable into:numVarList separated by ' ' from Map_num; 我用过: %put &numVarList{1}; 它给了我所有的变量:var1var2var3{1} 如何使用索引选择宏数组变量 更新20180305 奇怪的是 %put &numVarList.; 然后我得到了:age agenc_non_ccbt_fnd_bal chm

我使用以下方法创建marco阵列:

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

%put &numVarList{1};
它给了我所有的变量:
var1var2var3{1}

如何使用索引选择宏数组变量


更新20180305 奇怪的是

%put &numVarList.;
然后我得到了:age agenc_non_ccbt_fnd_bal chmtpd_tmpnt_bal crnyr_cnter_tdnum

%put %sysnc(scan(&numVarList.,1,str( )));
我得到:年龄agnc_非ccb


为什么?以及如何修复它?

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

但是,您可以使用
扫描
-功能访问每个元素:

%let first_ele = %scan(&numVarList.,1,%str( ));
结果是:
var1

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

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

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

但是,您可以使用
扫描
-功能访问每个元素:

%let first_ele = %scan(&numVarList.,1,%str( ));
结果是:
var1

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

%do i=1 %to %sysfunc(countw(&numVarList.,%str( )));
   %put %scan(&numVarList.,&i.,%str( ));
%end;
值的串联 用一个值填充单个宏变量,该值可以解释为一个列表,它是名为“variable”列中不同值的串联

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

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

宏数组 宏数组的概念仅仅是一组宏变量(当太多的“变量”概念发生冲突时,可以将其视为“符号”)和一个通用的基名和递增的数字后缀。这样一组宏变量是通过在
Proc-SQL
中使用略微不同的语法创建的

select distinct variable
into :symbol1-:symbol9999
from Map_num
9999代表了一个您预计不会超过的大数字。如果数据有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宏系统在其值解析阶段内部“循环”,并在其内部求值的每个步骤将存在状态压缩为
&
&

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

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

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

宏数组 宏数组的概念仅仅是一组宏变量(当太多的“变量”概念发生冲突时,可以将其视为“符号”)和一个通用的基名和递增的数字后缀。这样一组宏变量是通过在
Proc-SQL
中使用略微不同的语法创建的

select distinct variable
into :symbol1-:symbol9999
from Map_num
9999代表了一个您预计不会超过的大数字。如果数据有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);
这与您要查找的内容非常接近,只是语法不完全相同。如果您想构建新的变量/等等,也可以通过宏来实现,尽管编写一个通用宏可能会更复杂,因为您可能需要很多方法来实现这一点。这是一个非功能风格的版本

%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_;

基于@zuluk的答案,您不能使用运算符(如
{}
)访问宏“array”,因为它不是语言的一部分,也不可能在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);
这与您要查找的内容非常接近,只是语法不完全相同。如果您想构建新的变量/等等,也可以通过宏来实现,尽管编写一个通用宏可能会更复杂,因为您可能需要很多方法来实现这一点。这是一个非功能风格的版本

%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_;

请注意,您不再需要提供上限,只需添加连字符即可<代码>将名称选择到:name1-来自sashelp.class@Tom很棒的提示!现在我知道了如何识别谁在阅读每个SAS版本(而不是我)中的
新增内容
文档。请注意,您不再需要提供上限,只需添加连字符即可<代码>将名称选择到:name1-来自sashelp.class@Tom很棒的提示!现在我知道了如何识别谁在每个SAS版本(不是我)中阅读了
What's New
文档是的,但是如何构建新的宏变量,而不仅仅是将它们的值写入日志?我用你的方式