英文:
Plotting a SEM Actor-Partner Interdependence Model after runMI()
问题
我使用多次填补的数据来运行一个Actor-Partner Interdependence Model (APIM; Cook & Kenny, 2005)。我使用 mice
来填补我的数据,并参考 这个资源指南 来构建我的APIM使用 lavaan
。
据我所知,只有 一个与我的问题相关的StackOverflow问题。然而,我无法直接将那个答案应用于我的APIM。还有一个 三年前的Github问题涉及到semPaths
,似乎自从其他StackOverflow用户发布该问题以来没有取得任何进展。
我尝试调整其他StackOverflow答案,以适用于我的APIM,只保留两个Actor效应和两个Partner效应。我认为我已经接近了解决问题;如果你比较摘要输出与我的第三次尝试绘图的结果,你会发现semPaths()
绘制的摘要估计与之相似,但不完全相同。
是什么导致绘制的估计不准确?有没有一种更好的方式来绘制 lavaan.mi
对象,感觉不那么巧合?
以下是你提供的R代码的翻译部分:
# 你的R代码
如果你需要进一步的帮助或解释,请告诉我。
英文:
I am using multiply-imputed data to run an Actor-Partner Interdependence Model (APIM; Cook & Kenny, 2005). I am using mice
to impute my data and for reference, I am using this resource guide for constructing my APIM with lavaan
.
As far as I can tell, there is only one other StackOverflow question that is related my issue. However, I was unable to directly apply that answer to my APIM. There is also a three-year-old Github issue with semPaths
that doesn't seem to have made any progress since the other StackOverflow user posted about it.
I tried adjusting the other StackOverflow answer for my APIM by filtering out everything except the two actor effects and two partner effects. I think I'm almost there; if you compare the summary output with my third attempt at plotting, the summary estimates are similar to what's plotted by semPaths()
but not exact.
What's causing the plotted estimates to be off? Is there a better way of plotting lavaan.mi
objects that feels less hacky?
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)
# 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
答案1
得分: 2
以下是翻译的部分:
What's causing the plotted estimates to be off?
是什么原因导致绘制的估算结果不准确?
I just left a comment on the earlier post you linked to, informing them that standardizedSolution()
is not for lavaan.mi
objects. You should use an actual class?lavaan.mi
method, something like:
我刚刚在您链接的早前帖子上留下了评论,告知他们standardizedSolution()
不适用于lavaan.mi
对象。您应该使用真正的class?lavaan.mi
方法,类似于:
## so you can check it more easily:
output = "data.frame")
你应该像上面这样使用desired_output
,并仔细比较它的行和列与baseplot@Pars
的行和列,确保替代是合理的。
Also, you only need to set the miPackage=
when you want to impute within the runMI()
call, which is not recommended. You did the right thing by imputing first, but that is when setting your seed counts.
此外,只有当您希望在runMI()
调用中进行插补时才需要设置miPackage=
,但不建议这样做。您先进行了插补是正确的,但那是设置种子计数的时候。
imp <- mice::mice(df, m = 5, maxit = 10,
seed = 1234, printFlag = FALSE)
# conduct SEM
sem_model <- sem.mi(model = myapim, data = imp)
进行SEM分析
Is there a better way of plotting lavaan.mi objects that feels less hacky?
有没有更好的绘制lavaan.mi对象的方法,感觉不那么巧妙?
Not yet. Of course, the easiest and safest way to make this work would be if semPaths()
checked for the lavaan.mi
class and correctly extracted the necessary information itself. I'll make a note to send Sacha a pull request for semPlot
when I have time to work on semTools
again.
还没有。当然,使其正常工作的最简单和最安全的方法是,如果semPaths()
检查lavaan.mi
类并正确地自行提取所需信息。我会记下给Sacha发送一个有关semPlot
的pull请求,当我有时间再次处理semTools
时。
英文:
> What's causing the plotted estimates to be off?
I just left a comment on the earlier post you linked to, informing them that standardizedSolution()
is not for lavaan.mi
objects. You should use an actual class?lavaan.mi
method, something like:
desired_output <- summary(sem_model, standardized = "std.all",
## so you can check it more easily:
output = "data.frame")
And carefully compare the rows and columns of desired_output
to those of baseplot@Pars
to make sure your replacement makes sense.
Also, you only need to set the miPackage=
when you want to impute within the runMI()
call, which is not recommended. You did the right thing by imputing first, but that is when setting your seed counts.
# 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?
Not yet. Of course, the easiest and safest way to make this work would be if semPaths()
checked for the lavaan.mi
class and correctly extracted the necessary information itself. I'll make a note to send Sacha a pull request for semPlot
when I have time to work on semTools
again.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论