hi All,
can some please help me to get the desired data, I want number from 123456789101 to like this :1234-5678-9101....??
data a;
input number;
value=substr(number,1,4)||'-'||substr(number,5,7)||'-'||substr(number,8);
cards;
123456789101
;run;
thanks
proc format;
picture num
low-high ='9999-9999-9999';
run;
data a;
input number;
value=put(number,num.);
cards;
123456789101
;run;
data a;
input number;
array t(3) $4 _temporary_;
call pokelong(put(number,best12.),addrlong(t(1)),12);
value=catx('-',of t(*));
cards;
123456789101
;run;
Your own attempt would work if you executed it a bit more diligently:
data a (drop = _:) ;
input number ;
_c = put (number, z12.) ;
value = substr (_c,1,4) || '-' || substr (_c,5,4) || '-' || substr (_c,9) ;
cards ;
123456789101
;
run ;
_C prevents the step from generating data type conversion notes. Alternatively, you can use a loop to save some keystrokes:
data a ;
input number ;
length value $ 14 ;
do _n_ = 1, 5, 9 ;
value = catx ("-", value, substr (put (number, z12.), _n_, 4)) ;
end ;
put value= ;
cards ;
123456789101
;
run ;
Having said that, I think that the picture format approach offered by @novinosrin is a neater solution.
Kind regards
Paul D.
data _null_;
x=123456789101;
y=prxchange('s/(\d{4})(\d{4})(\d{4})/$1-$2-$3/', -1, x);
put y=;
run;
Wow. I admire your ability to put this kind of expression together.
But frankly, @novinosrin's picture format 9999-9999-9999 looks much more self-explanatory to me, plus it doesn't generate implicit data type conversion notes in the log.
Kind regards
Paul D.
@hashman I could not agree more, picture formats are the way to go here 🙂
If the length of the number is not known, you can use the below code:
In your case its 12 so it would be much simpler
data a(keep=s z);
s="123456789";
%macro nums;
c=length(s);
call symput('p',put(c,best.));
l=int(c/4);
call symput('k',put(l,best.));
%do i=1 %to &k.;
%if &i.=1 %then %do;
a&i.=substr(s,1,4);
%end;
%if &i. ne 1 %then %do;
a&i.=substr(s,(&i.-1)*4+1,4);
%end;
%if &i.=&k. %then %do;
%let m=%sysevalf(&k.+1,integer);
%put &m.;
a&m.=substr(s,(&i)*4+1);
%end;
%end;
length z $%sysevalf(&p.+&m.,integer).;
%do j=1 %to &m.;
%if &j.=1 %then %do;
z=a&j.;
%end;
%else %do;
z=cats(z,"-",trim(a&j.));
%end;
%end;
%mend nums;
%nums;
run;
As an opinion: O.K. as an exercise but in real live: Picture Format!
1. I'd suggest that you test your solution before posting it:
2. If your intent is to set the length of the character variable Z based on the number of digits in the digit string S determined at run time - or any other quantity determined at run time - it cannot be done because it is set at compile time; and the DATA step is not a time machine. You can only set the length of Z to the length of S by assigning Z=S, but then you won't have enough room for the intervening dashes.
3. Under the OP's conditions, the input variable NUMBER is a numeric variable whose value is integer. Even if setting the length of the "dashed" output string were possible at run time - say, based on the expression ceil(log10(number)), - it would be a wasted effort since the integer precision of a SAS numeric variable is limited to 15 digits under ASCII and 16 under EBCDIC, which means that under no circumstances you can have more than 3 dashes separating every 4 consecutive digits.
Kind regards
Paul D.
sorry my bad.. @hashman 😛 . Got what you wanted to say. I tweeked it a bit. I think this will work now
data a(keep=s z);
s="123456789";
%macro nums;
c=length(s);
c1=put(c,best.);
call symput('p',c1);
l=int(c/4);
l1=put(l,best.);
call symput('k',l1);
%do i=1 %to &k.;
%if &i.=1 %then %do;
a&i.=substr(s,1,4);
%end;
%if &i. ne 1 %then %do;
a&i.=substr(s,(&i.-1)*4+1,4);
%end;
%if &i.=&k. %then %do;
%let m=%sysevalf(&k.+1,integer);
%put &m.;
a&m.=substr(s,(&i)*4+1);
%end;
%end;
length z $%sysevalf(&p.+&m.,integer).;
%do j=1 %to &m.;
%if &j.=1 %then %do;
z=a&j.;
%end;
%else %do;
z=cats(z,"-",trim(a&j.));
%end;
%end;
%mend nums;
%nums;
run;
Please let me know if this works 🙂
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.