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 to compute and plot likelihood-slices for clm objects.
slice <- function(object, ...) {
UseMethod("slice")
}
slice.clm <-
function(object, parm = seq_along(par), lambda = 3, grid = 1e2,
quad.approx = TRUE, ...)
{
## argument matching and testing:
stopifnot(is.numeric(lambda) && lambda > 0)
stopifnot(is.numeric(grid) && grid >= 1)
grid <- as.integer(round(grid))
par <- coef(object, na.rm=TRUE)
par.names <- names(par)
npar <- length(par)
stopifnot(length(parm) == length(unique(parm)))
if(is.character(parm))
parm <- match(parm, par.names, nomatch = 0)
### disallow character argument due to ambiguity?
if(!all(parm %in% seq_along(par)))
stop("invalid 'parm' argument")
stopifnot(length(parm) > 0)
parm <- as.integer(round(parm))
## parm is an integer vector indexing non-aliased coef.
ml <- object$logLik
parm.names <- par.names[parm]
## get environment corresponding to object:
rho <- get_clmRho(object)
## rho <- update(object, doFit = FALSE)
names(par) <- NULL
rho$par <- par ## set rho$par to mle
stopifnot(isTRUE(all.equal(rho$clm.nll(rho), -object$logLik)))
## generate sequence of parameters at which to compute the
## log-likelihood:
curv <- sqrt(1/diag(object$Hessian)) ## curvature in nll wrt. par
par.range <- par + curv %o% c(-lambda, lambda)
## par.seq - list of length npar with a sequence of values for each
## parameter :
par.seq <- lapply(parm, function(ind) {
seq(par.range[ind, 1], par.range[ind, 2], length = grid) })
## compute relative logLik for all par.seq for each par:
logLik <- lapply(seq_along(parm), function(i) { # for each par
rho$par <- par ## reset par values to MLE
sapply(par.seq[[ i ]], function(par.val) { # for each par.seq value
rho$par[ parm[i] ] <- par.val
-rho$clm.nll(rho) - ml ## relative logLik
})
})
## collect parameter sequences and relative logLik in a list of
## data.frames:
res <- lapply(seq_along(parm), function(i) {
structure(data.frame(par.seq[[ i ]], logLik[[ i ]]),
names = c(parm.names[i], "logLik"))
})
## set attributes:
names(res) <- parm.names
attr(res, "original.fit") <- object
attr(res, "mle") <- par[parm]
class(res) <- "slice.clm"
if(!quad.approx) return(res)
## compute quadratic approx to *positive* logLik:
Quad <- function(par, mle, curv)
-((mle - par)^2 / curv^2 / 2)
for(i in seq_along(parm))
res[[ i ]]$quad <-
Quad(par.seq[[ i ]], par[ parm[i] ], curv[ parm[i] ])
return(res)
}
plot.slice.clm <-
function(x, parm = seq_along(x), type = c("quadratic", "linear"),
plot.mle = TRUE,
ask = prod(par("mfcol")) < length(parm) && dev.interactive(),
...)
{
## Initiala argument matching and testing:
type <- match.arg(type)
stopifnot(is.numeric(parm))
parm <- as.integer(round(parm))
of <- attr(x, "original.fit")
par <- coef(of)
ml <- of$logLik
## take the signed sqrt of nll and quad:
if(type == "linear") {
sgn.sqrt <- function(par, mle, logLik)
(2 * (par > mle) - 1) * sqrt(-logLik)
mle <- coef(attr(x, "original.fit"))
for(i in parm) {
x[[i]]$logLik <- sgn.sqrt(x[[i]][1], mle[i], x[[i]]$logLik)
if(!is.null(x[[i]]$quad))
x[[i]]$quad <- sgn.sqrt(x[[i]][1], mle[i], x[[i]]$quad)
}
ylab <- "Signed log-likelihood root"
}
else
ylab <- "Relative log-likelihood"
if(ask) {
oask <- devAskNewPage(TRUE)
on.exit(devAskNewPage(oask))
}
## actual plotting:
for(i in parm) {
z <- x[[i]]
plot(z[1:2], type = "l", ylab=ylab, ...)
if(!is.null(z$quad))
lines(z[[1]], z[[3]], lty = 2)
if(plot.mle && type == "quadratic")
## abline(v = par[i])
abline(v = attr(x, "mle")[i])
## abline(v = par[names(x)[i]])
}
return(invisible())
}
## slice.clm <-
## function(object, parm = seq_along(par), lambda = 3, grid = 1e2,
## quad.approx = TRUE, ...)
## {
## ## argument matching and testing:
## stopifnot(is.numeric(lambda) && lambda > 0)
## stopifnot(is.numeric(grid) && grid >= 1)
## grid <- as.integer(grid)
## par <- coef(object)
## par.names <- names(par)
## npar <- length(par)
## stopifnot(length(parm) == length(unique(parm)))
## if(is.character(parm))
## parm <- match(parm, par.names, nomatch = 0)
## if(!all(parm %in% seq_along(par)))
## stop("invalid 'parm' argument")
## stopifnot(length(parm) > 0)
## parm <- as.integer(parm)
## ml <- object$logLik
## parm.names <- par.names[parm]
##
## ## get environment corresponding to object:
## rho <- update(object, doFit = FALSE)
## names(par) <- NULL
## rho$par <- par ## set rho$par to mle
## stopifnot(isTRUE(all.equal(rho$clm.nll(rho), -object$logLik)))
##
## ## generate sequence of parameters at which to compute the
## ## log-likelihood:
## curv <- sqrt(1/diag(object$Hess)) ## curvature in nll wrt. par
## par.range <- par + curv %o% c(-lambda, lambda)
## ## par.seq - list of length npar:
## par.seq <- sapply(parm, function(ind) {
## seq(par.range[ind, 1], par.range[ind, 2], length = grid) },
## simplify = FALSE)
## ## compute relative logLik for all par.seq for each par:
## logLik <- lapply(seq_along(parm), function(i) { # for each par
## rho$par <- par ## reset par values to MLE
## sapply(par.seq[[ i ]], function(par.val) { # for each val
## rho$par[ parm[i] ] <- par.val
## -rho$clm.nll(rho) - ml ## relative logLik
## })
## })
##
## ## collect results in a list of data.frames:
## res <- lapply(seq_along(parm), function(i) {
## structure(data.frame(par.seq[[ i ]], logLik[[ i ]]),
## names = c(parm.names[i], "logLik"))
## })
##
## ## set attributes:
## names(res) <- parm.names
## attr(res, "original.fit") <- object
## class(res) <- "slice.clm"
##
## if(!quad.approx) return(res)
## ## compute quadratic approx to *positive* logLik:
## Quad <- function(par, mle, curv)
## -((mle - par)^2 / curv^2 / 2)
## for(i in seq_along(parm))
## res[[ i ]]$quad <-
## Quad(par.seq[[ i ]], par[ parm[i] ], curv[ parm[i] ])
##
## return(res)
## }
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.