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

Hi all,

 

I have this:

%let dsn=h1_1_final;

Data test;

       Us=count("&dsn.","_");

       Abv=scan("&dsn.",us,"_");

Run;

 

And i'm trying to end up with:

US=2

ABV=H1_1

 

However, the code above is giving me:

US=2

ABV=1

 

I can't figure out the right combination of scan or count and substr and length or whatever to get abv=h1_1

 

Any ideas?
Thanks

M


EDIT: This code will be part of a macro that cycles through 20+ different dataset names, some with 1 underscore, some with 2, etc.  So i need it to be dynamic.  Thanks

 

1 ACCEPTED SOLUTION

Accepted Solutions
SuzanneDorinski
Lapis Lazuli | Level 10

If you want everything up to the last underscore, you can use CALL SCAN.

 

%let dsn=h1_1_final;

Data test(drop=position length);
  Us=count("&dsn.","_");
  call scan("&dsn.",us,position,length,"_");
  abv=substr("&dsn.",1,position+length-1);
Run;

proc print data=test;
run;

View solution in original post

5 REPLIES 5
BrunoMueller
SAS Super FREQ

Hi

 

You can also use DATA Step functions in the macro language by using %SYSFUNC. The SCAN function returns "words" deilmited by some chars. For your example, check the position of the last underscore and use the %SUBSTR function. the negative number in the FIND function will search from right to left.

 

%let dsn = h1_1_final;

%let last_us = %sysfunc( find(&dsn, _, -256) );

%let first_part = %substr(&dsn, 1, %eval(&last_us -1));

%put NOTE: &=dsn &=last_us &=first_part;
Haikuo
Onyx | Level 15

For what it is worth, can also just be one-liner:

	   abv=prxchange('s/(^[^_]+_[^_]+)(_[^_]+$|\s*$)/$1/', -1, "&dsn.");

 

art297
Opal | Level 21

Also, FWIW, can be a one liner with something like:

abv=substr("&dsn.",1,findc("&dsn.","_",-999)-1);

Art, CEO, AnalystFinder.com

SuzanneDorinski
Lapis Lazuli | Level 10

If you want everything up to the last underscore, you can use CALL SCAN.

 

%let dsn=h1_1_final;

Data test(drop=position length);
  Us=count("&dsn.","_");
  call scan("&dsn.",us,position,length,"_");
  abv=substr("&dsn.",1,position+length-1);
Run;

proc print data=test;
run;
Ksharp
Super User

Very interesting question.

You only want the position of most right '_' ?

 

%let dsn=h1_1_final;
Data _null_;
       Us=count("&dsn.","_");
       Abv=substr("&dsn",1,findc("&dsn.","_",'b')-1);
put us= abv= ;
Run;

 

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1438 views
  • 2 likes
  • 6 in conversation