【问题标题】:R - Error using summary() from speedglm packageR - 使用 speedglm 包中的 summary() 时出错
【发布时间】:2016-01-19 21:30:19
【问题描述】:

我正在使用speedglm 来估计一些数据的逻辑回归模型。我创建了一个可重现的示例,它会产生与使用原始数据时相同的错误。

library(speedglm)
n <- 10000
dtf <- data.frame( y = sample(c(0,1), n, 1),
                  x1 = as.factor(sample(c("a","b"), n, 1)),
                  x2 = rnorm(n, 30, 10))
m <- speedglm(y ~ x1 + x2, dtf, family=binomial())
summary(m)

输出如下:

Generalized Linear Model of class 'speedglm':

Call:  speedglm(formula = y ~ x1 + x2, data = dtf, family = binomial()) 

Coefficients:
 ------------------------------------------------------------------ 
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 3, 0

我通过执行getS3method("summary", "speedglm")检查了summary.speedglm的源代码,找到了产生错误的代码行,但并没有帮助解决问题。

PS:拥有 1500+ 代表的人应该创建 speedglm 标签。

更新

speedglm 的维护者 Marco Enea 要求发布以下针对 summary.speedglmprint.summary.speedglm 的临时修复。

summary.speedglm <- function (object, correlation = FALSE, ...) 
{
  if (!inherits(object, "speedglm")) 
    stop("object is not of class speedglm")
  z <- object
  var_res <- as.numeric(z$RSS/z$df)
  dispersion <- if (z$family$family %in% c("poisson", "binomial")) 1 else var_res
  if (z$method == "qr") {
    z$XTX <- z$XTX[z$ok, z$ok]
  }
  inv <- solve(z$XTX, tol = z$tol.solve)
  covmat <- diag(inv)
  se_coef <- rep(NA, length(z$coefficients))
  se_coef[z$ok] <- sqrt(dispersion * covmat)
  if (z$family$family %in% c("binomial", "poisson")) {
    z1 <- z$coefficients/se_coef
    p <- 2 * pnorm(abs(z1), lower.tail = FALSE)
  } else {
    t1 <- z$coefficients/se_coef
    p <- 2 * pt(abs(t1), df = z$df, lower.tail = FALSE)
  }
  ip <- !is.na(p)
  p[ip] <- as.numeric(format(p[ip], digits = 3))
  dn <- c("Estimate", "Std. Error")
  if (z$family$family %in% c("binomial", "poisson")) {
    format.coef <- if (any(na.omit(abs(z$coef)) < 1e-04)) 
      format(z$coefficients, scientific = TRUE, digits = 4) else 
        round(z$coefficients, digits = 7)
    format.se <- if (any(na.omit(se_coef) < 1e-04)) 
      format(se_coef, scientific = TRUE, digits = 4) else round(se_coef, digits = 7)
    format.pv <- if (any(na.omit(p) < 1e-04)) 
      format(p, scientific = TRUE, digits = 4) else round(p, digits = 4)
    param <- data.frame(format.coef, format.se, round(z1, 
                                                      digits = 4), format.pv)
    dimnames(param) <- list(names(z$coefficients), c(dn, 
                                                     "z value", "Pr(>|z|)"))
  } else {
    format.coef <- if (any(abs(na.omit(z$coefficients)) < 
                             1e-04)) 
      format(z$coefficients, scientific = TRUE, digits = 4) else 
        round(z$coefficients, digits = 7)
    format.se <- if (any(na.omit(se_coef) < 1e-04)) 
      format(se_coef, scientific = TRUE, digits = 4) else 
        round(se_coef, digits = 7)
    format.pv <- if (any(na.omit(p) < 1e-04)) 
      format(p, scientific = TRUE, digits = 4) else round(p, digits = 4)
    param <- data.frame(format.coef, format.se, round(t1, 
                                                      digits = 4), format.pv)
    dimnames(param) <- list(names(z$coefficients), c(dn, 
                                                     "t value", "Pr(>|t|)"))
  }
  eps <- 10 * .Machine$double.eps
  if (z$family$family == "binomial") {
    if (any(z$mu > 1 - eps) || any(z$mu < eps)) 
      warning("fitted probabilities numerically 0 or 1 occurred")
  }
  if (z$family$family == "poisson") {
    if (any(z$mu < eps)) 
      warning("fitted rates numerically 0 occurred")
  }
  keep <- match(c("call", "terms", "family", "deviance", "aic", 
                  "df", "nulldev", "nulldf", "iter", "tol", "n", "convergence", 
                  "ngoodobs", "logLik", "RSS", "rank"), names(object), 
                0)
  ans <- c(object[keep], list(coefficients = param, dispersion = dispersion, 
                              correlation = correlation, cov.unscaled = inv, cov.scaled = inv * 
                                var_res))
  if (correlation) {
    ans$correl <- (inv * var_res)/outer(na.omit(se_coef), 
                                        na.omit(se_coef))
  }
  class(ans) <- "summary.speedglm"
  return(ans)
}

