BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Walternate
Obsidian | Level 7

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

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?

View solution in original post

3 REPLIES 3
ChrisHemedinger
Community Manager

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

SAS Hackathon registration is open! Build your skills. Make connections. Enjoy creative freedom. Maybe change the world.
Astounding
PROC Star

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
Obsidian | Level 7

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.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 2778 views
  • 3 likes
  • 3 in conversation