% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/hypotheses.R
\name{hypotheses}
\alias{hypotheses}
\title{(Non-)Linear Tests for Null Hypotheses, Joint Hypotheses, Equivalence, Non Superiority, and Non Inferiority}
\usage{
hypotheses(
  model,
  hypothesis = NULL,
  vcov = NULL,
  conf_level = NULL,
  df = NULL,
  equivalence = NULL,
  joint = FALSE,
  joint_test = "f",
  multcomp = FALSE,
  numderiv = "fdforward",
  ...
)
}
\arguments{
\item{model}{Model object or object generated by the \code{comparisons()}, \code{slopes()}, or \code{predictions()} functions.}

\item{hypothesis}{specify a hypothesis test or custom contrast using a number , formula, string equation, vector, matrix, or function.
\itemize{
\item Number: The null hypothesis used in the computation of Z and p (before applying \code{transform}).
\item String: Equation to specify linear or non-linear hypothesis tests. If the terms in \code{coef(object)} uniquely identify estimates, they can be used in the formula. Otherwise, use \code{b1}, \code{b2}, etc. to identify the position of each parameter. The \verb{b*} wildcard can be used to test hypotheses on all estimates. If a named vector is used, the names are used as labels in the output. Examples:
\itemize{
\item \code{hp = drat}
\item \code{hp + drat = 12}
\item \code{b1 + b2 + b3 = 0}
\item \verb{b* / b1 = 1}
}
\item Formula: \code{lhs ~ rhs | group}
\itemize{
\item \code{lhs}
\itemize{
\item \code{ratio}
\item \code{difference}
\item Leave empty for default value
}
\item \code{rhs}
\itemize{
\item \code{pairwise} and \code{revpairwise}: pairwise differences between estimates in each row.
\item \code{reference}: differences between the estimates in each row and the estimate in the first row.
\item \code{sequential}: difference between an estimate and the estimate in the next row.
\item \code{meandev}: difference between an estimate and the mean of all estimates.
\item `meanotherdev: difference between an estimate and the mean of all other estimates, excluding the current one.
\item \code{poly}: polynomial contrasts, as computed by the \code{stats::contr.poly()} function.
\item \code{helmert}: Helmert contrasts, as computed by the \code{stats::contr.helmert()} function. Contrast 2nd level to the first, 3rd to the average of the first two, and so on.
\item \code{trt_vs_ctrl}: difference between the mean of estimates (except the first) and the first estimate.
\item \code{I(fun(x))}: custom function to manipulate the vector of estimates \code{x}. The function \code{fun()} can return multiple (potentially named) estimates.
}
\item \code{group} (optional)
\itemize{
\item Column name of \code{newdata}. Conduct hypothesis tests withing subsets of the data.
}
\item Examples:
\itemize{
\item \code{~ poly}
\item \code{~ sequential | groupid}
\item \code{~ reference}
\item \code{ratio ~ pairwise}
\item \code{difference ~ pairwise | groupid}
\item \code{~ I(x - mean(x)) | groupid}
\item \verb{~ I(\\(x) c(a = x[1], b = mean(x[2:3]))) | groupid}
}
}
\item Matrix or Vector: Each column is a vector of weights. The the output is the dot product between these vectors of weights and the vector of estimates. The matrix can have column names to label the estimates.
\item Function:
\itemize{
\item Accepts an argument \code{x}: object produced by a \code{marginaleffects} function or a data frame with column \code{rowid} and \code{estimate}
\item Returns a data frame with columns \code{term} and \code{estimate} (mandatory) and \code{rowid} (optional).
\item The function can also accept optional input arguments: \code{newdata}, \code{by}, \code{draws}.
\item This function approach will not work for Bayesian models or with bootstrapping. In those cases, it is easy to use \code{get_draws()} to extract and manipulate the draws directly.
}
\item See the Examples section below and the vignette: \url{https://marginaleffects.com/chapters/hypothesis.html}
}}

\item{vcov}{Type of uncertainty estimates to report (e.g., for robust standard errors). Acceptable values:
\itemize{
\item FALSE: Do not compute standard errors. This can speed up computation considerably.
\item TRUE: Unit-level standard errors using the default \code{vcov(model)} variance-covariance matrix.
\item String which indicates the kind of uncertainty estimates to return.
\itemize{
\item Heteroskedasticity-consistent: \code{"HC"}, \code{"HC0"}, \code{"HC1"}, \code{"HC2"}, \code{"HC3"}, \code{"HC4"}, \code{"HC4m"}, \code{"HC5"}. See \code{?sandwich::vcovHC}
\item Heteroskedasticity and autocorrelation consistent: \code{"HAC"}
\item Mixed-Models degrees of freedom: "satterthwaite", "kenward-roger"
\item Other: \code{"NeweyWest"}, \code{"KernHAC"}, \code{"OPG"}. See the \code{sandwich} package documentation.
}
\item One-sided formula which indicates the name of cluster variables (e.g., \code{~unit_id}). This formula is passed to the \code{cluster} argument of the \code{sandwich::vcovCL} function.
\item Square covariance matrix
\item Function which returns a covariance matrix (e.g., \code{stats::vcov(model)})
}}

\item{conf_level}{NULL or numeric value between 0 and 1. Confidence level to use to build a confidence interval. When \code{NULL} and \code{model} was generated by \code{marginaleffects}, the confidence level is taken from the \code{conf_level} attribute of the model. Otherwise, the default value is 0.95.}

\item{df}{Degrees of freedom used to compute p values and confidence intervals. A single numeric value between 1 and \code{Inf}. When using \code{joint_test="f"}, the \code{df} argument should be a numeric vector of length 2.}

\item{equivalence}{Numeric vector of length 2: bounds used for the two-one-sided test (TOST) of equivalence, and for the non-inferiority and non-superiority tests. See Details section below.}

\item{joint}{Joint test of statistical significance. The null hypothesis value can be set using the \code{hypothesis} argument.
\itemize{
\item FALSE: Hypotheses are not tested jointly.
\item TRUE: All parameters are tested jointly.
\item String: A regular expression to match parameters to be tested jointly. \code{grep(joint, perl = TRUE)}
\item Character vector of parameter names to be tested. Characters refer to the names of the vector returned by \code{marginaleffects::get_coef(object)}.
\item Integer vector of indices. Which parameters positions to test jointly.
}}

\item{joint_test}{A character string specifying the type of test, either "f" or "chisq". The null hypothesis is set by the \code{hypothesis} argument, with default null equal to 0 for all parameters.}

\item{multcomp}{Logical or string. If \code{TRUE} or string, apply multiple comparison adjustment to the p values and report family-wise confidence intervals. Valid strings: "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "single-step", "Shaffer", "Westfall", "free". When \code{multcomp} is \code{TRUE}, the "holm" method is used.}

\item{numderiv}{string or list of strings indicating the method to use to for the numeric differentiation used in to compute delta method standard errors.
\itemize{
\item "fdforward": finite difference method with forward differences
\item "fdcenter": finite difference method with central differences (default)
\item "richardson": Richardson extrapolation method
\item Extra arguments can be specified by passing a list to the \code{numDeriv} argument, with the name of the method first and named arguments following, ex: \code{numderiv=list("fdcenter", eps = 1e-5)}. When an unknown argument is used, \code{marginaleffects} prints the list of valid arguments for each method.
}}

\item{...}{Additional arguments are passed to the \code{predict()} method
supplied by the modeling package.These arguments are particularly useful
for mixed-effects or bayesian models (see the online vignettes on the
\code{marginaleffects} website). Available arguments can vary from model to
model, depending on the range of supported arguments by each modeling
package. See the "Model-Specific Arguments" section of the
\code{?slopes} documentation for a non-exhaustive list of available
arguments.}
}
\description{
Uncertainty estimates are calculated as first-order approximate standard errors for linear or non-linear functions of a vector of random variables with known or estimated covariance matrix. In that sense, \code{\link{hypotheses}} emulates the behavior of the excellent and well-established \link[car:deltaMethod]{car::deltaMethod} and \link[car:linearHypothesis]{car::linearHypothesis} functions, but it supports more models; requires fewer dependencies; expands the range of tests to equivalence and superiority/inferiority; and offers convenience features like robust standard errors.

To learn more, read the hypothesis tests vignette, visit the
package website, or scroll down this page for a full list of vignettes:
\itemize{
\item \url{https://marginaleffects.com/chapters/hypothesis.html}
\item \url{https://marginaleffects.com/}
}

Warning #1: Tests are conducted directly on the scale defined by the \code{type} argument. For some models, it can make sense to conduct hypothesis or equivalence tests on the \code{"link"} scale instead of the \code{"response"} scale which is often the default.

Warning #2: For hypothesis tests on objects produced by the \code{marginaleffects} package, it is safer to use the \code{hypothesis} argument of the original function.  Using \code{hypotheses()} may not work in certain environments, in lists, or when working programmatically with *apply style functions.

Warning #3: The tests assume that the \code{hypothesis} expression is (approximately) normally distributed, which for non-linear functions of the parameters may not be realistic. More reliable confidence intervals can be obtained using the \code{inferences()} function with \code{method = "boot"}.
}
\section{Joint hypothesis tests}{

The test statistic for the joint Wald test is calculated as (R * theta_hat - r)' * inv(R * V_hat * R') * (R * theta_hat - r) / Q,
where theta_hat is the vector of estimated parameters, V_hat is the estimated covariance matrix, R is a Q x P matrix for testing Q hypotheses on P parameters,
r is a Q x 1 vector for the null hypothesis, and Q is the number of rows in R. If the test is a Chi-squared test, the test statistic is not normalized.

The p-value is then calculated based on either the F-distribution (for F-test) or the Chi-squared distribution (for Chi-squared test).
For the F-test, the degrees of freedom are Q and (n - P), where n is the sample size and P is the number of parameters.
For the Chi-squared test, the degrees of freedom are Q.
}

\section{Equivalence, Inferiority, Superiority}{


\eqn{\theta} is an estimate, \eqn{\sigma_\theta} its estimated standard error, and \eqn{[a, b]} are the bounds of the interval supplied to the \code{equivalence} argument.

Non-inferiority:
\itemize{
\item \eqn{H_0}{H0}: \eqn{\theta \leq a}{\theta <= a}
\item \eqn{H_1}{H1}: \eqn{\theta > a}
\item \eqn{t=(\theta - a)/\sigma_\theta}{t=(\theta - a)/\sigma_\theta}
\item p: Upper-tail probability
}

Non-superiority:
\itemize{
\item \eqn{H_0}{H0}: \eqn{\theta \geq b}{\theta >= b}
\item \eqn{H_1}{H1}: \eqn{\theta < b}
\item \eqn{t=(\theta - b)/\sigma_\theta}{t=(\theta - b)/\sigma_\theta}
\item p: Lower-tail probability
}

Equivalence: Two One-Sided Tests (TOST)
\itemize{
\item p: Maximum of the non-inferiority and non-superiority p values.
}

Thanks to Russell V. Lenth for the excellent \code{emmeans} package and documentation which inspired this feature.
}

\examples{
library(marginaleffects)
mod <- lm(mpg ~ hp + wt + factor(cyl), data = mtcars)

hypotheses(mod)

# Test of equality between coefficients
hypotheses(mod, hypothesis = "hp = wt")

# Non-linear function
hypotheses(mod, hypothesis = "exp(hp + wt) = 0.1")

# Robust standard errors
hypotheses(mod, hypothesis = "hp = wt", vcov = "HC3")

# b1, b2, ... shortcuts can be used to identify the position of the
# parameters of interest in the output of
hypotheses(mod, hypothesis = "b2 = b3")

# wildcard
hypotheses(mod, hypothesis = "b* / b2 = 1")

# term names with special characters have to be enclosed in backticks
hypotheses(mod, hypothesis = "`factor(cyl)6` = `factor(cyl)8`")

mod2 <- lm(mpg ~ hp * drat, data = mtcars)
hypotheses(mod2, hypothesis = "`hp:drat` = drat")

# predictions(), comparisons(), and slopes()
mod <- glm(am ~ hp + mpg, data = mtcars, family = binomial)
cmp <- comparisons(mod, newdata = "mean")
hypotheses(cmp, hypothesis = "b1 = b2")

mfx <- slopes(mod, newdata = "mean")
hypotheses(cmp, hypothesis = "b2 = 0.2")

pre <- predictions(mod, newdata = datagrid(hp = 110, mpg = c(30, 35)))
hypotheses(pre, hypothesis = "b1 = b2")

# The `hypothesis` argument can be used to compute standard errors for fitted values
mod <- glm(am ~ hp + mpg, data = mtcars, family = binomial)

f <- function(x) predict(x, type = "link", newdata = mtcars)
p <- hypotheses(mod, hypothesis = f)
head(p)

f <- function(x) predict(x, type = "response", newdata = mtcars)
p <- hypotheses(mod, hypothesis = f)
head(p)

# Complex aggregation
# Step 1: Collapse predicted probabilities by outcome level, for each individual
# Step 2: Take the mean of the collapsed probabilities by group and `cyl`
library(dplyr)
library(MASS)
library(dplyr)

dat <- transform(mtcars, gear = factor(gear))
mod <- polr(gear ~ factor(cyl) + hp, dat)

aggregation_fun <- function(x) {
  predictions(x, vcov = FALSE) |>
    mutate(group = ifelse(group \%in\% c("3", "4"), "3 & 4", "5")) |>
    summarize(estimate = sum(estimate), .by = c("rowid", "cyl", "group")) |>
    summarize(estimate = mean(estimate), .by = c("cyl", "group")) |>
    rename(term = cyl)
}

hypotheses(mod, hypothesis = aggregation_fun)

# Equivalence, non-inferiority, and non-superiority tests
mod <- lm(mpg ~ hp + factor(gear), data = mtcars)
p <- predictions(mod, newdata = "median")
hypotheses(p, equivalence = c(17, 18))

mfx <- avg_slopes(mod, variables = "hp")
hypotheses(mfx, equivalence = c(-.1, .1))

cmp <- avg_comparisons(mod, variables = "gear", hypothesis = ~pairwise)
hypotheses(cmp, equivalence = c(0, 10))

# joint hypotheses: character vector
model <- lm(mpg ~ as.factor(cyl) * hp, data = mtcars)
hypotheses(model, joint = c("as.factor(cyl)6:hp", "as.factor(cyl)8:hp"))

# joint hypotheses: regular expression
hypotheses(model, joint = "cyl")

# joint hypotheses: integer indices
hypotheses(model, joint = 2:3)

# joint hypotheses: different null hypotheses
hypotheses(model, joint = 2:3, hypothesis = 1)
hypotheses(model, joint = 2:3, hypothesis = 1:2)

# joint hypotheses: marginaleffects object
cmp <- avg_comparisons(model)
hypotheses(cmp, joint = "cyl")

# Multiple comparison adjustment
# p values and family-wise confidence intervals
cmp <- avg_comparisons(model)
hypotheses(cmp, multcomp = "hochberg")

}
