R/extract.R

Defines functions extract.wls extract.weibreg extract.vglm extract.truncreg extract.tobit extract.texreg extract.systemfit extract.svyglm extract.survreg extract.stergm extract.speedglm extract.simex extract.sienaFit extract.selection extract.Sarlm extract.rq extract.rem.dyad extract.polr extract.pmg extract.plm extract.pgmm extract.pglm extract.pcce extract.ols extract.oglmx extract.netlogit extract.mtergm extract.negbinmfx extract.negbinirr extract.multinom extract.model.selection extract.mnlogit extract.mlogit extract.maxLik extract.maBina extract.lrm extract.lqmm extract.logitor extract.logitmfx extract.lnam extract.lmRob extract.lmrob extract.lme4 extract.lme extract.lm.cluster extract.lm extract.H2OBinomialModel extract.gnm extract.gmm extract.gls extract.glmmTMB extract.glmmadmb extract.glm extract.geeglm extract.gee extract.gamlssZadj extract.gamlss extract.gam extract.fixest extract.feglm extract.felm extract.betareg extract.feis extract.fGARCH extract.ergmm extract.ergm extract.coxph.penal extract.coxph extract.coeftest extract.clogit extract.clmm extract.clm extract.censReg extract.btergm extract.biglm extract.broom extract.bife extract.betaor extract.betamfx extract.bergm extract.averaging extract.Arima

Documented in extract.Arima extract.averaging extract.bergm extract.betamfx extract.betaor extract.betareg extract.bife extract.biglm extract.broom extract.btergm extract.censReg extract.clm extract.clmm extract.clogit extract.coeftest extract.coxph extract.coxph.penal extract.ergm extract.ergmm extract.feglm extract.feis extract.felm extract.fGARCH extract.fixest extract.gam extract.gamlss extract.gamlssZadj extract.gee extract.geeglm extract.glm extract.glmmadmb extract.glmmTMB extract.gls extract.gmm extract.gnm extract.H2OBinomialModel extract.lm extract.lm.cluster extract.lme extract.lme4 extract.lmrob extract.lmRob extract.lnam extract.logitmfx extract.logitor extract.lqmm extract.lrm extract.maBina extract.maxLik extract.mlogit extract.mnlogit extract.model.selection extract.mtergm extract.multinom extract.negbinirr extract.negbinmfx extract.netlogit extract.oglmx extract.ols extract.pcce extract.pglm extract.pgmm extract.plm extract.pmg extract.polr extract.rem.dyad extract.rq extract.Sarlm extract.selection extract.sienaFit extract.simex extract.speedglm extract.stergm extract.survreg extract.svyglm extract.systemfit extract.texreg extract.tobit extract.truncreg extract.vglm extract.weibreg extract.wls

# Generic function -------------------------------------------------------------

#' Extract details from statistical models for table construction
#'
#' Extract details from statistical models for table construction. The function
#' has methods for a range of statistical models.
#'
#' The \code{\link{extract}} function serves to retrieve coefficients, standard
#' errors, p-values, confidence intervals, and goodness-of-fit statistics from
#' statistical models in \R. More than 100 \code{\link{extract}} methods
#' ("extensions") for various statistical models are available. The function
#' returns a \linkS4class{texreg} object.
#'
#' \code{\link{extract}} is a generic function, which extracts coefficients and
#' GOF measures from statistical model objects. \code{\link{extract}} methods
#' for the specific model types are called by the generic \code{\link{extract}}
#' function if it encounters a model known to be handled by the specific method.
#' The output is a \linkS4class{texreg} object, which is subsequently used by
#' the \code{\link{texreg}} function and related functions.
#'
#' To list the model classes for which extract methods exist, type
#' \code{showMethods("extract")} or \code{methods("extract")}. To show the
#' method definition (i.e., the function body) of a specific extract method, use
#' the \code{getMethod} function, for example \code{getMethod("extract", "lm")}
#' for linear models. To get help on a specific extract method, type something
#' like \code{?`extract,lm-method`} (or something similar for other models,
#' where \code{"lm"} needs to be replaced by the class name of the respective
#' model). You can also list the available methods by displaying the
#' \link[=texreg-package]{texreg package} help index.
#'
#' Users can contribute their own extensions for additional statistical models.
#' Examples are contained in the article in the Journal of Statistical Software
#' referenced below. Suggestions can be submitted as pull requests at
#' \url{https://github.com/leifeld/texreg/pulls} or through the issue tracker at
#' \url{https://github.com/leifeld/texreg/issues}.
#'
#' @param model A statistical model object.
#' @param ... Custom parameters, which are handed over to subroutines. The
#'   arguments are usually passed to the \code{summary} function, but in some
#'   cases to other functions.
#' @return The function returns a \linkS4class{texreg} object.
#'
#' @author Philip Leifeld
#' @seealso \code{\link{createTexreg}}, \code{\link{matrixreg}},
#'   \code{\link{screenreg}}, \code{\link{texreg}}
#'
#' @references Leifeld, Philip (2013). texreg: Conversion of Statistical Model
#'   Output in R to LaTeX and HTML Tables. Journal of Statistical Software
#'   55(8): 1-24. \doi{10.18637/jss.v055.i08}.
#'
#' @export
setGeneric("extract", function(model, ...) standardGeneric("extract"),
           package = "texreg")


# -- extract.Arima (stats) -----------------------------------------------------

#' @noRd
extract.Arima <- function(model,
                          include.pvalues = TRUE,
                          include.aic = TRUE,
                          include.bic = TRUE,
                          include.loglik = TRUE,
                          include.nobs = TRUE,
                          ...) {

  mask <- model$mask
  nam <- names(model$coef)
  co <- model$coef
  se <- sqrt(diag(model$var.coef))

  if (include.pvalues == TRUE) {
    t.rat <- rep(NA, length(mask))
    t.rat[mask] <- co[mask] / se
    p <- 2 * pnorm(-abs(t.rat))
    setmp <- rep(NA, length(mask))
    setmp[mask] <- se
  } else {
    p <- numeric()
    setmp <- se
  }

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, BIC(model))
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model$loglik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, model$nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = setmp,
    pvalues = p,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{Arima} objects
#'
#' \code{\link{extract}} method for \code{Arima} objects created by the
#' \code{\link[stats]{arima}} function in the \pkg{stats} package.
#'
#' @param model A statistical model object.
#' @param include.pvalues Report p-values?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract Arima
#' @aliases extract.Arima
#' @importFrom stats pnorm BIC
#' @export
setMethod("extract", signature = className("Arima", "stats"),
          definition = extract.Arima)


# -- extract.forecast_ARIMA (forecast) -----------------------------------------

