DATA Step, Macro, Functions and more

Help with simple cntlin proc format example

Reply
Regular Contributor
Posts: 169

Help with simple cntlin proc format example

[ Edited ]

Hi,

 

I have a simple cntlin based proc format defined and it is choking when trying to define it.  For the life of me I can't see what it is. 

The data is:

Obs    EEXCL     FUZZ     fmtname    type    start     end        label         hlo

 1       Y       1E-12    binfmt      N       0.50    0.55    50.0% to 54.9%     L
 2       Y       1E-12    binfmt      N       0.55    0.60    55.0% to 59.9%
 3       Y       1E-12    binfmt      N       0.60    0.65    60.0% to 64.9%
 4       Y       1E-12    binfmt      N       0.65    0.70    65.0% to 69.9%
 5       Y       1E-12    binfmt      N       0.70    0.75    70.0% to 74.9%
 6       Y       1E-12    binfmt      N       0.75    0.80    75.0% to 79.9%     H

 

and running this into proc format, the error I get is:

2 proc format cntlin=temp.binfmt;

ERROR: These two ranges overlap: LOW-<0.55 and 0.55-<0.6 (fuzz=1E-12).

ERROR: These two ranges overlap: 0.6-<0.65 and 0.65-<0.7 (fuzz=1E-12).

2 ! run;

 

What have I overlooked? I did set the fuzz to .0001 with no change.

Thanks much!

 

--Ben

Super Contributor
Posts: 251

Re: Help with simple cntlin proc format example

Have you tried it with fuzz=0? (I always use that - any other is problematic)

Super User
Posts: 10,500

Re: Help with simple cntlin proc format example

The error has nothing to do with fuzz, it has to do with defined ranges.

Because you did not set the SEXCL or EEXCL variables, which say to Start exclude (N is default) or End Exclude (N is default) but you want a Y for the end then the end values were included in all of the ranges.

 

Look at the output set Work.cntlout from this code:

proc format library=work cntlout=work.cntlout;
value binfmt
.5 - <.55 = '50% to 54.9%'
.55 - .6  = '55% to 59.6%'
;
run;

 to see. The same thing is happening with the .65 value

 

Regular Contributor
Posts: 169

Re: Help with simple cntlin proc format example

Thanks; I think you will see an EEXCL column in the dataset I pasted above with 'Y' in each observation. ?
Super Contributor
Posts: 251

Re: Help with simple cntlin proc format example

I've just run this code and it worked fine. Is there something else in your original code you may have overlooked?

 

data cntl;
infile cards firstobs=2 dsd dlm=' ';
attrib eexcl type length=$ 1;
attrib fuzz informat=best. format=best.;
attrib fmtname length=$ 8;
attrib start end length=8 format=best.;
attrib label length=$ 30;
attrib hlo length=$ 1;
input eexcl
      fuzz
      fmtname
      type
      start
      end
      label
      hlo;
cards;
EEXCL     FUZZ     fmtname    type    start     end        label         hlo 
Y 1E-12 binfmt N 0.50 0.55 "50.0% to 54.9%" L
Y 1E-12 binfmt N 0.55 0.60 "55.0% to 59.9%"
Y 1E-12 binfmt N 0.60 0.65 "60.0% to 64.9%"
Y 1E-12 binfmt N 0.65 0.70 "65.0% to 69.9%"
Y 1E-12 binfmt N 0.70 0.75 "70.0% to 74.9%"
Y 1E-12 binfmt N 0.75 0.80 "75.0% to 79.9%" H
;
run;

proc format cntlin=cntl;
run;

proc format fmtlib;
select binfmt;
run;
Regular Contributor
Posts: 169

Re: Help with simple cntlin proc format example

Wow.  That's just bizarre.

11 proc print data=temp.binfmt;
12 run;

NOTE: There were 6 observations read from the data set TEMP.BINFMT.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.03 seconds
cpu time 0.01 seconds


13
14 proc format cntlin=temp.binfmt;
ERROR: These two ranges overlap: LOW-<0.55 and 0.55-<0.6 (fuzz=1E-12).
ERROR: These two ranges overlap: 0.6-<0.65 and 0.65-<0.7 (fuzz=1E-12).
14 ! run;

WARNING: RUN statement ignored due to previous errors. Submit QUIT; to terminate the procedure.
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

NOTE: The SAS System stopped processing this step because of errors.
NOTE: There were 6 observations read from the data set TEMP.BINFMT.

 

And the output from the proc print:

The SAS System 13:21 Monday, February 6, 2017 2

Obs EEXCL FUZZ fmtname type start end label hlo

1 Y 1E-12 binfmt N 0.50 0.55 50.0% to 54.9% L
2 Y 1E-12 binfmt N 0.55 0.60 55.0% to 59.9%
3 Y 1E-12 binfmt N 0.60 0.65 60.0% to 64.9%
4 Y 1E-12 binfmt N 0.65 0.70 65.0% to 69.9%
5 Y 1E-12 binfmt N 0.70 0.75 70.0% to 74.9%
6 Y 1E-12 binfmt N 0.75 0.80 75.0% to 79.9% H

 

Am running on 9.4 TS1M3 on a 64 bit server. ?

 

--Ben

 

Super Contributor
Posts: 251

Re: Help with simple cntlin proc format example

Can you try running this:

proc format lib=work;
 value binfmt(fuzz=1E-12 min=1 max=40)
 LOW -< 0.55 = "50.0% to 54.9%"
 0.55 -< 0.6 = "55.0% to 59.9%"
 0.6 -< 0.65 = "60.0% to 64.9%"
 0.65 -< 0.7 = "65.0% to 69.9%"
 0.7 -< 0.75 = "70.0% to 74.9%"
 0.75 -< HIGH = "75.0% to 79.9%"
 ;
 run;

 

I took the format that created it and ran it through my reverse-engineering macro %genfmt. It takes an existing format and creates the code that could have been used to create it.

 

If this doesn't work in your environment, there may be some weird option setting which is overriding your requirements.

Super User
Posts: 10,500

Re: Help with simple cntlin proc format example

Use the instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... to make datastep code of your data set and paste that here in a code box opened with {i} icon. There may be something else happening that is not obvious with the way you are pasting your data.

Regular Contributor
Posts: 169

Re: Help with simple cntlin proc format example

The coworker who was working with this one used the Round() function on the start value to bring it within the fuzz value and that worked. I believe he used the 1e-12 argument for the rounding. So apparently there was some floating point issues with these values on the server we are on.

Thanks much for the assistance!
Ask a Question
Discussion stats
  • 8 replies
  • 249 views
  • 0 likes
  • 3 in conversation