Discover information about SAS formats... programmatically

6

SAS formats are very useful and can be used in a myriad of creative ways. For example, you can use formats to display decimal values as a fraction. However, SAS supports so many formats that it is difficult to remember details about the format syntax, such as the default field width. I often use the "Formats by Category" page in the SAS documentation to look up the range of valid values of the field width (w) and decimal places (d) that are associated with a format such as PERCENTw.d or DATETIMEw.d. (Recall that the field width specifies the width for the formatted output.)

The documentation provides the minimum, maximum, and default values of the field width, but did you know that you can discover these value programmatically? In SAS 9.4m3 you can call the FMTINFO function, which provide information about SAS formats and informats. The FMTINFO function takes two arguments (the name of a format or informat, and a keyword) and returns a character value. For brevity, I will refer to the first argument as the "format," even though the function also supports informats.

You can use the FMTINFO function to create a personalized "cheat sheet" of the formats/informats that you use most often. The following SAS DATA step uses the FMTINFO function to retrieve information about SAS formats, including a short description, default parameter values, and the minimum and maximum values of the width and decimal parameters. You can modify the DATALINES statement to produce a table for your favorite formats.

Create a "cheat sheet" of your favorite #SAS formats. Click To Tweet
data FormatInfo;
length Name $9. Type $8. Category $4. Desc $40. 
       DefW $5. MinW $5. MaxW $5. DefD $2. MinD $2. MaxD $2.; 
input Name @@;
Category = fmtinfo(Name, "Cat");  /* numeric, character, date, ... */
Type = fmtinfo(Name, "Type");     /* format, informat, or both */
Desc = fmtinfo(Name, "Desc");     /* short description of the format */
DefW = fmtinfo(Name, "DefW");     /* default width if you omit w. Example: BEST. */
MinW = fmtinfo(Name, "MinW");     /* minimum width */
MaxW = fmtinfo(Name, "MaxW");     /* maximum width */
DefD = fmtinfo(Name, "DefD");     /* default decimal digits */
MinD = fmtinfo(Name, "MinD");     /* minimum decimal digits */
MaxD = fmtinfo(Name, "MaxD");     /* maximum decimal digits */
datalines;
ANYDTDTE BEST   
DATETIME DOLLAR 
FRACT    PERCENT
PVALUE   $UPCASE
;
 
proc print data=FormatInfo noobs;
   var Name Type Category Desc;
run;
 
proc print data=FormatInfo noobs;
   var Name DefW MinW MaxW DefD MinD MaxD;
run;
Attributes of SAS formats as output by the FMTINFO function
Field width and decimal places of SAS formats as output by the FMTINFO function

The first table shows the name of a few SAS formats and informats. The TYPE column shows whether the name is a format, an informat, or both. The CATEGORY column shows the general category of data to which the format applies. The DESC column gives a brief description of the format.

The second table shows default, minimum, and maximum values of the field width (w) and the decimal places (d) that are displayed. The columns that display field width information are the most valuable for me. You can see that the default and minimum field widths vary quite a bit among the formats. In contrast, most of the formats in the table display zero decimal places by default. (The exception is the PVALUE. format, which displays numbers between 0 and 1.) If the maximum number of decimal places is zero, it means that the format does not support a decimal value. For example, character formats do not support decimal places.

Other than creating a cheat sheet, I don't think that the casual SAS programmer will need this function very often. It seems most useful for advanced applications such as validating input from a GUI, but maybe I'm wrong. What do you think? Do you anticipate using the FMTINFO function in your work? Leave a comment.

Share

About Author

Rick Wicklin

Distinguished Researcher in Computational Statistics

Rick Wicklin, PhD, is a distinguished researcher in computational statistics at SAS and is a principal developer of SAS/IML software. His areas of expertise include computational statistics, simulation, statistical graphics, and modern methods in statistical data analysis. Rick is author of the books Statistical Programming with SAS/IML Software and Simulating Data with SAS.

6 Comments

  1. Ooohhhhh interesting to learn about FMTINFO function. I like the cheat sheet idea! I wonder if it could be used when writing data dependent code and validating widths of formats. I'm looking forward to see the comments...

  2. Interesting function, somehow overlooked. One of the usages I see is to self-document user-defined formats/informats. But there must be a mechanism of adding CATEGORY and DESCRIPTION when user creates them. I don't know anything like that in PROC FORMAT. For user defined formats, this function returns all the fmtinfo values but Category (UNKN) and Description (NO DESC FOUND). Any idea on how to get this info in? Thank you.

    • Rick Wicklin

      Good question. I assumed that FMTINFO works only on built-in formats, but a quick experiment shows that FMTINFO can get the field width information for user-defined formats.

      I posed your question to Rick Langston who is giving a paper on this topic at SAS Global Forum 2017. He says that CATEGORY and DESC are not currently supported but are being considered for a future release. If you attend his talk at SAS Global Forum, let him know that you want that feature.

    • Interesting sweeping declaration. I use the fmtinfo() function to identify the format category. Neither category nor description is available in dictionary.formats.

  3. Louise Hadden on

    Late to the game - but in fact, you can add information to user defined formats via PROC CATALOG. It is the ONLY way to do this. I'm doing a quick tip on FMTINFO() this year at PharmaSUG!
    Thanks, Rick, for clarifying some of the information of FMTINFO()

Leave A Reply

Back to Top