Hi Everyone,
I run the below code to get weight schedule.
The problem is that when I want to get (sum of element)=1, SAS do not return row value such as factor1=0, factor2=0 and factor3=1.
I am not sure if it is my SAS issue or else, thus I keep the count in each part so you can can check.
Can you please help to review?
Thanks,
HHC
data have;
do factor1 = 0 to 1 by 0.1;
do factor2 = 0 to 1 by 0.1;
do factor3 = 0 to 1 by 0.1;
output;
end;
end;
end;
run;
/*The data set WORK.HAVE has 1331 observations and 3 variables*/
data weight_schedule; set have;
if factor1 + factor2 + factor3 = 1;
run;
/*The data set WORK.WEIGHT_SCHEDULE has 53 observations*/
/********this return CORRECT count*******/
data CORRECT_COUNT; set have;
if 0.99<factor1 + factor2 + factor3<1.01;
run;
/* The data set WORK.W has 66 observations*/
There is documentation and long discussions around numeric precision and representation of floating point numbers. You'll find them if searching a bit.
What was surprising to me is that there is such a precision issue with values 0, 0 and 1. This must be related to how SAS populates the iteration variable if you've got a BY 0.1.
If there are no further answers that provide more explanation like that this is already widely known then it would be worth to also raise this directly with SAS Tech Support.
For your case: Round your sum to some non-significant decimal before the comparison.
data have;
do factor1 = 0 to 1 by 0.1;
do factor2 = 0 to 1 by 0.1;
do factor3 = 0 to 1 by 0.1;
output;
end;
end;
end;
run;
data test;
set have;
if round(factor1 + factor2 + factor3,.000001) = 1;
precision_diff_flg= round(factor1 + factor2 + factor3,.000001) ne (factor1 + factor2 + factor3);
run;
proc print data=test;
run;
There is documentation and long discussions around numeric precision and representation of floating point numbers. You'll find them if searching a bit.
What was surprising to me is that there is such a precision issue with values 0, 0 and 1. This must be related to how SAS populates the iteration variable if you've got a BY 0.1.
If there are no further answers that provide more explanation like that this is already widely known then it would be worth to also raise this directly with SAS Tech Support.
For your case: Round your sum to some non-significant decimal before the comparison.
data have;
do factor1 = 0 to 1 by 0.1;
do factor2 = 0 to 1 by 0.1;
do factor3 = 0 to 1 by 0.1;
output;
end;
end;
end;
run;
data test;
set have;
if round(factor1 + factor2 + factor3,.000001) = 1;
precision_diff_flg= round(factor1 + factor2 + factor3,.000001) ne (factor1 + factor2 + factor3);
run;
proc print data=test;
run;
Your are getting a numeric precision problem. It's not a software bug. Try this:
if round(sum(factor1, factor2, factor3), 0.1) = 1;
This is a numeric precision problem, not a SAS problem. It will happen with all computing software using floating point arithmetic (which needs to be the case given that 0.1 is the do loop increment.
For instance, the loop
do factor1=0 to 1 by 0.1;
will NOT produce factor1=1, because at least one of the values 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9 can not be exactly represented using floating point arithmetic.
Therefore none of the factor combinations that should have two zeroes and a one will not appear. The same will happen with some of the other combinations.
I suggest you use
do factor=0 to 10 by 1;
The program below will then produce 66 observations:
data have;
do factor1 = 0 to 10 by 1;
do factor2 = 0 to 10 by 1;
do factor3 = 0 to 10 by 1;
output;
end;
end;
end;
run;
/*The data set WORK.HAVE has 1331 observations and 3 variables*/
data weight_schedule; set have;
if factor1 + factor2 + factor3 = 10;
run;
If you want, you can divide the factors, and their sums by 10 AFTER you do the filtering.
Editted addition:
PS: It's more than just the representation of numbers, it's the sequence of adding.
For instance, 0.1+0.1+0.8 (factor1+factor2+factor3) appears in WEIGHT_SCHEDULE, but 0.1+0.8+0.1 and 0.8+0.1+0.1 do not. I.e. 0.1+0.8 (in either order) does not generate the exact representation of 0.9.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.