Hello
I try to create this format.
What is the way to create it by dynamic code and not manually type all this code?
proc format;
value F_Ronein
0='(1) 0'
0<-100='(2) 0-100'
100<-200='(3) 100-200'
200<-300='(4) 200-300'
300<-400='(5) 300-400'
400<-500='(6) 400-500'
500<-1000='(7) 500-1000'
1000<-2000='(8) 1000-2000'
2000<-3000='(9) 2000-3000'
3000<-4000='(10) 3000-4000'
4000<-5000='(11) 4000-5000'
5000<-6000='(12) 5000-6000'
6000<-7000='(13) 6000-7000'
7000<-8000='(14) 7000-8000'
8000<-9000='(15) 8000-9000'
9000<-10000='(16) 9000-10000'
10000<-15000='(17) 10000-15000'
15000<-High='(18) 15000+'
;
Run;
If you have the intervals stored in a data set/table, you can feed PROC FORMAT using CNTLIN.
SAS Help Center: Creating a Format from a CNTLIN= Data Set.
Some fun with macro looping could work too:
%macro loopFormat(s,e,b=1,r=1,z=00);
%do i=&s. %to &e. %by &b.;
%eval(&i.-&b.)&z.<-&i.&z.="(%eval(&i.+&r.)) %eval(&i.-&b.)&z. - &i.&z."
%end;
%mend loopFormat;
options Mprint;
proc format;
value F_Ronein
0='(1) 0'
%loopFormat(1,5,r=1)
%loopFormat(10,10,b=5,r=-3)
%loopFormat(2,10,r=6,z=000)
10000<-15000='(17) 10000-15000'
15000<-High='(18) 15000+'
;
Run;
But @LinusH idea of input data set seems to be more practical.
B.
look at the issue without code. What is your rule for building the right side from the value on the left side, in plain language?
A crude way to create the CNTLIN dataset would be
data cntlin;
length
fmtname $32
type $1
start $8
end $8
label $40
sexcl $1
eexcl $1
;
fmtname = "F_Ronein";
type = "N";
do i = 1 to 18;
if i = 1
then do;
start = "0";
end = "0";
label = "(1) 0";
sexcl = "N";
eexcl = "N";
end;
else if i = 2
then do;
start = "0";
end = "100";
label = "(2) 0-100";
sexcl = "Y";
excl = "N";
end;
else if i lt 7
then do;
start = put((i - 2) * 100,8.);
end = put((i - 1) * 100,8.);
label = cats("(",i,")") !! " " !! catx("-",start,end);
sexcl = "Y";
eexcl = "N";
end;
else if i = 7
then do;
start = "500";
end = "1000";
label = "(7) 500-1000";
sexlc = "Y";
eexcl = "N";
end;
else if i lt 17
then do;
start = put((i - 7) * 1000,8.);
end = put((i - 6) * 1000,8.);
label = cats("(",i,")") !! " " !! catx("-",start,end);
sexcl = "Y";
eexcl = "N";
end;
else if i = 17
then do;
start = "10000";
end = "15000";
label = cats("(",i,")") !! " " !! catx("-",start,end);
sexcl = "Y";
eexcl = "N";
end;
else /* 18 */ do;
start = "15000";
end = "HIGH";
label = "(18) 15000+";
HLO = "H";
sexcl = "Y";
eexcl = "N";
end;
output;
end;
run;
You can optimize from that.
Probably best to build a control dataset you can pass into PROC FORMAT to make.
What does it need to look like? Why not ask PROC FORMAT to tell you.
proc format;
value F_Ronein
0='(1) 0'
0<-100='(2) 0-100'
100<-200='(3) 100-200'
200<-300='(4) 200-300'
300<-400='(5) 300-400'
400<-500='(6) 400-500'
500<-1000='(7) 500-1000'
1000<-2000='(8) 1000-2000'
2000<-3000='(9) 2000-3000'
3000<-4000='(10) 3000-4000'
4000<-5000='(11) 4000-5000'
5000<-6000='(12) 5000-6000'
6000<-7000='(13) 6000-7000'
7000<-8000='(14) 7000-8000'
8000<-9000='(15) 8000-9000'
9000<-10000='(16) 9000-10000'
10000<-15000='(17) 10000-15000'
15000<-High='(18) 15000+'
;
run;
proc format cntlout=formats; run;
proc print data=formats;
var fmtname hlo sexcl eexcl start end label;
run;
Obs FMTNAME HLO SEXCL EEXCL START END LABEL 1 F_RONEIN N N 0 0 (1) 0 2 F_RONEIN Y N 0 100 (2) 0-100 3 F_RONEIN Y N 100 200 (3) 100-200 4 F_RONEIN Y N 200 300 (4) 200-300 5 F_RONEIN Y N 300 400 (5) 300-400 6 F_RONEIN Y N 400 500 (6) 400-500 7 F_RONEIN Y N 500 1000 (7) 500-1000 8 F_RONEIN Y N 1000 2000 (8) 1000-2000 9 F_RONEIN Y N 2000 3000 (9) 2000-3000 10 F_RONEIN Y N 3000 4000 (10) 3000-4000 11 F_RONEIN Y N 4000 5000 (11) 4000-5000 12 F_RONEIN Y N 5000 6000 (12) 5000-6000 13 F_RONEIN Y N 6000 7000 (13) 6000-7000 14 F_RONEIN Y N 7000 8000 (14) 7000-8000 15 F_RONEIN Y N 8000 9000 (15) 8000-9000 16 F_RONEIN Y N 9000 10000 (16) 9000-10000 17 F_RONEIN Y N 10000 15000 (17) 10000-15000 18 F_RONEIN H Y N 15000 HIGH (18) 15000+
options missing=' ';
data cntl;
retain fmtname 'F_RONEIN' type 'N' sexcl "N";
length s e i 8 label $64;
s=0;
do e = 0, 1e2 to 5e2 by 1e2, 1e3 to 1e4 by 1e3, 15e3,.H;
i + 1;
start = s;
end = e;
select(end);
when(.h) do;
hlo = 'H';
label = catx(' ',cats('(',i,')'),cats(s,'+'));
end;
otherwise do;
hlo = ' ';
label = catx(' ',cats('(',i,')'),catx('-',s,ifn(e=0,.,e)));
end;
end;
output;
s = e;
sexcl = 'Y';
end;
run;
proc print;
run;
proc format cntlin=cntl cntlout=cntlout;
run;
proc print;
run;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.