How to extract metafor::rma.mv() equivalent of lme4::VarCorr() for multilevel mixed effect meta-regression with random slopes

huangapple go评论106阅读模式
英文:

How to extract metafor::rma.mv() equivalent of lme4::VarCorr() for multilevel mixed effect meta-regression with random slopes

问题

我正在尝试计算多层混合效应元回归(包括随机斜率)的伪R平方,使用metafor包中的类似方法(即rma.mv()对象),该方法与以下引文类似:

https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.12225

我正在研究这篇引文中的代码,该代码使用lme4/nlme包演示了如何进行计算,似乎需要一个metafor等效的lme4/nlme拟合模型的VarCorr()输出摘要。

我正在努力弄清楚如何获得rma.mv()对象中每个随机效应层级的方差(或标准差)的摘要。在这方面,任何见解都将不胜感激!

这是引文中用于计算伪R平方的代码:

  1. # 拟合模型
  2. orangemod.rs <-
  3. lmer(circumference ~ ageYears + (ageYears | Tree), data = Orange)
  4. # 首先我们需要设计矩阵(X)、观测数量(n)和固定效应估计值(Beta)
  5. X <- model.matrix(orangemod.rs)
  6. n <- nrow(X)
  7. Beta <- fixef(orangemod.rs)
  8. # 首先计算固定效应的方差(Nakagawa & Schielzeth的方程27):
  9. Sf <- var(X %*% Beta)
  10. # 其次,计算随机效应的协方差矩阵列表。
  11. # 这里列表只有一个元素,因为只有一个随机效应层级。
  12. (Sigma.list <- VarCorr(orangemod.rs))
  13. # 使用论文中的方程11估计随机效应的方差分量。
  14. # 使用sapply确保在存在多个随机效应时(即length(Sigma.list) > 1)也能正常工作。
  15. Sl <-
  16. sum(
  17. sapply(Sigma.list,
  18. function(Sigma)
  19. {
  20. Z <-X[,rownames(Sigma)]
  21. sum(diag(Z %*% Sigma %*% t(Z)))/n
  22. }))
  23. # 由于该模型是LMM,加性离散方差Se等于残差方差。残差标准差存储为Sigma.list的属性:
  24. Se <- attr(Sigma.list, "sc")^2
  25. # 最后,LMM的分布特定方差Sd为零:
  26. Sd <- 0
  27. # 使用Nakagawa & Schielzeth的方程29和30估计边际和条件R平方:
  28. total.var <- Sf + Sl + Se + Sd
  29. (Rsq.m <- Sf / total.var)
  30. (Rsq.c <- (Sf + Sl) / total.var)

除了使用VarCorr()函数的步骤之外,所有这些步骤都可以轻松地用于rma.mv()对象:

  1. # 其次,计算随机效应的协方差矩阵列表。
  2. # 这里列表只有一个元素,因为只有一个随机效应层级。
  3. (Sigma.list <- VarCorr(orangemod.rs))
  4. # Groups Name Std.Dev. Corr
  5. # Tree (Intercept) 1.8966
  6. # ageYears 8.7757 -1.000
  7. # Residual 10.0062

这是一个简单的模型,用于说明这一点,并突出了rma.mv()模型的两个可能有必要信息的组成部分,但我不确定如何将其转换为最终的VarCorr()格式。

  1. library(metafor)
  2. library(tidyverse)
  3. data("dat.konstantopoulos2011")
  4. df=dat.konstantopoulos2011%>%
  5. as.data.frame()
  6. # 拟合随机斜率模型
  7. m1=rma.mv(yi ~ year, vi, random = list(~year|study, ~year|district, ~1|school), data = df,
  8. cvvc = TRUE)
  9. lme4::VarCorr(m1)
  10. nlme::VarCorr(m1)
  11. # 可能有用的组成部分
  12. m1$V
  13. m1$vvc
  14. 我希望重新创建的内容
  15. # Groups Name Std.Dev. Corr
  16. # study (Intercept) [VALUE]
  17. # ageYears [VALUE] [VALUE]
  18. # district (Intercept)
  19. # ageYears [VALUE]
  20. # school (Intercept)
  21. # Residual [VALUE]
英文:

I am attempting to calculate pseudo R squared's for a multilevel mixed-effect meta-regression that includes random slopes in the metafor package (i.e., rma.mv() object) using a similar approach to the following citation:

https://besjournals.onlinelibrary.wiley.com/doi/10.1111/2041-210X.12225

Digging into the code of this citation that uses the lme4/nlme packages to demonstrate how to perform the calculations, it seems like a metafor equivalent of a VarCorr() output of a lme4/nlme fit model is needed.

I am struggling to figure out how to obtain this summary of the variances (or SD) at each level of the random effects for a rma.mv() object. Any insight here is appreciated!

