% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/drop1.loglm.R
\name{drop1.loglm}
\alias{drop1.loglm}
\alias{LRanova}
\alias{assoc_strength}
\title{Term-level tests and effect sizes for loglm models}
\usage{
\method{drop1}{loglm}(object, scope, test = c("Chisq", "none"), abbrev = FALSE, ...)

LRanova(
  object,
  baseline = NULL,
  test = c("Chisq", "none"),
  abbrev = FALSE,
  ...
)

assoc_strength(
  object,
  scope,
  method = c("Cramer", "Cohen"),
  abbrev = FALSE,
  ...
)
}
\arguments{
\item{object}{a fitted \code{MASS::loglm} model}

\item{scope}{character vector of term labels (colon-separated, as in
\code{"A:B"}) to test; must be a subset of the model's generating class.
Defaults to the full generating class. Used by \code{drop1.loglm()} and
\code{assoc_strength()}.}

\item{test}{\code{"Chisq"} (default) to include an LR p-value column, or
\code{"none"} to omit it.}

\item{abbrev}{passed to \code{\link[=get_model]{get_model()}} for the \verb{Model:}/\verb{Baseline:}
heading line(s); \code{FALSE} (default) for full factor names, or an integer
(e.g. \code{4}) to abbreviate each factor name to that many characters --
useful when the generating class has many terms and the heading line
gets long (see the DaytonSurvey example below).}

\item{...}{currently unused in \code{drop1.loglm()}; passed on to it from
\code{LRanova()}/\code{assoc_strength()}.}

\item{baseline}{\code{NULL} (default) to use the model of mutual independence
over the variables in \code{object}'s generating class, or a fitted \code{loglm}
model nested within \code{object} to use as the reference for partial R^2.
Used by \code{LRanova()} only.}

\item{method}{\code{"Cramer"} (default) for partial Cramer's V, generalized to
terms of any order by using the \emph{smallest} factor level count among the
term's variables in place of the usual two-way \code{min(r,c)}; this reduces
exactly to the ordinary two-way Cramer's V (as used by
\code{\link[vcd:assocstats]{vcd::assocstats()}}) when the term has two factors. Bounded to \verb{[0,1]}.
\code{"Cohen"} for Cohen's w = \code{sqrt(Delta-X^2 / N)}: unbounded, but requires
no reference to table shape, so it stays well-defined uniformly for
terms of any order. Used by \code{assoc_strength()} only.}
}
\value{
An object of class \code{c("anova", "data.frame")} with columns \code{Df},
\verb{LR Chisq}, \verb{Pearson Chisq}, and (if \code{test = "Chisq"}) \verb{Pr(>Chi)}, one
row per tested term plus a \verb{<none>} reference row. The fitted models
underlying each row -- \code{object} itself as \code{"<none>"}, plus the refit
dropping each term in \code{scope} -- are attached as \code{attr(., "models")}, a
\code{loglmlist} (see \code{\link[=loglmlist]{loglmlist()}}) with names matching the table's row
names. This is free (the models are already fit to compute the
Delta-statistics) and makes the whole \verb{*.loglmlist} toolchain available
without refitting, e.g. \code{mosaic(attr(result, "models"), ask = FALSE)}
for a grid of the full model and every drop-one model, or
\code{LRstats(attr(result, "models"))} for an AIC/BIC comparison.

\code{LRanova()} adds a \verb{Partial R2} column. The baseline model is attached
separately as \code{attr(., "baseline")}, since it's a single reference
model rather than one of the \verb{<none>}/drop-one rows in
\code{attr(., "models")}.

\code{assoc_strength()} adds a \code{"Cramer's V"} or \code{"Cohen's w"} column. Note
this is a \emph{partial} association -- conditional on the other terms in
\code{object} -- not the marginal association from \code{vcd::assocstats()} on
the term's own two-way margin; the two can differ sharply (see the
UCBAdmissions \code{Admit:Gender} example below, a classic Simpson's-paradox
case).
}
\description{
\code{drop1.loglm()} performs single-term deletion tests for the generating
class of a fitted \code{\link[MASS:loglm]{MASS::loglm()}} model: for each term in that
class, it drops that term, refits via \code{update()}, and reports the change
in both the LR statistic (G^2) and the Pearson statistic (X^2).
}
\details{
\code{LRanova()} wraps \code{drop1.loglm()} and adds a partial R^2 effect-size
column: the fraction of a baseline model's G^2 attributable to each
dropped term.

\code{assoc_strength()} wraps \code{drop1.loglm()} and adds a partial Cramer's V or
Cohen's w effect-size column, converting each term's partial Pearson X^2
into a bounded or semi-bounded measure of association strength.

All three functions test terms in the model's \emph{generating class} --
the set of highest-order terms in a hierarchical loglinear model, from
which every lower-order relative (main effects, lower interactions) is
implied and so doesn't need to be listed or tested separately.

For example, with four factors \code{A}, \code{B}, \code{C}, \code{D} and the model
\code{~ (A + B + C + D)^2} (all terms up to two-way), the fitted model
contains ten terms in all -- four main effects and six two-way
interactions -- but its generating class is just the six two-way terms:
\code{A:B}, \code{A:C}, \code{A:D}, \code{B:C}, \code{B:D}, \code{C:D} (bracket notation \verb{[A,B] [A,C] [A,D] [B,C] [B,D] [C,D]}).

None of the four main effects is maximal on
its own -- \code{A}, say, is already implied by \code{A:B} (or any of \code{A:C},
\code{A:D}) -- so they're excluded from the generating class even though
they're very much still part of the fitted model. This is exactly what
\code{MASS::loglm()} stores in \code{object$margin}, and exactly the set of terms
\code{scope} defaults to and \code{drop1.loglm()} tests: dropping \code{A:B} removes
only that interaction, leaving \code{A} and \code{B}'s main effects in place
(still implied by \code{A:C}/\code{A:D} and \code{B:C}/\code{B:D} respectively), so the
reduced model stays hierarchical.
\subsection{Comparison with \code{drop1.glm()}}{

A hierarchical \code{loglm()} model has an equivalent fit via
\code{glm(family = poisson)}, and \code{stats::drop1.glm()}'s default \code{scope}
already restricts to the same generating-class terms as \code{object$margin},
so \code{Df} and the LR statistic agree exactly between the two. \code{drop1.loglm()}
works directly on table/array or \code{Freq ~ ...} data, adds the Pearson X^2
column, and returns the fitted drop-one models for reuse; its \code{scope}
validation also guards against testing a non-generating-class term, which
\code{drop1.glm()} will silently allow with a misleading result. See
\code{dev/anova-like/drop1-compare.R} for a worked comparison.
}
}
\examples{
library(MASS)
ucb <- loglm(~ (Admit + Gender + Dept)^2, data = UCBAdmissions)

drop1.loglm(ucb)
drop1.loglm(ucb, scope = "Admit:Gender")   # test only a subset
drop1.loglm(ucb, abbrev = 4)               # abbreviate factor names
names(attr(drop1.loglm(ucb), "models"))    # the fitted models, for free

# data.frame + `Freq ~ ...` form works too, not just array/table data
data(DaytonSurvey, package = "vcdExtra")
DS <- loglm(Freq ~ (cigarette + alcohol + marijuana + sex + race)^2,
            data = DaytonSurvey)
drop1.loglm(DS)

LRanova(ucb)  # default baseline: mutual independence over Admit, Gender, Dept

# supply a specific (nested) baseline other than the default -- here, one
# that already includes Admit:Gender, so partial R^2 is now relative to a
# smaller remaining G^2 than the mutual-independence baseline above
partial_baseline <- loglm(~ Admit + Gender + Dept + Admit:Gender, data = UCBAdmissions)
LRanova(ucb, baseline = partial_baseline)

assoc_strength(ucb)                     # Cramer's V (default)
assoc_strength(ucb, method = "Cohen")   # Cohen's w

# partial (conditional on Dept) vs. marginal association -- the small
# partial Admit:Gender V here versus the much larger marginal V below is
# the classic Simpson's-paradox story for this dataset
vcd::assocstats(margin.table(UCBAdmissions, c(1, 2)))

# Cramer's V and Cohen's w coincide when every factor in a term is binary,
# and diverge once a term involves a factor with more levels
hec <- loglm(~ (Hair + Eye + Sex)^2, data = HairEyeColor)
assoc_strength(hec)  # Hair, Eye each have 4 levels
}
\seealso{
\code{\link[=mosaic.loglmlist]{mosaic.loglmlist()}}, \code{\link[=LRstats]{LRstats()}}, \code{\link[=get_models]{get_models()}}
}
\author{
Michael Friendly
}
