BookmarkSubscribeRSS Feed
Ronein
Meteorite | Level 14

Hello

I am trying to learn using str function.

Please see example below.

In data set test  the length of varaible  groupCat1 groupCat2 is too short.

How can I add length statement to following code?

data test;
input age @@;
&age4.;
&age2.;
datalines;
19 50 10 34 44 15 30
;
run;

 

 

 

Here is the full code:

 

%let age4=%str(if age<20 then groupCat1 ='<20';
else if age<35 then groupCat1='20-34';
else if age<45 then groupCat1='35-44';
else groupCat1='45+';
);

%let age2=%str(if age<35 then groupCat2='<35';
else groupCat2='35+';);


data test;
input age @@;
&age4.;
&age2.;
datalines;
19 50 10 34 44 15 30
;
run;

3 REPLIES 3
RW9
Diamond | Level 26 RW9
Diamond | Level 26

I can understand your wanting to learn a function, but step 1 of any learning activity should be to learn how to do things as simply and efficiently as possible, and I am afraid that if you are resorting to %str or one of those types of macro functions, or multiple & signs, then that code is neither simple nor efficient.  For instance, in this example you give, the simplest method would be to create a format, then:

proc format;
  value agrpfmt
    0-<20="<20"
    20-<35="20-34"
    ...;
run;

data want;
  set have;
  groupcat1=put(age,grpfmt.);
run;

So much simpler.  The format statement can be managed externally to the program so as to provide expandability and managability without re-validating the other code.  Much easier to read the code, and support the code.  

 

to note, Base SAS is the programming language, it can do everything.  Macro is a helper component which is there to build text strings, nothing more.  Do not use it as an alternative to Base SAS.

Guardian
Calcite | Level 5

Hi Ronein.

 

In your example are a few issues, please see my corrected  version below:

 

1. you need to use %NRSTR (because of the ; in your code)

2. a missing )

3. always use an explicit length statement, otherwise sas will use the length from the FIRST assignment in the data stept (after resoving the macro variables)

groupCat1 ='<20' <- (as expression length is 3)

groupCat2='<35' <- (as expression length is 3)

 

updated example

 

%let age4=%nrstr(if age<20 then groupCat1 ='<20';
else if age<35 then groupCat1='20-34';
else if age<45 then groupCat1='35-44';
else groupCat1='45+';
);

 

%let age2=%nrstr(if age<35 then groupCat2='<35';
else groupCat2='35+';
);

 


data test;
length groupcat1 groupcat2 $20;
input age @@;
&age4.;
&age2.;
datalines;
19 50 10 34 44 15 30
;
run;

 

I recommend to use %macro /%mend instead of macro variables having sas code.

 

 

 

 

Astounding
PROC Star

You could easily add it:

 

%let age4=%str(length groupCat1 $ 5; if age<20 then groupCat1 ='<20';
else if age<35 then groupCat1='20-34';
else if age<45 then groupCat1='35-44';
else groupCat1='45+';
);

 

As you mentioned, this is a practice exercise.  It would be rare for %str to be used this way in practice just as a matter of style.  But it is perfectly valid for learning purposes.  If this logic were re-usable code that would apply to many DATA steps, you might actually create a macro instead of a macro variable:

 

%macro age4;

length groupCat1 $ 5;

if age<20 then groupCat1 ='<20';
else if age<35 then groupCat1='20-34';
else if age<45 then groupCat1='35-44';
else groupCat1='45+';
%mend age4;

 

It's re-usable, since macros can be stored permanently.  It's easier to read.  And calling the macro is just as easy as using a macro variable:

 

%age4

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 3 replies
  • 843 views
  • 0 likes
  • 4 in conversation