storing variable names in %let by using loop outside the dataset

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 10
Accepted Solution

storing variable names in %let by using loop outside the dataset

Hello All,

 

I am trying to create a subgroup of varlist from the main %let statment outside the datastep, such that if I select the first one then %let will keep all the others except the selected.

My initial throughts were to count all the variables through do loop and then count them agaim with another loop, and if first count (i) is not equal to the second count(j) then otherlist will contain all the rest of the vars.

for example if %let varlist=a b c d e f g h; and when &next=a then &varlsit should be = b c d e f g h

or if &next=b then &varlsit should be =a c d e f g h or if &next=c then &varlsit should be =a b d e f g h or if &next=d then &varlsit should be =a b c e f g h  and so on....

 

 

 

 

%let varlist=a b c d e f g h i j;

%macro test();

%local i next ;

%let i=1;

%do i=1 %to %sysfunc(countw(&varlist));

%let next=%scan(&varlist,&i);

%do j=1 %to %sysfunc(countw(&varlist));

%let otherlist=%scan(&varlist,&j);

%end;

 

/*%let allvars = catx(" ", OF &other); */

%put &next &otherlist &allvars;

%end;

%end;

 

 

 

%mend;

 

%test();

 

 

 


My problem is that I'm not sure how to solve, or if this is even the right way to do it.  Please help me identify a solution!

Please note, I have to do it outside the datastep.

 

Regards,

 

 

 

SAS 9.4


Accepted Solutions
Solution
‎03-30-2018 02:17 PM
Super User
Super User
Posts: 8,069

Re: storing variable names in %let by using loop outside the dataset

Not sure what you are trying to do but if you want build up a space delimited list into a macro variable named ALLVARS then the key thing is to include the current value in the assignment.  So if you want to add the value of NEXTVAR to the end of ALLVARS you line of code would look like this.

%let allvars=&allvars &nextvar ;

For your actual stated problem it would be easier to just remove the one value from the list using the TRANWRD() function.

%let list=a b c d;
%let i=2 ;
%let next=%scan(&list,&i);
%let subset=%sysfunc(tranwrd(%str( &list ),%str( &next ),%str( )));

 

View solution in original post


All Replies
Occasional Contributor
Posts: 10

Re: storing variable names in %let by using loop outside the dataset

Sorry the code is as below......

 

%local i next ;

%let i=1;

%do i=1 %to %sysfunc(countw(&varlist));

%let next=%scan(&varlist,&i);

%do j=1 %to %sysfunc(countw(&varlist));

 

%if (&j ne &i) %then %do;

 

%let other=%scan(&varlist,&j);

retain allvars ' ';

%end;

%let allvars = catx(" ", OF &other);

%put &next &i &other &allvars;

%end;

%end;

Solution
‎03-30-2018 02:17 PM
Super User
Super User
Posts: 8,069

Re: storing variable names in %let by using loop outside the dataset

Not sure what you are trying to do but if you want build up a space delimited list into a macro variable named ALLVARS then the key thing is to include the current value in the assignment.  So if you want to add the value of NEXTVAR to the end of ALLVARS you line of code would look like this.

%let allvars=&allvars &nextvar ;

For your actual stated problem it would be easier to just remove the one value from the list using the TRANWRD() function.

%let list=a b c d;
%let i=2 ;
%let next=%scan(&list,&i);
%let subset=%sysfunc(tranwrd(%str( &list ),%str( &next ),%str( )));

 

Occasional Contributor
Posts: 10

Re: storing variable names in %let by using loop outside the dataset

Hi,

 

Thank you so much for the reply.

 

Please could you more clarify the code as it's not working.

 

%let varlist= a b c d e f g h;

 

 

%macro test();

%do i=1 %to %sysfunc(countw(&varlist));

%let next=%scan(&varlist,&i);

%let subset=%sysfunc(tranwrd(%str( &varlist ),%str( &next ),%str( )));

%end;

 

 

%mend;

 

%test();

 

 

Kind Regards,

 

 

 

Super User
Super User
Posts: 8,069

Re: storing variable names in %let by using loop outside the dataset


@hira wrote:

Hi,

 Thank you so much for the reply.

 Please could you more clarify the code as it's not working.

 %let varlist= a b c d e f g h;

  

%macro test();

%do i=1 %to %sysfunc(countw(&varlist));

%let next=%scan(&varlist,&i);

%let subset=%sysfunc(tranwrd(%str( &varlist ),%str( &next ),%str( )));

%end;

 %mend;

 

%test();

 

Kind Regards,

  


How do you know it didn't work?  The code you posted is overwriting the value of SUBSET macro variable and never doing anything with it. You didn't even print it to the log so that you could see what happened.

 

What is it that you want to do with these list of variables?

 

Occasional Contributor
Posts: 10

Re: storing variable names in %let by using loop outside the dataset

