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
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);
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
Thanks for your reply, but "if 0<= c <=10 then group=1" is doing the same thing, doesn't work.
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
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);
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
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.