使用混合效应模型 (lme4) 和模型平均 (MuMIn) 的二项式数据绘制逻辑回归结果

2024-01-10

我正在尝试显示逻辑回归的结果。我的模型使用 lme4 包中的 glmer() 进行拟合,然后我使用 MuMIn 进行模型平均。

我的模型的简化版本使用mtcars数据集:

glmer(vs ~ wt +  am + (1|carb), database, family = binomial, na.action = "na.fail")

我想要的输出是两个图,显示预测的概率vs=1,1为wt,它是连续的,一个为am,这是二项式。

在@KamilBartoń 发表评论后,我得到了这么多工作:

database <- mtcars

# Scale data
database$wt <- scale(mtcars$wt)
database$am <- scale(mtcars$am)

# Make global model
model.1 <- glmer(vs ~ wt + am + (1|carb), database, family = binomial, na.action = "na.fail")

# Model selection
model.1.set <- dredge(model.1, rank = "AICc")

# Get models with <10 delta AICc
top.models.1 <- get.models(model.1.set,subset = delta<10)

# Model averaging
model.1.avg <- model.avg(top.models.1)

# make dataframe with all values set to their mean
xweight <- as.data.frame(lapply(lapply(database[, -1], mean), rep, 100))

# add new sequence of wt to xweight along range of data
xweight$wt <- (wt = seq(min(database$wt), max(database$wt), length = 100))

# predict new values
yweight <- predict(model.1.avg, newdata = xweight, type="response", re.form=NA)

# Make plot 
plot(database$wt, database$vs, pch = 20, xlab = "WEIGHT (g)", ylab = "VS")

# Add predicted line
lines(xweight$wt, yweight)

生产:

剩下的问题是数据按比例缩放并以 0 为中心,这意味着无法解释该图。我可以使用 @BenBolker 的答案来取消数据缩放这个问题 https://stackoverflow.com/questions/53324971/back-transform-coefficients-from-glmer-with-scaled-independent-variables-for-pre/53735644#53735644但这不能正确显示:

## Ben Bolker's unscale function:
## scale variable x using center/scale attributes of variable y
scfun <- function(x,y) {
  scale(x,
        center=attr(y,"scaled:center"),
        scale=attr(y,"scaled:scale"))
        }

## scale prediction frame with scale values of original data -- for all variables
xweight_sc <- transform(xweight,
                        wt = scfun(wt, database$wt),
                        am = scfun(am, database$am))

# predict new values
yweight <- predict(model.1.avg, newdata = xweight_sc, type="response", re.form=NA)

# Make plot 
plot(mtcars$wt, mtcars$vs, pch = 20, xlab = "WEIGHT (g)", ylab = "VS")

# Add predicted line
lines(xweight$wt, yweight)

生产:

我尝试了几种不同的方法,但无法找出问题所在。我做错了什么?

另外,还有一个遗留问题:如何绘制二项式图am?


setup

library(lme4)
library(MuMIn)
database <- mtcars
database$wt <- scale(mtcars$wt)
database$am <- factor(mtcars$am) ## <== note the difference here. It is a factor not numeric
model.1 <- glmer(vs ~ wt + am + (1|carb), database, family = binomial, na.action = "na.fail")
model.1.set <- dredge(model.1, rank = "AICc")
top.models.1 <- get.models(model.1.set,subset = delta<10)
model.1.avg <- model.avg(top.models.1)
nPoints <- 100
wt_pred_data <- data.frame(wt = seq(min(database$wt), max(database$wt), length = nPoints),
                           am = database$am[which.min(database$am)], #Base level for the factor
                           var = 'wt')
am_pred_data <- data.frame(wt = mean(database$wt), 
                           am = unique(database$am),
                           var = 'am')
pred_data <- rbind(wt_pred_data, am_pred_data)
rm(wt_pred_data, am_pred_data)
pred_data$vs <- predict(model.1.avg, newdata = pred_data, re.form = NA, type = 'response')

实际答案

添加到我之前的答案,因为托马斯似乎对人们如何处理感兴趣factor以及如何使用引导程序获得置信区间。

处理因素

首先处理因子并不比处理数值变量困难多少。这里的区别在于

  1. 当绘制对数值变量的影响时,因子应设置为其基本水平(例如,对于am作为一个因素,其值为 1)
  2. 绘制因子时,将所有数值变量设置为平均值,并将所有其他因子设置为基准水平。

