proc sql 总和加起来不正确
proc sql sum doesn't add up correctly
我有这样的数据:
ID Date1 Date2 Paid Amount
A 1/25/2012 -168.48
A 1/25/2012 -59.44
A 1/25/2012 -13.18
A 1/25/2012 -8.02
A 1/25/2012 8.02
A 1/25/2012 13.18
A 1/25/2012 59.44
A 1/25/2012 168.48
A 12/28/2011 1/25/2012 50.00
A 12/28/2011 1/25/2012 61.00
Proc sql;
Create table SUM as
Select id, date1, date2, sum(paid_amount) as paid_amount
From SUM_0
Group by id, date1, date2;
我得到这样的结果:
ID Date1 Date2 paid_amount
A 1/25/2012 4.547474E-13
A 12/28/2011 1/25/2012 111.00
仅通过目测,很明显空白日期 1 的 paid_amount 总和应该为 0,但 1/25/2012 日期 2 应该为 0。出于某种原因,对于这个和其他类似设置,我得到了各种与 E-13 值相加。
您可能应该在 sum()
.
中添加像 numeric(10, 2)
这样的演员表
sum(cast(paid_amount as decimal(10, 2)))
正如其他人所指出的,这是一个浮点数问题。就像:
2/3 - 1/3 - 1/3 = 0
但是
.6667 - .3333 - .3333 > 0
浮点数本质上是不精确的。
在 SAS
中,您可以通过几种不同的方式处理此问题。最简单的两个:
- 一轮。
round(sum(...),0.01)
会将其四舍五入到最接近的 0.01,如果您愿意,可以四舍五入到最接近的 0.000001;通常 E-12
是您开始发现浮点精度问题的地方,因此任何数量小于 10 左右的零都可以。
- 模糊。
Fuzz(...)
自动将接近整数的数字四舍五入到该整数。它不四舍五入否则,只是接近实数的东西变成一。
例如:
data test;
input ID $ Date1 :mmddyy10. Date2 :mmddyy10. Amount;
datalines;
A . 1/25/2012 -168.48
A . 1/25/2012 -59.44
A . 1/25/2012 -13.18
A . 1/25/2012 -8.02
A . 1/25/2012 8.02
A . 1/25/2012 13.18
A . 1/25/2012 59.44
A . 1/25/2012 168.48
A 12/28/2011 1/25/2012 50.00
A 12/28/2011 1/25/2012 61.00
;;;;
run;
proc sql;
select id, date1, date2, round(sum(amount),.01)
from test
group by 1,2,3;
quit;
我有这样的数据:
ID Date1 Date2 Paid Amount
A 1/25/2012 -168.48
A 1/25/2012 -59.44
A 1/25/2012 -13.18
A 1/25/2012 -8.02
A 1/25/2012 8.02
A 1/25/2012 13.18
A 1/25/2012 59.44
A 1/25/2012 168.48
A 12/28/2011 1/25/2012 50.00
A 12/28/2011 1/25/2012 61.00
Proc sql;
Create table SUM as
Select id, date1, date2, sum(paid_amount) as paid_amount
From SUM_0
Group by id, date1, date2;
我得到这样的结果:
ID Date1 Date2 paid_amount
A 1/25/2012 4.547474E-13
A 12/28/2011 1/25/2012 111.00
仅通过目测,很明显空白日期 1 的 paid_amount 总和应该为 0,但 1/25/2012 日期 2 应该为 0。出于某种原因,对于这个和其他类似设置,我得到了各种与 E-13 值相加。
您可能应该在 sum()
.
numeric(10, 2)
这样的演员表
sum(cast(paid_amount as decimal(10, 2)))
正如其他人所指出的,这是一个浮点数问题。就像:
2/3 - 1/3 - 1/3 = 0
但是
.6667 - .3333 - .3333 > 0
浮点数本质上是不精确的。
在 SAS
中,您可以通过几种不同的方式处理此问题。最简单的两个:
- 一轮。
round(sum(...),0.01)
会将其四舍五入到最接近的 0.01,如果您愿意,可以四舍五入到最接近的 0.000001;通常E-12
是您开始发现浮点精度问题的地方,因此任何数量小于 10 左右的零都可以。 - 模糊。
Fuzz(...)
自动将接近整数的数字四舍五入到该整数。它不四舍五入否则,只是接近实数的东西变成一。
例如:
data test;
input ID $ Date1 :mmddyy10. Date2 :mmddyy10. Amount;
datalines;
A . 1/25/2012 -168.48
A . 1/25/2012 -59.44
A . 1/25/2012 -13.18
A . 1/25/2012 -8.02
A . 1/25/2012 8.02
A . 1/25/2012 13.18
A . 1/25/2012 59.44
A . 1/25/2012 168.48
A 12/28/2011 1/25/2012 50.00
A 12/28/2011 1/25/2012 61.00
;;;;
run;
proc sql;
select id, date1, date2, round(sum(amount),.01)
from test
group by 1,2,3;
quit;