The residual-covaraince matrix \( (2 \times 2) \) at level-1, \( (\Theta_{1,1}) \) is .
Corresponding intercept vector is:
A(B) and B(A) include reciprocal exchangable ratings of members of the same dyad. Hence, the within-level parameters are constrained to be equal.
Resudual covariance matrix at level-2 \( (\Theta_{2,2}) \) is contrained to be equal to level-1 residual covariance.
Similarly, intercepts are also constrained across the two levels.
At level-3, we have two latent variables: Target effects for \( y_1 \) and \( y_2 \). There is a single parameter matrix, latent factor covariance matrix at the target level.
The latent covariance matrix is a \( (2 \times 2) \) matrix:
Similarly, at level-4, there are two latent variables: Rater effects for \( y_1 \) and \( y_2 \) and a corresponding latent factor covariance matrix..
The latent covariance matrix is a \( (2 \times 2) \) matrix with two variances and single covariance:
There are four factor-loading matrices:
All four of these are \( 2 \times 2 \) identity matrices.
Residuals of levels A(B) and B(A) covary across levels:
However, across-level, across-variable residual-covariances are constrained to equality, \( \theta_{1,2}^{1,2} = \theta_{2,1}^{1,2} \).
Target and Rater level latent variables levels are allowed to covary:
xxM library needs to be loaded first.
library(xxm)
SRM model has four real levels:
and two virtual levels:
xxM requires separate datasets for six levels:
Structure of each of these datasets is described below. Note:
attach("nlsem.srm.xxm.RData")
A(B) includes rater B's ratings of target A and includes following columns:
str(A_B)
## 'data.frame': 209 obs. of 5 variables:
## $ a_b : int 2030202 2040202 2040203 2060201 2060202 2070202 2070203 2070204 2080205 2110205 ...
## $ target: int 202 202 203 201 202 202 203 204 205 205 ...
## $ rater : int 203 204 204 206 206 207 207 207 208 211 ...
## $ like : num 7 9 4 9 2 9 9 9 7 7 ...
## $ warm : num 9 7 3 7 2 9 8 9 8 7 ...
B(A) includes rater A's ratings of target B and includes following columns:
str(B_A)
## 'data.frame': 256 obs. of 5 variables:
## $ b_a : int 2030202 2040202 2040203 2060202 2060204 2070202 2080205 2100203 2100206 2110205 ...
## $ target: int 203 204 204 206 206 207 208 210 210 211 ...
## $ rater : int 202 202 203 202 204 202 205 203 206 205 ...
## $ like : num 7 8 8 1 1 8 8 4 1 7 ...
## $ warm : num 8 9 4 3 1 8 4 2 1 3 ...
target dataset includes a single column:
str(target)
## 'data.frame': 164 obs. of 1 variable:
## $ target: int 201 202 203 204 205 206 207 208 209 210 ...
rater dataset includes a single column:
str(rater)
## 'data.frame': 114 obs. of 1 variable:
## $ rater: int 202 203 204 205 206 207 208 211 213 214 ...
dyad dataset includes a single column:
str(dyad)
## 'data.frame': 383 obs. of 1 variable:
## $ dyad: int 2030202 2040202 2040203 2060201 2060202 2060204 2070202 2070203 2070204 2080205 ...
person dataset includes a single column:
str(person)
## 'data.frame': 172 obs. of 1 variable:
## $ person: int 201 202 203 204 205 206 207 208 209 210 ...
For each parameter matrix, construct three related matrices:
# Within matrices for A(B) and B(A)
theta_wn_pat <- matrix(1, 2, 2)
theta_wn_val <- diag(3, 2)
theta_wn_lab <- matrix(c("like_like", "like_warm", "like_warm", "warm_warm"),
2, 2)
nu_pat <- matrix(1, 2, 1)
nu_val <- matrix(6, 2, 1)
nu_lab <- matrix(c("like_mean", "warm_mean"), 2, 1)
# Note: The use of common labels for nu (nu_lab) and theta (theta_wn_lab)
# for A(B) and B(A) imposes equality constraints on corresponding parameter
# estimates.
# Within latent covariance matrix for target
target_psi_pat <- matrix(1, 2, 2)
target_psi_val <- diag(0.1, 2)
# Within latent covariance matrix for rater
rater_psi_pat <- matrix(1, 2, 2)
rater_psi_val <- diag(0.1, 2)
# Across level dyadic residual-covaraince (A_B with B_A)
theta_bw_pat <- matrix(1, 2, 2)
theta_bw_val <- diag(0, 2)
theta_bw_lab <- matrix(c("like1_like2", "like1_warm2", "like1_warm2", "warm1_warm2"))
# Note: The use of common labels like1_warm2 imposes equality constraints on
# across-level [A(B) and B(A)] covariance between `like` and `warm`.
# Across level Target-Rater covariance
rater_target_psi_pat <- matrix(1, 2, 2)
rater_target_psi_val <- matrix(0, 2, 2)
# Across-level factor loadings are all (2x2) identity matrices
lambda_pat <- matrix(0, 2, 2)
lambda_val <- diag(1, 2)
xxmModel() is used to declare level names. The function returns a model object that is passed as a parameter to subsequent statements. Variable name for the return value can be anything.
zz <- xxmModel(c("a_b", "b_a", "target", "rater"))
## A new model was created.
For SRM, only real levels have observed and/or latent variables. Only real levels need to be declared using the xxmModel command. Virtual levels are declared in a separate command.
In this case, we have four real levels:
Note that the two levels with observed dependent variables come before the levels with latent independnet variables.
For each vitual level we need three pieces of information.
There are two commands that together accomplish these goals:
xxmVirtuals() informs our model that there are virtual levels and binds each virtual level with the corresponding set of real levels. The function has two parameters.
alias is a named list with as many elements as the number of virtual levels. The name of each element is the name of the virtual level. For each virtual level, a list of corresponding real levels is provided. In this case, there are two virtual levels:
xxmVirtualIds() adds data for a virtual level with a single column of IDs to our model. In this case, person and dyad datasets are added to our model.
alias = list(person = c("target", "rater"), dyad = c("a_b", "b_a"))
zz <- xxmVirtuals(zz, alias)
## Creating virtual `person` with 2 aliases
## Creating virtual `dyad` with 2 aliases
## Aliases created
zz <- xxmVirtualids(zz, person)
## Virtual level `person` was created
zz <- xxmVirtualids(zz, dyad)
## Virtual level `dyad` was created
For each declared level xxmSubmodel() is invoked to add corresponding submodel to the model object. The function adds three types of information to the model object:
In this case, a submodel is declared for each of the four real levels. Note, virtual levels do not need a submodel! Their sole purpose is to bind real levels so that we can include across-level covariances.
# Level 1: A(B)
zz <- xxmSubmodel(model = zz, level = "a_b", parents = c("target", "rater"),
ys = c("like", "warm"), xs = , etas = , data = A_B, )
## Creating role model `a_b` for virtual `dyad`
## Submodel for level `a_b` was created.
# Level 1: B(A)
zz <- xxmSubmodel(model = zz, level = "b_a", parents = c("target", "rater"),
ys = c("like", "warm"), xs = , etas = , data = B_A, )
## Creating role model `b_a` for virtual `dyad`
## Submodel for level `b_a` was created.
# Level 3: Target
zz <- xxmSubmodel(model = zz, level = "target", parents = , ys = , xs = , etas = c("like-target",
"warm-target"), data = target, )
## Creating role model `target` for virtual `person`
## Submodel for level `target` was created.
# Level 3: Rater
zz <- xxmSubmodel(model = zz, level = "rater", parents = , ys = , xs = , etas = c("like-rater",
"warm-rater"), data = rater, )
## Creating role model `rater` for virtual `person`
## Submodel for level `rater` was created.
## @ knitr xxmWithinMatrix Level 1: A_B :: Intercepts
zz <- xxmWithinMatrix(model = zz, level = "a_b", type = "nu", pattern = nu_pat,
value = nu_val, label = nu_lab, name = )
##
## 'nu' matrix does not exist and will be added.
## Added `nu` matrix.
# Level 1: A_B :: Residual-covariance
zz <- xxmWithinMatrix(model = zz, level = "a_b", "theta", pattern = theta_wn_pat,
value = theta_wn_val, label = theta_wn_lab, )
##
## 'theta' matrix does not exist and will be added.
## Added `theta` matrix.
# Level 2: B_A :: Intercepts
zz <- xxmWithinMatrix(model = zz, level = "b_a", type = "nu", pattern = nu_pat,
value = nu_val, label = nu_lab, )
##
## 'nu' matrix does not exist and will be added.
## Added `nu` matrix.
# Level 2: B_A :: Residual-covariance
zz <- xxmWithinMatrix(model = zz, level = "b_a", type = "theta", pattern = theta_wn_pat,
value = theta_wn_val, label = theta_wn_lab, )
##
## 'theta' matrix does not exist and will be added.
## Added `theta` matrix.
# Level 3: Target
zz <- xxmWithinMatrix(model = zz, level = "target", type = "psi", pattern = target_psi_pat,
value = target_psi_val, , )
##
## 'psi' matrix does not exist and will be added.
## Added `psi` matrix.
# Level 4: Rater
zz <- xxmWithinMatrix(model = zz, level = "rater", type = "psi", pattern = rater_psi_pat,
value = rater_psi_val, , )
##
## 'psi' matrix does not exist and will be added.
## Added `psi` matrix.
## @ knitr xxmBetweenMatrix A(B)-B(A) residual covariance
zz <- xxmBetweenMatrix(model = zz, parent = "b_a", child = "a_b", type = "theta",
pattern = theta_bw_pat, value = theta_bw_val, label = theta_bw_lab, )
##
## 'theta' matrix does not exist and will be added.
## Added `theta` matrix.
### Target-Rater covariance
zz <- xxmBetweenMatrix(model = zz, parent = "rater", child = "target", type = "psi",
pattern = rater_target_psi_pat, value = rater_target_psi_val, , )
##
## 'psi' matrix does not exist and will be added.
## Added `psi` matrix.
# Target -> A_B link matrix:
zz <- xxmBetweenMatrix(model = zz, parent = "target", child = "a_b", type = "lambda",
pattern = lambda_pat, value = lambda_val, label = )
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
# Target -> A_B link matrix:
zz <- xxmBetweenMatrix(model = zz, parent = "target", child = "b_a", type = "lambda",
pattern = lambda_pat, value = lambda_val, label = )
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
# Rater -> A_B link matrix:
zz <- xxmBetweenMatrix(model = zz, parent = "rater", child = "a_b", type = "lambda",
pattern = lambda_pat, value = lambda_val, label = )
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
# Rater -> B_A link matrix:
zz <- xxmBetweenMatrix(model = zz, parent = "rater", child = "b_a", type = "lambda",
pattern = lambda_pat, value = lambda_val, label = )
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
For each declared level xxmWithinMatrix() is used to add within-level parameter matrices. For each parameter matrix, the function adds the three matrices constructed earlier:
Pairs of levels that share parent-child relationship have regression relationships. xxmBetweenMatrix() is used to add corresponding rergession matrices connecting the two levels.
For each parameter matrix, the function adds the three matrices constructed earlier:
Estimation process is initiated by xxmRun(). If all goes well, a q&d summary of the results is printed.
zz <- xxmRun(zz)
## ------------------------------------------------------------------------------
## Estimating model parameters
## ------------------------------------------------------------------------------
## 3845.6787733309
## 1010
## 3827.0022965414
## 3813.2807817324
## 3800.1973631633
## 3792.8027509368
## 3787.2429488352
## 3781.1339685640
## 3773.3712242050
## 3754.7344587277
## 1010
## 3745.7106123263
## 3743.0787783140
## 3741.5194034727
## 3732.1782471290
## 3728.1121445111
## 3727.2437463610
## 3724.7609317541
## 3718.9189004660
## 3717.5244086705
## 3717.4465498261
## 3717.6208968386
## 3716.8867202835
## 3717.5992659136
## 3718.5415793043
## 3722.2117551244
## 3722.0321341161
## 3721.9343251739
## 3721.8510434386
## 3721.7369256222
## 3721.6958881212
## 3721.6649608229
## 3721.6546033034
## 3721.6416413801
## 3721.6309393732
## 3721.6287124801
## 3721.6263509909
## 3721.6253391056
## 3721.6249232333
## 3721.6243861740
## 3721.6237942327
## 3721.6217367473
## 3721.6195869373
## 3721.6172747980
## 3721.6130437022
## 3721.6097309518
## 3721.6087287044
## 3721.6080373175
## 3721.6078041279
## 3721.6069571707
## 3721.6060237656
## 3721.6056525807
## 3721.6047551826
## 3721.6046911642
## 3721.6044512253
## 3721.6043859237
## 3721.6042990222
## 3721.6042344755
## 3721.6042182606
## 3721.6042180248
## 3721.6042180269
## 3721.6042180280
## 3721.6042180166
## Model converged normally
## nParms: 18
## ------------------------------------------------------------------------------
## *
## 1: like_like :: 2.705 [ 0.000, 0.000]
##
## 2: like_warm :: 0.741 [ 0.000, 0.000]
##
## 3: warm_warm :: 3.160 [ 0.000, 0.000]
##
## 4: like_mean :: 6.683 [ 0.000, 0.000]
##
## 5: warm_mean :: 5.677 [ 0.000, 0.000]
##
## 6: like1_like2 :: 1.158 [ 0.000, 0.000]
##
## 7: like1_warm2 :: 0.678 [ 0.000, 0.000]
##
## 8: warm1_warm2 :: 0.592 [ 0.000, 0.000]
##
## 9: target_psi_1_1 :: 0.406 [ 0.000, 0.000]
##
## 10: target_psi_1_2 :: 0.614 [ 0.000, 0.000]
##
## 11: target_psi_2_2 :: 0.977 [ 0.000, 0.000]
##
## 12: target_rater_psi_1_1 :: 0.477 [ 0.000, 0.000]
##
## 13: target_rater_psi_2_1 :: 0.626 [ 0.000, 0.000]
##
## 14: target_rater_psi_1_2 :: 0.224 [ 0.000, 0.000]
##
## 15: target_rater_psi_2_2 :: 0.355 [ 0.000, 0.000]
##
## 16: rater_psi_1_1 :: 0.785 [ 0.000, 0.000]
##
## 17: rater_psi_1_2 :: 0.360 [ 0.000, 0.000]
##
## 18: rater_psi_2_2 :: 0.533 [ 0.000, 0.000]
##
## ------------------------------------------------------------------------------
Once parameters are estimated, confidence intervals are estimated by invoking xxmCI(). Depending on the the number of observations and the complexity of the model, xxmCI() may take a long time to compute. xxmCI() also prints a summary of parameter estimates and CIS.
zz <- xxmCI(zz)
A summary of results may be retrived as an R list by a call to xxmSummary(). The returned list has two elements:
bivariate.srm.results <- xxmSummary(zz)
bivariate.srm.results
## $fit
## $fit$deviance
## [1] 3722
##
## $fit$nParameters
## [1] 18
##
## $fit$nObservations
## [1] 907
##
## $fit$aic
## [1] 3758
##
## $fit$bic
## [1] 3844
##
##
## $estimates
## child parent to from label estimate
## 1 a_b a_b like like like_like 2.7051
## 2 a_b a_b like warm like_warm 0.7412
## 3 a_b a_b warm warm warm_warm 3.1601
## 4 a_b a_b like One like_mean 6.6832
## 5 a_b a_b warm One warm_mean 5.6766
## 6 a_b b_a like like like1_like2 1.1579
## 7 a_b b_a warm like like1_warm2 0.6781
## 8 a_b b_a like warm like1_warm2 0.6781
## 9 a_b b_a warm warm warm1_warm2 0.5920
## 10 b_a b_a like like like_like 2.7051
## 11 b_a b_a like warm like_warm 0.7412
## 12 b_a b_a warm warm warm_warm 3.1601
## 13 b_a b_a like One like_mean 6.6832
## 14 b_a b_a warm One warm_mean 5.6766
## 23 target target like-target like-target target_psi_1_1 0.4059
## 24 target target like-target warm-target target_psi_1_2 0.6136
## 25 target target warm-target warm-target target_psi_2_2 0.9769
## 34 target rater like-target like-rater target_rater_psi_1_1 0.4769
## 35 target rater warm-target like-rater target_rater_psi_2_1 0.6257
## 36 target rater like-target warm-rater target_rater_psi_1_2 0.2240
## 37 target rater warm-target warm-rater target_rater_psi_2_2 0.3547
## 38 rater rater like-rater like-rater rater_psi_1_1 0.7851
## 39 rater rater like-rater warm-rater rater_psi_1_2 0.3598
## 40 rater rater warm-rater warm-rater rater_psi_2_2 0.5329
## low high
## 1 2.287256 3.2109
## 2 0.379996 1.1559
## 3 2.652929 3.7913
## 4 6.386750 6.9747
## 5 5.371974 5.9772
## 6 0.501311 1.7819
## 7 0.056552 1.2619
## 8 0.056552 1.2619
## 9 -0.541477 1.6542
## 10 2.287256 3.2109
## 11 0.379996 1.1559
## 12 2.652929 3.7913
## 13 6.386750 6.9747
## 14 5.371974 5.9772
## 23 0.171238 0.7465
## 24 0.336852 0.9695
## 25 0.539157 1.5608
## 34 0.197031 0.8120
## 35 0.268629 1.0393
## 36 -0.065961 0.5347
## 37 -0.007319 0.7394
## 38 0.436826 1.2729
## 39 0.078493 0.7133
## 40 0.188153 1.0057
xxM model object may hog a significant amount of RAM outside of R's workspace. This memory will automatically be released, when the workspace is cleared by a call to rm(list=ls()) or at the end of the R session. Alternatively, it is recommended that xxmFree() may be called to release the memory.
zz <- xxmFree(zz)
rm(list = ls())