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.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
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.
Ready to level-up your skills? Choose your own adventure.