简体   繁体   English

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

[英]SAS create new dataset variable using macro

So I'm trying to create new columns, mon_&cur_buy and times_&cur_buy that hold values that are set to the values money and times, respectively, from the work.t table. 因此,我正在尝试创建新列mon_&cur_buy和times_&cur_buy,以容纳分别来自work.t表的值money和times的值。

The criteria for assigning the new variables their values is if the name of the &cur_buy macro variable matches the current row's value for BuyName in the work.t table. 为新变量分配值的标准是,如果&cur_buy宏变量的名称与work.t表中BuyName的当前行的值匹配。

The &buyers macro variable referenced is simply a list of names separated by commas. 引用的&buyers宏变量只是用逗号分隔的名称列表。

The error that I'm getting saying that the new variables, mon_&cur_buy and times_&cur_buy are invalid. 我要说的错误是新变量mon_&cur_buy和times_&cur_buy无效。

The names are resolved correctly but are never written to the new dataset, decvars. 名称可以正确解析,但永远不会写入新数据集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;

Ultimately, I'm trying to create separate columns for purchases from each buyer for regression analysis that only contain values of purchases from a certain buyer. 最终,我试图为每个购买者的购买创建单独的列以进行回归分析,以仅包含某个购买者的购买值。 If you have any advice about how to automate this kind of process using a macro variable, please let me know. 如果您对如何使用宏变量自动化此类过程有任何建议,请告诉我。

I'm not exactly surehow you want your output to look like and it seems to me want you are attempting will not return what you expect. 我不确定您希望您的输出看起来如何,在我看来,您想要的尝试不会返回您期望的结果。 If you want your macrovars to resolve in time you need to put the data step in a macro. 如果希望宏变量及时解决,则需要将数据步骤放入宏中。 It has to do with the compilation and execution order of macros. 它与宏的编译和执行顺序有关。

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

But you might want to play around with the proc transpose to archieve what you want. 但是您可能想使用proc换位来存档所需的内容。 I presume there is a solution without macros. 我认为有没有宏的解决方案。

This problem is rooted in when macro variables are resolved. 解决宏变量时,便会出现此问题。 In short, the macro variables are resolved and THEN the data step is run...so your macro variables are resolved as (ie stay as) mon_&cur_buy and times_&cur_buy. 简而言之,宏变量被解析,然后运行数据步骤...因此,您的宏变量被解析为(即保持为)mon_&cur_buy和times_&cur_buy。

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

With reference to the flow diagram, your question code is 'open code' ie it is not within a macro like Laurent de Walick's answer. 参考流程图,您的问题代码是“开放代码”,即它不在像Laurent de Walick的答案这样的宏中。

Say, as in Lauren De Walicks solution (except in open code), you run: 说,就像在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;

What SAS will do is generate this data step, then run it: 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM