BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Yoko
Obsidian | Level 7

Hello, 

 

I have character strings which look like: 20012, 24012, 20021, 28021, 20040, etc.

I want to select character strings whose last 3 characters are 012 or 040, for example, using %let statement (e.g., %let valid = )

That is, 20012, 24012, and 20040 should be selected in this example. 

Can anybody help me completing the let macro statement? 

 

Thank you, 

 

Yoko

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;
data want;
    set have;
    if left(reverse(string)) in :('210','040') then output;
run;

 

No macros needed. Please note that the IF statement requires a colon before ('210','040') which then tests if the reverse of the string starts with these values, and if it starts with these values, then the un-reversed string ends with the reverse of these values. Please note that I am testing against ('210','040') which is the reverse of what you asked for (you asked for: ends with 012 or 040), but it works in this application because I am testing the reverse strings.

--
Paige Miller

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;
data want;
    set have;
    if left(reverse(string)) in :('210','040') then output;
run;

 

No macros needed. Please note that the IF statement requires a colon before ('210','040') which then tests if the reverse of the string starts with these values, and if it starts with these values, then the un-reversed string ends with the reverse of these values. Please note that I am testing against ('210','040') which is the reverse of what you asked for (you asked for: ends with 012 or 040), but it works in this application because I am testing the reverse strings.

--
Paige Miller
Yoko
Obsidian | Level 7

Thank you for your suggestion. 

This is a part of a macro, so I have use %let. 

I'll incorporate your suggestion to something like this:

 

%let valid = ;

data _null_;

set have;

if left(reverse(string)) in :('210','040') then output;
run;

 

I hope this works. 

 

Thank you, 

 

Yoko

 

 

jklaverstijn
Rhodochrosite | Level 12

A macro solution could be obtained by marrying the wonderful %sysfunc() and prx*() functions. This works for me:

%let string=20040;
%let regex=/012$|040$/;
%let regid=%sysfunc(prxparse(&regex));
%put &=regid;
%let valid = %sysfunc(prxmatch(&regid, &string));
%put &=valid;

The code could be further condensed but this is the most descriptive.

%let string=20040;
%let valid = %sysfunc(prxmatch(/012$|040$/, &string));
%put &=valid;

The macro variable "valid" has a value of 0 (zero) if there is no match or a positive integer indicating startposition of the pattern searched for.

 

Needless to say I am a fan of the prx functions and highly recommend them in these situations.

 

Hope this helps,

- Jan.

Reeza
Super User

You haven't clarified your question enough. Are you strings values in a data set? Are they in a macro variable?
What do you the macro variable created to be? What are you going to use it for?

Ksharp
Super User
data have;
input string $;
cards;
20012
24012
20021
28021
20040
;

%let valid = 012 040 ;
data want;
    set have;
    if findw("&valid",strip(substrn(string,length(string)-2)));
run;
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
  • 2665 views
  • 2 likes
  • 5 in conversation