BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
BruceBrad
Lapis Lazuli | Level 10

I'm trying to strip some operators from a string, leaving behind variable names. I'm using the following code which doesn't work. Is there some quoting needed?

 

%let expression = vara / (varb + varc);

%macro stripsym(string);
%sysfunc(translate(&string,,+-*/()));
%mend stripsym;

%put Output: %stripsym(&expression);
%put Desired: vara varb varc;
1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15
%let expression = vara / (varb + varc);

%macro stripsym(string);
%sysfunc(compbl(%sysfunc(translate(&string,%STR(      ),+-*/()))));
%mend stripsym;

%put Output: %stripsym(&expression);
%put Desired: vara varb varc;

%STR() masks spaces in translate, COMPBL() compress multiple spaces 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

12 REPLIES 12
Tom
Super User Tom
Super User

You post is empty.  Do you have a question?  Or are you trying to share something?

BruceBrad
Lapis Lazuli | Level 10
Question edited now.
ballardw
Super User

COMPRESS is the more natural function to remove characters.

 

Need some quoting function or the first ) is treated as the end of a function call.

If you want to use a the call like a function do not end the statement with a ;

 

This works for your example:

%let expression = vara / (varb + varc);

%macro stripsym(string);
%sysfunc(compress(&string,%str(+/-())))

%mend stripsym;

%put Output: %stripsym(&expression);
BruceBrad
Lapis Lazuli | Level 10
Thanks. But I see my example didn't cover all my use needs. In particular, I don't always have spaces between my operators (eg vara+varb). I would like the output to have spaces between the variable names.
Patrick
Opal | Level 21

You could replace any character not part of the SAS naming convention with a blank using the translate() function BUT.... things will become quickly complicated if your expressions also can contain functions like sum(varA,varB). 

If you can limit your expressions to certain patterns then writing some code might be feasible. Something that would work for any valid SAS syntax would be very involved.

BruceBrad
Lapis Lazuli | Level 10
Yes, I can see that a fully general function would be challenging. My purpose here is that I'm writing simple expressions to do some data checks (generally just adding up checks), and then would like to put all the component variables to the log if the check fails. (I already have code that generates the put statement from a list of variable names separated by spaces).
So, can someone help with the quoting needed to get my original example to work?
yabwon
Onyx | Level 15
%let expression = vara / (varb + varc);

%macro stripsym(string);
%sysfunc(compbl(%sysfunc(translate(&string,%STR(      ),+-*/()))));
%mend stripsym;

%put Output: %stripsym(&expression);
%put Desired: vara varb varc;

%STR() masks spaces in translate, COMPBL() compress multiple spaces 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



BruceBrad
Lapis Lazuli | Level 10
Thanks. This does what I need. I'm still puzzled by how strings get passed to translate(). Why don't I need to put quote marks around &string, but do need to use %str( ) for the space?
Tom
Super User Tom
Super User

@BruceBrad wrote:
Thanks. This does what I need. I'm still puzzled by how strings get passed to translate(). Why don't I need to put quote marks around &string, but do need to use %str( ) for the space?

In normal SAS syntax (and most programming languages) you use quotes around string constants so the parser/compiler can tell the string 'DATA' from the keyword DATA or from a variable name.  Or it can tell the difference between the number 100 and the string "100".  But to the macro processor everything is a string.  it is only looking for the macro trigger characters of & or % to know when it needs to handle things specially.

 

But spaces are tricky because normally extra spaces do not mean anything in SAS syntax.  So without the quotes to demark the string you need some other way to tell the macro processor that you want this space to be special.

 

Note that another way to do the current task is to enclose both strings being passed to TRANSLATE() in quotes.  That is because that would just be telling TRANSLATE() to convert the quote characters back into quote characters.  Then you would not need macro quoting at all. The only trouble with that would be that you need count the number of characters correctly so that the closing quotes align with each other.  Note that normally you can use a shorter target string and it will be padded with spaces.

1    %put %sysfunc(translate(ABCD,Z,ABC));
Z  D

