Nothing
multilevelR2 <- function(model, print = c("RB1", "RB2", "SB", "MVP")){
# print argument case insensitive
print <- toupper(print)
print <- match.arg(print, several.ok = TRUE)
method <- NULL
# select method
if(is.list(model)){
cls <- class(model[[1]])
if(inherits(model[[1]], "merMod")) method <- "lmer"
if(inherits(model[[1]], "lme")) method <- "nlme"
}else{
cls <- class(model)
if(inherits(model, "merMod")) method <- "lmer"
if(inherits(model, "lme")) method <- "nlme"
}
if(is.null(method)) stop("Calculation of multilevel R-squared statistics not supported for models of class '", paste0(cls, collapse = "|"), "'.")
# calculate R-squared
if(is.list(model)){
out <- sapply(model, .getRsquared, print = print, method = method)
if(is.null(dim(out))) out <- matrix(out, nrow = 1)
out <- rowMeans(out)
}else{
out <- .getRsquared(model, print, method)
}
out
}
.getRsquared <- function(model, print, method){
# R squared for single model fit (lme4)
# check if refit is necessary
refit <- any(c("RB1", "RB2", "SB") %in% print)
if(method == "lmer"){
# model terms
trm <- terms(model)
if(!as.logical(attr(trm, "intercept"))) stop("Model must contain intercept.")
yvr <- as.character(attr(trm, "variables")[-1])[attr(trm, "response")]
cvr <- names(lme4::getME(model, "flist"))
if(length(cvr)>1) stop("Calculation of R-squared only support for models with a single cluster variable.")
cvr <- cvr[1]
if(refit){
# fit null model
fml0 <- formula(paste0(yvr, "~1+(1|", cvr, ")"))
model0 <- update(model, fml0)
# variance components under null
vc0 <- lme4::VarCorr(model0)
s0 <- attr(vc0, "sc")^2
t0.0 <- vc0[[cvr]][1, 1]
}
# alternative model components
beta <- lme4::fixef(model)[-1]
X <- lme4::getME(model, "X")[, -1, drop = F]
Z <- lme4::getME(model, "mmList")[[1]][, -1, drop = F]
muX <- colMeans(X)
muZ <- colMeans(Z)
vZ <- cov(Z)
# predicted and total variance
vc1 <- lme4::VarCorr(model)
t0.1 <- vc1[[cvr]][1, 1]
t10.1 <- vc1[[cvr]][1, -1]
t11.1 <- vc1[[cvr]][-1, -1, drop = F]
s1 <- attr(vc1, "sc")^2
}
if(method == "nlme"){
# model terms
trm <- terms(model)
if(!as.logical(attr(trm, "intercept"))) stop("Model must contain intercept.")
yvr <- as.character(attr(trm, "variables")[-1])[attr(trm, "response")]
cvr <- attr(nlme::getGroups(model), "label")
if(length(nlme::getGroupsFormula(model, asList = T))>1) stop("Calculation of R-squared only support for models with a single cluster variable.")
if(refit){
# fit null model
ffml0 <- formula(paste0(yvr, "~1"))
rfml0 <- formula(paste0("~1|", cvr, ""))
if(is.null(nlme::getData(model))) stop("No data sets found in 'lme' fit. See '?testModels' for an example.")
model0 <- update(model, fixed = ffml0, random = rfml0, data = model$data)
# variance components under null
vc0 <- nlme::getVarCov(model0)
s0 <- model0$sigma^2
t0.0 <- vc0[1, 1]
}
# alternative model components
beta <- nlme::fixef(model)[-1]
fe <- model$terms
X <- model.matrix(fe, nlme::getData(model))[, -1, drop = F]
re <- attr(model$modelStruct$reStruct[[1]], "formula")
Z <- model.matrix(re, nlme::getData(model))[, -1, drop = F]
muX <- colMeans(X)
muZ <- colMeans(Z)
vZ <- cov(Z)
# predicted and total variance
vc1 <- nlme::getVarCov(model)
t0.1 <- vc1[1, 1]
t10.1 <- vc1[1, -1]
t11.1 <- vc1[-1, -1, drop = F]
s1 <- model$sigma^2
}
# calculate R2
vyhat <- var( X %*% beta )
vy <- vyhat + t0.1 + 2*(muZ %*% t10.1) + muZ%*%t11.1%*%muZ + sum(diag(t11.1%*%vZ)) + s1
if(refit){
rb1 <- 1 - s1/s0
rb2 <- 1 - t0.1/t0.0
sb <- 1 - (s1+t0.1)/(s0+t0.0)
}else{
rb1 <- rb2 <- sb <- NA
}
mvp <- as.vector(vyhat/vy)
c(RB1 = rb1, RB2 = rb2, SB = sb, MVP = mvp)[print]
}
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.