DATA Step, Macro, Functions and more

Can a macro do this?

Reply
Occasional Contributor
Posts: 7

Can a macro do this?

First, I'm new to this forum and I'm not sure if this is the right group.

But, here's an example of what I'm trying to do.

I have a data set with 6 variables (group, variable_1-variable_5). Can I run a macro that would run the following for all variables but with only one call:

proc glm data=some_dataset;
class group;
model variable_x = group;
lsmeans group /pdiff adjust=bon;
run;

Can I make 1 call and the macro would be run 5 times? Another way, is there a way to run the macro for each variable (or subset) in a data set with a simple loop?

Thanks.
Super User
Posts: 5,256

Re: Can a macro do this?

Yes, you can use a %DO loop within a macro for this.
I'm not familiar with PROC GLM, but maybe there is a way to run the PROC just once for all variables, which might save some processing time if the source table is big. Maybe you have to transpose the table it first.

/Linus
Data never sleeps
Super Contributor
Super Contributor
Posts: 3,174

Re: Can a macro do this?

Macro language basics use the %DO and %END to iterate, possibly adding a macro variable to increment with each loop - see simple code snippet below.

And from the SAS support http://support.sas.com/ website where I did a search on the argument "macro language iterative loop" and found the following technincal and SAS documentation references:

SAS® Macro Dynamics - From Simple Basics to Powerful Invocations
Rick Andrews, Centers for Medicare and Medicaid Services, Baltimore, MD
http://www2.sas.com/proceedings/sugi31/039-31.pdf

%DO, Iterative Statement
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/a000543755.htm

Scott Barry
SBBWorks, Inc.

%MACRO DOIT;
%PUT COUNT WITH ME: ;
%DO I=1 %TO 5;
%PUT &I;
%END;
%PUT DONE. ;
%MEND DOIT;
%DOIT;
Occasional Contributor
Posts: 7

Re: Can a macro do this?

Thanks for your responses. I think this could work if the variables were named x1, x2, x3, etc.

But, what if they are named height, width, volume, mass, etc. I'm looking for something that will work like proc means. If you specify variables, it will only run those variables. If you don't specify variables, it will run all variables in the dataset.

Is there an "internal" variable name in a dataset other than the name specified in the data statement that can be accessed? Perhaps it looks like x1, x2, x3, etc.

Thanks
Super User
Posts: 5,256

Re: Can a macro do this?

Do you really want to call your PROC with no regards to the column name? If no, you will have to specify somehow which columns you wish to use. If yes, this can be don in a number of ways.

You can have a data step reading SASHELP.VCOLUMN and do call execute to your macro with your proc.

The other way is to open your table using datastep functions, and loop trough the different variables. In this case they are called by position. This can be done within a data step or a macro.

/Linus
Data never sleeps
Super Contributor
Super Contributor
Posts: 3,174

Re: Can a macro do this?

Here is a Google advanced search argument against SAS.COM website where you will find relative topic-oriented technical papers and documentation on the subject:

iterate dictionary columns generate code site:sas.com

Look at generating a list of macro variables and execute a general purpose SAS macro to invoke whatever code is necessary against each variable in the list, by referencing the macro variables.

Scott Barry
SBBWorks, Inc.
Occasional Contributor
Posts: 7

Re: Can a macro do this?

Thanks Linus,

Believe it or not, the answer is yes. I just received an Excel speadsheet that has 218 columns. The first column represents the group. They want the glm procedure with class=group on the 217 remaining variables.

I did it by brute force: a separate call for each variable. I figured there was an easier way to do this for the next time.

Ashy
Respected Advisor
Posts: 3,777

Re: Can a macro do this?

In GLM you can use a list of variables or a "SAS Variable List" as the dependents in the model statement.

A "SAS Variable List" is a special way of referring to a list of variables. See docs for details but some are _CHAR_ _NUMERIC_ _ALL_ plus enumerate variable lists x1-x10 or variable range lists. You could use _NUMERIC_ of GROUP is a character or a range list as hight--mass as in the example you specified above.

Probably the easiset is to make GROUP character and specify

[pre]
class group;
model _numeric_ = group;
[/pre]

Look at the docs to learn the details of this very powerfull SAS feature. Message was edited by: data _null_;
Occasional Contributor
Posts: 7

Re: Can a macro do this?

Thanks data _null_;

That should do the trick. What they want may be wrong, but at least I won't get carpal tunnel by typing control-v 1000 times.
Occasional Contributor
Posts: 7

Re: Can a macro do this?

Thanks again,

This seems to work. The numbers are the same but the order of the output is a bit different. I don't mind. They have other problems to correct: i.e 217 variables and 300 records. Also, they can adapt to the new output order.
Respected Advisor
Posts: 3,777

Re: Can a macro do this?

GLM will group the dependents by missing values. The maintain the order of the specified in the MODEL transpose the data and use a BY statement.

[pre]
dm 'clear log; clear output;';
data class;
set sashelp.class;
if _n_ in (2,3) then height=.;
run;
proc contents varnum short;
run;
proc glm;
class _character_;
model _numeric_ = sex;
run;



* To maintain variable order
1) transpose
2) establish variable order
3) sort
4) use BY statement in GLM
;
step1:
proc transpose data=class out=tall(rename=(col1=y));
by name sex; *unique ID for each row;
var _numeric_; *the default;
run;

step2_a:
proc transpose data=class(obs=0) out=vorder;
var _numeric_;
run;
step2_b:
data vorder(keep=_name_ vorder index=(_name_));
set vorder;
vorder + 1;
run;
step2_c:
data tall;
set tall;
set vorder key=_name_/unique;
run;
step3:
proc sort;
by vorder;
run;
proc print;
run;

step4:
proc glm;
by _name_ /*_label_*/ notsorted;
class sex;
model y = sex;
run;
[/pre]
Ask a Question
Discussion stats
  • 10 replies
  • 196 views
  • 0 likes
  • 4 in conversation