Nothing
sigmaMethod <-
getExportedValue(if(getRversion() >= "3.3.0") "stats" else "lme4", "sigma")
setClass("FLXMRlmer",
representation(random = "formula",
lmod = "list",
control = "ANY",
preproc.z = "function"),
prototype(preproc.z = function(x, ...) x),
contains = "FLXMRglm")
defineComponent_lmer <- function(para) {
predict <- function(x, ...) x%*%para$coef
logLik <- function(x, y, lmod, ...) {
z <- as.matrix(lmod$reTrms$Zt)
grouping <- lmod$reTrms$flist[[1]]
llh <- vector(length=nrow(x))
for (i in seq_len(nlevels(grouping))) {
index1 <- which(grouping == levels(grouping)[i])
index2 <- rownames(z) %in% levels(grouping)[i]
V <- crossprod(z[index2,index1,drop=FALSE], para$sigma2$Random) %*% z[index2, index1, drop=FALSE] + diag(length(index1)) * para$sigma2$Residual
llh[index1] <- mvtnorm::dmvnorm(y[index1,], mean=predict(x[index1,,drop=FALSE], ...), sigma = V, log=TRUE)/length(index1)
}
llh
}
new("FLXcomponent",
parameters=list(coef=para$coef, sigma2=para$sigma2),
logLik=logLik, predict=predict,
df=para$df)
}
FLXMRlmer <- function(formula = . ~ ., random, weighted = TRUE,
control = list(), eps = .Machine$double.eps)
{
random <- if (length(random) == 3) random else formula(paste(".", paste(deparse(random), collapse = "")))
missCtrl <- missing(control)
if (missCtrl || !inherits(control, "lmerControl")) {
if (!is.list(control))
stop("'control' is not a list; use lmerControl()")
control <- do.call(lme4::lmerControl, control)
}
object <- new("FLXMRlmer", formula = formula, random = random, control = control,
family = "gaussian", weighted = weighted, name = "FLXMRlmer:gaussian")
if (weighted) object@preproc.z <- function(lmod) {
if (length(unique(names(lmod[["reTrms"]][["flist"]]))) != 1) stop("only a single variable for random effects is allowed")
for (i in seq_along(lmod[["reTrms"]][["flist"]])) {
DIFF <- t(sapply(levels(lmod[["reTrms"]]$flist[[i]]), function(id) {
index1 <- which(lmod[["reTrms"]]$flist[[i]] == id)
index2 <- rownames(lmod[["reTrms"]]$Zt) == id
sort(apply(lmod[["reTrms"]]$Zt[index2, index1, drop=FALSE], 1, paste, collapse = ""))
}))
if (length(unique(table(lmod[["reTrms"]][["flist"]][[i]]))) != 1 || nrow(unique(DIFF)) != 1)
stop("FLXMRlmer does only work correctly if the covariates of the random effects are the same for all observations")
}
lmod
}
lmer.wfit <- function(x, y, w, lmod) {
zero.weights <- any(w < eps)
if (zero.weights) {
ok <- w >= eps
w <- w[ok]
lmod[["fr"]] <- lmod[["fr"]][ok, , drop = FALSE]
lmod[["X"]] <- lmod[["X"]][ok, , drop = FALSE]
lmod[["reTrms"]][["Zt"]] <- lmod[["reTrms"]][["Zt"]][, ok, drop = FALSE]
for (i in seq_along(lmod[["reTrms"]][["flist"]])) {
lmod[["reTrms"]][["flist"]][[i]] <- lmod[["reTrms"]][["flist"]][[i]][ok]
}
}
wts <- sqrt(w)
lmod$X <- lmod$X * wts
lmod$fr[[1]] <- lmod$fr[[1]] * wts
devfun <- do.call(lme4::mkLmerDevfun, c(lmod, list(start = NULL, verbose = FALSE,
control = control)))
opt <- lme4::optimizeLmer(devfun, optimizer = control$optimizer,
restart_edge = control$restart_edge, control = control$optCtrl,
verbose = FALSE, start = NULL)
mer <- lme4::mkMerMod(environment(devfun), opt, lmod$reTrms, fr = lmod$fr)
sigma_res <- sigmaMethod(mer) / sqrt(mean(w))
vc <- lme4::VarCorr(mer)
n <- c(0, cumsum(sapply(vc, ncol)))
Random <- matrix(0, max(n), max(n))
for (i in seq_along(vc)) {
index <- (n[i]+1):n[i+1]
Random[index, index] <- vc[[i]]
}
Random <- Random / mean(w)
list(coefficients = lme4::fixef(mer),
sigma2 = list(Random = Random,
Residual = sigma_res^2),
df = length(lme4::fixef(mer)) + 1 + length(mer@theta))
}
object@defineComponent <- defineComponent_lmer
object@fit <- function(x, y, w, lmod){
fit <- lmer.wfit(x, y, w, lmod)
object@defineComponent(
list(coef = coef(fit),
df = fit$df,
sigma2 = fit$sigma2))
}
object
}
setMethod("FLXgetModelmatrix", signature(model="FLXMRlmer"),
function(model, data, formula, lhs=TRUE, contrasts = NULL, ...)
{
formula_nogrouping <- RemoveGrouping(formula)
if (identical(paste(deparse(formula_nogrouping), collapse = ""), paste(deparse(formula), collapse = ""))) stop("please specify a grouping variable")
model <- callNextMethod(model, data, formula, lhs)
random_formula <- update(model@random,
paste(".~. |", .FLXgetGroupingVar(formula)))
fullformula <- model@fullformula
if (!lhs) fullformula <- fullformula[c(1,3)]
fullformula <- update(fullformula,
paste(ifelse(lhs, ".", ""), "~. + ", paste(deparse(random_formula[[3]]), collapse = "")))
model@fullformula <- update(model@fullformula,
paste(ifelse(lhs, ".", ""), "~. |", .FLXgetGroupingVar(formula)))
model@lmod <- lme4::lFormula(fullformula, data, REML = FALSE, control = model@control)
model@lmod <- model@preproc.z(model@lmod)
model
})
setMethod("FLXmstep", signature(model = "FLXMRlmer"),
function(model, weights, ...)
{
apply(weights, 2, function(w) model@fit(model@x, model@y, w, model@lmod))
})
setMethod("FLXdeterminePostunscaled", signature(model = "FLXMRlmer"), function(model, components, ...) {
sapply(components, function(x) x@logLik(model@x, model@y, model@lmod))
})
setMethod("rFLXM", signature(model = "FLXMRlmer", components="FLXcomponent"),
function(model, components, ...) {
sigma2 <- components@parameters$sigma2
z <- as.matrix(model@lmod$reTrms$Zt)
grouping <- model@lmod$reTrms$flist[[1]]
y <- matrix(0, nrow=nrow(model@x), ncol = 1)
for (i in seq_len(nlevels(grouping))) {
index1 <- which(grouping == levels(grouping)[i])
index2 <- rownames(z) %in% levels(grouping)[i]
V <- crossprod(z[index2,index1,drop=FALSE], sigma2$Random) %*% z[index2, index1, drop=FALSE] + diag(length(index1)) * sigma2$Residual
y[index1, 1] <- mvtnorm::rmvnorm(1, mean=components@predict(model@x[index1,,drop=FALSE], ...), sigma = V)
}
y
})
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.