获取因子基准水平的一种方法是factor[which.min(factor)]还有一个是factor(levels(factor)[0], levels(factor)). The ggeffects包使用一些与此类似的方法。

引导

现在,实践中的引导有容易的,也有困难的。可以使用参数、半参数或非参数引导程序。
非参数引导是最容易解释的。只需对原始数据集进行采样(例如 2/3、3/4 或 4/5。较少的数据可用于“良好”的较大数据集),使用该样本重新拟合模型,然后预测该新模型。然后重复该过程 N 次,并使用它来估计标准差或分位数,并将其用于置信区间。似乎没有实现的方法MuMIn为我们处理这件事,所以我们似乎必须自己处理这件事。
通常代码会变得非常混乱,而使用函数可以让它变得更加清晰。令我沮丧的是MuMIn然而,这似乎有问题,所以下面是一种非功能性的方法。在此代码中,我选择的样本大小为 4/5,因为数据集大小相当小。

###                            ###
## Non-parametric bootstrapping ##
## Note: Gibberish with         ##
##       singular fit!          ##
###                            ###

# 1) Create sub-sample from the dataset (eg 2/3, 3/4 or 4/5 of the original dataset)
# 2) refit the model using the new dataset and estimate model average using this dataset
# 3) estimate the predicted values using the refitted model
# 4) refit the model N times

nBoot <- 100
frac <- 4/5 #number of points in each sample. Better datasets can use less.
bootStraps <- vector('list', nBoot)
shutup <- function(x) #Useful helper function for making a function shut up
  suppressMessages(suppressWarnings(force(x)))
ii <- seq_len(n <- nrow(database))
nn <- ceiling(frac * n)
nb <- nn * nBoot
samples <- sample(ii, nb, TRUE)
samples <- split(samples, (nn + seq_len(nb) - 1) %/% nn) #See unique((nn + seq_len(nb) - 1) %/% nn) # <= Gives 1 - 100.
#Not run:
# lengths(samples) # <== all of them are 26 long! ceiling(frac * n) = 26!
# Run the bootstraps
for(i in seq_len(nBoot)){
  preds <- try({
    # 1) Sample 
    d <- database[samples[[i]], ]
    # 2) fit the model using the sample
    bootFit <- shutup(glmer(vs ~ wt + am + (1|carb), d, family = binomial, na.action = "na.fail"))
    bootAvg <- shutup(model.avg(get.models(dredge(bootFit, rank = 'AICc'), subset = delta < 10)))
    # 3) predict the data using the new model
    shutup(predict(bootAvg, newdata = pred_data, re.form = NA, type = 'response'))
  }, silent = TRUE)
  #save the predictions for later
  if(!inherits(preds, 'try-error'))
    bootStraps[[i]] <- preds
  # repeat N times
}
# Number of failed bootStraps:
sum(failed <- sapply(bootStraps, is.null)) #For me 44, but will be different for different datasets, samples and seeds.
bootStraps <- bootStraps[which(!failed)]
alpha <- 0.05
# 4) use the predictions for calculating bootstrapped intervals
quantiles <- apply(do.call(rbind, bootStraps), 2, quantile, probs = c(alpha / 2, 0.5, 1 - alpha / 2))
pred_data[, c('lower', 'median', 'upper')] <-  t(quantiles)
pred_data[, 'type'] <- 'non-parametric'

请注意,这当然完全是胡言乱语。拟合是单一的,因为mtcars不是显示混合效果的数据集,因此引导置信区间will完全不正常(值的范围太分散)。另请注意,对于这样一个不稳定的数据集,相当多的引导程序无法收敛到合理的结果。

对于参数引导,我们可以转向lme4::bootMer。该函数需要一个merMod model (glmer or lmer结果)以及在每次参数改装时评估的函数。所以创建这个函数bootMer可以照顾剩下的事情。我们对预测值感兴趣,因此函数应该返回这些值。请注意该函数与上述方法的相似性

