DATA Step, Macro, Functions and more

Suppressing ZIPSTATE Note: / Error:

Posts: 28

Suppressing ZIPSTATE Note: / Error:

I've searched online quite a bit and haven't found a solution to this. Is there any way to suppress the following Note/Error when an invalid zipcode is passed to the zipstate function?

NOTE: Invalid argument to function ZIPSTATE at line 109 column 85.
ERROR: Limit set by ERRORS= option reached. Further errors of this type will
not be printed.

I realize it is a valid error, but I'd rather just have the result of the zipstate function return a null with no note/error in the log if the zipcode being passed to it is invalid.

Trusted Advisor
Posts: 2,113

Re: Suppressing ZIPSTATE Note: / Error:

You could always query the data table directly, SASHELP.ZIPCODE, to get the state.

Note that the data is generally a year or two out of date. I just installed SAS 9.2 TS2M2 and the data are still from April 2008. See
Posts: 28

Re: Suppressing ZIPSTATE Note: / Error:

Thanks, Doc. That's sort of the approach I'm going with.

Can anyone confirm that the zipstate function feeds off of SASHELP.ZIPCODE directly? I try to update the ZIPCODE table in HELP from SAS's website ( as soon as they become available. However, I'm seeing some major discrepancies when comparing the results of ZIPSTATE versus SASHELP.ZIPCODE. The online doc states the following:

"The SASHELP.ZIPCODE data set contains postal code information that is used with the ZIPSTATE and other ZIP code functions. This data set is updated with each new release of SAS software."

Is this true for manual updates after a software release as well? I'm seeing 7 state differences between the two sources. Also, if you loop from 0 to 99999 and feed it to zipstate, it assigns a state to 95,760 zipcodes whereas my current sashelp.zipcodes has 42,085.
Posts: 28

Re: Suppressing ZIPSTATE Note: / Error:

Thinking about it some more ZIPSTATE returning more zipcodes with states than SASHELP.ZIPCODE is making sense. I would imagine the latter is only active zips at that size. ZIPSTATE would return a state for any zipcode that's ever been active. Let's say this theory is accurate and explains the difference in zipcode count.

It still doesn't explain differences in state assignment to a zipcode if zipstate is feeding off of sashelp.

/*zipcode sashelp_state zipstate_state*/
/*20588 MD DC*/
/*20598 VA DC*/
/*83414 WY ID*/
/*96595 CA */
/*96598 CA */
/*96599 CA */
/*96939 PW GU*/
Trusted Advisor
Posts: 2,113

Re: Suppressing ZIPSTATE Note: / Error:

The reason that ZIPSTATE returns more codes than are in the table is in the documentation that I referenced:

"To determine which state corresponds to a particular ZIP code, this function uses a zone table that consists of the start and end ZIP code values for each state. It then finds the corresponding state for that range of ZIP codes. The zone table consists of start and end ZIP code values for each state to allow for exceptions, and does not validate ZIP code values."

It also documents why you find differences in location over time.

"With very few exceptions, a zone does not span multiple states. The exceptions are included in the zone table. It is possible for new zones or new exceptions to be added by the U.S. Postal Service at any time. "
Posts: 28

Re: Suppressing ZIPSTATE Note: / Error:

Thanks again. For anyone that's interested, this is what I ended up doing. There are no errors in the log for invalid arguments and it actually runs a little faster than the function straight up. Below is the code I used as a base and then my code.

* Zipcode to State using ZIPSTATE() = zipstate;
data fmts(drop=i);
length start $ 5 end $ 5 fmtname $ 8 label $ 2 type $ 1;
retain fmtname "zipstate" hlo " " type "C";
do i=0 to 99999;
if label > '' then output;
start=' '; hlo = 'O'; label=' '; output;
proc format library = VAULT cntlin=fmts; run;
proc datasets library=work nolist; delete fmts; quit;
Ask a Question
Discussion stats
  • 5 replies
  • 2 in conversation