#' @noRd
extract.forecast_ARIMA <- function (model,
                                    include.pvalues = TRUE,
                                    include.aic = TRUE,
                                    include.aicc = TRUE,
                                    include.bic = TRUE,
                                    include.loglik = TRUE,
                                    include.nobs = TRUE,
                                    ...) {
  mask <- model$mask
  nam <- names(model$coef)
  co <- model$coef
  se <- sqrt(diag(model$var.coef))
  if (include.pvalues == TRUE) {
    t.rat <- rep(NA, length(mask))
    t.rat[mask] <- co[mask] / se
    p <- 2 * pnorm(-abs(t.rat))
    setmp <- rep(NA, length(mask))
    setmp[mask] <- se
  } else {
    p <- numeric()
    setmp <- se
  }

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- model$aic
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.aicc == TRUE) {
    gof <- c(gof, model$aicc)
    gof.names <- c(gof.names, "AICc")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, model$bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model$loglik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, model$nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = setmp,
    pvalues = p,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{forecast_ARIMA} objects
#'
#' \code{\link{extract}} method for \code{forecast_ARIMA} objects created by the
#' \code{\link[forecast]{Arima}} function in the \pkg{forecast} package.
#'
#' @param model A statistical model object.
#' @param include.pvalues Report p-values?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.aicc Report AICC in the GOF block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract forecast_ARIMA
#' @aliases extract.forecast_ARIMA
#' @importFrom stats pnorm
#' @export
setMethod("extract",
          signature = className("forecast_ARIMA", "forecast"),
          definition = extract.forecast_ARIMA)


# -- extract.averaging (MuMIn) -------------------------------------------------

#' @noRd
extract.averaging <- function(model, use.ci = FALSE, adjusted.se = FALSE,
                              include.nobs = TRUE, ...) {

  # MuMIn >= 1.15.0 : c("coefmat.subset", "coefmat.full")
  # MuMIn < 1.15.0 : c("coefmat", "coefmat.full")
  ct <- summary(model)$coefmat.full
  coefs <- ct[, 1L]
  se <- ct[, if(adjusted.se) 3L else 2L]

  if (include.nobs == TRUE) {
    gof <- as.numeric(attr(model, "nobs"))
    gof.names <- "Num. obs."
    gof.decimal <- FALSE
  } else {
    gof <- numeric(0L)
    gof.names <- character(0L)
    gof.decimal <- logical(0L)
  }

  if (use.ci == TRUE) {
    ci <- stats::confint(model, full = TRUE)
    tr <- createTexreg(
      coef.names = names(coefs),
      coef = coefs,
      ci.low = ci[, 1L],
      ci.up = ci[, 2L],
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )
  } else {
    tr <- createTexreg(
      coef.names = names(coefs),
      coef = coefs,
      se = se,
      pvalues = ct[, 5L],
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )
  }
  return(tr)
}

#' \code{\link{extract}} method for \code{averaging} objects
#'
#' \code{\link{extract}} method for \code{averaging} objects created by the
#' \code{\link[MuMIn]{model.avg}} function in the \pkg{MuMIn} package.
#'
#' @param model A statistical model object.
#' @param use.ci Report confidence intervals in the GOF block?
#' @param adjusted.se Report adjusted standard error in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract averaging
#' @aliases extract.averaging
#' @importFrom stats confint
#' @export
setMethod("extract", signature = className("averaging", "MuMIn"),
          definition = extract.averaging)


# -- extract.bergm (Bergm) -----------------------------------------------------

#' @noRd
extract.bergm <- function(model, posterior.median = FALSE, level = 0.95, ...) {
  rNames <- paste("theta",
                  seq(1, model$dim),
                  " (",
                  model$specs[seq(1, model$dim)],
                  ")",
                  sep = "") # from Bergm 5.0.5 summary.Bergm method
  coefs <- apply(model$Theta, 2, ifelse(isTRUE(posterior.median), median, mean))
  alpha <- (1 - level) / 2
  cil <- apply(model$Theta, 2, function(x) quantile(x, (1 - level) / 2))
  ciu <- apply(model$Theta, 2, function(x) quantile(x, 1 - ((1 - level) / 2)))

  tr <- createTexreg(
    coef.names = rNames,
    coef = coefs,
    ci.low = cil,
    ci.up = ciu
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{bergm} objects
#'
#' \code{\link{extract}} method for \code{bergm} objects created by the
#' \code{\link[Bergm]{bergm}} function in the \pkg{Bergm} package.
#'
#' @param model A statistical model object.
#' @param posterior.median Report the posterior median instead of the default
#'   posterior mean as coefficients?
#' @param level Confidence level, i.e., the proportion of the posterior
#'   distribution to be included in the credible interval.
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract bergm
#' @aliases extract.bergm
#' @export
setMethod("extract", signature = className("bergm", "Bergm"),
          definition = extract.bergm)


# -- extract.betamfx (mfx) -----------------------------------------------------

#' @noRd
extract.betamfx <- function(model, include.pseudors = TRUE,
                            include.loglik = TRUE, include.nobs = TRUE, ...) {
  coefnames <- rownames(model$mfxest)
  coefs <- model$mfxest[, 1]
  se <- model$mfxest[, 2]
  pval <- model$mfxest[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    gof <- c(gof, model$fit$nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, model$fit$loglik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.pseudors == TRUE) {
    gof <- c(gof, model$fit$pseudo.r.squared)
    gof.names <- c(gof.names, "Pseudo R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefnames,
    coef = coefs,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{betamfx} objects
#'
#' \code{\link{extract}} method for \code{betamfx} objects created by the
#' \code{\link[mfx]{betamfx}} function in the \pkg{mfx} package.
#'
#' @param model A statistical model object.
#' @param include.pseudors Report pseudo R^2 in the GOF block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract betamfx
#' @aliases extract.betamfx
#' @export
setMethod("extract", signature = className("betamfx", "mfx"),
          definition = extract.betamfx)


# -- extract.betaor (mfx) -----------------------------------------------------

#' @noRd
extract.betaor <- function(model, include.pseudors = TRUE,
                           include.loglik = TRUE, include.nobs = TRUE, ...) {
  coefnames <- rownames(model$oddsratio)
  coefs <- model$oddsratio[, 1]
  se <- model$oddsratio[, 2]
  pval <- model$oddsratio[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    gof <- c(gof, model$fit$nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, model$fit$loglik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.pseudors == TRUE) {
    gof <- c(gof, model$fit$pseudo.r.squared)
    gof.names <- c(gof.names, "Pseudo R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefnames,
    coef = coefs,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{betaor} objects
#'
#' \code{\link{extract}} method for \code{betaor} objects created by the
#' \code{\link[mfx]{betaor}} function in the \pkg{mfx} package.
#'
#' @param model A statistical model object.
#' @param include.pseudors Report pseudo R^2 in the GOF block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract betaor
#' @aliases extract.betaor
#' @export
setMethod("extract", signature = className("betaor", "mfx"),
          definition = extract.betaor)


# -- extract.bife (bife) ----------------------------------------------------

#' @noRd
extract.bife <- function(model,
                         include.loglik = TRUE,
                         include.deviance = TRUE,
                         include.nobs = TRUE,
                         ...) {
  s <- summary(model)
  coefficient.names <- rownames(s$cm)
  co <- s$cm[, 1]
  se <- s$cm[, 2]
  pval <- s$cm[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.loglik == TRUE) {
    lik	<- logLik(model)
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    gof <- c(gof, deviance(model))
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- s$nobs["nobs"]
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{bife} objects
#'
#' \code{\link{extract}} method for \code{bife} objects created by the
#' \code{\link[bife]{bife}} function in the \pkg{bife} package.
#'
#' @param model A statistical model object.
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.deviance Report the residual deviance?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract bife
#' @aliases extract.bife
#' @author Philip Leifeld, Christoph Riedl, Claudia Zucca
#' @importFrom stats logLik
#' @export
setMethod("extract", signature = className("bife", "bife"),
          definition = extract.bife)


# -- extract.broom (broom) -----------------------------------------------------

#' @noRd
extract.broom <- function(model, ...) {
  if (!requireNamespace("broom", quietly = TRUE)) {
    stop("texreg does not directly support models of class ",
         class(model)[1],
         ", but it can sometimes use the ``broom`` package to extract model ",
         "information. Call texreg again after installing the ``broom`` ",
         "package to see if this is possible.")
  }
  coefficients <- try(broom::tidy(model)[, c("term",
                                             "estimate",
                                             "std.error",
                                             "p.value")],
                      silent = TRUE)
  gof <- try({
    # extract
    out <- broom::glance(model)[1, ]
    gof.decimal <- sapply(out, function(k) class(k)[1]) # type inference
    gof.decimal <- ifelse(gof.decimal %in% c("integer", "logical"), FALSE, TRUE)
    out <- data.frame("gof.names" = colnames(out),
                      "gof" = as.numeric(out),
                      "gof.decimal" = gof.decimal,
                      stringsAsFactors = FALSE)
    # rename
    gof_dict <- c(
      "adj.r.squared" = "Adj. R$^2$",
      "deviance" = "Deviance",
      "df" = "DF",
      "df.residual" = "DF Resid.",
      "finTol" = "Tolerance",
      "isConv" = "Convergence",
      "logLik" = "Log Likelihood",
      "null.deviance" = "Deviance (Null)",
      "p.value" = "P Value",
      "r.squared" = "R$^2$",
      "sigma" = "Sigma",
      "statistic" = "Statistic"
    )
    gof_dict <- gof_dict[names(gof_dict) %in% out$gof.names]
    idx <- match(names(gof_dict), out$gof.names)
    out$gof.names[idx] <- gof_dict
    if (any(is.na(out$gof))) {
      warning(paste("texreg used the broom package to extract the following GOF",
                    "measures, but could not cast them to numeric type:",
                    out$gof.names[is.na(out$gof)]))
    }
    stats::na.omit(out)
  }, silent = TRUE)
  if ("try-error" %in% class(coefficients) || "try-error" %in% class(gof)) {
    stop("Neither texreg nor broom supports models of class ",
         class(model)[1],
         ".")
  }
  tr <- createTexreg(coef.names = coefficients$term,
                     coef = coefficients$estimate,
                     se = coefficients$std.error,
                     pvalues = coefficients$p.value,
                     gof.names = gof$gof.names,
                     gof = gof$gof,
                     gof.decimal = gof$gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{broom} objects
#'
#' \code{\link{extract}} method for \code{broom} objects created by the
#' \code{\link[broom]{broom}} function in the \pkg{broom} package.
#'
#' @param model A statistical model object.
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract broom
#' @aliases extract.broom extract.ANY extract.ANY-method extract,ANY-method
#' @importFrom stats na.omit
#' @export
setMethod("extract", signature = className("ANY"), definition = extract.broom)


# -- extract.biglm (biglm) -----------------------------------------------------

#' @noRd
extract.biglm <- function(model, include.nobs = TRUE, include.aic = TRUE,
                          use.ci = FALSE, ...) {

  tab <-summary(model)$mat

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    gof <- c(gof, model$n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.aic == TRUE) {
    gof <- c(gof, AIC(model))
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  if (use.ci == TRUE) {
    tr <- createTexreg(
      coef.names = rownames(tab),
      coef = tab[, 1],
      ci.low = tab[, 2],
      ci.up = tab[, 3],
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )

  } else {
    tr <- createTexreg(
      coef.names = rownames(tab),
      coef = tab[, 1],
      se = tab[, 4],
      pvalues = tab[, 5],
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )
  }
  return(tr)
}

#' \code{\link{extract}} method for \code{biglm} objects
#'
#' \code{\link{extract}} method for \code{biglm} objects created by the
#' \code{\link[biglm]{biglm}} function in the \pkg{biglm} package.
#'
#' @param model A statistical model object.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param use.ci Report confidence intervals in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract biglm
#' @aliases extract.biglm
#' @author Claudia Zucca, Philip Leifeld
#' @export
setMethod("extract", signature = className("biglm", "biglm"),
          definition = extract.biglm)


# -- extract.brmsfit (brms) ----------------------------------------------------

#' @noRd
extract.brmsfit <- function (model,
                             use.HDI = TRUE,
                             level = 0.9,
                             include.random = TRUE,
                             include.rsquared = TRUE,
                             include.nobs = TRUE,
                             include.loo.ic = TRUE,
                             reloo = FALSE,
                             include.waic = TRUE,
                             ...) {
  sf <- summary(model, ...)$fixed
  coefnames <- rownames(sf)
  coefs <- sf[, 1]
  se <- sf[, 2]
  if (isTRUE(use.HDI)) {
    hdis <- coda::HPDinterval(brms::as.mcmc(model, combine_chains = TRUE),
                              prob = level)
    hdis <- hdis[seq(1:length(coefnames)), ]
    ci.low = hdis[, "lower"]
    ci.up = hdis[, "upper"]
  } else { # default using 95% posterior quantiles from summary.brmsfit
    ci.low = sf[, 3]
    ci.up = sf[, 4]
  }

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (isTRUE(include.random) & isFALSE(!nrow(model$ranef))) {
    sr <- summary(model, ...)$random
    sd.names <- character()
    sd.values <- numeric()
    for (i in 1:length(sr)) {
      sd <- sr[[i]][, 1]
      sd.names <- c(sd.names, paste0("SD: ", names(sr)[[i]], names(sd)))
      sd.values <- c(sd.values, sd)
    }
    gof <- c(gof, sd.values)
    gof.names <- c(gof.names, sd.names)
    gof.decimal <- c(gof.decimal, rep(TRUE, length(sd.values)))
  }
  if (isTRUE(include.rsquared)) {
    rs <- brms::bayes_R2(model)[1]
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.nobs)) {
    n <- stats::nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (isTRUE(include.loo.ic)) {
    looic <- brms::loo(model, reloo = reloo)$estimates["looic", "Estimate"]
    gof <- c(gof, looic)
    gof.names <- c(gof.names, "loo IC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.waic)) {
    waic <- brms::waic(model)$estimates["waic", "Estimate"]
    gof <- c(gof, waic)
    gof.names <- c(gof.names, "WAIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(coef.names = coefnames,
                     coef = coefs,
                     se = se,
                     ci.low = ci.low,
                     ci.up = ci.up,
                     gof.names = gof.names,
                     gof = gof,
                     gof.decimal = gof.decimal)
  return(tr)
}

#' \code{\link{extract}} method for \code{brmsfit} objects
#'
#' \code{\link{extract}} method for \code{brmsfit} objects created by the
#' \code{\link[brms]{brm}} function in the \pkg{brms} package.
#'
#' @param model A statistical model object.
#' @param use.HDI Report highest posterior density (HPD) intervals (HDI) using
#'   the \code{\link[coda]{HPDinterval}} function in the \pkg{coda} package,
#'   with the probability given in the \code{level} argument, instead of the
#'   default 95 percent posterior quantiles?
#' @param level Significance level (\code{1 - alpha}) for HPDs (in combination
#'   with the \code{use.HDI} argument).
#' @param include.random Include random effects (standard deviations) in the GOF
#'   block of the table?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.loo.ic Report Leave-One-Out Information Criterion?
#' @param reloo Recompute exact cross-validation for problematic observations
#'   for which approximate leave-one-out cross-validation may return incorrect
#'   results? This is done using the \code{\link[brms]{reloo.brmsfit}} function
#'   and may take some time to compute.
#' @param include.waic Report Widely Applicable Information Criterion (WAIC)?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract brmsfit
#' @aliases extract.brmsfit
#' @author Hyunjin (Jin) Song, Philip Leifeld
#' @importFrom stats nobs
#' @export
setMethod("extract",
          signature = className("brmsfit", "brms"),
          definition = extract.brmsfit)


# -- extract.btergm (btergm) ---------------------------------------------------

#' @noRd
extract.btergm <- function(model, level = 0.95, include.nobs = TRUE, ...) {

  tab <- btergm::confint(model, level = level)

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    gof <- c(gof, model@nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = rownames(tab),
    coef = tab[, which(grepl("Estimate", colnames(tab)))],
    ci.low = tab[, which(grepl("2.5", colnames(tab)))],
    ci.up = tab[, which(grepl("97.5", colnames(tab)))],
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )

  return(tr)
}

#' \code{\link{extract}} method for \code{btergm} objects
#'
#' \code{\link{extract}} method for \code{btergm} objects created by the
#' \code{\link[btergm]{btergm}} function in the \pkg{btergm} package.
#'
#' @param model A statistical model object.
#' @param level Significance or confidence level (\code{1 - alpha}) for
#'   computing confidence intervals.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract btergm
#' @aliases extract.btergm
#' @export
setMethod("extract", signature = className("btergm", "btergm"),
          definition = extract.btergm)


# -- extract.censReg (censReg) -------------------------------------------------

#' @noRd
extract.censReg <- function(model, include.aic = TRUE, include.bic = TRUE,
                            include.loglik = TRUE, include.nobs = TRUE, ...) {
  s <- summary(model, ...)

  coefs <- s$estimate[, 1]
  rn <- rownames(s$estimate)
  se <- s$estimate[, 2]
  pval <- s$estimate[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    gof <- c(gof, AIC(model)[1])
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, BIC(model)[1])
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, logLik(model)[1])
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, s$nObs)
    gof.names <- c(gof.names, "Num. obs.", "Left-censored", "Uncensored",
                   "Right-censored")
    gof.decimal <- c(gof.decimal, FALSE, FALSE, FALSE, FALSE)
  }

  tr <- createTexreg(
    coef.names = rn,
    coef = coefs,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{censReg} objects
#'
#' \code{\link{extract}} method for \code{censReg} objects created by the
#' \code{censReg} function in the \pkg{censReg} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract censReg
#' @aliases extract.censReg
#' @export
setMethod("extract", signature = className("censReg", "censReg"),
          definition = extract.censReg)


# -- extract.clm (ordinal) -----------------------------------------------------

#' @noRd
extract.clm <- function(model,
                        include.thresholds = TRUE,
                        include.aic = TRUE,
                        include.bic = TRUE,
                        include.loglik = TRUE,
                        include.nobs = TRUE,
                        ...) {
  s <- summary(model, ...)

  tab <- s$coefficients
  thresh <- tab[rownames(tab) %in% names(s$aliased$alpha), ]
  threshold.names <- rownames(thresh)
  threshold.coef <- thresh[, 1]
  threshold.se <- thresh[, 2]
  threshold.pval <- thresh[, 4]
  beta <- tab[rownames(tab) %in% names(s$aliased$beta), , drop = FALSE]
  beta.names <- rownames(beta)
  beta.coef <- beta[, 1]
  beta.se <- beta[, 2]
  beta.pval <- beta[, 4]
  if (include.thresholds == TRUE) {
    names <- c(beta.names, threshold.names)
    coef <- c(beta.coef, threshold.coef)
    se <- c(beta.se, threshold.se)
    pval <- c(beta.pval, threshold.pval)
  } else {
    names <- beta.names
    coef <- beta.coef
    se <- beta.se
    pval <- beta.pval
  }

  n <- nobs(model)
  lik <- logLik(model)[1]
  aic <- AIC(model)
  bic <- BIC(model)
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = coef,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{clm} objects
#'
#' \code{\link{extract}} method for \code{clm} objects created by the
#' \code{\link[ordinal]{clm}} function in the \pkg{ordinal} package.
#'
#' @param model A statistical model object.
#' @param include.thresholds Report thresholds in the GOF block?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract clm
#' @aliases extract.clm
#' @export
setMethod("extract", signature = className("clm", "ordinal"),
          definition = extract.clm)


# -- extract.clmm (ordinal) ----------------------------------------------------

#' @noRd
extract.clmm <- function(model,
                         include.thresholds = TRUE,
                         include.loglik = TRUE,
                         include.aic = TRUE,
                         include.bic = TRUE,
                         include.nobs = TRUE,
                         include.groups = TRUE,
                         include.variance = TRUE,
                         ...) {
  s <- summary(model, ...)

  tab <- s$coefficients
  thresh <- tab[rownames(tab) %in% names(s$alpha), , drop = FALSE]
  threshold.names <- rownames(thresh)
  threshold.coef <- thresh[, 1]
  threshold.se <- thresh[, 2]
  threshold.pval <- thresh[, 4]
  beta <- tab[rownames(tab) %in% names(s$beta), , drop = FALSE]
  beta.names <- rownames(beta)
  beta.coef <- beta[, 1]
  beta.se <- beta[, 2]
  beta.pval <- beta[, 4]

  if (include.thresholds == TRUE) {
    cfnames <- c(beta.names, threshold.names)
    coef <- c(beta.coef, threshold.coef)
    se <- c(beta.se, threshold.se)
    pval <- c(beta.pval, threshold.pval)
  } else {
    cfnames <- beta.names
    coef <- beta.coef
    se <- beta.se
    pval <- beta.pval
  }

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.loglik == TRUE) {
    lik <- logLik(model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(model)
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE) {
    grp <- s$dims$nlev.gf
    grp.names <- paste0("Groups (", names(grp), ")")
    gof <- c(gof, grp)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grp)))
  }
  if (include.variance == TRUE) {
    var.names <- character()
    var.values <- numeric()
    for (i in 1:length(s$ST)) {
      variances <- diag(s$ST[[i]] %*% t(s$ST[[i]]))
      var.names <- c(var.names, paste0("Variance: ", names(s$ST)[[i]], ": ",
                                       names(variances)))
      var.values <- c(var.values, variances)
    }
    gof <- c(gof, var.values)
    gof.names <- c(gof.names, var.names)
    gof.decimal <- c(gof.decimal, rep(TRUE, length(var.values)))
  }

  tr <- createTexreg(
    coef.names = cfnames,
    coef = coef,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{clmm} objects
#'
#' \code{\link{extract}} method for \code{clmm} objects created by the
#' \code{\link[ordinal]{clmm}} function in the \pkg{ordinal} package.
#'
#' @param model A statistical model object.
#' @param include.thresholds Report thresholds in the GOF block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param include.variance Report group variances?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract clmm
#' @aliases extract.clmm
#' @export
setMethod("extract", signature = className("clmm", "ordinal"),
          definition = extract.clmm)


# -- extract.clogit (survival) -------------------------------------------------

#' @noRd
extract.clogit <- function(model,
                           include.aic = TRUE,
                           include.rsquared = TRUE,
                           include.maxrs = TRUE,
                           include.events = TRUE,
                           include.nobs = TRUE,
                           include.missings = TRUE,
                           ...) {
  s <- summary(model, ...)

  coefficient.names <- rownames(s$coef)
  coefficients <- s$coef[, 1]
  if (is.null(model$naive.var)) {
    standard.errors <- s$coef[, 3]
    significance <- s$coef[, 5]
  } else {
    standard.errors <- s$coef[, 4]
    significance <- s$coef[, 6]
  }

  event <- model$nevent
  n <- model$n
  mis <- length(model$na.action)
  rs <- s$rsq[1]
  maxrs <- s$rsq[2]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- stats::extractAIC(model)[2]
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rsquared == TRUE) {
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.maxrs == TRUE) {
    gof <- c(gof, maxrs)
    gof.names <- c(gof.names, "Max. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.events == TRUE) {
    gof <- c(gof, event)
    gof.names <- c(gof.names, "Num. events")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.missings == TRUE) {
    gof <- c(gof, mis)
    gof.names <- c(gof.names, "Missings")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{clogit} objects
#'
#' \code{\link{extract}} method for \code{clogit} objects created by the
#' \code{\link[survival]{clogit}} function in the \pkg{survival} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.maxrs Report maximal R^2 in the GOF block?
#' @param include.events Report the number of events in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.missings Report number of missing data points in the GOF
#'   block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract clogit
#' @aliases extract.clogit
#' @importFrom stats extractAIC
#' @export
setMethod("extract", signature = className("clogit", "survival"),
          definition = extract.clogit)


# -- extract.coeftest (lmtest) -------------------------------------------------

#' @noRd
extract.coeftest <- function(model, ...) {

  names <- rownames(model)
  co <- model[, 1]
  se <- model[, 2]
  pval <- model[, 4]

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{coeftest} objects
#'
#' \code{\link{extract}} method for \code{coeftest} objects created by the
#' \code{\link[lmtest]{coeftest}} function in the \pkg{lmtest} package.
#'
#' @param model A statistical model object.
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract coeftest
#' @aliases extract.coeftest
#' @export
setMethod("extract", signature = className("coeftest", "lmtest"),
          definition = extract.coeftest)


# -- extract.coxph (survival) -------------------------------------------------

#' @noRd
extract.coxph <- function(model,
                          include.aic = TRUE,
                          include.rsquared = TRUE,
                          include.maxrs = TRUE,
                          include.events = TRUE,
                          include.nobs = TRUE,
                          include.missings = TRUE,
                          include.zph = TRUE,
                          ...) {
  s <- summary(model, ...)

  coefficient.names <- rownames(s$coef)
  coefficients <- s$coef[, 1]
  if (is.null(model$naive.var)) {
    standard.errors <- s$coef[, 3]
    significance <- s$coef[, 5]
  } else {
    standard.errors <- s$coef[, 4]
    significance <- s$coef[, 6]
  }

  event <- model$nevent
  n <- model$n
  mis <- length(model$na.action)
  rs <- s$rsq[1]
  maxrs <- s$rsq[2]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- stats::extractAIC(model)[2]
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rsquared == TRUE) {
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.maxrs == TRUE) {
    gof <- c(gof, maxrs)
    gof.names <- c(gof.names, "Max. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.events == TRUE) {
    gof <- c(gof, event)
    gof.names <- c(gof.names, "Num. events")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.missings == TRUE) {
    gof <- c(gof, mis)
    gof.names <- c(gof.names, "Missings")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.zph == TRUE) {
    zph <- survival::cox.zph(model)$table
    zph <- zph[length(zph[, 1]), length(zph[1, ])]
    gof <- c(gof, zph)
    gof.names <- c(gof.names, "PH test")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{coxph} objects
#'
#' \code{\link{extract}} method for \code{coxph} objects created by the
#' \code{\link[survival]{coxph}} function in the \pkg{survival} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.maxrs Report maximal R^2 in the GOF block?
#' @param include.events Report the number of events in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.missings Report number of missing data points in the GOF
#'   block?
#' @param include.zph Report proportional hazard test in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract coxph
#' @aliases extract.coxph
#' @importFrom stats extractAIC pchisq
#' @export
setMethod("extract", signature = className("coxph", "survival"),
          definition = extract.coxph)


# -- extract.coxph.penal (survival) --------------------------------------------

#' @noRd
extract.coxph.penal <- function(model,
                                include.aic = TRUE,
                                include.rsquared = TRUE,
                                include.maxrs = TRUE,
                                include.events = TRUE,
                                include.nobs = TRUE,
                                include.missings = TRUE,
                                include.zph = TRUE,
                                ...) {

  coefficients <- coef(model, ...)
  coefficient.names <- names(coefficients)
  standard.errors <- sqrt(diag(model$var))
  significance <- 1 - pchisq(model$coefficients^2 / diag(model$var), 1)

  event <- model$nevent
  n <- model$n
  mis <- length(model$na.action)
  logtest <- -2 * (model$loglik[1] - model$loglik[2])
  rs <- 1 - exp( - logtest / model$n)
  maxrs <- 1 - exp((2 * model$loglik[1]) / model$n)

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- stats::extractAIC(model)[2]
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rsquared == TRUE) {
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.maxrs == TRUE) {
    gof <- c(gof, maxrs)
    gof.names <- c(gof.names, "Max. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.events == TRUE) {
    gof <- c(gof, event)
    gof.names <- c(gof.names, "Num. events")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.missings == TRUE) {
    gof <- c(gof, mis)
    gof.names <- c(gof.names, "Missings")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.zph == TRUE) {
    zph <- survival::cox.zph(model)$table
    zph <- zph[length(zph[, 1]), length(zph[1, ])]
    gof <- c(gof, zph)
    gof.names <- c(gof.names, "PH test")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{coxph.penal} objects
#'
#' \code{\link{extract}} method for \code{coxph.penal} objects created by the
#' \code{\link[survival]{coxph}} function in the \pkg{survival} package.
#'
#' @inheritParams extract,coxph-method
#'
#' @method extract coxph.penal
#' @aliases extract.coxph.penal
#' @export
setMethod("extract", signature = className("coxph.penal", "survival"),
          definition = extract.coxph.penal)


# -- extract.ergm (ergm) -------------------------------------------------------

#' @noRd
extract.ergm <- function(model, include.aic = TRUE, include.bic = TRUE,
                         include.loglik = TRUE, ...) {
  s <- summary(model, ...)
  coefs <- coef(s)
  coefficient.names <- rownames(coefs)
  coefficients <- coefs[, 1]
  standard.errors <- coefs[, 2]
  significance <- coefs[, 5]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE && !is.null(s$aic)) {
    aic <- s$aic
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE && !is.null(s$bic)) {
    bic <- s$bic
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE && !is.null(model$mle.lik)) {
    lik <- model$mle.lik[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{ergm} objects
#'
#' \code{\link{extract}} method for \code{ergm} objects created by the
#' \code{\link[ergm]{ergm}} function in the \pkg{ergm} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract ergm
#' @aliases extract.ergm
#' @export
setMethod("extract", signature = className("ergm", "ergm"),
          definition = extract.ergm)


# -- extract.ergmm (latentnet) -------------------------------------------------

#' @noRd
extract.ergmm <- function(model, include.bic = TRUE, ...) {
  s <- summary(model)

  coefficient.names <- rownames(s$pmean$coef.table)
  coefficients <- s$pmean$coef.table[, 1]
  ci.low <- s$pmean$coef.table[, 2]
  ci.up <- s$pmean$coef.table[, 3]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.bic == TRUE) {
    gof <- c(gof, s$bic$overall, s$bic$Y, s$bic$Z)
    gof.names <- c(gof.names, "BIC (Overall)", "BIC (Likelihood)",
                   "BIC (Latent Positions)")
    gof.decimal <- c(gof.decimal, TRUE, TRUE, TRUE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    ci.low = ci.low,
    ci.up = ci.up,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{ergmm} objects
#'
#' \code{\link{extract}} method for \code{ergmm} objects created by the
#' \code{\link[latentnet]{ergmm}} function in the \pkg{latentnet}
#' package.
#'
#' @param model A statistical model object.
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract ergmm
#' @aliases extract.ergmm
#' @export
setMethod("extract", signature = className("ergmm", "latentnet"),
          definition = extract.ergmm)


# -- extract.ets (forecast) ----------------------------------------------------

#' @noRd
extract.ets <- function (model,
                         include.pvalues = FALSE,
                         include.aic = TRUE,
                         include.aicc = TRUE,
                         include.bic = TRUE,
                         include.loglik = TRUE,
                         ...) {
  mask <- model$mask
  nam <- names(model$par)
  co <- model$par
  sdev <- rep(-Inf,length(co))
  name <- model$method
  if (include.pvalues == TRUE) {
    t.rat <- rep(NA, length(mask))
    t.rat[mask] <- co[mask] / sdev
    pt <- 2 * pnorm(-abs(t.rat))
    setmp <- rep(NA, length(mask))
    setmp[mask] <- sdev
  } else {
    pt <- numeric()
    setmp <- sdev
  }
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.aicc == TRUE) {
    gof <- c(gof, model$aicc)
    gof.names <- c(gof.names, "AICc")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, model$bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model$loglik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = setmp,
    pvalues = pt,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal,
    model.name = name
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{ets} objects
#'
#' \code{\link{extract}} method for \code{ets} objects created by the
#' \code{\link[forecast]{ets}} function in the \pkg{forecast} package.
#'
#' @param model A statistical model object.
#' @param include.pvalues Report p-values?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.aicc Report AICC in the GOF block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract ets
#' @aliases extract.ets
#' @export
setMethod("extract",
          signature = className("ets", "forecast"),
          definition = extract.ets)


# -- extract.fGARCH (fGarch) ---------------------------------------------------

#' @noRd
extract.fGARCH <- function(model, include.nobs = TRUE, include.aic = TRUE,
                           include.loglik = TRUE, ...) {
  namesOfPars <- rownames(model@fit$matcoef)
  co <- model@fit$matcoef[, 1]
  se <- model@fit$matcoef[, 2]
  pval <- model@fit$matcoef[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    n <- length(model@data)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.aic == TRUE) {
    aic <- model@fit$ics[1]
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model@fit$value
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = namesOfPars,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof.decimal = gof.decimal,
    gof = gof
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{fGARCH} objects
#'
#' \code{\link{extract}} method for \code{fGARCH} objects created by the
#' \code{\link[fGarch]{garchFit}} function in the \pkg{fGarch} package.
#'
#' @param model A statistical model object.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract fGARCH
#' @aliases extract.fGARCH
#' @export
setMethod("extract", signature = className("fGARCH", "fGarch"),
          definition = extract.fGARCH)


# -- extract.feis (feisr) ------------------------------------------------------

#' @noRd
extract.feis <- function(model,
                         include.rsquared = TRUE,
                         include.adjrs = TRUE,
                         include.nobs = TRUE,
                         include.groups = TRUE,
                         include.rmse = TRUE,
                         ...) {
  s <- summary(model, ...)

  coefficient.names <- rownames(coef(s))
  coefficients <- coef(s)[, 1]
  standard.errors <- coef(s)[, 2]
  significance <- coef(s)[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (isTRUE(include.rsquared)) {
    rs <- s$r.squared[1]
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.adjrs)) {
    adj <- s$r.squared[2]
    gof <- c(gof, adj)
    gof.names <- c(gof.names, "Adj. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.nobs)) {
    n <- length(model$residuals)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (isTRUE(include.groups)) {
    grps <-length(unique(model$id))
    grp.names <- model$call[[match(c("id"), names(model$call))]]
    grp.names <- paste("Num. groups:", grp.names)
    gof <- c(gof, grps)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (isTRUE(include.rmse)) {
    rmse <- sqrt(sum((model$residuals * model$residuals)) / model$df.residual)
    gof <- c(gof, rmse)
    gof.names <- c(gof.names, "RMSE")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- texreg::createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{feis} objects
#'
#' \code{\link{extract}} method for \code{feis} objects created by the
#' \code{\link[feisr]{feis}} function in the \pkg{feisr} package.
#'
#' @param model A statistical model object.
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.adjrs Report adjusted R^2 in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param include.rmse Report the root mean square error (RMSE; = residual
#'   standard deviation) in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract feis
#' @aliases extract.feis
#' @author Tobias Rüttenauer, Philip Leifeld
#' @importFrom stats nobs coef
#' @export
setMethod("extract", signature = className("feis", "feisr"),
          definition = extract.feis)


# -- extract.betareg (betareg) -------------------------------------------------

#' @noRd
extract.betareg <- function(model, include.precision = TRUE,
                            include.pseudors = TRUE, include.loglik = TRUE,
                            include.nobs = TRUE, ...) {

  s <- summary(model, ...)

  coef.block <- s$coefficients$mean
  if (include.precision == TRUE) {
    phi <- s$coefficients$precision
    rownames(phi) <- paste("Precision:", rownames(phi))
    coef.block <- rbind(coef.block, phi)
  }
  names <- rownames(coef.block)
  co <- coef.block[, 1]
  se <- coef.block[, 2]
  pval <- coef.block[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.pseudors == TRUE) {
    pseudors <- model$pseudo.r.squared
    gof <- c(gof, pseudors)
    gof.names <- c(gof.names, "Pseudo R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model$loglik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{betareg} objects
#'
#' \code{\link{extract}} method for \code{betareg} objects created by the
#' \code{\link[betareg]{betareg}} function in the \pkg{betareg} package.
#'
#' @param model A statistical model object.
#' @param include.precision Report precision in the GOF block?
#' @param include.pseudors Report pseudo R^2 in the GOF block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract betareg
#' @aliases extract.betareg
#' @export
setMethod("extract", signature = className("betareg", "betareg"),
          definition = extract.betareg)


# -- extract.felm (lfe) -----------------------------------------------

#' @noRd
extract.felm <- function(model,
                         include.nobs = TRUE,
                         include.rsquared = TRUE,
                         include.adjrs = TRUE,
                         include.fstatistic = FALSE,
                         include.proj.stats = TRUE,
                         include.groups = TRUE,
                         ...) {

  s <- summary(model, ...)
  nam <- rownames(s$coefficients)
  co <- s$coefficients[, 1]
  se <- s$coefficients[, 2]
  pval <- s$coefficients[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    gof <- c(gof, s$N)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.rsquared == TRUE) {
    gof <- c(gof, s$r2)
    gof.decimal <- c(gof.decimal, TRUE)
    if (include.proj.stats == TRUE) {
      gof <- c(gof, s$P.r.squared)
      gof.decimal <- c(gof.decimal, TRUE)
      gof.names <- c(gof.names, "R$^2$ (full model)", "R$^2$ (proj model)")
    } else {
      gof.names <- c(gof.names, "R$^2$")
    }
  }
  if (include.adjrs == TRUE) {
    gof <- c(gof, s$r2adj)
    gof.decimal <- c(gof.decimal, TRUE)
    if (include.proj.stats == TRUE) {
      gof <- c(gof, s$P.adj.r.squared)
      gof.decimal <- c(gof.decimal, TRUE)
      gof.names <- c(gof.names, "Adj. R$^2$ (full model)", "Adj. R$^2$ (proj model)")
    } else {
      gof.names <- c(gof.names, "Adj. R$^2$")
    }
  }
  if (include.fstatistic == TRUE) {
    gof <- c(gof, s$F.fstat[1], s$F.fstat[4])
    gof.decimal <- c(gof.decimal, TRUE, TRUE)
    if (include.proj.stats == TRUE) {
      gof <- c(gof, s$P.fstat[length(s$P.fstat) - 1], s$P.fstat[1])
      gof.decimal <- c(gof.decimal, TRUE, TRUE)
      gof.names <- c(gof.names, "F statistic (full model)",
                     "F (full model): p-value", "F statistic (proj model)",
                     "F (proj model): p-value")
    } else {
      gof.names <- c(gof.names, "F statistic", "F p-value")
    }
  }
  if (include.groups == TRUE && length(s$fe) > 0) {
    grp <- sapply(s$fe, function(x) length(levels(x)))
    grp.names <- paste0("Num. groups: ", names(grp))
    gof <- c(gof, grp)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grp)))
  }

  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{felm} objects
#'
#' \code{\link{extract}} method for \code{felm} objects created by the
#' \code{\link[lfe]{felm}} function in the \pkg{lfe} package.
#'
#' @param model A statistical model object.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.adjrs Report adjusted R^2 in the GOF block?
#' @param include.fstatistic Report the F-statistic in the GOF block?
#' @param include.proj.stats Include statistics for projected model in the GOF block?
#' @param include.groups Report the number of groups?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract felm
#' @aliases extract.felm
#' @author Christoph Riedl, Claudia Zucca, Oliver Reiter, Philip Leifeld
#' @export
setMethod("extract", signature = className("felm", "lfe"),
          definition = extract.felm)


# -- extract.forecast (forecast) -----------------------------------------------

#' @noRd
extract.forecast <- function (model, ...) {
  model <- model$model
  return(extract(model))
}

#' \code{\link{extract}} method for \code{forecast} objects
#'
#' \code{\link{extract}} method for \code{forecast} objects created by the
#' \code{\link[forecast]{forecast}} and \code{\link[forecast:ses]{holt}} functions
#' in the \pkg{forecast} package.
#'
#' @param model A statistical model object.
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract forecast
#' @aliases extract.forecast
#' @export
setMethod("extract", signature = className("forecast", "forecast"),
          definition = extract.forecast)


# -- extract.feglm (alpaca) ----------------------------------------------------

#' @noRd
extract.feglm <- function(model, include.deviance = TRUE, include.nobs = TRUE,
                          include.groups = TRUE, ...) {
  s <- summary(model, ...)
  coefficient.names <- rownames(s$cm)
  co <- s$cm[, 1]
  se <- s$cm[, 2]
  pval <- s$cm[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()

  if (include.deviance == TRUE) {
    dev <- s$deviance
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- s$nobs["nobs"]
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE) {
    grp <- s$lvls.k
    grp.names <- paste0("Num. groups: ", names(grp))
    gof <- c(gof, grp)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grp)))
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{feglm} objects
#'
#' \code{\link{extract}} method for \code{feglm} objects created by the
#' \code{\link[alpaca]{feglm}} function in the \pkg{alpaca} package.
#'
#' @param model A statistical model object.
#' @param include.deviance Report the deviance?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract feglm
#' @aliases extract.feglm
#' @author Christoph Riedl, Oliver Reiter, Philip Leifeld
#' @export
setMethod("extract", signature = className("feglm", "alpaca"),
          definition = extract.feglm)


# -- extract.fixest (fixest) ---------------------------------------------------

#' @noRd
extract.fixest <- function(model,
                           include.nobs = TRUE,       # both
                           include.groups = TRUE,     # both
                           include.rsquared = TRUE,   # OLS only
                           include.adjrs = TRUE,      # OLS only
                           include.proj.stats = TRUE, # OLS only
                           include.deviance = TRUE,   # GLM/MLE only
                           include.loglik = TRUE,     # GLM/MLE only
                           include.pseudors = TRUE,   # GLM/MLE only
                           ...) {
  # coefficient block
  s <- fixest::coeftable(model, ...)
  nam <- rownames(s)
  co <- s[, 1]
  se <- s[, 2]
  pval <- s[, 4]

  # GOF block: shared OLS and GLM/MLE statistics
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (isTRUE(include.nobs)) {
    gof <- c(gof, model$nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (isTRUE(include.groups) && any(model$fixef_sizes > 0)) {
    grp <- model$fixef_sizes
    grp.names <- paste0("Num. groups: ", names(grp))
    gof <- c(gof, grp)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grp)))
  }

  # GOF block: OLS-specific statistics
  if (model$method == "feols" && isTRUE(include.rsquared)) {
    gof <- c(gof, suppressWarnings(fixest::r2(model, "r2")))
    gof.decimal <- c(gof.decimal, TRUE)
    if (isTRUE(include.proj.stats)) {
      tryCatch({ # wrap in tryCatch because it does not work in some versions
        gof <- c(gof, suppressWarnings(fixest::r2(model, "wr2")))
        gof.decimal <- c(gof.decimal, TRUE)
        gof.names <- c(gof.names, "R$^2$ (full model)", "R$^2$ (proj model)")
      }, error = function(cond) {
        gof.names <- c(gof.names, "R$^2$")
      }, warning = function(cond) {
        # do nothing in case of a warning
      })
    } else {
      gof.names <- c(gof.names, "R$^2$")
    }
  }
  if (model$method == "feols" && isTRUE(include.adjrs)) {
    gof <- c(gof, suppressWarnings(fixest::r2(model, "ar2")))
    gof.decimal <- c(gof.decimal, TRUE)
    if (isTRUE(include.proj.stats)) {
      tryCatch({ # wrap in tryCatch because it does not work in some versions
        gof <- c(gof, suppressWarnings(fixest::r2(model, "war2")))
        gof.decimal <- c(gof.decimal, TRUE)
        gof.names <- c(gof.names,
                       "Adj. R$^2$ (full model)",
                       "Adj. R$^2$ (proj model)")
      }, error = function(cond) {
        gof.names <- c(gof.names, "Adj. R$^2$")
      }, warning = function(cond) {
        # do nothing in case of a warning
      })
    } else {
      gof.names <- c(gof.names, "Adj. R$^2$")
    }
  }

  # GOF block: GLM/MLE-specific statistics
  if (model$method != "feols" && isTRUE(include.deviance)) {
    gof <- c(gof, model$deviance)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (model$method != "feols" && isTRUE(include.loglik)) {
    gof <- c(gof, model$loglik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (model$method != "feols" && isTRUE(include.pseudors)) {
    gof <- c(gof, model$pseudo_r2)
    gof.names <- c(gof.names, "Pseudo R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{fixest} objects
#'
#' \code{\link{extract}} method for \code{fixest} objects created by the
#' model fitting functions in the \pkg{fixest} package. The method can deal with
#' OLS (fitted by \code{\link[fixest]{feols}}) and GLM/MLE models (fitted by
#' \code{\link[fixest]{feglm}} and other functions).
#'
#' @param model A statistical model object.
#' @param include.nobs Report the number of observations?
#' @param include.groups Report the number of groups?
#' @param include.rsquared Report R^2? (OLS only)
#' @param include.adjrs Report adjusted R^2? (OLS only)
#' @param include.proj.stats Include statistics for projected model? (OLS only)
#' @param include.deviance Report the deviance? (GLM/MLE only)
#' @param include.loglik Report the log likelihood? (GLM/MLE only)
#' @param include.pseudors Report Pseudo-R^2? (GLM/MLE only)
#' @param ... Custom parameters, which are handed over to the
#'  \code{\link[fixest]{coeftable}} method for the \code{fixest} object.
#'
#' @method extract fixest
#' @aliases extract.fixest
#' @author Christopher Poliquin, Philip Leifeld
#' @export
setMethod("extract", signature = className("fixest", "fixest"),
          definition = extract.fixest)


# -- extract.gam (mgcv) --------------------------------------------------------

#' @noRd
extract.gam <- function(model,
                        include.smooth = TRUE,
                        include.aic = TRUE,
                        include.bic = TRUE,
                        include.loglik = TRUE,
                        include.deviance = TRUE,
                        include.dev.expl = TRUE,
                        include.dispersion = TRUE,
                        include.rsquared = TRUE,
                        include.gcv = TRUE,
                        include.nobs = TRUE,
                        include.nsmooth = TRUE,
                        ...) {

  s <- summary(model, ...)

  coef.block <- s$p.table
  if (include.smooth == TRUE) {
    smooth <- s$s.table
    rownames(smooth) <- paste0("EDF:\ ", rownames(smooth))
    coef.block <- rbind(coef.block, smooth)
  }
  names <- rownames(coef.block)
  co <- coef.block[, 1]
  se <- coef.block[, 2]
  pval <- coef.block[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(model)
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- logLik(model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    dev <- deviance(model)
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.dev.expl == TRUE) {
    dev.expl <- s$dev.expl
    gof <- c(gof, dev.expl)
    gof.names <- c(gof.names, "Deviance explained")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.dispersion == TRUE) {
    dispersion <- s$dispersion
    gof <- c(gof, dispersion)
    gof.names <- c(gof.names, "Dispersion")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rsquared == TRUE) {
    rsq <- s$r.sq
    gof <- c(gof, rsq)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.gcv == TRUE) {
    gcv <- model$gcv.ubre
    gof <- c(gof, gcv)
    gof.names <- c(gof.names, "GCV score")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.nsmooth == TRUE) {
    m <- s$m
    gof <- c(gof, m)
    gof.names <- c(gof.names, "Num. smooth terms")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gam} objects
#'
#' \code{\link{extract}} method for \code{gam} objects created by the
#' \code{\link[mgcv]{gam}} function in the \pkg{mgcv} package.
#'
#' @param model A statistical model object.
#' @param include.smooth Report the smooth terms of a GAM? If they are
#'   reported, the EDF value is reported as the coefficient, and DF is included
#'   in parentheses (not standard errors because a chi-square test is used for
#'   the smooth terms).
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.deviance Report the deviance?
#' @param include.dev.expl Report the deviance explained?
#' @param include.dispersion Report the dispersion parameter?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.gcv Report the GCV score?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.nsmooth Report the number of smooth terms?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract gam
#' @aliases extract.gam
#' @export
setMethod("extract", signature = className("gam", "mgcv"),
          definition = extract.gam)


# -- extract.bam (mgcv) --------------------------------------------------------

#' @noRd
extract.bam <- extract.gam

#' \code{\link{extract}} method for \code{bam} objects
#'
#' \code{\link{extract}} method for \code{bam} objects created by the
#' \code{\link[mgcv]{bam}} function in the \pkg{mgcv} package.
#'
#' @inheritParams extract,gam-method
#'
#' @method extract bam
#' @aliases extract.bam
#' @export
setMethod("extract", signature = className("bam", "mgcv"),
          definition = extract.bam)

# -- extract.gamlss (gamlss) ---------------------------------------------------

#' @noRd
extract.gamlss <- function(model,
                           robust = FALSE,
                           include.nobs = TRUE,
                           include.nagelkerke = TRUE,
                           include.gaic = TRUE,
                           ...) {

  # VCOV extraction; create coefficient block
  covmat <- suppressWarnings(stats::vcov(model, type = "all", robust = robust,
                                         ...))
  cf <- covmat$coef  # coefficients
  namesOfPars <- names(cf)  # names of coefficients
  se <- covmat$se  # standard errors
  tvalue <- cf / se
  pvalue <-  2 * stats::pt(-abs(tvalue), model$df.res)  # p-values

  #add the parameter names to coefficients
  possiblePars <- c("$\\mu$", "$\\sigma$", "$\\nu$", "$\\tau$")
  parIndex <- 0
  parVector <- character()
  for (i in 1:length(namesOfPars)) {
    if (namesOfPars[i] == "(Intercept)") {
      parIndex <- parIndex + 1
    }
    parName <- possiblePars[parIndex]
    parVector <- c(parVector, parName)
  }
  namesOfPars <- paste(parVector, namesOfPars)

  # GOF block
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    n <- stats::nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.nagelkerke == TRUE) {
    nk <- gamlss::Rsq(model)
    gof <- c(gof, nk)
    gof.names <- c(gof.names, "Nagelkerke R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.gaic == TRUE) {
    gaic <- gamlss::GAIC(model)
    gof <- c(gof, gaic)
    gof.names <- c(gof.names, "Generalized AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  # create and return texreg object
  tr <- createTexreg(
    coef.names = namesOfPars,
    coef = cf,
    se = se,
    pvalues = pvalue,
    gof.names = gof.names,
    gof.decimal = gof.decimal,
    gof = gof
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gamlss} objects
#'
#' \code{\link{extract}} method for \code{gamlss} objects created by the
#' \code{\link[gamlss]{gamlss}} function in the \pkg{gamlss} package.
#'
#' @param model A statistical model object.
#' @param robust If TRUE computes robust standard errors in the
#'   variance-covariance matrix.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.nagelkerke Report Nagelkerke R^2 in the GOF block?
#' @param include.gaic Report Generalized Akaike's Information Criterion (AIC)
#'   in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{vcov} method for the object.
#'
#' @method extract gamlss
#' @aliases extract.gamlss
#' @importFrom stats nobs pt vcov
#' @export
setMethod("extract", signature = className("gamlss", "gamlss"),
          definition = extract.gamlss)


# -- extract.gamlssZadj (gamlss.inf) -------------------------------------------

#' @noRd
extract.gamlssZadj <- function(model,
                               type = c("qr", "vcov"),
                               include.nobs = TRUE,
                               include.gaic = TRUE,
                               ...) {

  type <- match.arg(type)
  # VCOV extraction; create coefficient block
  if (type == "vcov") {
    covmat <- suppressWarnings(stats::vcov(model, type = "all", ...))
    cf <- covmat$coef  # coefficients
    namesOfPars <- names(cf)  # names of coefficients
    se <- covmat$se  # standard errors
  }
  if (type == "qr") {
    invisible(utils::capture.output(covmat <- summary(model, type = "qr")))
    cf <- covmat[, 1]
    namesOfPars <- row.names(covmat)
    se <- covmat[, 2]
  }
  tvalue <- cf / se
  pvalue <-  2 * pt(-abs(tvalue), model$df.res)  # p-values
  # add the parameter names to coefficients
  possiblePars <- c("$\\mu$", "$\\sigma$", "$\\nu$", "$\\tau$",
                    "$\\mu$ (Zero model)")
  parIndex <- 0
  parVector <- character()
  for (i in 1:length(namesOfPars)) {
    if (namesOfPars[i] == "(Intercept)") {
      parIndex <- parIndex + 1
    }
    parName <- possiblePars[parIndex]
    parVector <- c(parVector, parName)
  }
  namesOfPars <- paste(parVector, namesOfPars)

  # GOF block
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.gaic == TRUE) {
    gaic <- gamlss::GAIC(model)
    gof <- c(gof, gaic)
    gof.names <- c(gof.names, "Generalized AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  # create and return texreg object
  tr <- createTexreg(
    coef.names = namesOfPars,
    coef = cf,
    se = se,
    pvalues = pvalue,
    gof.names = gof.names,
    gof.decimal = gof.decimal,
    gof = gof
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gamlssZadj} objects
#'
#' \code{\link{extract}} method for \code{gamlssZadj} objects created by the
#' \code{\link[gamlss.inf]{gamlssZadj}} function in the \pkg{gamlss.inf}
#' package.
#'
#' @param model A statistical model object.
#' @param type The type.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.gaic Report Generalized Akaike's Information Criterion (AIC)
#'   in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{vcov} method for the object.
#'
#' @method extract gamlssZadj
#' @aliases extract.gamlssZadj
#' @author Ricardo Graiff Garcia, Philip Leifeld
#' @importFrom stats nobs pt vcov
#' @export
setMethod("extract", signature = className("gamlssZadj", "gamlss.inf"),
          definition = extract.gamlssZadj)


# -- extract.gee (gee) ---------------------------------------------------------

#' @noRd
extract.gee <- function(model,
                        robust = TRUE,
                        include.scale = TRUE,
                        include.nobs = TRUE,
                        ...) {
  s <- summary(model, ...)

  names <- rownames(coef(s))
  co <- coef(s)[,1]
  if (robust == TRUE) {
    se <- coef(s)[, 4]
    zval <- coef(s)[, 5]
  } else {
    se <- coef(s)[, 2]
    zval <- coef(s)[, 3]
  }
  pval <- 2 * stats::pnorm(abs(zval), lower.tail = FALSE)

  n <- stats::nobs(model)
  disp <- s$scale

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.scale == TRUE) {
    gof <- c(gof, disp)
    gof.names <- c(gof.names, "Scale")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gee} objects
#'
#' \code{\link{extract}} method for \code{gee} objects created by the
#' \code{\link[gee]{gee}} function in the \pkg{gee} package.
#'
#' @param model A statistical model object.
#' @param robust If TRUE computes robust standard errors in the
#'   variance-covariance matrix.
#' @param include.scale Report the dispersion or scale parameter?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract gee
#' @aliases extract.gee
#' @importFrom stats pnorm
#' @export
setMethod("extract", signature = className("gee", "gee"),
          definition = extract.gee)


# -- extract.gel (gmm) ---------------------------------------------------------

#' @noRd
extract.gel <- function (model,
                         include.obj.fcn = TRUE,
                         include.overidentification = FALSE,
                         include.nobs = TRUE,
                         overIdentTest = c("LR", "LM", "J "),
                         ...) {

  overIdentTest <- match.arg(overIdentTest)
  s <- summary(model, ...)
  coefs <- s$coefficients
  names <- rownames(coefs)
  coef <- coefs[, 1]
  se <- coefs[, 2]
  pval <- coefs[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.obj.fcn == TRUE) {
    obj.fcn <- model$objective * 10^5
    gof <- c(gof, obj.fcn)
    gof.names <- c(gof.names, "Criterion function")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.overidentification == TRUE) {
    w <- which(strtrim(rownames(s$stest$test), 2) == overIdentTest)
    jtest <- s$stest$test[w, ]
    gof <- c(gof, jtest)
    ntest <- rownames(s$stest$test)[w]
    gof.names <- c(gof.names, c(ntest, paste0(ntest, " p-value")))
    gof.decimal <- c(gof.decimal, TRUE, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- NROW(model$gt)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = coef,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gel} objects
#'
#' \code{\link{extract}} method for \code{gel} objects created by the
#' \code{\link[gmm]{gel}} function in the \pkg{gmm} package.
#'
#' @param model A statistical model object.
#' @param include.obj.fcn Report the value of the objective function
#'   (= criterion function)? More precisely, this returns
#'   \code{E(g)var(g)^{-1}E(g)}.
#' @param include.overidentification Report the J-test for overidentification?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param overIdentTest Which test statistics should be included in an
#'   overidentification test?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract gel
#' @aliases extract.gel
#' @export
setMethod("extract", signature = className("gel", "gmm"),
          definition = extract.gel)


# -- extract.geeglm (geepack) --------------------------------------------------

#' @noRd
extract.geeglm <- function(model,
                           include.scale = TRUE,
                           include.correlation = TRUE,
                           include.nobs = TRUE,
                           ...) {
  s <- summary(model)
  names <- rownames(s$coef)
  co <- s$coef[, 1]
  se <- s$coef[, 2]
  pval <- s$coef[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()

  if (include.scale == TRUE) {
    gof = c(gof, s$geese$scale$estimate, s$geese$scale$san.se)
    gof.names = c(gof.names, "Scale parameter: gamma", "Scale parameter: SE")
    gof.decimal = c(gof.decimal, TRUE, TRUE)
  }
  if (include.correlation == TRUE) {
    gof = c(gof, s$geese$correlation$estimate, s$geese$correlation$san.se)
    gof.names = c(gof.names, "Correlation parameter: alpha",
                  "Correlation parameter: SE")
    gof.decimal = c(gof.decimal, TRUE, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nrow(model.frame(model))
    nclust <- length(s$geese$clusz)
    gof = c(gof, n, nclust)
    gof.names = c(gof.names, "Num. obs.", "Num. clust.")
    gof.decimal = c(gof.decimal, FALSE, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{geeglm} objects
#'
#' \code{\link{extract}} method for \code{geeglm} objects created by the
#' \code{geeglm} function in the \pkg{geepack} package.
#'
#' @param model A statistical model object.
#' @param include.scale Report the dispersion or scale parameter?
#' @param include.correlation Report the correlation parameter alpha and its
#'   standard error?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract geeglm
#' @aliases extract.geeglm
#' @export
setMethod("extract", signature = className("geeglm", "geepack"),
          definition = extract.geeglm)


# -- extract.glm (stats) -------------------------------------------------------

#' @noRd
extract.glm <- function(model, include.aic = TRUE, include.bic = TRUE,
                        include.loglik = TRUE, include.deviance = TRUE,
                        include.nobs = TRUE, ...) {
  s <- summary(model, ...)

  coefficient.names <- rownames(s$coef)
  coefficients <- s$coef[, 1]
  standard.errors <- s$coef[, 2]
  significance <- s$coef[, 4]

  aic <- AIC(model)
  bic <- BIC(model)
  lik <- logLik(model)[1]
  dev <- deviance(model)
  n <- nobs(model)

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{glm} objects
#'
#' \code{\link{extract}} method for \code{glm} objects created by the
#' \code{\link[stats]{glm}} function in the \pkg{stats} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.deviance Report the deviance?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract glm
#' @aliases extract.glm
#' @importFrom stats nobs AIC BIC logLik deviance
#' @export
setMethod("extract", signature = className("glm", "stats"),
          definition = extract.glm)


# -- extract.brglm (brglm) -----------------------------------------------------

#' @noRd
extract.brglm <- extract.glm

#' \code{\link{extract}} method for \code{brglm} objects
#'
#' \code{\link{extract}} method for \code{brglm} objects created by the
#' \code{\link[brglm]{brglm}} function in the \pkg{brglm} package.
#'
#' @inheritParams extract,glm-method
#'
#' @method extract brglm
#' @aliases extract.brglm
#' @importFrom stats pnorm
#' @export
setMethod("extract", signature = className("brglm", "brglm"),
          definition = extract.glm)


# -- extract.glm.cluster (miceadds) --------------------------------------------

#' @noRd
extract.glm.cluster <- function (model,
                                 include.aic = TRUE,
                                 include.bic = TRUE,
                                 include.loglik = TRUE,
                                 include.deviance = TRUE,
                                 include.nobs = TRUE,
                                 ...) {
  glm_model <- model$glm_res
  coefficient.names <- names(glm_model$coefficients)
  coefficients <- glm_model$coefficients
  standard.errors <- sqrt(diag(model$vcov))
  significance <- 2 * pnorm(-abs(coefficients / standard.errors))

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(glm_model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(glm_model)
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- logLik(glm_model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    dev <- deviance(glm_model)
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(glm_model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  tr <- createTexreg(coef.names = coefficient.names,
                     coef = coefficients,
                     se = standard.errors,
                     pvalues = significance,
                     gof.names = gof.names,
                     gof = gof,
                     gof.decimal = gof.decimal)
  return(tr)
}

#' \code{\link{extract}} method for \code{glm.cluster} objects
#'
#' \code{\link{extract}} method for \code{glm.cluster} objects created by the
#' \code{\link[miceadds:lm.cluster]{glm.cluster}} function in the \pkg{miceadds} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.deviance Report the deviance?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract glm.cluster
#' @aliases extract.glm.cluster
#' @author Alexander Staudt, Philip Leifeld
#' @importFrom stats nobs AIC BIC logLik deviance
#' @export
setMethod("extract", signature = className("glm.cluster", "miceadds"),
          definition = extract.glm.cluster)


# -- extract.glmmadb (glmmADB) -------------------------------------------------

#' @noRd
extract.glmmadmb <- function(model,
                             include.variance = TRUE,
                             include.dispersion = TRUE,
                             include.zero = TRUE,
                             include.aic = TRUE,
                             include.bic = TRUE,
                             include.loglik = TRUE,
                             include.nobs = TRUE,
                             include.groups = TRUE,
                             ...) {

  cf <- model$b
  nam <- names(cf)
  se <- model$stdbeta
  tval <- cf / se
  pval <- 2 * pnorm(-abs(tval))

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.variance == TRUE && !is.null(model$S)) {
    vc <- nlme::VarCorr(model)
    vari <- unlist(vc)
    for (i in 1:length(vari)) {
      gof <- c(gof, vari[i])
      gof.names <- c(gof.names, paste("Variance:", names(vari)[i]))
      gof.decimal <- c(gof.decimal, TRUE)
    }
  }
  if (include.dispersion == TRUE && !is.null(model$alpha)) {
    label <- switch(model$family,
                    truncnbinom = "Dispersion",
                    nbinom = "Dispersion",
                    gamma = "Shape",
                    beta = "Dispersion",
                    betabinom = "Dispersion",
                    gaussian = "Residual variance",
                    logistic = "Scale",
                    "Dispersion"
    )
    dsp.lab <- paste0(label, ": parameter")
    sd.lab <- paste0(label, ": SD")
    disp <- model$alpha
    sd <- model$sd_alpha
    gof <- c(gof, disp, sd)
    gof.names <- c(gof.names, dsp.lab, sd.lab)
    gof.decimal <- c(gof.decimal, TRUE, TRUE)
  }
  if (include.zero == TRUE && !is.null(model$pz)) {
    zero <- model$pz
    zero.sd <- model$sd_pz
    gof <- c(gof, zero, zero.sd)
    gof.names <- c(gof.names, "Zero inflation: parameter", "Zero inflation: SD")
    gof.decimal <- c(gof.decimal, TRUE, TRUE)
  }
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(model)
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- model$loglik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE && !is.null(model$q)) {
    groups <- model$q
    for (i in 1:length(groups)) {
      gof <- c(gof, groups[i])
      gof.names <- c(gof.names, paste("Num. groups:", names(groups)[i]))
      gof.decimal <- c(gof.decimal, FALSE)
    }
  }

  tr <- createTexreg(
    coef.names = nam,
    coef = cf,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{glmmadmb} objects
#'
#' \code{\link{extract}} method for \code{glmmadmb} objects created by the
#' \code{glmmadmb} function in the \pkg{glmmADMB} package.
#'
#' @param model A statistical model object.
#' @param include.variance Report group variances?
#' @param include.dispersion Report the dispersion parameter?
#' @param include.zero Should the binary part of a zero-inflated regression
#'   model or hurdle model be included in the coefficients block (after the
#'   count model)?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract glmmadmb
#' @aliases extract.glmmadmb
#' @importFrom stats pnorm
#' @export
setMethod("extract", signature = className("glmmadmb", "glmmADMB"),
          definition = extract.glmmadmb)



# -- extract.glmmTMB (glmmTMB) -------------------------------------------------

#' @noRd
extract.glmmTMB <- function(model, beside = FALSE, include.count = TRUE,
                            include.zero = TRUE, include.aic = TRUE,
                            include.groups = TRUE, include.variance = TRUE,
                            include.loglik = TRUE, include.nobs = TRUE, ...) {
  s <- summary(model, ...)
  if (model$modelInfo$allForm$ziformula == '~0') {
    include.zero <- FALSE
  }
  if (length(model$modelInfo$reTrms$cond$flist) == 0) {
    include.groups <- FALSE
  }
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- logLik(model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE) {
    grps <- sapply(model$modelInfo$reTrms$cond$flist,
                   function(x) length(levels(x)))
    grp.names <- names(grps)
    grp.names <- paste("Num. groups:", grp.names)
    gof <- c(gof, grps)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grps)))
  }
  if (include.variance == TRUE && !is.na(s$ngrps[1]) && (length(s$ngrps$cond) > 0 || length(s$ngrps$zi) > 0)) {
    vc <- glmmTMB::VarCorr(model)
    vc <- as.data.frame(rapply(vc, function(x) attr(x, "stddev")))^2
    rownames(vc) <- gsub("\\.", " ", rownames(vc))
    if (include.zero == TRUE) {
      for (i in grep("cond", rownames(vc), value = TRUE)) {
        gof.names <- c(gof.names,
                       paste("Var (count model):", sub("cond ", "", i)))
      }
      for (i in grep("zi", rownames(vc), value = TRUE)) {
        gof.names <- c(gof.names, paste("Var (zero model):", sub("zi ", "", i)))
      }
    } else {
      for (i in grep("cond", rownames(vc), value = TRUE)) {
        gof.names <- c(gof.names, paste("Var:", sub("cond ", "", i)))
      }
    }
    gof <- c(gof, vc[, 1])
    gof.decimal <- c(gof.decimal, rep(TRUE, nrow(vc)))
  }
  count <- coef(s)$cond
  zero <- coef(s)$zi
  if (beside == FALSE) {
    if (include.count == TRUE && include.zero == TRUE) {
      rownames(count) <- paste("Count model:", rownames(count))
      rownames(zero) <- paste("Zero model:", rownames(zero))
      coef.block <- rbind(count, zero)
    } else if (include.count == TRUE) {
      coef.block <- count
    } else if (include.zero == TRUE) {
      coef.block <- zero
    } else {
      stop(paste("Either the 'include.count' or the 'include.zero' argument",
                 "must be TRUE."))
    }
    names <- rownames(coef.block)
    co <- coef.block[, 1]
    se <- coef.block[, 2]
    pval <- coef.block[, 4]
    tr <- createTexreg(coef.names = names,
                       coef = co, se = se,
                       pvalues = pval,
                       gof.names = gof.names,
                       gof = gof,
                       gof.decimal = gof.decimal)
    return(tr)
  } else {
    trList <- list()
    c.names <- rownames(count)
    c.co <- count[, 1]
    c.se <- count[, 2]
    c.pval <- count[, 4]
    z.names <- rownames(zero)
    z.co <- zero[, 1]
    z.se <- zero[, 2]
    z.pval <- zero[, 4]
    if (include.count == TRUE) {
      tr <- createTexreg(coef.names = c.names,
                         coef = c.co,
                         se = c.se,
                         pvalues = c.pval,
                         gof.names = gof.names,
                         gof = gof,
                         gof.decimal = gof.decimal,
                         model.name = "Count model")
      trList[[length(trList) + 1]] <- tr
    }
    if (include.zero == TRUE) {
      tr <- createTexreg(coef.names = z.names,
                         coef = z.co,
                         se = z.se,
                         pvalues = z.pval,
                         gof.names = gof.names,
                         gof = gof,
                         gof.decimal = gof.decimal,
                         model.name = "Zero model")
      trList[[length(trList) + 1]] <- tr
    }
    if (length(trList) == 0) {
      stop(paste("Either the 'include.count' or the 'include.zero' argument",
                 "must be TRUE."))
    }
    return(trList)
  }
}

#' \code{\link{extract}} method for \code{glmmTMB} objects
#'
#' \code{\link{extract}} method for \code{glmmTMB} objects created by the
#' \code{\link[glmmTMB]{glmmTMB}} function in the \pkg{glmmTMB} package.
#'
#' @param model A statistical model object.
#' @param beside Arrange the model terms below each other or beside each other?
#'   The binary model parameters and the count parameters can be displayed in
#'   two separate columns of the table.
#' @param include.count Report the count parameters in the coefficients block
#'   (before the binary part for the zeros)?
#' @param include.zero Should the binary part of the model be included in the
#'   coefficients block (after the count parameters)?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.groups Report the number of groups?
#' @param include.variance Report group variances?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract glmmTMB
#' @aliases extract.glmmTMB
#' @author Ricardo Graiff Garcia, Philip Leifeld
#' @importFrom stats AIC logLik nobs
#' @export
setMethod("extract", signature = className("glmmTMB", "glmmTMB"),
          definition = extract.glmmTMB)


# -- extract.gls (nlme) --------------------------------------------------------

#' @noRd
extract.gls <- function(model, include.aic = TRUE, include.bic = TRUE,
                        include.loglik = TRUE, include.nobs = TRUE, ...) {
  s <- summary(model, ...)

  coefficient.names <- rownames(s$tTable)
  coefficients <- s$tTable[, 1]
  standard.errors <- s$tTable[, 2]
  significance <- s$tTable[, 4]

  lik <- s$logLik
  aic <- s$AIC
  bic <- s$BIC
  n <- nobs(model)

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gls} objects
#'
#' \code{\link{extract}} method for \code{gls} objects created by the
#' \code{\link[nlme]{gls}} function in the \pkg{nlme} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract gls
#' @aliases extract.gls
#' @export
setMethod("extract", signature = className("gls", "nlme"),
          definition = extract.gls)


# -- extract.gmm (gmm) -------------------------------------------------------

#' @noRd
extract.gmm <- function(model,
                        include.obj.fcn = TRUE,
                        include.overidentification = FALSE,
                        include.nobs = TRUE,
                        ...) {

  s <- summary(model, ...)

  coefs <- s$coefficients
  names <- rownames(coefs)
  coef <- coefs[, 1]
  se <- coefs[, 2]
  pval <- coefs[, 4]

  n <- model$n  # number of observations
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.obj.fcn == TRUE) {
    obj.fcn <- model$objective * 10^5  # the value of the objective function
    gof <- c(gof, obj.fcn)
    gof.names <- c(gof.names, "Criterion function")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.overidentification == TRUE) {
    jtest <- s$stest$test[1]
    gof <- c(gof, jtest)
    gof.names <- c(gof.names, "J-Test")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = coef,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gmm} objects
#'
#' \code{\link{extract}} method for \code{gmm} objects created by the
#' \code{\link[gmm]{gmm}} function in the \pkg{gmm} package.
#'
#' @inheritParams extract,gel-method
#'
#' @method extract gmm
#' @aliases extract.gmm
#' @export
setMethod("extract", signature = className("gmm", "gmm"),
          definition = extract.gmm)


# -- extract.gnls (nlme) -------------------------------------------------------

#' @noRd
extract.gnls <- extract.gls

#' \code{\link{extract}} method for \code{gnls} objects
#'
#' \code{\link{extract}} method for \code{gnls} objects created by the
#' \code{\link[nlme]{gnls}} function in the \pkg{nlme} package.
#'
#' @inheritParams extract,gls-method
#'
#' @method extract gnls
#' @aliases extract.gnls
#' @export
setMethod("extract", signature = className("gnls", "nlme"),
          definition = extract.gnls)


# -- extract.gnm (gnm) ---------------------------------------------------------

#' @noRd
extract.gnm <- function(model, include.aic = TRUE, include.bic = TRUE,
                        include.loglik = TRUE, include.deviance = TRUE,
                        include.nobs = TRUE, include.df = FALSE,
                        include.chisq = FALSE, include.delta = FALSE, ...) {

  s <- summary(model)
  coefficients.names <- names(model$coefficients)
  co <- s$coef[, 1]
  se <- s$coef[, 2]
  pval <- s$coef[, 3]

  table <- as.data.frame(cbind(coefficients.names, co, se, pval))
  table <- table[!is.na(table$se), ]
  coefficients.names <- as.character(table$coefficients.names)
  co <- as.numeric(as.character(table$co))
  se <- as.numeric(as.character(table$se))
  pval <- as.numeric(as.character(table$pval))

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()

  if (include.df == TRUE) {
    df <- model$df.residual
    gof <- c(gof, df)
    gof.names <- c(gof.names, "df. residuals")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.loglik == TRUE) {
    lik <- logLik(model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    dev <- deviance(model)
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.chisq == TRUE) {
    chisq <- sum(na.omit(c(residuals(model, "pearson")^2)))
    gof <- c(gof, chisq)
    gof.names <- c(gof.names, "Pearson chi-squared")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.aic == TRUE) {
    aic <- AIC(model)[1]
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(model)[1]
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.delta == TRUE) {
    delta <- sum(na.omit(c(abs(residuals(model,"response"))))) /
      sum(na.omit(c(abs(fitted(model))))) / 2 * 100 # Dissimilarity index
    gof <- c(gof, delta)
    gof.names <- c(gof.names, "Dissim. Index")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    nobs <- length(model$y)
    gof <- c(gof, nobs)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = coefficients.names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{gnm} objects
#'
#' \code{\link{extract}} method for \code{gnm} objects created by the
#' \code{\link[gnm]{gnm}} function in the \pkg{gnm} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.deviance Report the deviance?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.df Report the degrees of freedom?
#' @param include.chisq Report the chi squared statistic?
#' @param include.delta Report the delta statistic?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract gnm
#' @aliases extract.gnm
#' @importFrom stats nobs AIC BIC residuals logLik na.omit fitted
#' @export
setMethod("extract", signature = className("gnm", "gnm"),
          definition = extract.gnm)


# -- extract.H2OBinomialModel (h20) --------------------------------------------

#' @noRd
extract.H2OBinomialModel <- function(model,
                                     standardized = FALSE,
                                     include.mse = TRUE,
                                     include.rsquared = TRUE,
                                     include.logloss = TRUE,
                                     include.meanerror = TRUE,
                                     include.auc = TRUE,
                                     include.gini = TRUE,
                                     include.deviance = TRUE,
                                     include.aic = TRUE,
                                     ...) {

  # extract coefficient table from model:
  coefnames <- model@model$coefficients_table$names
  if (standardized == TRUE) {
    coefs <- model@model$coefficients_table$standardized_coefficients
  } else {
    coefs <- model@model$coefficients_table$coefficients
  }

  # create empty GOF vectors and subsequently add GOF statistics from model:
  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.mse == TRUE) {
    mse <- model@model$training_metrics@metrics$MSE
    gof <- c(gof, mse)
    gof.names <- c(gof.names, "MSE")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rsquared == TRUE) {
    r2 <- model@model$training_metrics@metrics$r2
    gof <- c(gof, r2)
    gof.names <- c(gof.names, "R^2")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.logloss == TRUE) {
    logloss <- model@model$training_metrics@metrics$logloss
    gof <- c(gof, logloss)
    gof.names <- c(gof.names, "LogLoss")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.meanerror == TRUE) {
    mpce <- model@model$training_metrics@metrics$mean_per_class_error
    gof <- c(gof, mpce)
    gof.names <- c(gof.names, "Mean Per-Class Error")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.auc == TRUE) {
    auc <- model@model$training_metrics@metrics$AUC
    gof <- c(gof, auc)
    gof.names <- c(gof.names, "AUC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.gini == TRUE) {
    gini <- model@model$training_metrics@metrics$Gini
    gof <- c(gof, gini)
    gof.names <- c(gof.names, "Gini")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    nulldev <- model@model$training_metrics@metrics$null_deviance
    resdev <- model@model$training_metrics@metrics$residual_deviance
    gof <- c(gof, nulldev, resdev)
    gof.names <- c(gof.names, "Null Deviance", "Residual Deviance")
    gof.decimal <- c(gof.decimal, TRUE, TRUE)
  }
  if (include.aic == TRUE) {
    aic <- model@model$training_metrics@metrics$AIC
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  # create texreg object:
  tr <- createTexreg(
    coef.names = coefnames,
    coef = coefs,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{H2OBinomialModel} objects
#'
#' \code{\link{extract}} method for \code{H2OBinomialModel} objects created by
#' the \code{\link[h2o]{h2o.glm}} function in the \pkg{h2o} package.
#'
#' @param model A statistical model object.
#' @param standardized Report standardized coefficients instead of raw
#'   coefficients?
#' @param include.mse Report the mean squared error in the GOF block?
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.logloss Report the log loss?
#' @param include.meanerror Report the mean per-class error?
#' @param include.auc Report the area under the curve (AUC)?
#' @param include.gini Report the Gini coefficient?
#' @param include.deviance Report the deviance?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract H2OBinomialModel
#' @aliases extract.H2OBinomialModel
#' @export
setMethod("extract", signature = className("H2OBinomialModel", "h2o"),
          definition = extract.H2OBinomialModel)


# -- extract.lm (stats) --------------------------------------------------------

#' @noRd
extract.lm <- function(model, include.rsquared = TRUE, include.adjrs = TRUE,
                       include.nobs = TRUE, include.fstatistic = FALSE,
                       include.rmse = FALSE, ...) {
  s <- summary(model, ...)

  names <- rownames(s$coefficients)
  co <- s$coefficients[, 1]
  se <- s$coefficients[, 2]
  pval <- s$coefficients[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (isTRUE(include.rsquared)) {
    rs <- s$r.squared  # extract R-squared
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.adjrs)) {
    adj <- s$adj.r.squared  # extract adjusted R-squared
    gof <- c(gof, adj)
    gof.names <- c(gof.names, "Adj. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.nobs)) {
    n <- nobs(model)  # extract number of observations
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (isTRUE(include.fstatistic)) {
    fstat <- s$fstatistic[[1]]
    gof <- c(gof, fstat)
    gof.names <- c(gof.names, "F statistic")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (isTRUE(include.rmse) && !is.null(s$sigma[[1]])) {
    rmse <- s$sigma[[1]]
    gof <- c(gof, rmse)
    gof.names <- c(gof.names, "RMSE")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lm} objects
#'
#' \code{\link{extract}} method for \code{lm} objects created by the
#' \code{\link[stats]{lm}} function in the \pkg{stats} package.
#'
#' @param model A statistical model object.
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.adjrs Report adjusted R^2 in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.fstatistic Report the F-statistic in the GOF block?
#' @param include.rmse Report the root mean square error (RMSE; = residual
#'   standard deviation) in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract lm
#' @aliases extract.lm
#' @importFrom stats nobs
#' @export
setMethod("extract", signature = className("lm", "stats"),
          definition = extract.lm)


# -- extract.dynlm (dynlm) -----------------------------------------------------

#' @noRd
extract.dynlm <- extract.lm

#' \code{\link{extract}} method for \code{dynlm} objects
#'
#' \code{\link{extract}} method for \code{dynlm} objects created by the
#' \code{\link[dynlm]{dynlm}} function in the \pkg{dynlm} package.
#'
#' @inheritParams extract,lm-method
#'
#' @method extract dynlm
#' @aliases extract.dynlm
#' @export
setMethod("extract", signature = className("dynlm", "dynlm"),
          definition = extract.dynlm)


# -- extract.ivreg (AER) -------------------------------------------------------

#' @noRd
extract.ivreg <- extract.lm

#' \code{\link{extract}} method for \code{ivreg} objects
#'
#' \code{\link{extract}} method for \code{ivreg} objects created by the
#' \code{\link[AER]{ivreg}} function in the \pkg{AER} package.
#'
#' @inheritParams extract,lm-method
#'
#' @method extract ivreg
#' @aliases extract.ivreg
#' @export
setMethod("extract", signature = className("ivreg", "AER"),
          definition = extract.ivreg)


# -- extract.lm.cluster (miceadds) ---------------------------------------------

#' @noRd
extract.lm.cluster <- function(model,
                               include.rsquared = TRUE,
                               include.adjrs = TRUE,
                               include.nobs = TRUE,
                               include.fstatistic = FALSE,
                               include.rmse = FALSE,
                               ...) {

  s <- summary(model$lm_res)
  lm_model <- model$lm_res
  nam <- names(lm_model$coefficients)
  co <- lm_model$coefficients
  se <- sqrt(diag(model$vcov))
  pval <- 2 * pnorm(-abs(co / se))


  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.rsquared == TRUE) {
    rs <- s$r.squared  # extract R-squared
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.adjrs == TRUE) {
    adj <- s$adj.r.squared  # extract adjusted R-squared
    gof <- c(gof, adj)
    gof.names <- c(gof.names, "Adj. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(lm_model)  # extract number of observations
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.fstatistic == TRUE) {
    fstat <- s$fstatistic[[1]]
    gof <- c(gof, fstat)
    gof.names <- c(gof.names, "F statistic")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.rmse == TRUE && !is.null(s$sigma[[1]])) {
    rmse <- s$sigma[[1]]
    gof <- c(gof, rmse)
    gof.names <- c(gof.names, "RMSE")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = nam,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lm.cluster} objects
#'
#' \code{\link{extract}} method for \code{lm.cluster} objects created by the
#' \code{\link[miceadds]{lm.cluster}} function in the \pkg{miceadds} package.
#'
#' @param model A statistical model object.
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.adjrs Report adjusted R^2 in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.fstatistic Report the F-statistic in the GOF block?
#' @param include.rmse Report the root mean square error (RMSE; = residual
#'   standard deviation) in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines. Currently
#'   not in use.
#'
#' @method extract lm.cluster
#' @aliases extract.lm.cluster
#' @author Alexander Staudt, Philip Leifeld
#' @export
setMethod("extract", signature = className("lm.cluster", "miceadds"),
          definition = extract.lm.cluster)


# -- extract.lme (nlme) --------------------------------------------------------

#' @noRd
extract.lme <- function(model, include.aic = TRUE, include.bic = TRUE,
                        include.loglik = TRUE, include.nobs = TRUE,
                        include.groups = TRUE, include.variance = FALSE, ...) {

  s <- summary(model, ...)

  coefficient.names <- rownames(s$tTable)
  coefficients <- s$tTable[, 1]
  standard.errors <- s$tTable[, 2]
  significance <- s$tTable[, 5]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- s$AIC
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- s$BIC
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- s$logLik
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- nobs(model)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE) {
    grp <- model$dims$ngrps[1:model$dims$Q]
    for(i in 1:length(grp)){
      gof <- c(gof, grp[i])
      gof.names <- c(gof.names, paste("Num. groups:", names(grp)[i]))
      gof.decimal <- c(gof.decimal, FALSE)
    }
  }
  if (include.variance == TRUE ) {
    sig.all <- s$sigma
    if (!is.null(sig.all) && !is.na(sig.all)) {
      gof <- c(gof, sig.all)
      gof.names <- c(gof.names, "sigma")
      gof.decimal <- c(gof.decimal, TRUE)
    }

    vc <- nlme::VarCorr(model)
    if ("(Intercept)" %in% rownames(vc) && "StdDev" %in% colnames(vc)) {
      sig.RE <- as.numeric(vc["(Intercept)", "StdDev"])
      if (!is.null(sig.RE) && !is.na(sig.RE)) {
        gof <- c(gof, sig.RE)
        gof.names <- c(gof.names, "sigma. RE")
        gof.decimal <- c(gof.decimal, TRUE)
      }
    }

    cf <- coef(model$modelStruct, unconstrained = FALSE)["corStruct.Phi1"]
    rho <- unname(cf)
    if (!is.null(rho) && !is.na(rho)) {
      gof <- c(gof, rho)
      gof.names <- c(gof.names, "rho")
      gof.decimal <- c(gof.decimal, TRUE)
    }
  }

  tr <- createTexreg(
    coef.names = coefficient.names,
    coef = coefficients,
    se = standard.errors,
    pvalues = significance,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lme} objects
#'
#' \code{\link{extract}} method for \code{lme} objects created by the
#' \code{\link[nlme]{lme}} function in the \pkg{nlme} package.
#'
#' @param model A statistical model object.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param include.variance Report group variances?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract lme
#' @aliases extract.lme
#' @export
setMethod("extract", signature = className("lme", "nlme"),
          definition = extract.lme)


# -- extract.glmmPQL (MASS) ----------------------------------------------------

#' @noRd
extract.glmmPQL <- extract.lme

#' \code{\link{extract}} method for \code{glmmPQL} objects
#'
#' \code{\link{extract}} method for \code{glmmPQL} objects created by the
#' \code{\link[MASS]{glmmPQL}} function in the \pkg{MASS} package.
#'
#' @inheritParams extract,lme-method
#'
#' @method extract glmmPQL
#' @aliases extract.glmmPQL
#' @export
setMethod("extract", signature = className("glmmPQL", "MASS"),
          definition = extract.glmmPQL)


# -- extract.lme4 (lme4) -------------------------------------------------------

#' @noRd
extract.lme4 <- function(model,
                         method = c("naive", "profile", "boot", "Wald"),
                         level = 0.95,
                         nsim = 1000,
                         include.aic = TRUE,
                         include.bic = TRUE,
                         include.dic = FALSE,
                         include.deviance = FALSE,
                         include.loglik = TRUE,
                         include.nobs = TRUE,
                         include.groups = TRUE,
                         include.variance = TRUE,
                         ...) {

  if (utils::packageVersion("lme4") < "1.0") {
    message("Please update to a newer 'lme4' version for full compatibility.")
  }

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.aic == TRUE) {
    aic <- AIC(model)
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    bic <- BIC(model)
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.dic == TRUE) {  # code from the arm package, version 1.7-07
    is_REML <- lme4::isREML(model)
    llik <- logLik(model, REML = is_REML)
    dev <- deviance(lme4::refitML(model))
    n <-  lme4::getME(model, "devcomp")$dims["n"]
    Dhat <- -2 * (llik)
    pD <- dev - Dhat
    DIC <- dev + pD[[1]]
    gof <- c(gof, DIC)
    gof.names <- c(gof.names, "DIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.deviance == TRUE) {
    dev <- deviance(lme4::refitML(model))
    gof <- c(gof, dev)
    gof.names <- c(gof.names, "Deviance")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    lik <- logLik(model)[1]
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    n <- dim(stats::model.frame(model))[1]
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.groups == TRUE) {
    grps <- sapply(model@flist, function(x) length(levels(x)))
    grp.names <- names(grps)
    grp.names <- paste("Num. groups:", grp.names)
    gof <- c(gof, grps)
    gof.names <- c(gof.names, grp.names)
    gof.decimal <- c(gof.decimal, rep(FALSE, length(grps)))
  }
  if (include.variance == TRUE) {
    vc <- as.data.frame(lme4::VarCorr(model))
    for (i in 1:nrow(vc)) {
      if (is.na(vc[i, 2]) && is.na(vc[i, 3])) {
        gof.names <- c(gof.names, "Var: Residual")
      } else if (is.na(vc[i, 3])) {
        gof.names <- c(gof.names, paste("Var:", vc[i, 1], vc[i, 2]))
      } else {
        gof.names <- c(gof.names, paste("Cov:", vc[i, 1], vc[i, 2], vc[i, 3]))
      }
      gof <- c(gof, vc[i, 4])
      gof.decimal <- c(gof.decimal, TRUE)
    }
    # vc <- lme4::VarCorr(model)
    # varcomps <- c(unlist(lapply(vc, diag)),   # random intercept variances
    #               attr(vc, "sc")^2)                     # residual variance
    # varnames <- names(varcomps)
    # varnames[length(varnames)] <- "Residual"
    # varnames <- paste("Variance:", varnames)
    # if (is.na(attr(vc, "sc"))) {
    #   varnames <- varnames[-length(varnames)]
    #   varcomps <- varcomps[-length(varcomps)]
    # }
    # gof <- c(gof, varcomps)
    # gof.names <- c(gof.names, varnames)
    # gof.decimal <- c(gof.decimal, rep(TRUE, length(varcomps)))
  }

  betas <- lme4::fixef(model, ...)
  if ("confint.merMod" %in% utils::methods("confint") && method[1] != "naive") {
    ci <- tryCatch({
      ci <- stats::confint(model, method = method[1], level = level, nsim = nsim, ...)
    },
    error = function(err) {
      method <- "naive"
      message("Confidence intervals not available for this model. Using naive p-values instead.")
    }
    )
    if (is.null(ci)) {
      method <- "naive"
    } else {
      last <- nrow(ci)
      number <- length(betas)
      first <- last - number + 1
      ci <- ci[first:last, ]
      if (is.matrix(ci)) {
        ci.l <- ci[, 1]
        ci.u <- ci[, 2]
      } else {
        ci.l <- ci[1]
        ci.u <- ci[2]
      }
    }
  } else if (method[1] != "naive") {
    method[1] <- "naive"
    message("confint.merMod method not found. Using naive p-values instead.")
  }

  if (method[1] == "naive") {
    Vcov <- tryCatch({
      Vcov <- stats::vcov(model, useScale = FALSE, ...)
    }, error = function(err) {  # Matrix package is sometimes used internally...
      stop(paste("Please load the Matrix package or update to the latest",
                 "development version of lme4 and run this command again."))
    })
    Vcov <- as.matrix(Vcov)
    se <- sqrt(diag(Vcov))
    zval <- betas / se
    pval <- 2 * pnorm(abs(zval), lower.tail = FALSE)

    tr <- createTexreg(
      coef.names = names(betas),
      coef = betas,
      se = se,
      pvalues = pval,
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )
  } else {
    tr <- createTexreg(
      coef.names = names(betas),
      coef = betas,
      ci.low = ci.l,
      ci.up = ci.u,
      gof.names = gof.names,
      gof = gof,
      gof.decimal = gof.decimal
    )
  }

  return(tr)
}

#' \code{\link{extract}} method for \code{lme4} objects
#'
#' \code{\link{extract}} method for \code{lme4} objects created by the
#' \pkg{lme4} package.
#'
#' @param model A statistical model object.
#' @param method The method used to compute confidence intervals or p-values.
#'   The default value \code{"naive"} computes naive p-values while the other
#'   methods compute confidence intervals using the \code{confint} function. See
#'   \code{\link[lme4]{confint.merMod}}.
#' @param level Significance or confidence level (\code{1 - alpha}) for
#'   computing confidence intervals.
#' @param nsim The MCMC sample size or number of bootstrapping replications on
#'   the basis of which confidence intervals are computed (only if the
#'   \code{method} argument does not specify \code{"naive"}, which is the
#'   default behavior). Note: large values may take considerable computing time.
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.dic Report the deviance information criterion (DIC)?
#' @param include.deviance Report the deviance?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.groups Report the number of groups?
#' @param include.variance Report group variances?
#' @param ... Arguments to be passed to the \code{\link[lme4]{fixef}} function
#'   in the \pkg{lme4} package.
#'
#' @method extract lme4
#' @aliases extract.lme4
#' @importFrom stats confint model.frame vcov
#' @importFrom utils methods packageVersion
#' @export
setMethod("extract", signature = className("lme4", "lme4"),
          definition = extract.lme4)


# -- extract.merMod (lme4) -----------------------------------------------------

#' @noRd
extract.merMod <- extract.lme4

#' \code{\link{extract}} method for \code{merMod} objects
#'
#' \code{\link{extract}} method for \code{merMod} objects created by the
#' \pkg{lme4} package.
#'
#' @inheritParams extract,lme4-method
#'
#' @method extract merMod
#' @aliases extract.merMod
#' @export
setMethod("extract", signature = className("merMod", "lme4"),
          definition = extract.merMod)


# -- extract.lmerMod (lme4) ----------------------------------------------------

#' @noRd
extract.lmerMod <- extract.lme4

#' \code{\link{extract}} method for \code{lmerMod} objects
#'
#' \code{\link{extract}} method for \code{lmerMod} objects created by the
#' \code{\link[lme4]{lmer}} function in the \pkg{lme4} package.
#'
#' @inheritParams extract,lme4-method
#'
#' @method extract lmerMod
#' @aliases extract.lmerMod
#' @export
setMethod("extract", signature = className("lmerMod", "lme4"),
          definition = extract.lmerMod)


# -- extract.glmerMod (lme4) ---------------------------------------------------

#' @noRd
extract.glmerMod <- extract.lme4

#' \code{\link{extract}} method for \code{glmerMod} objects
#'
#' \code{\link{extract}} method for \code{glmerMod} objects created by the
#' \code{\link[lme4]{glmer}} function in the \pkg{lme4} package.
#'
#' @inheritParams extract,lme4-method
#'
#' @method extract glmerMod
#' @aliases extract.glmerMod
#' @export
setMethod("extract", signature = className("glmerMod", "lme4"),
          definition = extract.glmerMod)


# -- extract.nlmerMod (lme4) ---------------------------------------------------

#' @noRd
extract.nlmerMod <- extract.lme4

#' \code{\link{extract}} method for \code{nlmerMod} objects
#'
#' \code{\link{extract}} method for \code{nlmerMod} objects created by the
#' \code{\link[lme4]{nlmer}} function in the \pkg{lme4} package.
#'
#' @inheritParams extract,lme4-method
#'
#' @method extract nlmerMod
#' @aliases extract.nlmerMod
#' @export
setMethod("extract", signature = className("nlmerMod", "lme4"),
          definition = extract.nlmerMod)


# -- extract.lmrob (robustbase) ------------------------------------------------

#' @noRd
extract.lmrob <- function(model, include.nobs = TRUE, ...) {
  s <- summary(model, ...)

  names <- rownames(s$coef)
  co <- s$coef[, 1]
  se <- s$coef[, 2]
  pval <- s$coef[, 4]

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()

  if (include.nobs == TRUE) {
    n <- length(model$residuals)
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lmrob} objects
#'
#' \code{\link{extract}} method for \code{lmrob} objects created by the
#' \code{lmrob} function in the \pkg{robustbase} package.
#'
#' @param model A statistical model object.
#' @param include.nobs Report the number of observations in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract lmrob
#' @aliases extract.lmrob
#' @export
setMethod("extract", signature = className("lmrob", "robustbase"),
          definition = extract.lmrob)


# -- extract.glmrob (robustbase) -----------------------------------------------

#' @noRd
extract.glmrob <- extract.lmrob

#' \code{\link{extract}} method for \code{glmrob} objects
#'
#' \code{\link{extract}} method for \code{glmrob} objects created by the
#' \code{glmrob} function in the \pkg{robustbase} package.
#'
#' @inheritParams extract,lmrob-method
#'
#' @method extract glmrob
#' @aliases extract.glmrob
#' @export
setMethod("extract", signature = className("glmrob", "robustbase"),
          definition = extract.glmrob)


# -- extract.lmRob (robust) ----------------------------------------------------

#' @noRd
extract.lmRob <- function(model, include.rsquared = TRUE,
                          include.nobs = TRUE, include.rmse = TRUE, ...) {
  s <- summary(model, ...)

  names <- rownames(s$coefficients)
  co <- s$coefficients[, 1]
  se <- s$coefficients[, 2]
  pval <- s$coefficients[, 4]

  rs <- s$r.squared  #extract R-squared
  n <- length(model$residuals)  #extract number of observations

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.rsquared == TRUE) {
    gof <- c(gof, rs)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.nobs == TRUE) {
    gof <- c(gof, n)
    gof.names <- c(gof.names, "Num. obs.")
    gof.decimal <- c(gof.decimal, FALSE)
  }
  if (include.rmse == TRUE && !is.null(s$sigma)) {
    rmse <- s$sigma[[1]]
    gof <- c(gof, rmse)
    gof.names <- c(gof.names, "RMSE")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = names,
    coef = co,
    se = se,
    pvalues = pval,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lmRob} objects
#'
#' \code{\link{extract}} method for \code{lmRob} objects created by the
#' \code{\link[robust]{lmRob}} function in the \pkg{robust} package.
#'
#' @param model A statistical model object.
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.nobs Report the number of observations in the GOF block?
#' @param include.rmse Report the root mean square error (RMSE; = residual
#'   standard deviation) in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{summary} method for the object.
#'
#' @method extract lmRob
#' @aliases extract.lmRob
#' @rdname extract-lmrob-method
#' @export
setMethod("extract", signature = className("lmRob", "robust"),
          definition = extract.lmRob)


# -- extract.lnam (sna) --------------------------------------------------------

#' @noRd
extract.lnam <- function(model,
                         include.rsquared = TRUE,
                         include.adjrs = TRUE,
                         include.aic = TRUE,
                         include.bic = TRUE,
                         include.loglik = TRUE,
                         ...) {
  coefs <- coef(model, ...)
  coef.names <- names(coefs)
  se <- c(model$beta.se, model$rho1.se, model$rho2.se)
  p <- 2 * (1 - pnorm(abs(coefs), 0, se))

  rss <- sum(model$residuals^2)
  mss <- sum((model$fitted - mean(model$fitted))^2)
  rdfns <- model$df.residual + 1
  rsquared <- mss / (mss + rss)
  adj.rsquared <- 1 - (1 - mss / (mss + rss)) * model$df.total / rdfns
  lik <- model$lnlik.model
  aic <- -2 * model$lnlik.model + 2 * model$df.model
  bic <- -2 * model$lnlik.model + log(model$df.total) * model$df.model

  gof <- numeric()
  gof.names <- character()
  gof.decimal <- logical()
  if (include.rsquared == TRUE) {
    gof <- c(gof, rsquared)
    gof.names <- c(gof.names, "R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.adjrs == TRUE) {
    gof <- c(gof, adj.rsquared)
    gof.names <- c(gof.names, "Adj. R$^2$")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.aic == TRUE) {
    gof <- c(gof, aic)
    gof.names <- c(gof.names, "AIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.bic == TRUE) {
    gof <- c(gof, bic)
    gof.names <- c(gof.names, "BIC")
    gof.decimal <- c(gof.decimal, TRUE)
  }
  if (include.loglik == TRUE) {
    gof <- c(gof, lik)
    gof.names <- c(gof.names, "Log Likelihood")
    gof.decimal <- c(gof.decimal, TRUE)
  }

  tr <- createTexreg(
    coef.names = coef.names,
    coef = coefs,
    se = se,
    pvalues = p,
    gof.names = gof.names,
    gof = gof,
    gof.decimal = gof.decimal
  )
  return(tr)
}

#' \code{\link{extract}} method for \code{lnam} objects
#'
#' \code{\link{extract}} method for \code{lnam} objects created by the
#' \code{lnam} function in the \pkg{sna} package.
#'
#' @param model A statistical model object.
#' @param include.rsquared Report R^2 in the GOF block?
#' @param include.adjrs Report adjusted R^2 in the GOF block?
#' @param include.aic Report Akaike's Information Criterion (AIC) in the GOF
#'   block?
#' @param include.bic Report the Bayesian Information Criterion (BIC) in the GOF
#'   block?
#' @param include.loglik Report the log likelihood in the GOF block?
#' @param ... Custom parameters, which are handed over to subroutines, in this
#'   case to the \code{coef} method for the object.
#'
#' @method extract lnam
#' @aliases extract.lnam
#' @importFrom stats pnorm
#' @export
setMethod("extract", signature = className("lnam", "sna"),
          definition =