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 🙂
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.