print.summary.speedglm <- function (x, digits = max(3, getOption("digits") - 3), ...) 
{
  cat("Generalized Linear Model of class 'speedglm':\n")
  if (!is.null(x$call)) 
    cat("\nCall: ", deparse(x$call), "\n\n")
  if (length(x$coef)) {
    cat("Coefficients:\n")
    cat(" ------------------------------------------------------------------", 
        "\n")
    sig <- function(z){
      if (!is.na(z)){
        if (z < 0.001) 
          "***"
        else if (z < 0.01) 
          "** "
        else if (z < 0.05) 
          "*  "
        else if (z < 0.1) 
          ".  "
        else "   "
      } else "   "
    }
    options(warn=-1)
    sig.1 <- sapply(as.numeric(as.character(x$coefficients[,4])), 
                    sig)
    options(warn=0)
    est.1 <- cbind(format(x$coefficients, digits = digits), 
                   sig.1)
    colnames(est.1)[ncol(est.1)] <- ""
    print(est.1)
    cat("\n")
    cat("-------------------------------------------------------------------", 
        "\n")
    cat("Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1", 
        "\n")
    cat("\n")
  }
  else cat("No coefficients\n")
  cat("---\n")
  cat("null df: ", x$nulldf, "; null deviance: ", round(x$nulldev, 
                                                        digits = 2), ";\n", "residuals df: ", x$df, "; residuals deviance: ", 
      round(x$deviance, digits = 2), ";\n", "# obs.: ", x$n, 
      "; # non-zero weighted obs.: ", x$ngoodobs, ";\n", "AIC: ", 
      x$aic, "; log Likelihood: ", x$logLik, ";\n", "RSS: ", 
      round(x$RSS, digits = 1), "; dispersion: ", x$dispersion, 
      "; iterations: ", x$iter, ";\n", "rank: ", round(x$rank, 
                                                       digits = 1), "; max tolerance: ", format(x$tol, scientific = TRUE, 
                                                                                                digits = 3), "; convergence: ", x$convergence, ".\n", 
      sep = "")
  invisible(x)
  if (x$correlation) {
    cat("---\n")
    cat("Correlation of Coefficients:\n")
    x$correl[upper.tri(x$correl, diag = TRUE)] <- NA
    print(x$correl[-1, -nrow(x$correl)], na.print = "", digits = 2)
  }
}

根据 42' 的建议,我还要添加以下内容:

environment(summary.speedglm) <- environment(speedglm)
environment(print.summary.speedglm) <- environment(speedglm)

【问题讨论】:

  • 我认为没有足够的问题来证明该标签的合理性,我们不会标记每个包名称。
  • 我已将dt 更改为dtf 以避免冲突,但错误仍然存​​在。你认为这是一个错误吗?

标签: r dataframe summary speedglm


【解决方案1】:

print.summary.speedglm 函数中有一个小错误。如果您更改此行:

sig.1 <- cbind(sapply(as.numeric(as.character(x$coefficients$"Pr(>|t|)")), sig))

到这一行:

 sig.1 <- cbind(sapply(as.numeric(as.character(x$coefficients$"Pr(>|z|)")), sig))

同时运行:

environment(print.summary.speedglm) <- environment(speedglm)

您将不会再看到错误消息。

报告错误的正确方法是联系维护人员(我会给他发一封电子邮件):

maintainer('speedglm')
[1] "Marco Enea <emarco76@libero.it>"

【讨论】:

  • 谢谢,我在看summary.speedglm 而不是print.summary.speedglm。我已经给维护者发了邮件,但如果你也发邮件也没关系:)
  • 我为什么要运行environment(print.summary.speedglm) &lt;- environment(speedglm)
  • 否则,新函数可能不在正确的命名空间中。如果您不这样做,“summary.speedglm”对象可能会被发送到未被替换的speedglm:::print.summary.speedglm 方法。在不同的位置可能有两种不同的功能。 (这是我从 pkg::car 破解绘图函数时学会做的事情。)assignInNamespace 可能更经济,因为它可以一次性完成。
  • 我明白了,谢谢。所以你建议我通过重新声明它并编辑原始源代码来重新定义函数,同时等待维护者发布新版本的库?
  • 对...这就是我所做的,至少在当前的工作会话中是这样。我没有修改包。如果您经常需要它,您可以对包进行库调用,然后修改 .profile 文件中的函数。我想如果你需要一个可靠的修复,你可以在包的源代码中进行编辑并重新编译它。
【解决方案2】:

这似乎是一个错误;在speedglm:::print.summary.speedglm 中有一行:

        sig.1 <- sapply(as.numeric(as.character(x$coefficients$"Pr(>|t|)")), 
        sig)

但是当你看物体时,你可以看到:

              Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.0546397  0.0655713 -0.8333    0.405
x1b         -0.0618225  0.0400126 -1.5451    0.122
x2           0.0020771  0.0019815  1.0483    0.295

它有一个Pr(&gt;|z|) 而不是Pr(&gt;|t|),所以 sig 星号失败。

【讨论】:

  • 尼尔·富尔茨,谢谢您的回答。你在@42- 前 1 分钟发布了它,但他的回答更完整,我应该接受它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 2012-06-12
  • 2017-06-10
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多