DATA Step, Macro, Functions and more

Return everything from the left of something

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 128
Accepted Solution

Return everything from the left of something

[ Edited ]

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

 


Accepted Solutions
Solution
‎05-16-2017 10:59 AM
Frequent Contributor
Posts: 89

Re: Return everything from the left of something

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


All Replies
SAS Super FREQ
Posts: 709

Re: Return everything from the left of something

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;
Respected Advisor
Posts: 3,156

Re: Return everything from the left of something

[ Edited ]
Posted in reply to Bruno_SAS

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

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

 

PROC Star
Posts: 7,487

Re: Return everything from the left of something

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

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

Art, CEO, AnalystFinder.com

Solution
‎05-16-2017 10:59 AM
Frequent Contributor
Posts: 89

Re: Return everything from the left of something

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;
Super User
Posts: 10,041

Re: Return everything from the left of something

[ Edited ]

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;

 

☑ This topic is solved.

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

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