I am so sorry, it did work in the loop.
Wondering if I would to subset more, would it be possible in TRANWRD
funtion to remove more then one value?
For example if next=a and subset = b c d e f g j , but if I would like
subset=b d e f g h j
Super User
Super User
Posts: 8,069

Re: storing variable names in %let by using loop outside the dataset

[ Edited ]

@hira wrote:
I am so sorry, it did work in the loop.
Wondering if I would to subset more, would it be possible in TRANWRD
funtion to remove more then one value?
For example if next=a and subset = b c d e f g j , but if I would like
subset=b d e f g h j

The TRANWRD() function just replaces text with different text. It cannot read your mind.

What are you trying to do?  If start with 

 b c d e f g j

And you want to end up with

b d e f g h j

Then is looks like you want to remove c and h.

Occasional Contributor
Posts: 10

Re: storing variable names in %let by using loop outside the dataset

But would it be possible to replace two texts in one TRANWRD function?

for example replacing next to ' ' and replacing some other value ie 'b' to missing  as well?

Super User
Super User
Posts: 8,069

Re: storing variable names in %let by using loop outside the dataset


@hira wrote:

But would it be possible to replace two texts in one TRANWRD function?

for example replacing next to ' ' and replacing some other value ie 'b' to missing  as well?


Just call it twice.  Pass in the result of the first call as the input to the second.

Respected Advisor
Posts: 2,981

Re: storing variable names in %let by using loop outside the dataset

The logic should work. The code needs to be cleaned up a little.

 

%do i=1 %to %sysfunc(countw(&varlist));
    %let next=%scan(&varlist,&i);
    %let allvars=;
    %do j=1 %to %sysfunc(countw(&varlist));
         %if (&j ne &i) %then %do;
              %let other=%scan(&varlist,&j);
              %let allvars=&allvars &other;
         %end;
         %put &=next &=i &=other &=allvars;
    %end;
%end;

Note that RETAIN is not a macro command. Also catx is not needed here, just do a macro concatenation as shown.

--
Paige Miller
Occasional Contributor
Posts: 10

Re: storing variable names in %let by using loop outside the dataset

Posted in reply to PaigeMiller

Hi ,

 

Thank you so much for the reply.

For running the following codes, would it be possible if I output only the last statement as its from outside the dataset.

At the moment the log is showing the ALLVARS values as below.

 

NEXT=a J=1 ALLVARS=

NEXT=a J=2 ALLVARS=b

NEXT=a J=3 ALLVARS=b c

NEXT=a J=4 ALLVARS=b c d

NEXT=a J=5 ALLVARS=b c d e

NEXT=a J=6 ALLVARS=b c d e f

NEXT=a J=7 ALLVARS=b c d e f g

NEXT=a J=8 ALLVARS=b c d e f g h

 

 

%do i=1 %to %sysfunc(countw(&varlist));
    %let next=%scan(&varlist,&i);
    %let allvars=;
    %do j=1 %to %sysfunc(countw(&varlist));
         %if (&j ne &i) %then %do;
              %let other=%scan(&varlist,&j);
              %let allvars=&allvars &other;
         %end;
         %put &=next &=i &=other &=allvars;
    %end;
%end;

 

 

Also is there a way to create an array to do so?

 

 

Kind Regards,

Respected Advisor
Posts: 2,981

Re: storing variable names in %let by using loop outside the dataset


@hira wrote:

Hi ,

 

Thank you so much for the reply.

For running the following codes, would it be possible if I output only the last statement as its from outside the dataset.

At the moment the log is showing the ALLVARS values as below.

 

NEXT=a J=1 ALLVARS=

NEXT=a J=2 ALLVARS=b

NEXT=a J=3 ALLVARS=b c

NEXT=a J=4 ALLVARS=b c d

NEXT=a J=5 ALLVARS=b c d e

NEXT=a J=6 ALLVARS=b c d e f

NEXT=a J=7 ALLVARS=b c d e f g

NEXT=a J=8 ALLVARS=b c d e f g h

 

 

%do i=1 %to %sysfunc(countw(&varlist));
    %let next=%scan(&varlist,&i);
    %let allvars=;
    %do j=1 %to %sysfunc(countw(&varlist));
         %if (&j ne &i) %then %do;
              %let other=%scan(&varlist,&j);
              %let allvars=&allvars &other;
         %end;
         %put &=next &=i &=other &=allvars;
    %end;
%end;

 

 

Also is there a way to create an array to do so?

 

 

Kind Regards,


Possible to only show the last output? Sure.

 

Can you do this with an array? Off the top of my head, I'm not seeing this as a problem that fits the purpose of the data step ARRAY statement.

 

As a wild guess, is this being done as some method to perform regressions on many different combinations of variables? If so, I would advise against that.

--
Paige Miller
☑ This topic is solved.

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

Discussion stats
  • 11 replies
  • 202 views
  • 0 likes
  • 3 in conversation