The resudual covariance 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.
Residual 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 a single latent variable influencing both \( y_1 \) and \( y_2 \). There is a single parameter matrix, latent factor covariance matrix at the target level.
The latent covariance matrix for target has a single element matrix fixed to 1.0:
Similarly, at level-4, there is a single latent variable: Rater effect.
The latent covariance matrix for target has a single element matrix fixed to 1.0:
There are four factor-loading matrices:
All four matrices are freely estiamted. However, the matrices for target and rater effects are constrained to be equal:
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 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")
## The following objects are masked from file:C://Paras//Projects//WAF//xxm/all//srm.xxm.RData:
##
## A_B, B_A, dyad, person, rater, target
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:
# A(B) and B(A) Within matrices: Observed residual-covariance
theta_wn_pat <- matrix(1, 2, 2)
theta_wn_val <- matrix(c(2, 0, 0, 2), 2, 2)
theta_wn_lab <- matrix(c("like_like", "like_warm", "like_warm", "warm_warm"),
2, 2)
# A(B) and B(A) Within matrices: Observed intercepts
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.
# Note: Latent factor variances for Target is fixed to 1.0 to define the
# scale of Target-Agree Level 3: Target
target_psi_pat <- diag(0, 1)
target_psi_val <- diag(1, 1)
# Note: Latent factor variances for Rater is fixed to 1.0 to define the
# scale of Rater-Agree Level 4: Rater
rater_psi_pat <- diag(0, 1)
rater_psi_val <- diag(1, 1)
###### Across-level matrices ###### Dyadic correlation (A_B with B_A)
theta_bw_pat <- matrix(1, 2, 2)
theta_bw_val <- matrix(0, 2, 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`.
# Generalized rater-target correlation
rater_target_psi_pat <- matrix(1, 1, 1)
rater_target_psi_val <- matrix(0, 1, 1)
# Rater -> Rating link matrices
rater_ly_pat <- matrix(1, 2, 1)
rater_ly_val <- matrix(0.1, 2, 1)
rater_ly_lab <- c("like_rater-agree", "warm_rater-agree")
# Target -> Rating link matrices:
target_ly_pat <- matrix(1, 2, 1)
target_ly_val <- matrix(0.1, 2, 1)
target_ly_lab <- c("like_target-agree", "warm_target-agree")
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("target_agree"),
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("rater_agree"),
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: Latent covariance
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: Latent covariance
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 Latent 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.
## Rater -> A_B factor-loading matrix
zz <- xxmBetweenMatrix(model = zz, parent = "rater", child = "a_b", type = "lambda",
pattern = rater_ly_pat, value = rater_ly_val, label = rater_ly_lab)
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
## Rater -> B_A factor-loading matrix
zz <- xxmBetweenMatrix(model = zz, parent = "rater", child = "b_a", type = "lambda",
pattern = rater_ly_pat, value = rater_ly_val, label = rater_ly_lab)
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
## Target -> A_B factor-loading matrix
zz <- xxmBetweenMatrix(model = zz, parent = "target", child = "a_b", type = "lambda",
pattern = target_ly_pat, value = target_ly_val, label = target_ly_lab)
##
## 'lambda' matrix does not exist and will be added.
## Added `lambda` matrix.
## Target -> B_A factor-loading matrix
zz <- xxmBetweenMatrix(model = zz, parent = "target", child = "b_a", type = "lambda",
pattern = target_ly_pat, value = target_ly_val, label = target_ly_lab)
##
## '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
## ------------------------------------------------------------------------------
## 4019.3977989295
## 3988.9023248341
##
## 1010
## 3970.2507786867
## 3958.2185837204
## 3955.4636492817
## 3949.3531090161
## 3941.3090383276
## 3907.8485191342
## 3837.3588108308
## 3802.7970408310
## 3778.6934137156
## 3767.6160091283
## 3761.6428729863
## 3744.9196855910
## 3738.1431586419
## 3732.6366955489
## 3728.3743011442
## 3732.4303786983
## 3729.2450818405
## 3729.2728768440
## 3728.5216127310
## 3728.4995717709
## 3728.4815946827
## 3728.4771698432
## 3728.4758427053
## 3728.4759427372
## 3728.4759200660
## 3728.4759089697
## 3728.4759104052
## 3728.4759176314
## 3728.4759176196
## Model converged normally
## nParms: 13
## ------------------------------------------------------------------------------
## *
## 1: like_like :: 2.716 [ 0.000, 0.000]
##
## 2: like_warm :: 0.654 [ 0.000, 0.000]
##
## 3: warm_warm :: 3.468 [ 0.000, 0.000]
##
## 4: like_mean :: 6.692 [ 0.000, 0.000]
##
## 5: warm_mean :: 5.684 [ 0.000, 0.000]
##
## 6: like1_like2 :: 1.136 [ 0.000, 0.000]
##
## 7: like1_warm2 :: 0.649 [ 0.000, 0.000]
##
## 8: warm1_warm2 :: 0.672 [ 0.000, 0.000]
##
## 9: like_target-agree :: 0.641 [ 0.000, 0.000]
##
## 10: warm_target-agree :: 0.980 [ 0.000, 0.000]
##
## 11: like_rater-agree :: 0.863 [ 0.000, 0.000]
##
## 12: warm_rater-agree :: 0.498 [ 0.000, 0.000]
##
## 13: target_rater_psi_1_1 :: 0.750 [ 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:
latent.srm.results <- xxmSummary(zz)
latent.srm.results
## $fit
## $fit$deviance
## [1] 3728
##
## $fit$nParameters
## [1] 13
##
## $fit$nObservations
## [1] 907
##
## $fit$aic
## [1] 3754
##
## $fit$bic
## [1] 3817
##
##
## $estimates
## child parent to from label estimate
## 1 a_b a_b like like like_like 2.7158
## 2 a_b a_b like warm like_warm 0.6543
## 3 a_b a_b warm warm warm_warm 3.4681
## 4 a_b a_b like One like_mean 6.6915
## 5 a_b a_b warm One warm_mean 5.6835
## 6 a_b b_a like like like1_like2 1.1358
## 7 a_b b_a warm like like1_warm2 0.6493
## 8 a_b b_a like warm like1_warm2 0.6493
## 9 a_b b_a warm warm warm1_warm2 0.6721
## 10 b_a b_a like like like_like 2.7158
## 11 b_a b_a like warm like_warm 0.6543
## 12 b_a b_a warm warm warm_warm 3.4681
## 13 b_a b_a like One like_mean 6.6915
## 14 b_a b_a warm One warm_mean 5.6835
## 15 a_b target like target_agree like_target-agree 0.6406
## 16 a_b target warm target_agree warm_target-agree 0.9800
## 17 b_a target like target_agree like_target-agree 0.6406
## 18 b_a target warm target_agree warm_target-agree 0.9800
## 20 a_b rater like rater_agree like_rater-agree 0.8635
## 21 a_b rater warm rater_agree warm_rater-agree 0.4982
## 22 b_a rater like rater_agree like_rater-agree 0.8635
## 23 b_a rater warm rater_agree warm_rater-agree 0.4982
## 24 target rater target_agree rater_agree target_rater_psi_1_1 0.7503
## low high
## 1 2.29002 3.2342
## 2 0.28152 1.0906
## 3 2.92579 4.1188
## 4 6.40223 6.9763
## 5 5.39336 5.9709
## 6 0.47440 1.7666
## 7 0.01461 1.2454
## 8 0.01461 1.2454
## 9 -0.44640 1.7076
## 10 2.29002 3.2342
## 11 0.28152 1.0906
## 12 2.92579 4.1188
## 13 6.40223 6.9763
## 14 5.39336 5.9709
## 15 0.41414 0.8688
## 16 0.71933 1.2462
## 17 0.41414 0.8688
## 18 0.71933 1.2462
## 20 0.63464 1.1055
## 21 0.18171 0.7970
## 22 0.63464 1.1055
## 23 0.18171 0.7970
## 24 0.37691 1.0000
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())