BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
hira
Calcite | Level 5

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

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

11 REPLIES 11
hira
Calcite | Level 5

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;

Tom
Super User Tom
Super User

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( )));

 

hira
Calcite | Level 5

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,

 

 

 

Tom
Super User Tom
Super User

@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?

 

hira
Calcite | Level 5
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
Tom
Super User Tom
Super User

@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.

hira
Calcite | Level 5

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?

Tom
Super User Tom
Super User

@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.

PaigeMiller
Diamond | Level 26

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
hira
Calcite | Level 5

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,

PaigeMiller
Diamond | Level 26

@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

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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