3

使用big64包时,将一个向量NAs与另一个整数向量相加会产生不准确的结果。根据NA向量是先求和还是最后求和,结果将分别是0正确答案的一个或两倍。

请注意,将NA向量从 integer64 转换为将消除该问题。

然而,当用其他小值代替 y 进行试验时,结果非常奇怪。例如:

40 + 35 = 75    but
35 + 40 = 80

关于发生了什么的任何想法?

例子:

  library(bit64)

  x <- as.integer64(c(20, 20))
  y <- as.integer64(c(NA, NA))

  sum(y, x, na.rm=TRUE)
  # integer64
  # [1] 80   # <~~~ Twice the correct value

  sum(x, y, na.rm=TRUE)
  # integer64
  # [1] 0   # <~~~~ Incorrect 0.  Should be 40. 

  ## Removing the NAs does not help. 
  y <- y[!is.na(y)]

  ## A vector of 0's gives the same issue
  y <- as.integer64(c(0, 0))

  ## Same results
  sum(y, x, na.rm=TRUE)
  # integer64
  # [1] 80

  sum(x, y, na.rm=TRUE)
  # integer64
  # [1] 0

  ## Converting to numeric does away with the issue (but is not a viable workaround, for obvious reasons)
  y <- as.numeric(y)

  sum(y, x, na.rm=TRUE)
  # [1] 1.97626e-322

  sum.integer64(y, x, na.rm=TRUE)
  # integer64
  # [1] 40

  sum(x, y, na.rm=TRUE)
  # integer64
  # [1] 40

y一个值,结果也很格格不入

  y <- as.integer64(c(35, NA, NA))
  sum.integer64(x, if (!all(is.na(y))) removeNA(y), na.rm=TRUE)
  sum.integer64(x, y[[1]], na.rm=TRUE)
  sum.integer64(y[[1]], x, na.rm=TRUE)

  ## No NA's present
  sum.integer64(as.integer64(35), x)
  # integer64
  # [1] 80
  sum.integer64(x, as.integer64(35))
  # integer64
  # [1] 70
4

1 回答 1

2

不是答案,而是探索。希望它可以帮助你。

从包的sum.integer64功能来看bit64

function (..., na.rm = FALSE) 
{
    l <- list(...)
    ret <- double(1)
    if (length(l) == 1) {
        .Call("sum_integer64", l[[1]], na.rm, ret)
        oldClass(ret) <- "integer64"
        ret
    }
    else {
        ret <- sapply(l, function(e) {
            if (is.integer64(e)) {
                .Call("sum_integer64", e, na.rm, ret)
                ret
            }
            else {
                as.integer64(sum(e, na.rm = na.rm))
            }
        })
        oldClass(ret) <- "integer64"
        sum(ret, na.rm = na.rm)
    }
}

这是您的示例:

library(bit64)
x <- as.integer64(c(20, 20))
y <- as.integer64(c(NA, NA))

na.rm <- TRUE
l <- list(y, x)
ret <- double(1)
ret
#[1] 0

# We use the sapply function as in the function:
ret <- sapply(l, function(e) { .Call("sum_integer64", e, na.rm, ret) })
oldClass(ret) <- "integer64"
ret
#integer64
#[1] 40 40      <-- twice the value "40"
sum(ret, na.rm = na.rm)
# integer64
#[1] 80         <-- twice the expected value, as you said

这里我们分解计算,对于每个向量:

ret <- double(1)
ret2 <- NULL
ret2[1] <- .Call("sum_integer64", y, na.rm, ret)
ret2[2] <- .Call("sum_integer64", x, na.rm, ret)
oldClass(ret2) <- "integer64"
ret2
#integer64
#[1] 0  40      <-- only once the value "40", and "0" because of NaNs
sum(ret2, na.rm = na.rm)
#integer64
#[1] 40         <- expected value
于 2015-02-13T08:36:51.430 回答