SAS使用宏创建新的数据集变量

时间:2013-10-23 00:20:29

标签: macros sas

所以我正在尝试创建新列,mon_& cur_buy和times_& cur_buy,它们分别保存从work.t表设置为money和times值的值。

为新变量分配值的标准是& cur_buy宏变量的名称与work.t表中当前行的BuyName值匹配。

引用的& buyer宏变量只是一个用逗号分隔的名称列表。

我得到的错误是新变量mon_& cur_buy和times_& cur_buy无效。

名称已正确解析,但从未写入新数据集decvars。

%let names = %quote(&buyers);
%let count = %sysfunc(countw(&buyers));
data decvars;
    set work.t;
    i=1;
    do while (i <= &count);
    %let cur_buy = %qscan(&names,&i,%str(,));
        length mon_&cur_buy 8;
        length times_&cur_buy 8; 
        if BuyName = "&cur_buy" then do; 
            mon_&cur_buy = money; /*still getting that statement is invalid        here*/
            times_&cur_buy = times;
        end;
    i=i+1;
    end;
run;

最终,我正在尝试为每位买家创建单独的列,以进行回归分析,其中只包含来自特定买方的购买价值。如果您对如何使用宏变量自动执行此类过程有任何建议,请告诉我们。

2 个答案:

答案 0 :(得分:0)

我不确定你想要你的输出看起来像我似乎想要你试图不会返回你期望的。如果您想要及时解析宏变量,则需要将数据步骤放在宏中。它与宏的编译和执行顺序有关。

%macro mDecVars;

 data decvars;
  set work.t;
  %do i =1 %to &count;
   %let cur_buy =  %qscan(&names,&i,%str(,));
   length mon_&cur_buy 8;
   length times_&cur_buy 8; 
   if BuyName = "&cur_buy" then do; 
    mon_&cur_buy = money; 
    times_&cur_buy = times;
   end;
  %end;
  run;

%mend;
%mDecVars;

但是你可能想要使用proc转置来实现你想要的东西。我认为有一个没有宏的解决方案。

答案 1 :(得分:0)

此问题源于解析宏变量时的问题。简而言之,宏变量被解析,然后运行数据步骤......所以你的宏变量被解析为(即保持为)mon_&amp; cur_buy和times_&amp; cur_buy。

此流程图非常有用:http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a001072110.htm

参考流程图,您的问题代码是“开放代码”,即它不在Laurent de Walick的回答中。

说,就像Lauren De Walicks解决方案(开放代码除外)一样,你运行:

%let names=name1,name2;
%let count=2;
data decvars;
    set work.t;
    %do i = 1 %to &count;
    %let cur_buy = %qscan(&names,&i,%str(,));
        length mon_&cur_buy 8;
        length times_&cur_buy 8; 
        if BuyName = "&cur_buy" then do; 
            mon_&cur_buy = money;
            times_&cur_buy = times;
        end;
    %end;
run;

SAS将做的是生成此数据步骤,然后运行它:

data decvars;
    set work.t;
        length mon_name1 8;
        length times_name1 8; 
        if BuyName = "name1" then do; 
            mon_name1 = money;
            times_name1 = times;
        end;
        length mon_name2 8;
        length times_name2 8; 
        if BuyName = "name2" then do; 
            mon_name2 = money;
            times_name2 = times;
        end;
run;