Desktop productivity for business analysts and programmers

Array Do Loop using macro from INTO: cluase

Accepted Solution Solved
Reply
Contributor
Posts: 28
Accepted Solution

Array Do Loop using macro from INTO: cluase

[ Edited ]

%macro use;

proc contents data=check(drop=y) out=_out;run;

proc sql;

select distinct name into: list separated by ' '

from _out;

%put the value of %nrstr(&list):&list;

quit;

data naya;

set check;

array n{*} &list;

array x{*} _numeric_;

%do i= 1 %to dim(n);

n{i}=(x({i}=.);

%end;

run;

%mend use;

options mprint mlogic symbolgen;

%use

 

/*********************************************/

 

Hi All,

I'm trying to use list of variables which are created using proc sql INTO: in to array do loop SAS code, but I have encountered following ERRORS:

 

ERROR: Required operator not found in expression: dim(n)

ERROR: The %TO value of the %DO I loop is invalid.

 

Any suggestion, helps are highly appreciated.

Thanks!


Accepted Solutions
Solution
‎05-24-2016 01:39 PM
Grand Advisor
Posts: 10,236

Re: Array Do Loop using macro from INTO: cluase

If you were by some chance expecting to loop over the number elements created here:

proc sql;

select distinct name into: list separated by ' '

from _out;

%put the value of %nrstr(&list):&list;

quit;

 

It may help IF EACH NAME is a single word that you can get a count :

%let namecount= %sysfunc(countw,&list,' '));

And use &namecount for the loop control.

 

Especially if you intended

Array n &list;

to declare an array consisting of variable names.

Of course you may have an issue with numeric and character variables as you can't mix those in a single array.

 

But if you want to do something to all of the numeric variables:

Data naya;

   set check;

   array n _numeric_;

   do i = 1 to dim(n);

   end;

run;

Similar you could declare an additional array of _character_ and no macro is needed at all.

View solution in original post


All Replies
Trusted Advisor
Posts: 1,114

Re: Array Do Loop using macro from INTO: cluase

Hi @koomalkc,

 

Data step information such as dim(n) is unavailable to macro statements (here: %DO), because macro statements are resolved before the data step is even compiled. You can simply use a data step DO-loop instead of a macro %DO-loop there. Hence, there is no longer a need for wrapping your code into a macro at all, so you can delete the %MACRO, %MEND and %USE statements altogether.

Respected Advisor
Posts: 4,997

Re: Array Do Loop using macro from INTO: cluase

On a separate note, it's a little strange to see two arrays here.  For the program to work at all (assuming the current error is worked through), the data set CHECK must contain only a single character variable named "Y".  Otherwise the dimensions of the two arrays will be different.

 

Is your intent to replace the original numeric variables with new values (1 for missing, 0 for nonmissing)?  In that case you would only need one array.

 

Or is your intent to create a new set of variables with these 0/1 values?  In that case, you need to do some more work to count and name a new set of variables.

Esteemed Advisor
Esteemed Advisor
Posts: 7,249

Re: Array Do Loop using macro from INTO: cluase

Post some test data in the form of a datastep, and what you want the output to look like.  I don't see any need for any macro code here, just do it in base SAS.

Esteemed Advisor
Posts: 6,698

Re: Array Do Loop using macro from INTO: cluase

What are you trying to accomplish with this:

n{i}=(x({i}=.);

?

It is at least syntactically incorrect by missing a closing paranthesis.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Solution
‎05-24-2016 01:39 PM
Grand Advisor
Posts: 10,236

Re: Array Do Loop using macro from INTO: cluase

If you were by some chance expecting to loop over the number elements created here:

proc sql;

select distinct name into: list separated by ' '

from _out;

%put the value of %nrstr(&list):&list;

quit;

 

It may help IF EACH NAME is a single word that you can get a count :

%let namecount= %sysfunc(countw,&list,' '));

And use &namecount for the loop control.

 

Especially if you intended

Array n &list;

to declare an array consisting of variable names.

Of course you may have an issue with numeric and character variables as you can't mix those in a single array.

 

But if you want to do something to all of the numeric variables:

Data naya;

   set check;

   array n _numeric_;

   do i = 1 to dim(n);

   end;

run;

Similar you could declare an additional array of _character_ and no macro is needed at all.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 5 replies
  • 361 views
  • 3 likes
  • 6 in conversation