But unfortunately if you use an empty target string then it does nothing instead of translating all source characters.

2    %put %sysfunc(translate(ABCD, ,ABC));
ABCD

One solution to that is to prefix both strings with the same character (so it gets translated to itself) and then the padding of spaces will again happen.

3    %put %sysfunc(translate(A+b+c-D,A,A+-));
A b c D
yabwon
Onyx | Level 15

When you program in 4GL you have very simple and clear difference between the code and data, code is in *.sas file, data are in SAS data set, they do not interleave between each other.

 

In macro programming both your code (macro language statements) and your data (4GL code) sit in one place, the *.sas file. So you have to figure out a way to tel SAS which is which. That's why there are % and & running around. If you realise this, everything is much simpler.

 

So now.

You don't need quotes because in the macro language there is only one variable type - text. 

Everything is a text string.

%let x=123;  - value of x is not one hundred and twenty three, but string build of digits 1, 2, and 3,

%let y=1+2; -  value of y is not 3, it's string "1+2", and you need %SYSEVALF() to "calculate the value"

%let z=ABC; - value of z is string ABC

Since everything is a string there is no need for quotes.

If you write:

 

%put %sysfunc(pathname("WORK"));

you will fail, because there is no library >>"WORK"<<

 

But if you do: 

 

%put %sysfunc(pathname(WORK));

everything works ok.

 

If you type:

 

%put %substr("TEST",2,1);

you will get T in the log not E as you would expect (in 4GL).

 

 

Now, for spaces.

For SAS an "empty string", or string on one space, or a string of 42 spaces is the same, both in 4GL and in macro language. The difference is that in 4GL you have quotes, which can be used to provide a single space character. In macro language

those two are the same:

 

%let x =;

%let y =                                         ;

both produce and empty value for macrovariabe x and y.

 

So when you run:

 

data A&x.B;
  set sashelp.class;
run;

data A&y.B;
  set sashelp.class;
run;

 

in both cases you will get data set AB as a resutl.

 

So the space is a "special" character (as comma or semicolon are too) and you need to mask them in proper way. You use %STR() for that purpose (among others).

If you do:

%let x =     ; /* 5 spaces */

%let y =%str(     ); /* 5 spaces */

and then repeat those two data steps, the first one gives you AB the other A and B.

 

Bottom line. If you want to use space as a value for macrofunction (e.g., %SCAN(...)) or a function wrapped in %SYSFUNC (e.g., %sysfunc(translate(...))) you will have to "mask" it.  

 

The best reading about masking special characters a.k.a. macroquotting is "Secrets of Macro Quoting Functions – How and Why" by Susan O’Connor, link: https://stats.oarc.ucla.edu/wp-content/uploads/2016/02/bt185.pdf

 

 

Bart

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



BruceBrad
Lapis Lazuli | Level 10

I think my confusion stems from how %sysfunc works. I was assuming that translate() was interpreted as a normal function, and following its documentation, would require quoted inputs. Is the %sysfunc(translate()) syntax best interpreted as turning translate() into a macro function, with macro-type inputs?

Patrick
Opal | Level 21

@BruceBrad wrote:

I think my confusion stems from how %sysfunc works. I was assuming that translate() was interpreted as a normal function, and following its documentation, would require quoted inputs. Is the %sysfunc(translate()) syntax best interpreted as turning translate() into a macro function, with macro-type inputs?


This is something that confused me as well in the beginning.

Translate() is still a SAS function and not a macro function but %sysfunc() is a macro function and that's why you don't need the quotes.

 

From the documentation for %SYSFUNC, %QSYSFUNC Macro Functions

function
is the name of the function to execute. This function can be a SAS function, a function written with SAS/TOOLKIT software, or a function created using the FCMP Procedure in Base SAS Procedures Guide. The function cannot be a macro function.

...

Because %SYSFUNC and %QSYSFUNC are macro functions, you do not need to enclose character values in quotation marks as you do in DATA step functions.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 12 replies
  • 673 views
  • 5 likes
  • 5 in conversation