Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 如何将变量序列(列表)传递给SAS宏_Variables_Sas_Sas Macro - Fatal编程技术网

Variables 如何将变量序列(列表)传递给SAS宏

Variables 如何将变量序列(列表)传递给SAS宏,variables,sas,sas-macro,Variables,Sas,Sas Macro,我的变量名为200701,200702,。。。截至201612年,每个包含该月的特定数字数据。如果满足以下条件,我想从中减去具体金额(变量cap_inc): %MACRO DeleteExc(var); DATA Working.Test; SET Working.Test; IF &var. GE cap_inc THEN &var. = SUM(&var., - cap_inc); ELSE &var. = &var.; RUN; %M

我的变量名为200701,200702,。。。截至201612年,每个包含该月的特定数字数据。如果满足以下条件,我想从中减去具体金额(变量cap_inc):

%MACRO DeleteExc(var);
DATA Working.Test;
SET Working.Test;
    IF &var. GE cap_inc THEN &var. = SUM(&var., - cap_inc);
    ELSE &var. = &var.;
RUN;
%MEND;
如果我只把一个月作为一个参数(例如200909),代码是有效的。。。但我想把这些变量的顺序放在这里。我尝试过像“OF _200701--OF _201612”或“OF _20:”这样的组合,但没有任何效果

我还有另一个宏,使用parmbuff参数,以“for each loop”的方式工作,例如,我可以放置更多用逗号分隔的变量

%DeleteExc(_200701, _200702, _200703)
但我仍然不能以一种方便易用的方式传递所有变量。(我不想键入所有参数,因为有120个参数)

有没有办法做到这一点?
谢谢大家!

这里有一些选择-也许有一个你还没有尝试过

data example;
    array months{*} _200701-_200712 _200801-_200812 (24*1);
    array underscores{*} _:;
    _randomvar = 100;
    s1 = sum(of _200701-_200812); /*Generates lots of notes about uninitialised variables but gives correct result*/
    s2 = sum(of _200701--_200812); /*Works only if there are no rogue columns in between month columns*/
    s3 = sum(of months{*}); /* Requires array definition*/
    s4 = sum(of _:); /*Sum any variables with _ prefix - potentially including undesired variables*/

    put (s1-s4)(=);
run;
双破折号(-)变量名称范围列表可用于指定数组中的变量。简单的迭代DO循环允许您对每个变量执行所需的操作

data want;
  set have;
  array month_named_variables _200701 -- _201612;
  do _index = 1 to dim(month_named_variables); drop _index;

    IF month_named_variables(_index) GE cap_inc THEN 
      month_named_variables(_index) = SUM(month_named_variables(_index), - cap_inc);
    ELSE
      month_named_variables(_index) = month_named_variables(_index);

  end;
run;
如果数据集的名称范围内有额外变量,则仍可使用数组和非宏代码:

data want;
  set have;
  array nums _numeric_;

  do _index = 1 to dim(nums); drop _index;

    _vname = vname(nums(_index)); drop _vname;
    if _vname ne: '_' 
      or not (2007 <= input(substr(_vname,2,4), ??4.) <= 2016)
      or not (01   <= input(substr(_vname,6,2), ??2.) <= 12)
      or not length(_vname) = 7 
    then continue;

    IF nums(_index) GE cap_inc THEN 
      nums(_index) = SUM(nums(_index), - cap_inc);
    ELSE
      nums(_index) = nums(_index);

  end;
run;

如果我的理解是正确的,您希望使用月份进行循环,这是关于数据中变量的,您可以设置开始日期和结束日期,然后进行循环

%macro month_loop(start,end);
%let start=%sysfunc(inputn(&start,yymmn6.));
%let end=%sysfunc(inputn(&end,yymmn6.));
%let date=&start;
%do %until (%sysfunc(indexw("&date","&end")));
     %let date=%sysfunc(intnx(month,&date,1));
     %let var=_%sysfunc(putn(&date,yymmn6.));
     data want;
        set have;
        IF &var. GE cap_inc THEN &var. = SUM(&var., - cap_inc);
        ELSE &var. = &var.;
     run;
%end;
%mend;
%month_loop(200701,201612) 

首先,如果要将列表传递到宏中,请不要使用逗号分隔列表。这只会让调用宏变得非常痛苦。您可能需要使用宏引号来隐藏逗号。或者使用
/parmbuff
选项覆盖SAS的参数处理,并添加逻辑以自行处理
&syspbuff
宏变量。使用值中未使用的其他字符作为分隔符。比如说|或者^。对于变量名列表,请使用空格作为分隔符

%DeleteExc(varlist=_200701 _200702 _200703)
然后,您可以在SAS需要变量列表的任何位置使用宏变量

array in &varlist ;
total = sum(of &varlist);
现在,由于您的列表实际上是一个月列表,那么请为您的宏指定开始和结束月份,并让它为您生成列表

%macro DeleteExc(start,end);
  %local i var ;
  %do i=0 %to %sysfunc(intck(month,&start,&end)) ;
    %let var=_%sysfunc(intnx(month,&start,&i,b),yymmn6);
IF .Z < cap_inc < &var. THEN &var. = &var - cap_inc;
  %end;
%mend;
DATA Working.Test;
  SET Working.Test;
%DeleteExc("01JAN2007"d,"01DEC2016"d);
RUN;
%宏DeleteExc(开始、结束);
%局部i-var;
%i=0%到%sysfunc(intck(月份、开始和结束));
%设var=%sysfunc(intnx(月、月、月、月、月),yymmn6);
如果.Z
请参见SAS宏附录中的演示宏,该附录显示了如何循环日期,也许您希望采用这种方法。
%macro DeleteExc(start,end);
  %local i var ;
  %do i=0 %to %sysfunc(intck(month,&start,&end)) ;
    %let var=_%sysfunc(intnx(month,&start,&i,b),yymmn6);
IF .Z < cap_inc < &var. THEN &var. = &var - cap_inc;
  %end;
%mend;
DATA Working.Test;
  SET Working.Test;
%DeleteExc("01JAN2007"d,"01DEC2016"d);
RUN;