###                     ###
## Parametric bootstraps ##
## Note: Singular fit    ##
##       makes this      ##
##       useless!        ##
###                     ###
bootFun <- function(model){
  preds <- try({
    bootAvg <- shutup(model.avg(get.models(dredge(model, rank = 'AICc'), subset = delta < 10)))
    shutup(predict(bootAvg, newdata = pred_data, re.form = NA, type = 'response'))
  }, silent = FALSE)
  if(!inherits(preds, 'try-error'))
    return(preds)
  return(rep(NA_real_, nrow(pred_data)))
}
boots <- bootMer(model.1, FUN = bootFun, nsim = 100, re.form = NA, type = 'parametric')
quantiles <- apply(boots$t, 2, quantile, probs = c(alpha / 2, 0.5, 1 - alpha / 2), na.rm = TRUE)
# Create data to be predicted with parametric bootstraps
pred_data_p <- pred_data
pred_data_p[, c('lower', 'median', 'upper')] <- t(quantiles)
pred_data_p[, 'type'] <- 'parametric'
pred_data <- rbind(pred_data, pred_data_p)
rm(pred_data_p)

再次注意,由于奇点,结果将是乱码。在这种情况下,结果将过于确定,因为奇点意味着模型对于已知数据将过于准确。因此,在实践中,这将使每个间隔的范围都为 0 或足够接近,以至于没有区别。

最后我们只需要绘制结果即可。我们可以用facet_wrap比较参数和非参数结果。再次注意,对于这个特定的数据集,比较完全无用的置信区间是非常胡言乱语的。

请注意,对于因子am i use geom_point and geom_errorbar我在哪里使用geom_line and geom_ribbon对于数值,与数值变量的连续性质相比,更好地表示因子的分组性质


#Finaly we can plot our result:
# wt
library(ggplot2)
ggplot(pred_data[pred_data$var == 'wt', ], aes(y = vs, x = wt)) + 
  geom_line() + 
  geom_ribbon(aes(ymax = upper, ymin = lower), alpha = 0.2) + 
  facet_wrap(. ~ type) + 
  ggtitle('gibberish numeric plot (caused by singularity in fit)')

