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

Dear Support,

 

I have a very simple program which used a number to divide group, but the result is unexpected. I cannot find the reason for this. Could you please help me with this? Please see the program below:

data t1;

    input id a b;

    cards;

1 56 50.4

2 25 22.5

3 55 49.4

;

run;

data t2;

    set t1;

    c=((a-b)*100/a);

    group=0;

    if 0<=c=10 then group=1;

    if c>10 then group=0;

run;

For id 1 and 2, c has value of 10, so group should equal to 1, however, group has 0 and 1. 

Any help is appreciated. thanks.

 

Xiumei

1 ACCEPTED SOLUTION

Accepted Solutions
s_lassen
Meteorite | Level 14

You obviously have an error in your program. The statement

    if 0<=c=10 then group=1;

resolves to 

  if 0<=c and c=10;

So I assume that you meant

  if 0<=c<=10 then group=1;

The problem you have, apart from that, is that SAS floating points are base 2, not base 10. This means that a decimal which is not a (negative) power of 2 is not represented exactly. So, for ID = 1 you have 50.4, which is not exactly representable in base 2. And, obviously, while the C value displays as 10, it is not exactly 10. If you subset your output data with "where c=10", you will see that your first observation is not included.

 

You can use ROUND to get around this problem, e.g.:

c=round((a-b)*100/a,0.0001);

View solution in original post

5 REPLIES 5
ballardw
Super User

did you intend

 

 if 0<= c <=10 then group=1;

 

instead of

 if 0<=c=10 then group=1;

in the latter if c is not equal to 10 then the c=10 bit is false and group is not set to 1

yangx
Obsidian | Level 7

Thanks for your reply, but  "if 0<= c <=10 then group=1" is doing the same thing, doesn't work. 

Reeza
Super User

Your IF statment is likely missing a < sign.

 

 

    if 0<=c=10 then group=1;

    if c>10 then group=0;

 

 

Should likely be:

 

 

    if 0 <= c <= 10 then group=1;
    else if c > 10 then group=0; * not needed since it was set already to 0;

You also may want to round the number to avoid issues.

 

This may help:

 

data t1;
    input id a b;
    cards;
1 56 50.4
2 25 22.5
3 55 49.4
;

run;

data t2;

    set t1;

    c=((a-b)*100)/a;
	d = round(c, 0.001);

    group=0;

    if 0 <= c <= 10 then group=1;
    else if c > 10 then group=0; * not needed since it was set already to 0;

	if 0 <= d <= 10 then groupD=1;
    else if d > 10 then groupD=0; * not needed since it was set already to 0;
    format c d 8.3;
run;

@yangx wrote:

Dear Support,

 

I have a very simple program which used a number to divide group, but the result is unexpected. I cannot find the reason for this. Could you please help me with this? Please see the program below:

data t1;

    input id a b;

    cards;

1 56 50.4

2 25 22.5

3 55 49.4

;

run;

data t2;

    set t1;

    c=((a-b)*100/a);

    group=0;

    if 0<=c=10 then group=1;

    if c>10 then group=0;

run;

For id 1 and 2, c has value of 10, so group should equal to 1, however, group has 0 and 1. 

Any help is appreciated. thanks.

 

Xiumei


 

 

s_lassen
Meteorite | Level 14

You obviously have an error in your program. The statement

    if 0<=c=10 then group=1;

resolves to 

  if 0<=c and c=10;

So I assume that you meant

  if 0<=c<=10 then group=1;

The problem you have, apart from that, is that SAS floating points are base 2, not base 10. This means that a decimal which is not a (negative) power of 2 is not represented exactly. So, for ID = 1 you have 50.4, which is not exactly representable in base 2. And, obviously, while the C value displays as 10, it is not exactly 10. If you subset your output data with "where c=10", you will see that your first observation is not included.

 

You can use ROUND to get around this problem, e.g.:

c=round((a-b)*100/a,0.0001);
yangx
Obsidian | Level 7

Thank you for your reply and explanation. I tried to use round function and it works. So based on your explanation, whenever decimal number is produced, we should use round function, otherwise, the result might be unexpected. 

 

yangx

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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
  • 5 replies
  • 651 views
  • 0 likes
  • 4 in conversation