Numeric and Character Type Conversions

SAS has fundamentally two data types: NUMERIC AND CHARACTER. On occasion you may have data stored as one type that you wish to use as the other type. That is, you may have a character string such as “50000” that represents an annual income, and you may wish to calculate \(ln(income)\). Or you may have a numeric value such as 53706 (a US zip code) which is actually a category label. This could be stored more efficiently as a character value since you will not be doing math with it.

In a DATA step, SAS may make the conversion for you (dynamic type conversion), but this will produce notes in the log. Although these notes can largely be ignored, the clutter in the log file can make it difficult to see other notes that are more consequential.

To suppress these type conversion notes, we use the input and put functions to make explicit conversions.

From Character to Numeric

Consider the following data set, where strzip is a character variable.

data example;
    input strzip $;
    datalines;
    53703
    53706
    53712
    53715
    ;
run;
ods select variables;
proc contents data=example;
run;
                          The CONTENTS Procedure

                Alphabetic List of Variables and Attributes
 
                       #    Variable    Type    Len

                       1    strzip      Char      8

Using character data with an arithmetic operator or function will cause a dynamic type conversion

data example;
    set example;
    intzip1 = strzip+0; /*produces notes*/
    run;
1                             The SAS System

NOTE: Character values have been converted to numeric 
      values at the places given by: (Line):(Column).
      4:12   
NOTE: There were 4 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK.EXAMPLE has 4 observations and 2 variables.

We can use the input function (note that this is distinct from the input statement used to read data from text files) to make an explicit conversion, and avoid the notes.

This takes the form

input(source, character_informat.)

In this example $5. is a character informat, reading 5 characters.

data example;
    set example;
    intzip1 = input(strzip, $5.); /*no note*/
    run;
1                             The SAS System

NOTE: There were 4 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK.EXAMPLE has 4 observations and 2 variables.

From Numeric to Character

Now consider this data set, where intzip is a numeric variable.

data example;
    input intzip;
    datalines;
    53703
    53706
    53712
    53715
    00001
    ;
run;
ods select variables;
proc contents data=example;
run;
                          The CONTENTS Procedure

                Alphabetic List of Variables and Attributes
 
                       #    Variable    Type    Len

                       1    intzip      Num       8

If we try to copy these data into a character variable, whose type is defined by the length statement, we again see notes.

data example;
    set example;
    length strzip1 $5;
    strzip1 = intzip; /*produces notes*/
    run;
1                             The SAS System

NOTE: Numeric values have been converted to character 
      values at the places given by: (Line):(Column).
      5:12   
NOTE: There were 5 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK.EXAMPLE has 5 observations and 2 variables.

Here we use a put function (again, distinct from the put statement used to write output to the log).

This takes the form:

put(source, numeric_format.)

Here we will use the “Zw.d” format to reproduce the leading zeros. (There are a huge number of numeric formats to choose from)

data example;
    set example;
    length strzip1 $5;
    strzip1 = put(intzip, z5.0); /*no note*/
    run;
1                             The SAS System

NOTE: There were 5 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK.EXAMPLE has 5 observations and 2 variables.
proc print; run;
                         Obs    intzip    strzip1

                          1      53703     53703 
                          2      53706     53706 
                          3      53712     53712 
                          4      53715     53715 
                          5          1     00001