简体   繁体   中英

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.

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.

The &buyers macro variable referenced is simply a list of names separated by commas.

The error that I'm getting saying that the new variables, mon_&cur_buy and times_&cur_buy are invalid.

The names are resolved correctly but are never written to the new dataset, 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. 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.

This flow diagram is quite useful: 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.

Say, as in Lauren De Walicks solution (except in open code), you run:

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

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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