Nothing
#############################################################################
## Copyright (c) 2010-2022 Rune Haubo Bojesen Christensen
##
## This file is part of the ordinal package for R (*ordinal*)
##
## *ordinal* is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 2 of the License, or
## (at your option) any later version.
##
## *ordinal* is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## A copy of the GNU General Public License is available at
## <https://www.r-project.org/Licenses/> and/or
## <http://www.gnu.org/licenses/>.
#############################################################################
## This file contains:
## methods for computing, manipulating and extracting design matrices,
## weights, offsets, model.frames and things like that.
## #################################
## ## call sequence
## clm() {
## get_clmFormulas()
## get_clm.mf()
## get_clmTerms() # optionally
## get_clmDesign()
##
## makeThresholds()
## drop.cols()
##
## clm.fit.default()
## get_clmInfoTab()
## }
##
## get_clmFormulas() {
## getFullForm()
## }
##
## get_clm.mf() {
## model.frame()
## }
##
## get_clmTerms() {
## get_clm.mf()
## }
##
## get_clmDesign() {
## checkContrasts()
## get_clmDM() ## for formula, scale, nominal
## getWeights()
## get_clmY()
## }
##
## get_clmDM() {
## model.matrix()
## getContrasts()
## getOffset()
## }
get_clmTerms <-
function(mc, formulas, call.envir=parent.frame(2L))
### Compute terms objects for each of the formulas.
{
## We need this approach in order to get the predvars and
## dataClasses attributes of the terms objects.
nms <- c("formula", "scale", "nominal")
keep <- match(nms, names(formulas), nomatch=0)
lapply(formulas[keep], function(form) {
terms(get_clm.mf(mc, form, attr(formulas, "envir"), call.envir))
})
}
get_clmDesign <- function(fullmf, terms.list, contrasts) {
### Compute (y, X, weights, off, S, NOM etc.) for a clm object.
### clm-internal+external
###
### terms.list: list of terms.objects.
stopifnot(all(sapply(terms.list, inherits, "terms")))
## Check that contrasts are specified only for terms in the model:
checkContrasts(terms=attr(fullmf, "terms"), contrasts=contrasts)
## Extract X (design matrix for location effects) + terms, offset:
res <- get_clmDM(fullmf, terms.list[["formula"]], contrasts,
type="formula")
res$terms <- terms.list[["formula"]]
res$contrasts <- attr(res$X, "contrasts")
res$xlevels <- .getXlevels(res$terms, fullmf)
res$na.action <- attr(fullmf, "na.action")
## Extract weights:
res$weights <- getWeights(fullmf)
## Extract model response:
res <- c(get_clmY(fullmf, res$weights), res)
## Extract S (design matrix for the scale effects):
if(!is.null(terms.list$scale)) {
ans <- get_clmDM(fullmf, terms.list[["scale"]], contrasts,
type="scale")
res$S <- ans$X
res$S.terms <- terms.list[["scale"]]
res$S.off <- ans$offset
res$S.contrasts <- attr(res$S, "contrasts")
res$S.xlevels <- .getXlevels(res$S.terms, fullmf)
if(attr(res$S.terms, "response") != 0)
stop("response not allowed in 'scale'", call.=FALSE)
}
## Extract NOM (design matrix for the nominal effects):
if(!is.null(terms.list$nominal)) {
ans <- get_clmDM(fullmf, terms.list[["nominal"]], contrasts,
type="nominal")
res$NOM <- ans$X
res$nom.terms <- terms.list[["nominal"]]
res$nom.contrasts <- attr(res$NOM, "contrasts")
res$nom.xlevels <- .getXlevels(res$nom.terms, fullmf)
if(attr(res$nom.terms, "response") != 0)
stop("response not allowed in 'nominal'", call.=FALSE)
if(!is.null(attr(res$nom.terms, "offset")))
stop("offset not allowed in 'nominal'", call.=FALSE)
}
## Return results (list of design matrices etc.):
res
### NOTE: X, S and NOM are with dimnames and intercepts are
### guaranteed. They may be column rank deficient.
}
get_clmDM <-
function(fullmf, terms, contrasts, check.intercept=TRUE,
type="formula", get.offset=TRUE)
### Get DM (=Design Matrix):
{
X <- model.matrix(terms, data=fullmf,
contrasts.arg=getContrasts(terms, contrasts))
## Test for intercept in X(?):
Xint <- match("(Intercept)", colnames(X), nomatch = 0)
if(check.intercept && Xint <= 0) {
X <- cbind("(Intercept)" = rep(1, nrow(X)), X)
warning(gettextf("an intercept is needed and assumed in '%s'", type),
call.=FALSE)
} ## Intercept in X is guaranteed.
res <- list(X=X)
if(get.offset)
res$offset <- getOffset(fullmf, terms)
res
}
get_clm.mf <-
function(mc, formula, form.envir, call.envir=parent.frame(2L))
### clm-internal
### Extract the model.frame from formula
### mc - matched call containing: data, subset, weights, na.action
{
## Extract the full model.frame(mf):
m <- match(c("data", "subset", "weights", "na.action"),
names(mc), 0)
mfcall <- mc[c(1, m)]
mfcall$formula <- formula
mfcall$drop.unused.levels <- TRUE
mfcall[[1]] <- as.name("model.frame")
if(is.null(mfcall$data)) mfcall$data <- form.envir
eval(mfcall, envir=call.envir)
}
get_clmY <- function(fullmf, weights) {
y <- model.response(fullmf, "any") ## any storage mode
if(is.null(y)) stop("'formula' needs a response", call.=FALSE)
if(!is.factor(y)) stop("response in 'formula' needs to be a factor", call.=FALSE)
## y.levels are the levels of y with positive weights
y.levels <- levels(droplevels(y[weights > 0]))
## check that y has at least two levels:
if(length(y.levels) == 1L)
stop(gettextf("response has only 1 level ('%s'); expecting at least two levels",
y.levels), call.=FALSE)
if(!length(y.levels))
stop("response should be a factor with at least two levels")
## return:
list(y=y, y.levels=y.levels)
}
get_clmFormulas <- function(mc, envir=parent.frame(2L))
### clm-internal
### Extracts and returns a list of formulas needed for further processing.
### mc: matched call
### envir: environment in which mc is to be evaluated
{
## Collect all variables in a full formula:
## evaluate the formulae in the enviroment in which clm was called
## (parent.frame(2)) to get them evaluated properly:
forms <- list(eval(mc$formula, envir=envir))
if(!is.null(mc$scale)) forms$scale <- eval(mc$scale, envir=envir)
if(!is.null(mc$nominal)) forms$nominal <- eval(mc$nominal, envir=envir)
## get the environment of the formula. If this does not have an
## enviroment (it could be a character), then use the parent frame.
form.envir <-
if(!is.null(env <- environment(forms[[1]]))) env else envir
## ensure formula, scale and nominal are formulas:
forms[] <- lapply(forms, function(x) { # 'is.character(.)' for scale = "~ ..."
tryCatch(formula(if(is.character(x)) x else Deparse(x),
env = form.envir),
error = function(e)e)
})
if(any(vapply(forms, inherits, FUN.VALUE=logical(1), what="error")))
stop("unable to interpret 'formula', 'scale' or 'nominal'")
## collect all variables in a full formula:
forms$fullForm <- do.call("getFullForm", forms)
### OPTION: do we actually need to set this name?
names(forms)[1] <- "formula"
## set environment of 'fullForm' to the environment of 'formula':
attr(forms, "envir") <- environment(forms$fullForm) <- form.envir
## return:
forms
}
get_clmRho <- function(object, ...) {
UseMethod("get_clmRho")
}
get_clmRho.default <-
function(object, terms.list, contrasts, link, threshold,
parent=parent.frame(), start=NULL, control=clm.control(), ...)
### .default method(?)
### object: model.frame (fullmf) with all variables present
### terms.list: list of terms.objects for each of the formulas in the
### clm object.
{
## Get design matrices etc:
design <- get_clmDesign(fullmf=object,
terms.list=terms.list,
contrasts=contrasts)
## Get threshold information:
design <- c(design, makeThresholds(design$y.levels, threshold))
## Drop columns for aliased coefs:
design <- drop.cols(design, drop.scale=FALSE, silent=TRUE)
## Set envir rho with variables: B1, B2, o1, o2, weights, fitted:
rho <- with(design, {
clm.newRho(parent.frame(), y=y, X=X, NOM=design$NOM, S=design$S,
weights=weights, offset=offset, S.offset=design$S.off,
tJac=tJac, control=control)
})
## Set and check starting values for the parameters:
start <- set.start(rho, start=start, get.start=is.null(start),
threshold=threshold, link=link, frames=design)
rho$par <- as.vector(start) ## remove attributes
## Set pfun, dfun and gfun in rho:
setLinks(rho, link)
## Return:
rho
}
get_clmRho.clm <-
function(object, parent=parent.frame(), ...) {
### Safely generate the model environment from a model object.
o <- object
get_clmRho.default(object=model.frame(o),
terms.list=terms(o, "all"),
contrasts=o$contrasts, start=c(o$start), link=o$link,
threshold=o$threshold, parent=parent, control=o$control,
...)
}
## get_mfcall <- function(mc, envir=parent.frame(2)) {
## m <- match(c("data", "subset", "weights", "na.action"),
## names(mc), 0)
## mf <- mc[c(1, m)]
## ## mf$formula <- fullForm
## mf$drop.unused.levels <- TRUE
## mf[[1]] <- as.name("model.frame")
## ## if(is.null(mf$data)) mf$data <- form.envir
## list(mfcall=mf, envir=parent.frame(2))
## }
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.