# am
ggplot(pred_data[pred_data$var == 'am', ], aes(y = vs, x = am)) + 
  geom_point() + 
  geom_errorbar(aes(ymax = upper, ymin = lower)) + 
  facet_wrap(. ~ type) + 
  ggtitle('gibberish factor plot (caused by singularity in fit)')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用混合效应模型 (lme4) 和模型平均 (MuMIn) 的二项式数据绘制逻辑回归结果 的相关文章

  • 将第 N 行上的 NA 行插入 data.frames 列表,其中 N 来自列表

    经过几个小时后 我发现自己无法解决以下问题 我有一个数据框列表 我想分别向每个 DF 插入 而不是替换 一行或多行 NA 始终至少一行 要插入的 NA 数量存储在单独的列表中 为了说明这一点 我有以下两个列表 list of datafra
  • 一段 R 代码会影响 foreach 输出中的随机数吗?

    我使用运行模拟foreach and doParallel并与随机数 名为random在代码中 简而言之 我模拟一个足球联赛 随机生成所有比赛的获胜者以及相应的结果 在dt base没有比赛进行 在dt ex1 and dt ex24场比赛
  • 如何添加链接以从我的 R闪亮应用程序在新窗口中打开 pdf 文件?

    我可以使用 a 从我的 Shiny 应用程序添加到外部站点的超链接 a google href http www google com 但如何创建一个链接来打开 pdf 或类似 文件 看起来应该很简单 但我找不到任何例子 我的问题与此类似
  • R、Rcpp 与 Armadillo 中矩阵 rowSums() 与 colSums() 的效率

    背景 来自 R 编程 我正在扩展到 C C 形式的编译代码Rcpp 作为循环交换 以及一般的 C C 效果的实践练习 我实现了 R 的等效项rowSums and colSums 矩阵的函数Rcpp 我知道它们以 Rcpp 糖的形式存在 并
  • 在 R 传单中添加不透明度滑块

    如何在 R leaflet 应用程序中添加滑块来控制特定图层的不透明度 对于这个应用程序 我不想使用闪亮 这里建议 在 R 传单应用程序中添加滑块 https stackoverflow com questions 37682619 add
  • R中的字典数据结构

    在 R 中 我有 例如 gt foo lt list a 1 b 2 c 3 如果我输入foo I get a 1 1 b 1 2 c 1 3 我怎样才能看透foo仅获取 键 列表 在这种情况下 a b c R 列表可以具有命名元素 因此可
  • R - 计算 bin 中特定值的数量

    我有一个如下所示的数据框 df Value lt c 1 1 0 2 1 3 4 0 0 1 2 0 3 0 4 5 2 3 0 6 Sl lt c 1 20 df lt data frame Sl Value gt df Sl Value
  • Quantmod 的简单功能不再起作用

    我明天要交论文 我收到了一条关于 quantmod 的非常奇怪的错误消息 这是我在过去几周使用这个包时从未遇到过的 我无法导入特定于道琼斯指数 DJI 的数据 我收到以下错误消息 getSymbols DJI src yahoo from
  • purrr::可能函数可能无法与map2_chr函数一起使用

    我怀疑这是 purrr 包中的错误 但想先在 StackOverflow 中检查我的逻辑 在我看来 possibly功能在内部不起作用map2 chr功能 我正在使用 purrr 版本 0 2 5 考虑这个例子 library dplyr
  • 需要在R中按行绑定列表数据

    我在 R 中按行绑定列表时遇到问题 我的列表数据集是 id 1 data k 1 id k b c 1 1 1 3 data k 2 id k b c 1 2 1 4 id 2 data k 1 id k b c 2 1 1 6 data
  • 在R中循环子文件夹

    我正在 R 环境中包含多个子文件夹的文件夹中工作 我想要循环遍历多个子文件夹 然后在每个子文件夹中调用 R 脚本来执行 我想出了下面的代码 但我的代码似乎添加了 到子文件夹列表 我收到错误 文件中的错误 文件名 r 编码 编码 无效的 描述
  • 绘制 Cox 回归的 Kaplan-Meier 图

    我使用 R 中的以下代码设置了一个 Cox 比例风险模型来预测死亡率 添加协变量 A B 和 C 只是为了避免混淆 即年龄 性别 种族 但我们真正对预测变量 X 感兴趣 X 是一个连续变量 cox model lt coxph Surv t
  • `dplyr::_join` 函数的命名向量“by”参数[重复]

    这个问题在这里已经有答案了 我正在写一个函数dplyr join两个数据框by不同的列 第一个数据帧的列名称动态指定为函数参数 我相信我需要使用rlang准引用 元编程 但未能找到可行的解决方案 我很感激任何建议 library dplyr
  • sapply - 保留列名称

    我试图总结数据集中许多不同列 变量 的平均值 标准差等 我已经编写了自己的汇总函数 以准确返回我需要和正在使用的内容sapply立即将此函数应用于所有变量 它工作正常 但是返回的数据帧没有列名 我似乎甚至无法使用列号引用重命名它们 也就是说
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • 如何按定义的顺序将图像合并到一个文件中

    我有大约 100 张图像 png 我不想手动执行此操作 而是希望将它们按照定义的顺序 基于文件名 并排放置在一个 pdf 中 每行 12 个图像 有人有什么建议吗 我按照下面托马斯告诉我的方法尝试了 它把它们贴在旁边有一个黑边 我怎样才能去
  • R Shinydashboard 自定义 CSS 到 valueBox

    我一直在尝试将 valueBox 的颜色更改为自定义颜色 超出 validColors 中可用的颜色 但一直无法这样做 我知道有一种方法可以使用标签来包含自定义 CSS 但是我无法将它们放在正确的位置 ui lt dashboardPage
  • 从数据框中绘制多条平滑线

    我对 R 比较陌生 我正在尝试绘制从 csv 文件加载的数据框 数据由 6 列组成 如下所示 xval col1 col2 col3 col4 col5 第一列 xval 由一系列单调递增的正整数 例如 10 40 60 等 组成 其他列
  • 如何根据 ggplot2 中的汇总数据创建堆积条形图

    我正在尝试使用 ggplot 2 创建堆积条形图 我的宽格式数据如下所示 每个单元格中的数字是响应的频率 activity yes no dontknow Social events 27 3 3 Academic skills works
  • case_when 与部分字符串匹配和 contains()

    我正在使用一个数据集 其中有许多名为 status1 status2 等的列 在这些列中 它表示某人是否豁免 完整 注册等 不幸的是 豁免投入并不一致 这是一个示例 library dplyr problem lt tibble perso

随机推荐