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));
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));
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;
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);
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.
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.
Thanks for all the tips. Worked and I got my datasets prepared!
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.
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.