BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
fieldsa83
Quartz | Level 8
Please see the section below. I have tried many different ways.
In some steps the leading zero is kept, but in the CAT it is stripped.
 
Main variable: HHLDID (unique 18 character string)
 
%macro doloop;
data _null_;
/*__ STEP 1: SET DATE RANGE _____________________________________________________*/
 
/* Start year    */      call symput ("startyear",'2016');              
/* Start month   */      call symput ("startmonth",'01');
/* End year      */      call symput ("endyear",'2016');
/* End month     */      call symput ("endmonth",'03');
stop;
run;
 
%do i=&startyear %to &endyear;
%do j=1 %to 12;
        %if &j.=1 and &i.=&startyear %then %let j=&startmonth;
                %let month=%sysfunc(putn(&j,z2.)); /* leading 0 for month if needed */
                %let year=%sysfunc(substrn(&i.,3)); /* last 2 digits of year */
                %if ( ((&endyear. ne &startyear) and (&i. ne &endyear)) or (&i.=&endyear and &month. le &endmonth) )
                        %then
                        %do;
 
 
data output.BOOT&month.&year.; */ ß THIS PART PUTS MONTH WITH LEADING 0 CORRECTLY */
 
set boot.bootstrap_rcomp&i.&month ; */ ß THIS PART PUTS MONTH WITH LEADING 0 CORRECTLY */
 
HHLDID_date= cat(HHLDID,%sysfunc(putn(&MONTH,z3.))&year); */ ß THIS PART STRIPS THE LEADING 0 IN THE MONTH */
 
 
                        %end;   
                        run;    
%end; %end;             
%mend;
%doloop;
1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Inside a data step you probably really shouldn't use the the macro function %sysfunc. You value gets treated by the macro processor not the data step.

 

Try

hhldid_date=cat(hhldid,put(&month,z3.),&year));

 

 

View solution in original post

6 REPLIES 6
ballardw
Super User

Inside a data step you probably really shouldn't use the the macro function %sysfunc. You value gets treated by the macro processor not the data step.

 

Try

hhldid_date=cat(hhldid,put(&month,z3.),&year));

 

 

Quentin
Super User

CAT function accepts both numeric and character arguments.  As written, after the macro processing is done you have given the CAT function something that looks like a number, so it treats it as a number and ignores leading zeros.  If you want it to treat it as character you need to add quotes, i.e.:

HHLDID_date= cat(HHLDID,"%sysfunc(putn(&MONTH,z3.))&year");

The quotes don't have meaning in the macro language, but int he data step language they tell the CAT function that the argument is a character literal value.

 

Here is a little example:

%let month=02;
%let year=2017;

data want;
  HHLDID="Some Text";
  try1= cat(HHLDID,%sysfunc(putn(&MONTH,z3.))&year);
  put try1=;

  try2= cat(HHLDID,"%sysfunc(putn(&MONTH,z3.))&year");
  put try2=;
run;
BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Reeza
Super User

CAT see's it as numeric and according to the docs:

 

If item is numeric, then its value is converted to a character string by using the BESTw. format.

 

You typically don't need the CAT function in macro though.

 

You're in a data step so you don't need the %SYSFUNC either.

 

HHLDID_date= cat(HHLDID, put(&MONTH,z3.), &year);
Quentin
Super User

Just for the sake of discussion, I actually like the %SYSFUNC() approach better here.

 

Compare:

HHLDID_date= cat(HHLDID,"%sysfunc(putn(&MONTH,z3.))&year") ;

HHLDID_date= cat(HHLDID, put(&MONTH,z3.), &year) ;

 

&Month is is a constant stored in a macro variable, as is &Year. 

 

If you use the first approach, the %sysfunc() is executed only once when the macro executes.  With the second approach, the PUT() function will execute once for every observation, as the DATA step executes.

 

With moderately sized data, I would expect a small efficiency gain from the first approach, but this sort of efficiency doesn't matter much to me.

 

I mostly like the first approach for clarity (though many may disagree : )  I think it's clearer to use the data step language to manipulate data step variables, and use the macro language to manipulate macro variables.

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
ballardw
Super User

If I thought I needed the macro side I would probably actually use

%let newmonth= %sysfunc(putn(&month,z3.))&year;

and then use &newmonth so there was only a single macro variable referenced inside the data step in that CAT.

 

I believe the original issue actually was that the result of the %sysfunc, whic was 001 behave like

 

var= cat(othervar,0012016); which uses the best format to convert the 0012016 to the string before concatenating. So I think you might need "%sysfunc(putn(&month,z3))&year" inside the cat function.

fieldsa83
Quartz | Level 8

Thanks for all the tips. Worked and I got my datasets prepared!

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 6 replies
  • 4938 views
  • 0 likes
  • 4 in conversation