r - 在 runMI() 之后绘制 SEM 参与者-合作伙伴相互依赖模型

标签 r plot r-mice r-lavaan semplot

我正在使用多重插补数据来运行参与者-合作伙伴相互依赖模型(APIM;Cook & Kenny, 2005)。我使用 mice 来估算我的数据,作为引用,我使用 this resource guidelavaan 构建我的 APIM。

据我所知,只有 one other StackOverflow question 与我的问题相关。但是,我无法直接将该答案应用于我的 APIM。还有一个 three-year-old Github issue with semPaths 自从其他 StackOverflow 用户发布相关信息以来似乎没有取得任何进展。

我尝试通过过滤掉除两个 Actor 效果和两个合作伙伴效果之外的所有内容来调整 APIM 的其他 StackOverflow 答案。我想我已经快到了;如果您将摘要输出与我第三次尝试绘制的结果进行比较,您会发现摘要估计与 semPaths() 绘制的结果类似,但并不准确。

是什么导致绘制的估计值偏离?有没有更好的方法来绘制 lavaan.mi 对象,感觉不那么老套?

library(mice)
library(lavaan)
library(tidyverse)
library(faux)
library(missMethods)
library(semTools)
library(semPlot)
set.seed(1234)

## prepwork
# generate data
df <- faux::rnorm_multi(n = 100, vars = 4, mu = 3, sd = 1, varnames = c("x1", "x2", "y1", "y2")) %>%
  mutate(id = rep(1:100)) %>% select(id, everything()) %>%
  missMethods::delete_MCAR(cols = c("x1", "x2", "y1", "y2"), p = .15)
  
# make lavaan object
myapim <- "x1  ~ a1*y1; x2  ~ a2*y2; x1  ~ p12*y2; x2  ~ p21*y1; y1 ~ mx1*1; y2 ~ mx2*1; x1 ~ my1*1; x2 ~ my2*1
           y1 ~~ vx1*y1; y2 ~~ vx2*y2; x1 ~~ vy1*x1; x2 ~~ vy2*x2; y2 ~~ cx*y1; x2 ~~ cy*x1 
           a_diff := a1 - a2; p_diff := p12 - p21; k1 := p12/a1; k2 := p21/a2
           k_diff := k1 - k2; i_diff := my1 - my2; a_ave := (a1 + a2)/2; p_ave := (p12 + p21)/2
           i_ave := (my1 +my2)/2; sum1 := (p12 + a1)/2; sum2 := (p21 + a2)/2; cont1 := a1 - p12; cont2 := a2 - p21
"
apimd <- lavaan::sem(myapim, data = df, fixed.x = FALSE, missing = "default")

# impute data
imp <- mice::mice(df, m = 5, maxit = 10, seed = 1234, printFlag = FALSE)

# conduct SEM
sem_model <- runMI(model = myapim, data = imp, fun = "sem", miPackage = "mice", seed = 1234)

## plot
# try to plot lavaan.mi
semPaths(sem_model, what = "est", sizeMan = 25, sizeMan2 = 10, 
         label.cex = 1.2, edge.label.position = 0.45, edge.label.cex = 1.5) #  error
#> Error in (function (classes, fdef, mtable) : unable to find an inherited method for function 'semPlotModel_S4' for signature '"lavaan.mi"'

# try to use other StackOverflow answer directly
other_model <- sem(myapim,  data = df)
SEMPLOT <- semPlot::semPlotModel(other_model)
desired_output <- data.frame(standardizedsolution(sem_model))
SEMPLOT@Pars$std <- desired_output$est.std # error
#> Error in `$<-.data.frame`(`*tmp*`, std, value = structure(c(0.164373878998654, : replacement has 27 rows, data has 14

# try to adjust the other StackOverflow answer for my APIM
baseplot <- semPlot::semPlotModel(other_model)
desired_output <- data.frame(standardizedsolution(sem_model))
desired_output <- desired_output %>% filter(op != ":=")
baseplot@Pars$est <- desired_output$est.std
semPaths(baseplot, 
         nCharNodes = 0, what = "est",
         fade = FALSE, layout = "tree2", 
         rotation = 2, style = "ram",
         intercepts = FALSE, residuals = FALSE, 
         optimizeLatRes = TRUE, curve = 3.1, nDigits = 3,
         sizeMan = 12, sizeMan2 = 10, 
         label.cex = 1.2, edge.label.position = 0.45, edge.label.cex = 1.5)

enter image description here

# I only pasted part of summary() to keep it short
> summary(sem_model)
lavaan.mi object based on 5 imputed data sets. 
See class?lavaan.mi help page for available methods. 

Convergence information:
The model converged on 5 imputed data sets 

Rubin's (1987) rules were used to pool point and SE estimates across 5 imputed data sets, and to calculate degrees of freedom for each parameter's t test and CI.

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Regressions:
                   Estimate  Std.Err  t-value       df  P(>|t|)
  x1 ~                                                         
    y1        (a1)    0.162    0.111    1.456   12.345    0.170
  x2 ~                                                         
    y2        (a2)   -0.005    0.112   -0.046   75.147    0.963
  x1 ~                                                         
    y2       (p12)    0.209    0.122    1.714   37.386    0.095
  x2 ~                                                         
    y1       (p21)    0.049    0.103    0.478   47.391    0.635

最佳答案

What's causing the plotted estimates to be off?

我刚刚对您链接到的之前的帖子发表了评论,通知他们 standardizedSolution() 不适用于 lavaan.mi 对象。您应该使用实际的 class?lavaan.mi 方法,例如:

desired_output <- summary(sem_model, standardized = "std.all",
                          ## so you can check it more easily:
                          output = "data.frame")

并仔细将 desired_output 的行和列与 baseplot@Pars 的行和列进行比较,以确保您的替换有意义。

此外,当您想要在 runMI() 调用中进行插补时,只需设置 miPackage=,但不建议这样做。您首先进行插补,这是正确的做法,但那是在设置种子数时。

# impute data
imp <- mice::mice(df, m = 5, maxit = 10,
                  seed = 1234, printFlag = FALSE)

# conduct SEM
sem_model <- sem.mi(model = myapim, data = imp)

Is there a better way of plotting lavaan.mi objects that feels less hacky?

还没有。当然,完成这项工作的最简单、最安全的方法是 semPaths() 检查 lavaan.mi 类并正确提取必要的信息本身。当我有时间再次使用 semTools 时,我会记下向 Sacha 发送 semPlot 的拉取请求。

关于r - 在 runMI() 之后绘制 SEM 参与者-合作伙伴相互依赖模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75573417/

相关文章:

使用stat ="count"时,geom_bar从高到低重新排序

r - 在矩阵中查找公共(public)链接并通过公共(public)交集进行分类

matlab - 如何通过 3D 图像可视化解决此问题?

python - Matplotlib 毫秒在 x 轴上打勾

r - 使用鼠标功能时出错 : nothing left to impute

r - 在小鼠中进行后处理,将一个变量替换为另一个变量

r - 分段回归 : davies. 测试返回 p 值 = NA

r - 使具有许多观察结果的多组线图更具可读性

r - R 中的插补 MICE 仍不存在于数据集中

r - 将 ID 字符串重新编码为其他字符串的最佳实践