Solved
Contributor
Posts: 40

# specifying options of proc factor as parameters in macro

aa,Hi,

I am trying to write a macro to perform factor analysis on a data set and score it using Proc Factor and Proc Score. I would like to provide two options of the Proc Factor as parameters -

1) the number of factors and the

2) minimum eigenvalue criteria for the factor.

The macro runs fine when I specify the maxfactors and eigenlimit when running it. However, I would like to provide the option of not specifying them to the user - in which case SAS will determine the best number of factors (instead of nfactors) to retain and will not eliminate any factor based on minimum eigen criteria (instead of mineigen)

This is also a general question on how to make the parameters of a macro optional.

%macro factorscore(input, maxfactors, eigenlimit);

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut NFACTORS = &maxfactors mineigen = &eigenlimit ;

run;

proc score data = inputds_factor score = FactOut out = FScore;

run;

options source notes;

%mend;

thanks,

nikhil

Accepted Solutions
Solution
‎01-20-2015 04:24 PM
Super User
Posts: 6,781

## Re: specifying options of proc factor as parameters in macro

Here's my preference on how to use %IF/%THEN for building pieces of a program.

The macro definition begins with %macro factorscore (input, maxfactors, eigenlimit);

Then inside the macro, build the appropriate statements:

PROC FACTOR

%if %length(&maxfactors) %then NFACTORS=&maxfactor;

%if %length(&eigenlimit) %then MINEIGEN=&eigenlimit;

data=&input method=P rotate=varimax priors=max;

As was noted, it's not done yet.  But that's one way to use %IF/%THEN to build a program within a macro.

The final semicolon ends the PROC FACTOR statement.  The first two semicolons each end an %IF/%THEN statement.

Good luck.

All Replies
Contributor
Posts: 53

## Re: specifying options of proc factor as parameters in macro

Can you instead pass  "NFACTORS = &maxfactors","mineigen = &eigenlimit" as the macro parms? So in case you do not want to pass these values, they won't get added to the PROC statement in the macro.

So you macro call looks like -

%factorscore(<value of input>, 'NFACTORS = <value of maxfactors>', 'mineigen = <value of eigenlimit>');

Contributor
Posts: 40

## Re: specifying options of proc factor as parameters in macro

How would SAS know that the parm 'NFACTORS = <value of maxfactors>' is an option for proc factor? And what if I have procedures prior to the proc factor step? I am not sure if this will work. I am trying an %IF %THEN %DO approach.

Contributor
Posts: 53

## Re: specifying options of proc factor as parameters in macro

It won't until you tell it.

Macro call -

%factorscore(<value of input>, 'NFACTORS = <value of maxfactors>', 'mineigen = <value of eigenlimit>');

Inside your macro you say -

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut &maxfactors &eigenlimit ;

run;

Here maxfactors then gets resolved to NFACTORS = <value of maxfactors> and eigenlimit to mineigen = <value of eigenlimit> during macro resolution. So your PROC FACTOR becomes -

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut NFACTORS = <value of maxfactors> mineigen = <value of eigenlimit>;

run;

Instead if you macro call said -

%factorscore(<value of input>, '', '');

During macro reslution, your proc factor statement wil become -

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut;

run;

Since both the macro variables to be substituted were simply blanks.

Super User
Posts: 23,754

## Re: specifying options of proc factor as parameters in macro

You can use %if/%then to create a set of new macro variables or provide your macro variables as the full statement above.

i.e. check if factors is empty, if not generate a macro variable that is NFACTORS=24

If it becomes more complex than just an option you may want to have different procs running under different conditions.

Solution
‎01-20-2015 04:24 PM
Super User
Posts: 6,781

## Re: specifying options of proc factor as parameters in macro

Here's my preference on how to use %IF/%THEN for building pieces of a program.

The macro definition begins with %macro factorscore (input, maxfactors, eigenlimit);

Then inside the macro, build the appropriate statements:

PROC FACTOR

%if %length(&maxfactors) %then NFACTORS=&maxfactor;

%if %length(&eigenlimit) %then MINEIGEN=&eigenlimit;

data=&input method=P rotate=varimax priors=max;

As was noted, it's not done yet.  But that's one way to use %IF/%THEN to build a program within a macro.

The final semicolon ends the PROC FACTOR statement.  The first two semicolons each end an %IF/%THEN statement.

Good luck.

Super User
Posts: 13,563

## Re: specifying options of proc factor as parameters in macro

If FactOut and FSCORE are the datasets to be compared later  you likely want to add one or more of those macro variables as suffixes to the dataset name so you have all of the output around and don't overwrite the set at each call.

something like

out=FactOut_&maxfactors._&eigenlimit

and similar for FSCORE. The underscores are to allow determination of difference between things like 8 /17 81/7 as parameters.

Contributor
Posts: 40

## Re: specifying options of proc factor as parameters in macro

yep I did that ! I've named them fscore_default or just fscore. the idea is to first compare the default output without specifying factors and eigenvalues. And then execute the macro with different nfactors and eigenlimit values.

thanks!

Contributor
Posts: 40

## Re: specifying options of proc factor as parameters in macro

This is what I have done for now and I know this code is not optimized but it works :

The &cutoff parms pertains to some cleaning before proc factor is applied.

%macro factorscore(input, cutoff, maxfactors, eigenlimit);

%IF &maxfactors gt 0 AND &eigenlimit > 0  %THEN %DO;

/* Proc Factor & Score Procedure */

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut NFACTORS = &maxfactors MINEIGEN = &eigenlimit;

run;

proc score data = inputds_factor score = FactOut out = FScore;

run;

%END;

%ELSE %DO;

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut_default;

run;

proc score data = inputds_factor score = FactOut_default out = FScore_default;

run;

%END;

options source notes;

%mend;

Contributor
Posts: 53

## Re: specifying options of proc factor as parameters in macro

Macro hack -

proc factor data = inputds_factor method = P priors = max rotate = varimax score outstat = FactOut

%IF &maxfactors gt 0 AND &eigenlimit > 0  %THEN %DO;

/* Proc Factor & Score Procedure */

NFACTORS = &maxfactors MINEIGEN = &eigenlimit

%END;

;

run;

proc score data = inputds_factor score = FactOut out = FScore;

run;

🔒 This topic is solved and locked.