This is the code from the citation used to calculate the pseudo R squared's:

  1. # Fit Model
  2. orangemod.rs &lt;-
  3. lmer(circumference ~ ageYears + (ageYears | Tree), data = Orange)
  4. # First we need the design matrix (X), the number of observations (n)
  5. # and the fixed effect estimates (Beta)
  6. X &lt;- model.matrix(orangemod.rs)
  7. n &lt;- nrow(X)
  8. Beta &lt;- fixef(orangemod.rs)
  9. # First the fixed effects variance (eqn 27 of Nakagawa &amp; Schielzeth):
  10. Sf &lt;- var(X %*% Beta)
  11. # Second, the list of covariance matrices of the random effects.
  12. # Here the list has only a single element because there is only
  13. # one level of random effects.
  14. (Sigma.list &lt;- VarCorr(orangemod.rs))
  15. # Use equation 11 in the paper to estimate the random effects variance
  16. # component.
  17. # Using sapply ensures that the same code will work when there are multiple
  18. # random effects (i.e. where length(Sigma.list) &gt; 1)
  19. Sl &lt;-
  20. sum(
  21. sapply(Sigma.list,
  22. function(Sigma)
  23. {
  24. Z &lt;-X[,rownames(Sigma)]
  25. sum(diag(Z %*% Sigma %*% t(Z)))/n
  26. }))
  27. # As this model is an LMM, the additive dispersion variance, Se, is
  28. # equivalent to the residual variance. The residual standard deviation
  29. # is stored as an attribute of Sigma.list:
  30. Se &lt;- attr(Sigma.list, &quot;sc&quot;)^2
  31. # Finally, the distribution-specific variance, Sd, is zero for LMMs:
  32. Sd &lt;- 0
  33. # Use eqns 29 and 30 from Nakagawa &amp; Schielzeth to estimate marginal and
  34. # conditional R-squared:
  35. total.var &lt;- Sf + Sl + Se + Sd
  36. (Rsq.m &lt;- Sf / total.var)
  37. (Rsq.c &lt;- (Sf + Sl) / total.var)

All of these steps can be easily reproduced for the rma.mv() object besides the step with VarCorr() as this function doesn't accept rma.mv() objects:

  1. # Second, the list of covariance matrices of the random effects.
  2. # Here the list has only a single element because there is only
  3. # one level of random effects.
  4. (Sigma.list &lt;- VarCorr(orangemod.rs))
  5. # Groups Name Std.Dev. Corr
  6. # Tree (Intercept) 1.8966
  7. # ageYears 8.7757 -1.000
  8. # Residual 10.0062

Here is a simple model that illustrates the point and highlights two of the components of the rma.mv() model that I think might have the necessary information but I'm not exactly sure how to get it into the final VarCorr() format.

  1. library(metafor)
  2. library(tidyverse)
  3. data(&quot;dat.konstantopoulos2011&quot;)
  4. df=dat.konstantopoulos2011%&gt;%
  5. as.data.frame()
  6. #fit random slope model
  7. m1=rma.mv(yi ~ year, vi, random = list(~year|study, ~year|district, ~1|school), data = df,
  8. cvvc = TRUE)
  9. lme4::VarCorr(m1)
  10. nlme::VarCorr(m1)
  11. #potentially useful components
  12. m1$V
  13. m1$vvc
  14. What I&#39;m looking to recreate
  15. # Groups Name Std.Dev. Corr
  16. # study (Intercept) [VALUE]
  17. # ageYears [VALUE] [VALUE]
  18. # district (Intercept)
  19. # ageYears [VALUE]
  20. # school (Intercept)
  21. # Residual [VALUE]

答案1

得分: 0

~year|study对应的随机效应的方差-协方差矩阵可以通过m1$G提取。如果只需要方差,可以使用m1$tau2~year|district的方差-协方差矩阵是m1$H,方差在m1$gamma2中。~1|school对应的方差是m1$sigma2

请注意,如果您想要随机斜率,那么您正在拟合的模型不提供该功能。您需要使用以下代码:

  1. rma.mv(yi ~ year, vi,
  2. random = list(~year|study, ~year|district, ~1|school),
  3. struct=c("GEN","GEN"), data = df)

参考链接:https://wviechtb.github.io/metafor/reference/rma.mv.html#specifying-random-effects

英文:

The variance-covariance matrix of the random effects corresponding to ~year|study can be extracted with m1$G. If you only need the variances, then m1$tau2 will do. The var-cov matrix for ~year|district is m1$H and the variances are in m1$gamma2. The variance corresponding to ~1|school is m1$sigma2.

Note that if you want random slopes, then the model you are fitting doesn't provide that. You would need to use:

  1. rma.mv(yi ~ year, vi,
  2. random = list(~year|study, ~year|district, ~1|school),
  3. struct=c(&quot;GEN&quot;,&quot;GEN&quot;), data = df)

See: https://wviechtb.github.io/metafor/reference/rma.mv.html#specifying-random-effects

huangapple
  • 本文由 发表于 2023年8月8日 22:39:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定