ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

R语言lavaan包结构方程模型实战指南:从潜变量到非递归模型

R语言lavaan包结构方程模型实战指南:从潜变量到非递归模型 做结构方程模型十个人里有九个会提到 R 的lavaan包。剩下那个可能还在用 Mplus但看到高昂的授权费之后大概率也会转回来。这个包的火爆不是没有道理它能用一套接近 Mplus 的模型语法把潜变量、复合变量、多组比较、嵌套数据、时间/空间结构、非递归模型全塞进同一个框架里。我这些年处理问卷数据、纵向追踪数据、多地区调研数据绝大多数项目都是靠lavaan一个包扛完的。这篇文章不是来抄文档的而是把我实际踩过的坑和验证过的路径按场景拆开讲。你会看到每一类模型用什么代码、在哪一步最容易翻车、模型不收敛了先查什么。标题里那些术语听起来很多实际上落到代码里就是~、~、~~、:这几条路径规则的组合。先把基础语法吃透后面所有复杂模型都是搭积木。1. 为什么是 lavaan先搞懂它解决了什么问题1.1 它的定位和能做的范围lavaan的定位很明确一个开源、免费、语法接近 Mplus 的结构方程建模工具。它支持的模型类型包括验证性因子分析CFA、完整结构方程模型SEM、潜在增长曲线模型、多组 SEM、多水平 SEM、以及带反馈回路的非递归模型。说直白一点传统回归只能处理因变量是观测变量的情况而 SEM 可以把测量误差、因子结构、间接效应、跨组不变性这些需求一次性纳入。它最大的优势是模型语法足够简洁。比如定义一个潜变量只要一行f1 ~ y1 y2 y3这行代码表示潜变量 f1 由观测变量 y1、y2、y3 反映。加上回归路径y ~ x、协方差x ~~ y、参数标签a*x几乎所有 SEM 模型都能拼出来。相比 Mplus你不用单独写数据文件、变量列表、模型命令所有东西都可以在 R 里用数据框一次性搞定。1.2 什么场景优先选 lavaan什么场景要慎重优先选lavaan的场景是经典结构方程模型、中介/调节效应分析、潜变量 CFA、多组比较、增长曲线模型。这些场景lavaan的表现已经非常稳定而且社区资料丰富。要慎重的场景是复杂的多水平随机斜率模型、贝叶斯 SEM、潜变量交互效应、空间计量结构方程。这些不是lavaan的强项。比如潜变量交互lavaan需要配合indProd包做乘积指标复杂多水平模型我一般会转向 Mplus 或brms。判断标准很简单如果你的模型只涉及测量模型 结构路径lavaan完全够用如果模型里有大量跨层随机效应别硬刚。2. 潜变量模型从 CFA 到完整 SEM 的落地细节2.1 测量模型先确认你的因子结构站得住所有潜变量模型的第一步都是先跑一个 CFA确认观测指标和潜变量之间的关系没问题。我见过太多人直接跑完整 SEM结果结构路径显著但测量模型一塌糊涂最后整个模型不可解释。正确顺序是先做测量模型再做结构模型。先看一个标准的二阶潜变量 CFA 模型library(lavaan) cfa_model - f1 ~ x1 x2 x3 x4 f2 ~ x5 x6 x7 x8 f3 ~ x9 x10 x11 x12 fit_cfa - cfa(cfa_model, data mydata, estimator MLR) summary(fit_cfa, fit.measures TRUE, standardized TRUE)这里有个细节estimator MLR是中庸选择。如果你的数据是李克特量表变量最多五到七级严格来说不满足多元正态。MLR 提供稳健标准误和卡方统计量能抵抗一定程度的非正态。如果数据严重偏态可以考虑把变量当有序类别处理但那是另一个话题。跑完之后先看三样东西每个标准化载荷是否大于 0.5理想是 0.7 以上修正指数MI里面有没有高得离谱的交叉载荷拟合指数 CFI 是否大于 0.90RMSEA 是否小于 0.08。如果某个指标载荷特别低比如 0.3别急着删。先看这个题项的措辞和潜变量理论定义是否一致。删除指标必须有理论依据不能光靠统计。另一件容易被忽略的事潜变量必须设置尺度要么固定某个指标载荷为 1要么固定潜变量方差为 1。lavaan默认把第一个指标的载荷固定为 1所以你在语法里不用特意写。2.2 结构模型加入路径与间接效应测量模型通过之后加上结构路径就变成了完整 SEM。最常见的设定是外生潜变量f1影响内生潜变量f2f2又影响f3形成中介链条。代码长这样sem_model - f1 ~ x1 x2 x3 f2 ~ x4 x5 x6 f3 ~ x7 x8 x9 f2 ~ a*f1 f3 ~ b*f2 c*f1 indirect : a*b total : c a*b fit_sem - sem(sem_model, data mydata, estimator MLR, se bootstrap, bootstrap 1000):是lavaan定义新参数的运算符。indirect : a*b表示间接效应是路径 a 和 b 的乘积。这里不要自己手动去乘标准误直接用 bootstrap 会给出间接效应的置信区间。运行后看parameterEstimates(fit_sem, ci TRUE)输出的置信区间是否包含 0。踩过一个典型坑直接设置se bootstrap但忘记设置bootstrap次数默认值只有 100效果不稳定。建议至少 1000 次。另外用 MLR 时 bootstrap 会计算比较慢数据量大就晚上挂机跑。3. 复合变量与测量模型变体打包、二阶因子、形成性指标3.1 复合变量到底指什么复合变量这个术语在不同文章里含义不一样。常见有两种一种是把多个观测变量按某种逻辑合并成一个总分或合成指数比如把量表各题加总后的总分这种是 observed composite另一种是形成性测量模型里的复合构造比如社会经济地位是由收入、教育、职业三个指标形成的构念而不是由它们反映出来的潜变量。很多人会混淆这两件事。确认清楚你要处理的是哪种复合变量直接决定你在lavaan里怎么写模型。如果你的复合变量只是一个保存好的总分比如total_score - rowSums(df[, items])那么它就是一个普通观测变量。直接放进结构方程里作为 X、M、Y 都可以但代价是测量误差被忽略了。如果你的复合变量是形成性的理论上lavaan原生语法不支持形成性测量模型最常用的做法是把它作为带权重的外生变量或者改用其他方法近似实现。3.2 三种实操处理方式第一种最省事把复合变量当观测变量。适用于量表总分、均值分、指数分比如把三个题的平均值作为一个变量。代码里直接写y ~ composite_x完事。缺点是这些指标原本的测量误差没有建模容易造成参数估计有偏但偏的方向通常是保守的很多实际场景可接受。第二种用二阶因子模型如果复合变量是多个潜变量的综合比如整体工作满意度由薪酬满意度、发展满意度、关系满意度三个分维度构成用二阶因子比直接加总更干净second_order - f1 ~ x1 x2 x3 f2 ~ x4 x5 x6 f3 ~ x7 x8 x9 overall ~ f1 f2 f3 这相当于让一个高阶潜变量去解释三个一阶因子。这种做法保留了测量误差信息也符合整体构念是分维度之上的更高层级的理论逻辑。第三种形成性指标的近似实现。如果你一定要在lavaan里做类似形成性复合变量的东西一个可接受但不完美的办法是把复合变量作为潜变量指标载荷全部固定为 1并让复合变量的方差自由估计composite_model - comp ~ 1*x1 1*x2 1*x3 comp ~~ comp y ~ comp 这种做法本质上是在估计一个“指标等权重加权和”的复合变量。它和真正的形成性测量模型还有距离因为形成性指标之间不一定需要相关而且指标对构念的方向是指标 - 构念~语法表达的是构念 - 指标。所以如果你的模型特别强调形成性逻辑建议换到 Mplus 或写 Stan 模型。在我自己处理过的项目里审稿人对形成性模型的接受度其实不高大家更习惯看到二阶因子模型。3.3 指标打包的副作用还有一种和复合变量相关的操作叫指标打包parceling就是把同一因子下的多个题目随机或按维度合并成 2-3 个总分再用这些打包变量作为因子指标。打包能减少指标数量、提升模型拟合、缩小样本量需求但代价是掩盖了题目层面的信息容易让测量误差结构变得不合理。我的建议是如果你的样本量足够N 300不要打包如果因子有 6 个以上题目且样本量紧张可以按维度打包成 3 个左右但要在论文里写明打包依据。4. 分组与嵌套数据多组 SEM 和多水平 SEM4.1 多组 SEM分组比较与测量不变性当你手里的数据来自不同群体比如不同性别、不同干预组、不同地区你的问题通常不是这个模型在所有群体里拟合如何而是这个模型的结构在不同群体之间是不是等价的。多组 SEM 就是为此设计的。基础语法很简单fit_mg - sem(sem_model, data mydata, group gender) summary(fit_mg, fit.measures TRUE, standardized TRUE)lavaan会为每个组分别估计一套参数。但真正做跨组比较要先做测量不变性检验。完整的测量不变性测试顺序是形态等值configural- 弱等值metric因子载荷相等- 强等值scalar截距相等- 严格等值残差方差相等。老版本里可以直接用semTools::measurementInvariance一键跑完但新版semTools更推荐自己用update逐步设置group.equallibrary(semTools) fit_config - sem(cfa_model, data mydata, group gender) fit_metric - sem(cfa_model, data mydata, group gender, group.equal c(loadings)) fit_scalar - sem(cfa_model, data mydata, group gender, group.equal c(loadings, intercepts))然后比较 CFI 变化量delta CFI小于 0.01 通常认为没有显著恶化。这一步在发问卷类论文时基本是必选项。我之前有一次犯了只报告拟合指数不报不变性检验的错误审稿人直接点名要求补从那以后我就默认多组数据先跑一遍不变性检验。4.2 嵌套数据用 cluster 参数处理组内相关数据不是独立抽样的时候比如一个班的学生、一个医院的病人、同一个社区的家庭观测点之间并不独立。最简单的处理思路是用cluster参数做聚类稳健标准误fit_cluster - sem(sem_model, data mydata, cluster school) summary(fit_cluster, fit.measures TRUE)这个方式相当于告诉lavaan虽然我没有为每个学校单独建模但我在学校水平上考虑了相关性修正标准误。适合你的模型重点是个体层面只是不想忽略聚类影响。如果聚类效应本身就是研究问题比如你想看学校氛围对学生满意度的影响并同时控制个体层面的变量那就需要多水平 SEM。lavaan从 0.6 版本开始支持两水平模型语法是在同一个模型里分别写level: 1和level: 2块ml_model - level: 1 satisfaction ~ motivation workload level: 2 school_climate ~ climate1 climate2 climate3 school_sat ~ satisfaction school_sat ~ school_climate fit_ml - sem(ml_model, data mydata, cluster school)注意这个两级模型不是完全功能完备的多水平 SEM随机斜率等复杂设定在lavaan里很容易遇到识别问题。如果你只需要随机截距、组间路径lavaan能胜任一旦需要每个学校自己有一条斜率赶紧转 Mplus不要浪费时间调参。4.3 分组与嵌套的选择逻辑分组数据和多水平数据的共同点是非独立区别在于你处理的是组间参数差异还是组间方差。多组 SEM 比较的是参数在不同组之间是否相等多水平 SEM 是假设参数跨组相同但对组内相关性进行建模并估计组间方差和组间效应。实际操作时如果你的组数很少比如只有男、女两组用多组 SEM如果组数很多比如几十上百个学校用多水平 SEM。反过来把几十个学校的虚拟变量全放进模型里做多组会爆炸。5. 时间与空间数据纵向 SEM、增长模型与空间变量的处理5.1 纵向数据交叉滞后与潜在增长曲线时间维度的数据在 SEM 里有两种常见处理路径。第一种是交叉滞后面板模型CLPM用来评估两个变量在不同时间点的相互预测关系。比如你在 T1、T2 两个时间点都测了焦虑和失眠想看看是焦虑先影响失眠还是失眠先影响焦虑。clpm_model - anxiety2 ~ anxiety1 insomnia1 insomnia2 ~ insomnia1 anxiety1 anxiety1 ~~ insomnia1 anxiety2 ~~ insomnia2 anxiety1 ~ 1 insomnia1 ~ 1 fit_clpm - sem(clpm_model, data longitudinal_data, estimator MLR)这里的关键是让anxiety2和insomnia2的残差相关因为同一时间点的共同未测混淆因素确实存在。如果不写anxiety2 ~~ insomnia2这个相关会被强行固定为 0通常是不合理的。CLPM 的局限是它把个体间差异和个体内变化混在一起所以现在很多研究改用随机截距交叉滞后面板模型RI-CLPMlavaan也可以写但那是另一个进阶话题。第二种是潜在增长曲线模型LGM。如果研究重点是变化趋势比如四波追踪数据里压力水平是怎么变化的LGM 更合适lgm_model - i ~ 1*t1 1*t2 1*t3 1*t4 s ~ 0*t1 1*t2 2*t3 3*t4 i ~~ i s ~~ s i ~~ s fit_lgm - growth(lgm_model, data longitudinal_data) summary(fit_lgm, fit.measures TRUE, standardized TRUE)i是截距因子代表初始水平s是斜率因子代表变化速度。你把时间载荷设成 0、1、2、3意思是每波测量间隔等距。如果你的追踪时间间隔不等比如 0、1、4、12 个月就把载荷改成实际间隔。这里的常见错误是把第一波载荷固定为 0第二波以后却用1*的等距假设结果模型拟合很差还找不到原因。先检查时间编码是不是和数据实际间隔一致。5.2 纵向中介横断面结果与纵向验证的差异现在很多研究都会先做横断面分析发现 X 和 Y 相关X 和 M 相关M 和 Y 相关然后就说支持中介效应。这种结论最容易被质疑因为横断面数据无法排除反向因果和混杂因素。更靠谱的做法是设计纵向中介T1 测 XT2 测 MT3 测 Y然后用 SEM 估计 X - M - Y 的路径。long_med - M2 ~ a*X1 Y3 ~ b*M2 c*X1 ab : a*b fit_lm - sem(long_med, data longitudinal_data, se bootstrap, bootstrap 1000)这种设计让变量在时间上有了先后顺序虽然仍不能证实因果但比横断面证据强得多。我在实际项目中很少直接用 T1 的 M 和 T1 的 Y 去做中介因为那本质上还是一次横断面分析只是加了自回归。合理设置是 X、M、Y 来自三个不同时间点中间至少隔一段有意义的时间窗口。5.3 空间数据lavaan 不是空间计量包但可以这样处理先说结论lavaan没有内置空间权重矩阵、空间滞后项、空间误差项这些功能。但空间数据不等于一定要用空间计量模型。根据你的研究问题有三种路线可以把空间数据放进 SEM 框架。第一种把空间单元作为分组变量做多组 SEM。比如你想比较东、中、西部三个区域模型结构是否一致直接用group region跑多组 SEM再测不变性。这个方法最稳也最容易解释。第二种如果空间自相关是干扰因素用cluster region或者更细的网格 ID。这等同于说同一个区域的样本可能彼此相似我不估计空间效应但我修正标准误。成本最低适合你的问题里空间不是主角的情况。第三种如果空间效应是主角比如你要检验邻域社会经济水平是否通过社区参与影响居民幸福感可以在lavaan之外先把空间滞后变量算出来再放进模型当观测变量。library(spdep) coords - cbind(data$lon, data$lat) nb - knn2nb(knearneigh(coords, k 4)) lw - nb2listw(nb) data$neighbor_ses - lag.listw(lw, data$ses)然后跑一个常规 SEMsem_model_sp - participation ~ ses neighbor_ses wellbeing ~ participation ses neighbor_ses 这种方法假设空间效应只会通过构造的空间滞后变量进入方程不会处理空间误差项属于准空间 SEM。如果你要做完整的空间误差结构建议去看spatialreg、INLA或者brms而不是硬塞给lavaan。空间数据处理里最容易被骂的是权重矩阵的选择。k 4意思是用最近 4 个邻居定义邻接关系换 k 值结果可能会差很多。哲学上最好预先根据地理理论选权重不要反复调 k 调到显著为止。我自己的经验是空间分析部分只要涉及空间权重矩阵一定要做至少两种权重矩阵的敏感性分析比如 k4 和距离衰减阈值。6. 非递归模型当因果方向不再单向6.1 什么是非递归模型前面讲的 SEM 都是递归模型意思是路径没有反馈回路变量之间的影响是单向的。但现实里很多关系天然是双向的员工士气影响绩效绩效反过来影响士气同伴之间的行为互相影响企业与行业环境之间存在反馈。这种模型术语上叫非递归模型。非递归模型的路径图上至少有一个双向箭头表示的反馈回路比如y1 - y2和y2 - y1同时存在。这里最大的问题是识别如果一个方程里包含内生变量而你又没有给每个内生变量找到足够的外生工具变量模型会欠识别估计出来的参数没有任何意义。6.2 用 lavaan 实现一个可识别的非递归模型要在lavaan里写非递归模型语法和普通 SEM 没有太大区别nonrecursive_model - y1 ~ b12*y2 x1 y2 ~ b21*y1 x2 y1 ~~ 0*y2 fit_nr - sem(nonrecursive_model, data mydata) summary(fit_nr, fit.measures TRUE, standardized TRUE)这个模型能识别依赖两个条件x1 只出现在 y1 的方程里x2 只出现在 y2 的方程里它们是各自的排他性工具变量y1 和 y2 的残差协方差被固定为 0避免残差层面的相关掩盖真实反馈关系。如果行业内理论认为残差相关性一定要估计那么你还得多加工具变量或路径约束否则模型就变成欠识别。不要尝试写出y1 ~ y2; y2 ~ y1然后什么都没有的模型lavaan会给你报错因为这种循环路径在没有外部约束时没法唯一估计。6.3 非递归模型的稳定性问题即使识别没问题非递归模型还要考虑稳定条件。简单说反馈回路里的路径系数乘积不能超过 1如果b12 * b21接近 1 或大于 1系统的反馈就会发散模型估计会特别不稳定。这就像两个人互相喊话每喊一次音量放大最后爆音。所以跑非递归模型时把参数估计结果拿出来自己算一下b12 * b21。如果结果大于 0.8就要警惕可能模型设定有问题或者这些变量本质上应该用联立方程以外的框架处理。实测下来非递归模型在lavaan里的收敛速度比普通模型慢很多。如果出现警告iteration limit reached先别急着调迭代次数。优先检查是不是欠识别再检查起始值是否合理。可以在语法里给路径一个合理的初值比如b12*0.3这往往能让迭代稳定下来。7. 样本量估算与横断面/纵向中介效应设计7.1 SEM 样本量的基础规则很多人在跑 SEM 前第一句问的就是我该收多少问卷。这个问题没有统一答案但有几个经验法则可以帮你缩小范围。经典经验法则是 N:q 比例即样本量至少是自由参数数量的 5 到 20 倍。一个包含 12 个指标、3 个因子的 CFA 大约有 30 个自由参数最少要 150舒服一点要 300 以上。有关潜变量模型每个因子至少要有 3 个指标否则模型识别困难。如果你用的是 MLR 或 bootstrap样本量尽量不低于 200因为小样本下稳健标准误和置信区间表现都不好。最稳妥的方法不是猜而是做蒙特卡洛模拟。simsem包可以根据你设定的模型、效应量、样本量生成模拟数据然后计算功效。大致流程是定义模型语法、设定参数值、设定样本量、跑 500 次模拟看目标参数在 95% 区间里不包含 0 的比例。这个比例就是功效。虽然开发成本高一些但写论文时有这一张图审稿人基本不会在样本量上问太多。7.2 纵向中介的样本量怎么估纵向中介比横断面中介需要更多样本因为你要估计 3 个时间点的变量关系还要考虑序列相关带来的信息稀释。我一般会先做一个简化版功效估算假设 X1 对 M2 的标准化回归系数是 0.3M2 对 Y3 的标准化回归系数是 0.3那么间接效应大约是 0.09。用蒙特卡洛模拟结果显示要在这个水平下达到 80% 功效样本量通常需要 200 到 300。如果你的预期效应更小比如 0.2 再乘 0.2那样本量很可能要冲到 500 以上。不要相信某些横断面研究的最小样本量公式能直接套到纵向中介上因为纵向数据的自相关会让你的有效信息量缩水。实际操作中我会分两步走先跑一个早期数据的小样本模型得到每条路径的粗略效应量再基于这个效应量做正式样本量计算。比凭空设定参数靠谱得多。7.3 横断面看影响因素的常见误读热搜里那句横断面看影响因素 纵向结构方程模型检验中介效应其实概括了一条标准的进阶路径横断面分析用来筛选变量、确定路径方向纵向数据用来验证时间顺序。但横断面 SEM 最容易出现的问题是因果方向不可辩。比如你发现工作压力与离职意愿显著相关你可以说压力影响离职意愿也可以说想离职的人更倾向于报告压力大。横断面数据里这两条路径的拟合程度可能一样好。一种补充手段是跑替代模型比较。比如把路径方向反过来对比两个模型的 AIC 或 BIC但这只能说明哪个模型和数据更匹配不能证明因果。纵向设计才是把这种争议压下去的武器。真正写结论时横断面只说相关/关联纵向模型可以说预测但不要轻易说因果。8. 常见报错、排查与经验清单8.1 模型不收敛先查这六个地方lavaan不收敛几乎是每个新手都会遇到的事。我排查的顺序如下检查模型识别有无哪个潜变量只有 1 到 2 个指标。两个指标勉强可以一个指标基本无法识别。给每个因子至少 3 个指标是最保险的。检查样本量是否过小。N 不到 100 时模型奇异很常见。如果数据本身有限可以考虑使用贝叶斯 SEM。检查量纲差异。变量之间数值差异巨大比如一个变量在 0-1 之间另一个变量在 0-10000 之间模型迭代会痛苦。对观测变量做标准化处理通常能解决。检查起始值。可以在语法里手动给路径一个合理标签和初始值比如b1*0.3。lavaan会自动用这些数值做迭代起点。检查是否是 Heywood case。所谓 Heywood case 就是潜变量方差或残差方差出现负的估计说明模型设定可能有问题比如指标过度冗余、存在奇异值或样本量太小。输出里看到负的方差值就要警惕。检查数据是否存在缺失模式。如果使用列表删除导致样本量骤降换missing FIML全信息极大似然估计能有效利用所有信息。8.2 拟合指数不达标不是所有修改都合理模型能收敛但 CFI 只有 0.85RMSEA 0.09很多人第一反应是看修正指数然后疯狂加相关路径直到拟合指数冲到 0.95。这种做法最大的问题是你可能把原本理论上独立的残差全部拉通了模型变成一个数据驱动模型难以复制。我的做法是先看理论基础预先设定哪些残差可能相关比如同一子量表里的项、同一时间点的变量把它们写进模型。不要事后看着 MI 去添加那些事后再加的必须在论文里说明是探索性修改。如果一个载荷特别低的题目拖累整个拟合考虑删除但需要用理论解释。量表题项不是越多越好冗余题目反而会造成局部依赖。如果模型整体拟合不好比较一下是测量模型部分不好还是结构部分不好。你可以先单独跑每个因子的 CFA确认测量模型过关再整合成完整 SEM。不要一上来就全模型乱调。8.3 缺失数据与稳健估计的实际配置处理缺失数据时lavaan默认是列表删除但问卷数据用列表删除很容易丢掉 20% 甚至更多样本。设置成 FIML 很简单fit - sem(model, data mydata, missing FIML, estimator MLR)FIML 的适用前提是数据至少是随机缺失MAR如果完全随机缺失当然更好。MAR 的意思是缺失概率只和已观测到的变量有关和缺失值本身无关。这个假设没法完全验证但可以通过检查高分组人群是否系统性少填某个题来侧面判断。如果发现缺失和数据本身有关那无论什么方法都救不了要先解决数据采集问题。8.4 建立自己的模型体检清单每次拟合完lavaan模型我都会按下面这个清单快速扫一遍拟合是否成功有无估计标准误为 NA 的参数所有方差是否为正标准化载荷是否没有大于 1CFI/TLI、RMSEA、SRMR 是否符合预期实际样本量是否足够结果是否对起始值稳健核心路径置信区间是否包含 0多组模型是否做过测量不变性检验。这套清单能挡住 80% 的低级错误。我自己有个印象很深的案例一个模型看起来拟合完美CFI 0.99RMSEA 0.01结果发现标准化载荷有一个是 1.8潜变量方差几乎为 0。这种完美拟合实际上是模型退化完全不可信。所以体检不能只看拟合指数一定要看参数具体值。经验补充小技巧与工具搭配最后分享一个让我少走很多弯路的经验lavaan的模型语法和结果输出可以配合semPlot包画路径图。路径图不是论文里的装饰品它能帮你直观看到模型里每个参数是什么方向、有没有画反箭头。做复杂模型时我习惯先画图再对着图写代码。尤其是非递归模型没有图非常容易把y1 ~ y2和y2 ~ y1写混。还有一个安排把变量命名和模型语法定义写在一个 R 脚本顶部加注释说明每个变量代表什么、来自哪道题。这个习惯帮我解决过无数次三个月后回来看代码看不懂的问题。lavaan虽然代码简洁但模型复杂以后标签的含义很快就会模糊。给所有参数起有意义的名字而不是a1、b2后面做敏感性分析和改模型会省力很多。至于更复杂的模型比如带随机斜率的交叉滞后模型、多水平非递归模型、贝叶斯 SEMlavaan的能力边界已经很明确。遇到这种需求我会先评估是转 Mplus还是改用brms写贝叶斯模型。lavaan是日常 SEM 的瑞士军刀但一个成熟的数据分析师手里不应该只有一把刀。知道什么时候换工具比学会所有lavaan技巧更重要。
返回列表