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;
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.

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!

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