如何在 R 包函数中全局抑制警告

How to suppress warnings globally in a R package function

这是对旧问题的更新,How to suppress warnings globally in an R Script

解决方案就像使用

    warn <- options(warn=-1)
    on.exit(options(warn))

但是现在 CRAN 说 options(warn=-1) 是不允许的,并说要使用 suppressWarnings() 来代替。因此,我的包裹被拒绝了。 但这在全球范围内都行不通。可以做什么?

您可以将整个函数体放在 suppressWarnings() 块中,例如

foo <- function(a,b,c) {
  ret_values <- suppressWarnings({
    ## body of the function goes here
  })
  return(ret_values)
}

这是一个 hack(除其他外,它会使 source-level 调试更难),原来的 options()/on.exit(options(...)) 解决方案更好,但如果 CRAN 不喜欢它,你就会被卡住.

如果您只是想阻止 特定的 函数调用发出警告(根据您上面的评论,在您的情况下是 chol()),那么 suppressWarnings(chol(...)) 应该有效,并且应该比上面建议的 brute-force 解决方案更好(基于 this commit 看起来你已经实现了这个 ...)

如果能够仅捕获特定 警告会更好:例如sqrt(-1)sqrt(10000000000000000000000L) return 不同的警告,人们可能想要捕获“NaNs produced”警告而不是“non-integer value qualified with L”警告。不幸的是,出于 explained on the r-devel mailing list in 2012 的原因(即警告消息可能会被翻译,因此您不能在消息中使用 text-matching),(AFAIK)没有可靠的方法来做到这一点。

在我的用例中,解决方案只是捕获对 chol() 的调用,这将发出警告。

ellipsoid <- function(center, 
                      shape, 
                      radius=1, 
                      segments=60, 
                      warn.rank=FALSE){

    # adapted from the shapes3d demo in the rgl package and from the Rcmdr package
    degvec <- seq(0, 2*pi, length=segments)
    ecoord2 <- function(p) c(cos(p[1])*sin(p[2]), 
                             sin(p[1])*sin(p[2]), 
                             cos(p[2]))
    v <- t(apply(expand.grid(degvec,degvec), 1, ecoord2))
    # if (!warn.rank){
    #   warn <- options(warn=-1)
    #   on.exit(options(warn))
    # }
    if (warn.rank) {
    Q <- chol(shape, pivot=TRUE)
    }
    else {
      Q <- suppressWarnings(chol(shape, pivot=TRUE))
    }
    order <- order(attr(Q, "pivot"))
    v <- center + radius * t(v %*% Q[, order])
    v <- rbind(v, rep(1,ncol(v))) 
    e <- expand.grid(1:(segments-1), 1:segments)
    i1 <- apply(e, 1, function(z) z[1] + segments*(z[2] - 1))
    i2 <- i1 + 1
    i3 <- (i1 + segments - 1) %% segments^2 + 1
    i4 <- (i2 + segments - 1) %% segments^2 + 1
    i <- rbind(i1, i2, i4, i3)
    x <- asEuclidean(t(v))
    ellips <- qmesh3d(v, i)
    return(ellips)
}