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.
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?
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
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?
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.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.