turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- Numeric variable adding extra digits

Topic Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

07-06-2015 02:27 PM

Hi,

I have a dataset with two character variables (composed entirely of numbers). Each person will have a value for Char_var1 or Char_var2, but not both. I created a variable that basically combines the values of Char_var1 and Char_var2, so everyone will have a value for the combined variable. I wanted the combination variable to be numeric so I added a length statement:

data want;

length combined_var 3.;

set have;

if char_var1 ne " " then combined_var=char_var1;

else if char_var1=" " then combined_var=char_var2;

run;

The problem is that in the resulting dataset, the combined_var has added several digits to each value:

Char_var1 Char_var2 Combined_var

1.5 1.51493

6.3 6.32139

7.0 7.01493

I'm not sure where the digits came from--the source data has only one digit after the decimal point for Char_var1 and Char_var2. Any help is much appreciated.

Accepted Solutions

Solution

07-06-2015
03:44 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Walternate

07-06-2015 03:44 PM

The culprit here is the LENGTH statement. SAS stores numerics in a converted format, storing the value (not the digits themselves). Decimal fractions can't be stored exactly, and so should use a length of 8 (not 3) for maximum possible precision.

Even with that in mind, it's surprising that 1.5 and 7.0 can't be stored exactly. Those are values that a length of 3 should be able to store with no trouble. 6.3 is another story. Like trying to store 1/3 in a decimal system, there's no exact equivalent to 6.3 in a binary system. But there are very short binary equivalents to 1.5 and 7.0 in binary (1.1, and 111). Are those real-life examples, or are they typed in just to illustrate the issue?

All Replies

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Walternate

07-06-2015 03:02 PM

Walternate,

Instead of allowing SAS to convert that character value into a number for you, you should probably convert it explicitly with an INPUT function. For example:

combined_var=input(char_var1, 4.1); /* read in to first decimal precision */

More on this topic here:

http://blogs.sas.com/content/sgf/2015/05/01/converting-variable-types-do-i-use-put-or-input/

On the Fringe,

Chris

Solution

07-06-2015
03:44 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Walternate

07-06-2015 03:44 PM

The culprit here is the LENGTH statement. SAS stores numerics in a converted format, storing the value (not the digits themselves). Decimal fractions can't be stored exactly, and so should use a length of 8 (not 3) for maximum possible precision.

Even with that in mind, it's surprising that 1.5 and 7.0 can't be stored exactly. Those are values that a length of 3 should be able to store with no trouble. 6.3 is another story. Like trying to store 1/3 in a decimal system, there's no exact equivalent to 6.3 in a binary system. But there are very short binary equivalents to 1.5 and 7.0 in binary (1.1, and 111). Are those real-life examples, or are they typed in just to illustrate the issue?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Astounding

07-06-2015 03:48 PM

You're right--I invented those examples, and now that I look at it more closely, the values ending in .0 or .5 were actually converted correctly.

Changing my length statement to 8. fixed the issue.