1

我正在尝试处理 R 中的百分比,但我遇到了奇怪的问题。当我将向量的值转换为向量的百分比时sum,经常会发生它们加起来不等于一的情况。

最小的例子:

data <- rnorm(1000)*100
max <- 50
unlist(lapply(0:(1000/max-1), 
     function(i) 
        sum(
            data[(i*max+1):(i*(max+1))]
            /
            sum(data[(i*max+1):(i*(max+1))])
           )
        ))-1 

它应该给出零向量,但是我得到了这个:

[1]  0.000000e+00  0.000000e+00 -1.110223e-16 -1.110223e-16  0.000000e+00 -1.110223e-16  0.000000e+00  0.000000e+00  0.000000e+00
[10]  0.000000e+00  0.000000e+00  2.220446e-16  0.000000e+00 -4.440892e-16  0.000000e+00  0.000000e+00  0.000000e+00  4.440892e-16
[19] -1.110223e-16  0.000000e+00

有什么补救办法吗?

4

2 回答 2

4

他们偏离了一个微不足道的数字。如果您想更改浮点运算中固有的这些微不足道的差异的显示方式,您可以使用 format 函数或其表亲之一,如 sprintf 或 formatC。这实际上是FAQ 7.31 的一个实例。如果您确实需要格式化方面的帮助,您应该描述一个特定的应用程序。如果您想强制查看零,您也可以使用 round()

round( unlist(lapply(0:(1000/max-1), 
 function(i) 
    sum(
        data[(i*max+1):(i*(max+1))]
        /
        sum(data[(i*max+1):(i*(max+1))])
       )
    ))-1  , digits=4)
于 2012-10-24T15:35:18.947 回答
4

一个更重要的问题是为什么你认为这些应该是0

您正在使用浮点运算,并非所有数字都可以在您的计算机中精确表示。这在R FAQ 7.31中涵盖(或相关),它解释了这种现象。

您可以忽略它(出于所有意图和目的,这些值为0

> all.equal(tmp, rep(0, length(tmp))) ## tmp contain your numbers
[1] TRUE

或学习为您的特定操作相应地处理它。一种方法是在某种程度上将它们四舍五入:

> round(tmp, 2)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> round(tmp, 3)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> round(tmp, 4)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> round(tmp, 5)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

但这确实取决于你想用这些数字做什么。

于 2012-10-24T15:38:59.060 回答