有类似的问题。在 lavaan 中,您必须使用跟踪规则、邓肯规则或直接效应矩阵乘法手动编写间接和总效应的语法(参见 Maruyama,结构方程建模基础中的一般解释)。
您可以编写一些代码来生成该语法,这是我在这里的尝试和下面的摘要。它在 r 和 python 中使用符号矩阵库。希望您可以根据需要调整代码或想法。
首先,我描述了没有显式间接或总体影响的测量和结构模型并运行它:
model.cfa <- "quality =~ Q068_1 + Q068_4
delivery =~ Q069_2 + Q069_5
flexibility =~ Q071_1 + Q071_4 + Q071_5
costs =~ Q070_1 + Q070_2 + Q070_3
innovation =~ Q072_1 + Q072_3 + Q072_2"
model.sem_1a <- paste(model.cfa, "
delivery ~ quality
flexibility ~ delivery
costs ~ flexibility
innovation ~ costs")
fit.sem_1a <- sem(model.sem_1a, data = dataset, missing = "fiml")
summary(fit.sem_1a, fit.measures = T, standardized = T, rsquare = T)
然后我得到标准化直接效应系数的矩阵并将其转置以使因变量出现在列中,独立变量出现在行中:
# Get matrix of beta coefficients from lavInspect function:
mtx <- lavInspect(fit.sem_1a, what = "std", add.labels = TRUE, add.class = TRUE,
list.by.group = TRUE,
drop.list.single.group = TRUE)$beta
m <- t(mtx) # transpose matrix
m矩阵的输出:
qualty delvry flxblt costs innvtn
quality 0 0.52 0.000 0.000 0.000
delivery 0 0.00 0.412 0.000 0.000
flexibility 0 0.00 0.000 0.309 0.000
costs 0 0.00 0.000 0.000 0.442
innovation 0 0.00 0.000 0.000 0.000
然后我切换到 rSymPy 包 - 在 r 中实现 python Sympy 库 - 并通过将系数的数值替换为字符串标签来重新创建直接系数矩阵:
rn <- rownames(m)
cn <- colnames(m)
library(rSymPy)
symbolic_mtrx <- matrix(nrow=length(rownames(m)), ncol=length(colnames(m))) # initialize empty symbolic matrix with correct dimensions
# Now fill in the matrix with 'z' for zero elements and abbreviations for non-zero path coefficients
for (i in 1:length(rownames(m))){
for (j in 1:length(colnames(m))){
symbolic_mtrx[i,j]<-noquote('z') # noquote not necessary
if (m[i,j]!=0) {
#print(m[i,j])
l<-paste0(substr(rownames(m)[i],1,1),substr(colnames(m)[j],1,1)) # create a name for a coefficient from first letter of each construct name
symbolic_mtrx[i,j]<-noquote(l)
}
}
}
symbolic_mtrx # print the symbolic matrix
symbolic_mtrx 的输出:
[,1] [,2] [,3] [,4] [,5]
[1,] "z" "qd" "z" "z" "z"
[2,] "z" "z" "df" "z" "z"
[3,] "z" "z" "z" "fc" "z"
[4,] "z" "z" "z" "z" "ci"
[5,] "z" "z" "z" "z" "z"
由于我无法在 rSymPy 中执行矩阵乘法,我切换到 python 并根据需要多次乘以符号矩阵:
library(reticulate)
```{python}
from sympy import Matrix
rsm_direct = Matrix(r.symbolic_mtrx) #get direct effects matrix from r
rsm_indirect_1 = rsm_direct*rsm_direct # get first order indirect effects by multiplication
rsm_indirect_2 = rsm_indirect_1*rsm_direct # get second order indirect effects by multiplication. Would be nice to know in advance how many levels of indirect effects exist.
rsm_total_indirect = rsm_indirect_1 + rsm_indirect_2 # sum of first and second order indirect effects
rsm_total = rsm_total_indirect + rsm_direct # get total effects
```
rsm_total(总效应公式)的输出,其中 z 表示零系数:
Matrix([[qd*z + 4*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z, 2*qd*z + qd*(qd*z + 4*z**2) + qd + 3*z**2 + z*(df*qd + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2), df*qd + df*(2*qd*z + 3*z**2) + 4*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z, fc*z + fc*(df*qd + 4*z**2) + qd*z + 3*z**2 + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z, ci*z + ci*(fc*z + qd*z + 3*z**2) + qd*z + 3*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z], [df*z + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z, df*z + qd*z + qd*(df*z + 4*z**2) + 3*z**2 + z*(df*fc + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z, 2*df*z + df*(df*z + qd*z + 3*z**2) + df + 3*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2), df*fc + fc*(2*df*z + 3*z**2) + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z, ci*z + ci*(df*fc + 4*z**2) + df*z + 3*z**2 + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z], [fc*z + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z, fc*z + qd*z + qd*(fc*z + 4*z**2) + 3*z**2 + z*(ci*fc + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z, df*z + df*(fc*z + qd*z + 3*z**2) + fc*z + 3*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z, 2*fc*z + fc*(df*z + fc*z + 3*z**2) + fc + 3*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2), ci*fc + ci*(2*fc*z + 3*z**2) + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z], [ci*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z, ci*z + qd*z + qd*(ci*z + 4*z**2) + 3*z**2 + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z, ci*z + df*z + df*(ci*z + qd*z + 3*z**2) + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z, ci*z + fc*z + fc*(ci*z + df*z + 3*z**2) + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z, 2*ci*z + ci*(ci*z + fc*z + 3*z**2) + ci + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2)], [5*z**3 + 5*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z, 5*qd*z**2 + qd*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z, df*z + df*(qd*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z, fc*z + fc*(df*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z, ci*z + ci*(fc*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(qd*z + 4*z**2) + z]])
根据乘符号矩阵中的文本字符串创建间接和总效果的语法(仍在 python 中,但不一定):
```{python}
l=len(r.rn) # number of matrix rows, taken from r object
total_effects_syntax = str() # initialize empty string for syntax
for i,rname in enumerate(r.rn): # both row index and row elements in matrix are needed, thefore use of enumerate()
for j,cname in enumerate(r.cn): # now traverse through columns
if i!=j: # exclude path coefficients that go from construct to itself
total_effects_syntax+= " "+rname[0]+cname[0]+"_total:= "+str(rsm_total[i*l+j]) + " \n " # create a string for lavaan total effects
# Now indicate that z means zero:
total_effects_syntax = "z:=0" + " \n" + total_effects_syntax + " "
print(total_effects_syntax)
```
输出是总效果的语法,将被插入到结构模型的描述中(出于显示目的手动清理的输出):
z:=0
qd_total:= 2*qd*z + qd*(qd*z + 4*z**2) + qd + 3*z**2 + z*(df*qd + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2)
qf_total:= df*qd + df*(2*qd*z + 3*z**2) + 4*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
qc_total:= fc*z + fc*(df*qd + 4*z**2) + qd*z + 3*z**2 + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
qi_total:= ci*z + ci*(fc*z + qd*z + 3*z**2) + qd*z + 3*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
dq_total:= df*z + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
df_total:= 2*df*z + df*(df*z + qd*z + 3*z**2) + df + 3*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2)
dc_total:= df*fc + fc*(2*df*z + 3*z**2) + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
di_total:= ci*z + ci*(df*fc + 4*z**2) + df*z + 3*z**2 + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
fq_total:= fc*z + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
fd_total:= fc*z + qd*z + qd*(fc*z + 4*z**2) + 3*z**2 + z*(ci*fc + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
fc_total:= 2*fc*z + fc*(df*z + fc*z + 3*z**2) + fc + 3*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2)
fi_total:= ci*fc + ci*(2*fc*z + 3*z**2) + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
cq_total:= ci*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
cd_total:= ci*z + qd*z + qd*(ci*z + 4*z**2) + 3*z**2 + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
cf_total:= ci*z + df*z + df*(ci*z + qd*z + 3*z**2) + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z
ci_total:= 2*ci*z + ci*(ci*z + fc*z + 3*z**2) + ci + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2)
iq_total:= 5*z**3 + 5*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z
id_total:= 5*qd*z**2 + qd*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z
if_total:= df*z + df*(qd*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z
ic_total:= fc*z + fc*(df*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z
最后,切换回 r 并第二次运行模型,但现在将总效果的语法添加到模型定义中:
model.sem_1a <- paste(model.cfa, "
delivery ~ qd*quality
flexibility ~ df*delivery
costs ~ fc*flexibility
innovation ~ ci*costs
", py$total_effects_syntax)
fit.sem_1a <- sem(model.sem_1a, data = dataset, missing = "fiml")
summary(fit.sem_1a, fit.measures = T, standardized = T, rsquare = T)
这是模型(model.sem_1a)描述,添加了总效果的语法,我们的最终目标:
quality =~ Q068_1 + Q068_4
delivery =~ Q069_2 + Q069_5
flexibility =~ Q071_1 + Q071_4 + Q071_5
costs =~ Q070_1 + Q070_2 + Q070_3
innovation =~ Q072_1 + Q072_3 + Q072_2
delivery ~ qd*quality
flexibility ~ df*delivery
costs ~ fc*flexibility
innovation ~ ci*costs
z:=0
qd_total:= 2*qd*z + qd*(qd*z + 4*z**2) + qd + 3*z**2 + z*(df*qd + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2)
qf_total:= df*qd + df*(2*qd*z + 3*z**2) + 4*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
qc_total:= fc*z + fc*(df*qd + 4*z**2) + qd*z + 3*z**2 + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
qi_total:= ci*z + ci*(fc*z + qd*z + 3*z**2) + qd*z + 3*z**2 + z*(df*qd + 4*z**2) + z*(qd*z + 4*z**2) + z*(2*qd*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
dq_total:= df*z + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
df_total:= 2*df*z + df*(df*z + qd*z + 3*z**2) + df + 3*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2)
dc_total:= df*fc + fc*(2*df*z + 3*z**2) + 4*z**2 + z*(df*fc + 4*z**2) + z*(df*z + 4*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
di_total:= ci*z + ci*(df*fc + 4*z**2) + df*z + 3*z**2 + z*(df*z + 4*z**2) + z*(2*df*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(df*z + qd*z + 3*z**2) + z
fq_total:= fc*z + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
fd_total:= fc*z + qd*z + qd*(fc*z + 4*z**2) + 3*z**2 + z*(ci*fc + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
fc_total:= 2*fc*z + fc*(df*z + fc*z + 3*z**2) + fc + 3*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(2*fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2)
fi_total:= ci*fc + ci*(2*fc*z + 3*z**2) + 4*z**2 + z*(ci*fc + 4*z**2) + z*(fc*z + 4*z**2) + z*(df*z + fc*z + 3*z**2) + z*(fc*z + qd*z + 3*z**2) + z
cq_total:= ci*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
cd_total:= ci*z + qd*z + qd*(ci*z + 4*z**2) + 3*z**2 + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2) + z
cf_total:= ci*z + df*z + df*(ci*z + qd*z + 3*z**2) + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + fc*z + 3*z**2) + z
ci_total:= 2*ci*z + ci*(ci*z + fc*z + 3*z**2) + ci + 3*z**2 + z*(ci*z + 4*z**2) + z*(2*ci*z + 3*z**2) + z*(ci*z + df*z + 3*z**2) + z*(ci*z + qd*z + 3*z**2)
iq_total:= 5*z**3 + 5*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z
id_total:= 5*qd*z**2 + qd*z + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z \n if_total:= df*z + df*(qd*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(df*z + 4*z**2) + z*(fc*z + 4*z**2) + z
ic_total:= fc*z + fc*(df*z + 4*z**2) + 5*z**3 + 4*z**2 + z*(ci*z + 4*z**2) + z*(fc*z + 4*z**2) + z*(qd*z + 4*z**2) + z