Subscores and Popular Models

Multidimensional Measurement Models (Fall 2023): Lecture 14

Today’s Lecture

  • The Educational Measurement Problem: Total vs. Subscores
    • The problem with subscores when having a unidimensional total score
    • The problem with a unidimensional total score when having a multidimensional assessment
  • Bifactor IRT Models
  • Higher Order IRT Models
  • Historical issues with Bifactor and Higher Order Models

Key Definition: Subscore

A subscore is a score that is formed by taking some items of an assessment

  • For instance, consider an algebra test measuring four algebra standards:

    • The total score (measuring algebra) is formed using all the items
      • Note: “formed” is intentionally ambiguous and can mean summing all items (a parallel items model) or estimating a latent variable score using scoring methods from IRT
    • A subscore for each standard can be formed using only the items measuring that standard

The Educational Measurement Problem: Total vs. Subscores

The issue (from K-12 assessment):

  • Assessment programs are designed to provide a single score for each student for each subject (e.g., reading, math, science, etc.)
  • However, many states also wish to provide more detailed information to each student
    • “Subscores” are often used to provide more detailed information about a student’s performance
  • A subscore is a score that is based on a subset of the items on a test
    • For example, a reading test may have a subscore for “vocabulary” and a subscore for “reading comprehension”
    • A math test may have a subscore for “algebra” and a subscore for “geometry”

The problem with subscores when having a unidimensional total score

  • The basic problem is a modeling problem:
    • The total score has a unidimensional model
    • The subscores have a multidimensional model
    • The two models are incompatible and cannot both be correct

Unidimensional Model

The model for the total score is often a unidimensional model:

\[ P(Y_{pi} = 1 | \theta_p) = \frac{\exp \left(a_i \left( \theta_p - b_i \right) \right)} {1 + \exp \left(a_i \left( \theta_p - b_i \right) \right)} \]

This model applies for all items \(i\) and all persons \(p\)

Note: The model shown is a two-parameter IRT model, but in general, there will be one latent variable in a unidimensional model

# format data 
responseMatrix = temp$responseMatrix
Qmatrix = temp$Qmatrix

reducedQ = Qmatrix[which(rownames(Qmatrix) %in% paste0("item", 11:30)), ]
reducedQ = reducedQ[, which(colSums(reducedQ) > 0)]


# using only Algebra items (11:30) ====================================================================================
dataMat = responseMatrix[paste0("item", 11:30)]

# remove cases that are all NA ========================================================================================
dataMat = dataMat[apply(dataMat, 1, function(x) !all(is.na(x))), ]

# create lavaan model for unidimensional model ========================================================================

names(responseMatrix)
 [1] "item1"           "item2"           "item3"           "item4"          
 [5] "item5"           "item6"           "item7"           "item8"          
 [9] "item9"           "item10"          "item11"          "item12"         
[13] "item13"          "item14"          "item15"          "item16"         
[17] "item17"          "item18"          "item19"          "item20"         
[21] "item21"          "item22"          "item23"          "item24"         
[25] "item25"          "item26"          "item27"          "item28"         
[29] "item29"          "item30"          "item31"          "item32"         
[33] "item33"          "item34"          "item35"          "item36"         
[37] "item37"          "item38"          "item39"          "item40"         
[41] "item41"          "item42"          "item43"          "item44"         
[45] "item45"          "item46"          "item47"          "item48"         
[49] "item49"          "item50"          "courseNameCombo" "id"             
unidimensionalModel_syntax = "

theta =~ item11 + item12 + item13 + item14 + item15 + 
         item16 + item17 + item18 + item19 + item20 + 
         item21 + item22 + item23 + item24 + item25 + 
         item26 + item27 + item28 + item29 + item30

"

unidimensionalModel = cfa(
  model = unidimensionalModel_syntax, 
  data = responseMatrix, 
  estimator = "WLSMV", 
  ordered = paste0("item", 11:30), 
  std.lv = TRUE, 
  parameterization = "theta"
)

summary(unidimensionalModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.15 ended normally after 15 iterations

  Estimator                                       DWLS
  Optimization method                           NLMINB
  Number of model parameters                        40

                                                  Used       Total
  Number of observations                          1099        2541

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               419.002     514.212
  Degrees of freedom                               170         170
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.847
  Shift parameter                                           19.655
    simple second-order correction                                

Model Test Baseline Model:

  Test statistic                              5341.853    3322.839
  Degrees of freedom                               190         190
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.644

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.952       0.890
  Tucker-Lewis Index (TLI)                       0.946       0.877
                                                                  
  Robust Comparative Fit Index (CFI)                         0.799
  Robust Tucker-Lewis Index (TLI)                            0.775

Root Mean Square Error of Approximation:

  RMSEA                                          0.037       0.043
  90 Percent confidence interval - lower         0.032       0.039
  90 Percent confidence interval - upper         0.041       0.047
  P-value H_0: RMSEA <= 0.050                    1.000       0.997
  P-value H_0: RMSEA >= 0.080                    0.000       0.000
                                                                  
  Robust RMSEA                                               0.073
  90 Percent confidence interval - lower                     0.065
  90 Percent confidence interval - upper                     0.080
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         0.061

Standardized Root Mean Square Residual:

  SRMR                                           0.066       0.066

Parameter Estimates:

  Standard errors                           Robust.sem
  Information                                 Expected
  Information saturated (h1) model        Unstructured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta =~                                                              
    item11            0.864    0.074   11.634    0.000    0.864    0.654
    item12            0.286    0.053    5.421    0.000    0.286    0.275
    item13            0.768    0.062   12.382    0.000    0.768    0.609
    item14            0.589    0.053   11.017    0.000    0.589    0.508
    item15            0.474    0.049    9.626    0.000    0.474    0.428
    item16            0.703    0.055   12.835    0.000    0.703    0.575
    item17            0.710    0.056   12.576    0.000    0.710    0.579
    item18            0.867    0.066   13.192    0.000    0.867    0.655
    item19            0.912    0.067   13.547    0.000    0.912    0.674
    item20            0.820    0.078   10.577    0.000    0.820    0.634
    item21            0.173    0.045    3.799    0.000    0.173    0.170
    item22            0.310    0.057    5.441    0.000    0.310    0.296
    item23            0.437    0.056    7.736    0.000    0.437    0.400
    item24            0.374    0.052    7.164    0.000    0.374    0.350
    item25            0.433    0.053    8.129    0.000    0.433    0.398
    item26            0.569    0.062    9.150    0.000    0.569    0.494
    item27            0.422    0.048    8.785    0.000    0.422    0.389
    item28            0.605    0.057   10.706    0.000    0.605    0.518
    item29            0.257    0.058    4.411    0.000    0.257    0.249
    item30            0.390    0.053    7.292    0.000    0.390    0.363

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            0.000                               0.000    0.000
   .item12            0.000                               0.000    0.000
   .item13            0.000                               0.000    0.000
   .item14            0.000                               0.000    0.000
   .item15            0.000                               0.000    0.000
   .item16            0.000                               0.000    0.000
   .item17            0.000                               0.000    0.000
   .item18            0.000                               0.000    0.000
   .item19            0.000                               0.000    0.000
   .item20            0.000                               0.000    0.000
   .item21            0.000                               0.000    0.000
   .item22            0.000                               0.000    0.000
   .item23            0.000                               0.000    0.000
   .item24            0.000                               0.000    0.000
   .item25            0.000                               0.000    0.000
   .item26            0.000                               0.000    0.000
   .item27            0.000                               0.000    0.000
   .item28            0.000                               0.000    0.000
   .item29            0.000                               0.000    0.000
   .item30            0.000                               0.000    0.000
    theta             0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11|t1         0.460    0.055    8.384    0.000    0.460    0.348
    item12|t1         0.645    0.043   14.979    0.000    0.645    0.620
    item13|t1         0.128    0.048    2.654    0.008    0.128    0.102
    item14|t1         0.131    0.044    2.966    0.003    0.131    0.113
    item15|t1         0.082    0.042    1.955    0.051    0.082    0.074
    item16|t1        -0.141    0.046   -3.060    0.002   -0.141   -0.115
    item17|t1        -0.038    0.046   -0.815    0.415   -0.038   -0.031
    item18|t1        -0.044    0.050   -0.877    0.381   -0.044   -0.033
    item19|t1        -0.113    0.051   -2.214    0.027   -0.113   -0.083
    item20|t1         0.610    0.057   10.675    0.000    0.610    0.472
    item21|t1         0.266    0.039    6.824    0.000    0.266    0.262
    item22|t1         0.824    0.046   17.874    0.000    0.824    0.787
    item23|t1         0.623    0.046   13.661    0.000    0.623    0.571
    item24|t1         0.512    0.043   11.893    0.000    0.512    0.480
    item25|t1         0.484    0.044   11.049    0.000    0.484    0.444
    item26|t1         0.618    0.049   12.572    0.000    0.618    0.537
    item27|t1         0.170    0.041    4.109    0.000    0.170    0.157
    item28|t1         0.345    0.046    7.485    0.000    0.345    0.295
    item29|t1         0.781    0.045   17.458    0.000    0.781    0.756
    item30|t1         0.551    0.044   12.571    0.000    0.551    0.513

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            1.000                               1.000    0.572
   .item12            1.000                               1.000    0.925
   .item13            1.000                               1.000    0.629
   .item14            1.000                               1.000    0.742
   .item15            1.000                               1.000    0.817
   .item16            1.000                               1.000    0.669
   .item17            1.000                               1.000    0.665
   .item18            1.000                               1.000    0.571
   .item19            1.000                               1.000    0.546
   .item20            1.000                               1.000    0.598
   .item21            1.000                               1.000    0.971
   .item22            1.000                               1.000    0.912
   .item23            1.000                               1.000    0.840
   .item24            1.000                               1.000    0.877
   .item25            1.000                               1.000    0.842
   .item26            1.000                               1.000    0.755
   .item27            1.000                               1.000    0.849
   .item28            1.000                               1.000    0.732
   .item29            1.000                               1.000    0.938
   .item30            1.000                               1.000    0.868
    theta             1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11            0.757                               0.757    1.000
    item12            0.962                               0.962    1.000
    item13            0.793                               0.793    1.000
    item14            0.862                               0.862    1.000
    item15            0.904                               0.904    1.000
    item16            0.818                               0.818    1.000
    item17            0.816                               0.816    1.000
    item18            0.756                               0.756    1.000
    item19            0.739                               0.739    1.000
    item20            0.773                               0.773    1.000
    item21            0.985                               0.985    1.000
    item22            0.955                               0.955    1.000
    item23            0.916                               0.916    1.000
    item24            0.937                               0.937    1.000
    item25            0.918                               0.918    1.000
    item26            0.869                               0.869    1.000
    item27            0.921                               0.921    1.000
    item28            0.856                               0.856    1.000
    item29            0.969                               0.969    1.000
    item30            0.932                               0.932    1.000
unidimensionalScores = lavPredict(unidimensionalModel)

semPlot::semPaths(unidimensionalModel, sizeMan = 2.5, style = "mx", intercepts = FALSE, thresholds = FALSE)

Unidimensional Model Path Diagram

semPlot::semPaths(unidimensionalModel, 
                  sizeMan = 2.5, 
                  style = "mx", 
                  intercepts = FALSE, 
                  thresholds = FALSE)

Common Subscore Estimation Methods

With an overall score from the unidimensional model, often subscores are formed by one of the following methods:

  1. Using the unidimensional model parameters to create IRT-based subscores where:

    • Each score is a latent variable estimate from the IRT model
    • Each estimate is with respect to only the set of items that contribute/measure the subdomains
  2. Summing items that measure the subdomains (here, the standards)

    • Lecture 13 showed this was a parallel items model

Each of these methods has problems (to be discussed)

Unidimensional IRT-Model Based Subscores

Unidimensional IRT-Model Subscores are created by:

  • Taking the estimated parameters of only the items measuring a subdomain
  • Using IRT-based scoring methods

Note: As I am using lavaan for this lecture, I cannot easily create these scores

  • Instead: Showing a simulation with the mirt package
    • See file subscoreSame.R for methods for constructing scores

Unidimensional IRT-Model Based Subscores Are Just Short-Form Scores of the Same Construct

Sum-score Based Subscores

Sum-score based subscores are estimated by summing the items that measure each subdomain

reducedQ = Qmatrix[which(rownames(Qmatrix) %in% paste0("item", 11:30)), ]
reducedQ = reducedQ[, which(colSums(reducedQ) > 0)]

sumScores = as.matrix(dataMat) %*% as.matrix(reducedQ)

# problem with sumscores: missing data 
head(sumScores)
   A.REI.1 A.REI.2 A.REI.8 A.CED.2
1        2       5       0       1
2        3       0       0       1
4        2       1       1       2
7        1       2       1       0
9        4       1       2       0
11       3       4       4       4

Sum-score Based Subscores: Missing Data

One problem with sum-score based subscores is missing data

  • If a person omits a response, their total score possible is lower

Solution: Mean-based Subscores (the mean of all items administered)

# resolution: make an average score for each student
averageScores = nItems = matrix(0, nrow = nrow(sumScores), ncol = ncol(sumScores))

for (person in 1:nrow(dataMat)){
  for (col in 1:ncol(reducedQ)){
    for (row in 1:nrow(reducedQ)){
      if (reducedQ[row, col] == 1 && !is.na(dataMat[person, row])){
        averageScores[person, col] = averageScores[person, col] + dataMat[person, row]
        nItems[person, col] = nItems[person, col] + 1
      }   
    }
    averageScores[person, col] = averageScores[person, col] / nItems[person, col]
  }
}

head(averageScores)
     [,1] [,2] [,3] [,4]
[1,]  0.4  1.0  0.0  0.2
[2,]  0.6  0.0  0.0  0.2
[3,]  0.4  0.2  0.2  0.4
[4,]  0.2  0.4  0.2  0.0
[5,]  0.8  0.2  0.4  0.0
[6,]  0.6  0.8  0.8  0.8

Plots of Subscores vs. Overall Score

# plotting scores:
par(mfrow = c(2, 2))
for (standard in 1:ncol(reducedQ)){
  plot(x = sumScores[,standard], y = unidimensionalScores, main = "Sum Scores vs. Unidimensional Scores", 
       ylab = "IRT Total Theta",
       xlab = paste0("Sum Score ", colnames(reducedQ)[standard]))
}

par(mfrow = c(1,1))

Measurement Model Implied by Sumscore-based Subscores

The measurement model implied by sumscore-based subscores is a multidimensional CFA model where:

  • Each item intercept, loading, and unique variance are constrained to be equal across subdomains
  • The correlation between factors is fixed to zero

Subscore 1: \[ \begin{array}{c} Y_{p1} = \mu_1 + \lambda_1 F_{p1} + e_{p1}; e_{p1} \sim N(0, \psi^2_1) \\ Y_{p2} = \mu_2 + \lambda_1 F_{p1} + e_{p2}; e_{p2} \sim N(0, \psi^2_1) \\ \vdots \\ Y_{p5} = \mu_5 + \lambda_1 F_{p1} + e_{p5}; e_{p5} \sim N(0, \psi^2_1) \end{array} \]

Subscore 2: \[ \begin{array}{c} Y_{p6} = \mu_6 + \lambda_2 F_{p2} + e_{p6}; e_{p6} \sim N(0, \psi^2_2) \\ Y_{p7} = \mu_7 + \lambda_2 F_{p2} + e_{p7}; e_{p7} \sim N(0, \psi^2_2) \\ \vdots \\ Y_{p10} = \mu_10 + \lambda_2 F_{p2} + e_{p10}; e_{p10} \sim N(0, \psi^2_2) \end{array} \]

Structural model:

\[ \begin{bmatrix} \theta_{p1} \\ \theta_{p2} \\ \theta_{p3} \\ \theta_{p4} \\ \end{bmatrix} \sim N \left(\boldsymbol{0}, \boldsymbol{I}_{4} \right) \]

Implementing Sumscore-Based Subscore Model in lavaan

parallelItems_syntax = "

# constrain all loadings to be equal within each subscore
theta1 =~ L1*item11 + L1*item12 + L1*item13 + L1*item14 + L1*item15
theta2 =~ L2*item16 + L2*item17 + L2*item18 + L2*item19 + L2*item20
theta3 =~ L3*item21 + L3*item22 + L3*item23 + L3*item24 + L3*item25
theta4 =~ L4*item26 + L4*item27 + L4*item28 + L4*item29 + L4*item30

# set the unique variances to be equal within each subscore
item11 ~~ U1*item11; item12 ~~ U1*item12; item13 ~~ U1*item13; item14 ~~ U1*item14; item15 ~~ U1*item15;
item16 ~~ U2*item16; item17 ~~ U2*item17; item18 ~~ U2*item18; item19 ~~ U2*item19; item20 ~~ U2*item20;
item21 ~~ U3*item21; item22 ~~ U3*item22; item23 ~~ U3*item23; item24 ~~ U3*item24; item25 ~~ U3*item25;
item26 ~~ U4*item26; item27 ~~ U4*item27; item28 ~~ U4*item28; item29 ~~ U4*item29; item30 ~~ U4*item30;

# set all covariances to zero
theta1 ~~ 0*theta2
theta1 ~~ 0*theta3
theta1 ~~ 0*theta4
theta2 ~~ 0*theta3
theta2 ~~ 0*theta4
theta3 ~~ 0*theta4


"

parallelItemsModel = cfa(
  model = parallelItems_syntax, 
  data = dataMat, 
  estimator = "MLR",
  std.lv = TRUE, 
)

summary(parallelItemsModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.15 ended normally after 17 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        40
  Number of equality constraints                    32

  Number of observations                          1099

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                              1189.531    1236.996
  Degrees of freedom                               202         202
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.962
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              2354.623    2286.856
  Degrees of freedom                               190         190
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.030

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.544       0.506
  Tucker-Lewis Index (TLI)                       0.571       0.536
                                                                  
  Robust Comparative Fit Index (CFI)                         0.539
  Robust Tucker-Lewis Index (TLI)                            0.566

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)             -14167.940  -14167.940
  Scaling correction factor                                  0.158
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)     -13573.174  -13573.174
  Scaling correction factor                                  0.955
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                               28351.879   28351.879
  Bayesian (BIC)                             28391.896   28391.896
  Sample-size adjusted Bayesian (SABIC)      28366.487   28366.487

Root Mean Square Error of Approximation:

  RMSEA                                          0.067       0.068
  90 Percent confidence interval - lower         0.063       0.065
  90 Percent confidence interval - upper         0.070       0.072
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    0.000       0.000
                                                                  
  Robust RMSEA                                               0.067
  90 Percent confidence interval - lower                     0.063
  90 Percent confidence interval - upper                     0.071
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         0.000

Standardized Root Mean Square Residual:

  SRMR                                           0.119       0.119

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta1 =~                                                             
    item11    (L1)    0.207    0.008   25.443    0.000    0.207    0.428
    item12    (L1)    0.207    0.008   25.443    0.000    0.207    0.428
    item13    (L1)    0.207    0.008   25.443    0.000    0.207    0.428
    item14    (L1)    0.207    0.008   25.443    0.000    0.207    0.428
    item15    (L1)    0.207    0.008   25.443    0.000    0.207    0.428
  theta2 =~                                                             
    item16    (L2)    0.267    0.007   39.947    0.000    0.267    0.542
    item17    (L2)    0.267    0.007   39.947    0.000    0.267    0.542
    item18    (L2)    0.267    0.007   39.947    0.000    0.267    0.542
    item19    (L2)    0.267    0.007   39.947    0.000    0.267    0.542
    item20    (L2)    0.267    0.007   39.947    0.000    0.267    0.542
  theta3 =~                                                             
    item21    (L3)    0.151    0.010   14.505    0.000    0.151    0.330
    item22    (L3)    0.151    0.010   14.505    0.000    0.151    0.330
    item23    (L3)    0.151    0.010   14.505    0.000    0.151    0.330
    item24    (L3)    0.151    0.010   14.505    0.000    0.151    0.330
    item25    (L3)    0.151    0.010   14.505    0.000    0.151    0.330
  theta4 =~                                                             
    item26    (L4)    0.180    0.009   19.182    0.000    0.180    0.389
    item27    (L4)    0.180    0.009   19.182    0.000    0.180    0.389
    item28    (L4)    0.180    0.009   19.182    0.000    0.180    0.389
    item29    (L4)    0.180    0.009   19.182    0.000    0.180    0.389
    item30    (L4)    0.180    0.009   19.182    0.000    0.180    0.389

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta1 ~~                                                             
    theta2            0.000                               0.000    0.000
    theta3            0.000                               0.000    0.000
    theta4            0.000                               0.000    0.000
  theta2 ~~                                                             
    theta3            0.000                               0.000    0.000
    theta4            0.000                               0.000    0.000
  theta3 ~~                                                             
    theta4            0.000                               0.000    0.000

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11    (U1)    0.192    0.003   56.690    0.000    0.192    0.817
   .item12    (U1)    0.192    0.003   56.690    0.000    0.192    0.817
   .item13    (U1)    0.192    0.003   56.690    0.000    0.192    0.817
   .item14    (U1)    0.192    0.003   56.690    0.000    0.192    0.817
   .item15    (U1)    0.192    0.003   56.690    0.000    0.192    0.817
   .item16    (U2)    0.171    0.003   49.772    0.000    0.171    0.706
   .item17    (U2)    0.171    0.003   49.772    0.000    0.171    0.706
   .item18    (U2)    0.171    0.003   49.772    0.000    0.171    0.706
   .item19    (U2)    0.171    0.003   49.772    0.000    0.171    0.706
   .item20    (U2)    0.171    0.003   49.772    0.000    0.171    0.706
   .item21    (U3)    0.187    0.003   55.545    0.000    0.187    0.891
   .item22    (U3)    0.187    0.003   55.545    0.000    0.187    0.891
   .item23    (U3)    0.187    0.003   55.545    0.000    0.187    0.891
   .item24    (U3)    0.187    0.003   55.545    0.000    0.187    0.891
   .item25    (U3)    0.187    0.003   55.545    0.000    0.187    0.891
   .item26    (U4)    0.183    0.003   53.285    0.000    0.183    0.849
   .item27    (U4)    0.183    0.003   53.285    0.000    0.183    0.849
   .item28    (U4)    0.183    0.003   53.285    0.000    0.183    0.849
   .item29    (U4)    0.183    0.003   53.285    0.000    0.183    0.849
   .item30    (U4)    0.183    0.003   53.285    0.000    0.183    0.849
    theta1            1.000                               1.000    1.000
    theta2            1.000                               1.000    1.000
    theta3            1.000                               1.000    1.000
    theta4            1.000                               1.000    1.000

Plotting Sumscores vs. Latent Variable Scores

# create latent variable estimates
parallelItemsScores = lavPredict(parallelItemsModel)

# plotting model scores with sumscores
par(mfrow = c(2,2))
for (standard in 1:ncol(reducedQ)){
  plot(x = parallelItemsScores[, standard],  y = sumScores[, standard], 
      main = "Parallel Items Model Score vs. Sum Score", 
      xlab = paste0("Parallel Items Model Score: ", colnames(reducedQ)[standard]), 
      ylab = paste0("Sum Score: ", colnames(reducedQ)[standard])
  )
}

par(mfrow = c(1,1))

A Better Measurement Model Implied by Subscores

Contrast the unidimensional model with that assumed by the subscores: the multidimensional model

Standards measured (and measurement model):

  • A.REI.1 (\(\theta_{p1}\))

\[P(Y_{pi} = 1 | \theta_{p1}) = \frac{\exp \left(a_i \left( \theta_{p1} - b_i \right) \right)}{1 + \exp \left(a_i \left( \theta_{p1} - b_i \right) \right)} \]

  • A.REI.2 (\(\theta_{p2}\))

\[P(Y_{pi} = 1 | \theta_{p2}) = \frac{\exp \left(a_i \left( \theta_{p2} - b_i \right) \right)}{1 + \exp \left(a_i \left( \theta_{p2} - b_i \right) \right)} \]

  • A.REI.8 (\(\theta_{p3}\))

\[P(Y_{pi} = 1 | \theta_{p3}) = \frac{\exp \left(a_i \left( \theta_{p3} - b_i \right) \right)}{1 + \exp \left(a_i \left( \theta_{p3} - b_i \right) \right)} \]

  • A.CED.2 (\(\theta_{p4}\))

\[P(Y_{pi} = 1 | \theta_{p4}) = \frac{\exp \left(a_i \left( \theta_{p4} - b_i \right) \right)}{1 + \exp \left(a_i \left( \theta_{p4} - b_i \right) \right)} \]

Structural Model Implied by Subscores

\[ \begin{bmatrix} \theta_{p1} \\ \theta_{p2} \\ \theta_{p3} \\ \theta_{p4} \\ \end{bmatrix} \sim N \left(\boldsymbol{0}, \boldsymbol{\Sigma}_{M} \right) \]

Where:

\[ \mathbf{\Sigma}_{M} = \begin{bmatrix} 1 & \rho_{\theta_1, \theta_2} & \rho_{\theta_1, \theta_3} & \rho_{\theta_1, \theta_4} \\ \rho_{\theta_1, \theta_2} & 1 & \rho_{\theta_2, \theta_3} & \rho_{\theta_2, \theta_4} \\ \rho_{\theta_1, \theta_3} & \rho_{\theta_2, \theta_3} & 1 & \rho_{\theta_3, \theta_4} \\ \rho_{\theta_1, \theta_4} & \rho_{\theta_2, \theta_4} & \rho_{\theta_3, \theta_4} & 1 \\ \end{bmatrix} \]

Here, \(\mathbf{\Sigma}_{M}\) is a correlation matrix implying identification via standardized factors

multidimensionalModel_syntax = "

theta1 =~ item11 + item12 + item13 + item14 + item15
theta2 =~ item16 + item17 + item18 + item19 + item20
theta3 =~ item21 + item22 + item23 + item24 + item25
theta4 =~ item26 + item27 + item28 + item29 + item30

"

multidimensionalModel = cfa(
  model = multidimensionalModel_syntax, 
  data = responseMatrix, 
  estimator = "WLSMV", 
  ordered = paste0("item", 11:30), 
  std.lv = TRUE, 
  parameterization = "theta"
)

summary(multidimensionalModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.16 ended normally after 26 iterations

  Estimator                                       DWLS
  Optimization method                           NLMINB
  Number of model parameters                        46

                                                  Used       Total
  Number of observations                          1099        2541

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               233.931     298.881
  Degrees of freedom                               164         164
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.832
  Shift parameter                                           17.797
    simple second-order correction                                

Model Test Baseline Model:

  Test statistic                              5341.853    3322.839
  Degrees of freedom                               190         190
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.644

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.986       0.957
  Tucker-Lewis Index (TLI)                       0.984       0.950
                                                                  
  Robust Comparative Fit Index (CFI)                         0.916
  Robust Tucker-Lewis Index (TLI)                            0.903

Root Mean Square Error of Approximation:

  RMSEA                                          0.020       0.027
  90 Percent confidence interval - lower         0.014       0.022
  90 Percent confidence interval - upper         0.025       0.032
  P-value H_0: RMSEA <= 0.050                    1.000       1.000
  P-value H_0: RMSEA >= 0.080                    0.000       0.000
                                                                  
  Robust RMSEA                                               0.048
  90 Percent confidence interval - lower                     0.038
  90 Percent confidence interval - upper                     0.057
  P-value H_0: Robust RMSEA <= 0.050                         0.642
  P-value H_0: Robust RMSEA >= 0.080                         0.000

Standardized Root Mean Square Residual:

  SRMR                                           0.051       0.051

Parameter Estimates:

  Standard errors                           Robust.sem
  Information                                 Expected
  Information saturated (h1) model        Unstructured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta1 =~                                                             
    item11            1.060    0.109    9.769    0.000    1.060    0.727
    item12            0.307    0.057    5.362    0.000    0.307    0.294
    item13            0.914    0.083   10.988    0.000    0.914    0.675
    item14            0.678    0.065   10.470    0.000    0.678    0.561
    item15            0.531    0.056    9.410    0.000    0.531    0.469
  theta2 =~                                                             
    item16            0.808    0.067   12.124    0.000    0.808    0.629
    item17            0.809    0.069   11.760    0.000    0.809    0.629
    item18            1.005    0.086   11.670    0.000    1.005    0.709
    item19            1.072    0.090   11.864    0.000    1.072    0.731
    item20            0.919    0.098    9.397    0.000    0.919    0.677
  theta3 =~                                                             
    item21            0.227    0.058    3.920    0.000    0.227    0.221
    item22            0.419    0.078    5.408    0.000    0.419    0.387
    item23            0.679    0.093    7.333    0.000    0.679    0.562
    item24            0.593    0.079    7.537    0.000    0.593    0.510
    item25            0.680    0.088    7.758    0.000    0.680    0.562
  theta4 =~                                                             
    item26            0.764    0.094    8.152    0.000    0.764    0.607
    item27            0.565    0.062    9.161    0.000    0.565    0.492
    item28            0.857    0.089    9.609    0.000    0.857    0.651
    item29            0.325    0.070    4.665    0.000    0.325    0.309
    item30            0.498    0.067    7.434    0.000    0.498    0.446

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta1 ~~                                                             
    theta2            0.754    0.036   20.945    0.000    0.754    0.754
    theta3            0.522    0.056    9.336    0.000    0.522    0.522
    theta4            0.765    0.044   17.284    0.000    0.765    0.765
  theta2 ~~                                                             
    theta3            0.624    0.047   13.315    0.000    0.624    0.624
    theta4            0.583    0.045   12.964    0.000    0.583    0.583
  theta3 ~~                                                             
    theta4            0.542    0.066    8.179    0.000    0.542    0.542

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            0.000                               0.000    0.000
   .item12            0.000                               0.000    0.000
   .item13            0.000                               0.000    0.000
   .item14            0.000                               0.000    0.000
   .item15            0.000                               0.000    0.000
   .item16            0.000                               0.000    0.000
   .item17            0.000                               0.000    0.000
   .item18            0.000                               0.000    0.000
   .item19            0.000                               0.000    0.000
   .item20            0.000                               0.000    0.000
   .item21            0.000                               0.000    0.000
   .item22            0.000                               0.000    0.000
   .item23            0.000                               0.000    0.000
   .item24            0.000                               0.000    0.000
   .item25            0.000                               0.000    0.000
   .item26            0.000                               0.000    0.000
   .item27            0.000                               0.000    0.000
   .item28            0.000                               0.000    0.000
   .item29            0.000                               0.000    0.000
   .item30            0.000                               0.000    0.000
    theta1            0.000                               0.000    0.000
    theta2            0.000                               0.000    0.000
    theta3            0.000                               0.000    0.000
    theta4            0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11|t1         0.507    0.065    7.814    0.000    0.507    0.348
    item12|t1         0.649    0.044   14.888    0.000    0.649    0.620
    item13|t1         0.138    0.052    2.639    0.008    0.138    0.102
    item14|t1         0.137    0.046    2.956    0.003    0.137    0.113
    item15|t1         0.084    0.043    1.954    0.051    0.084    0.074
    item16|t1        -0.148    0.049   -3.060    0.002   -0.148   -0.115
    item17|t1        -0.040    0.049   -0.816    0.415   -0.040   -0.031
    item18|t1        -0.047    0.053   -0.877    0.381   -0.047   -0.033
    item19|t1        -0.122    0.055   -2.215    0.027   -0.122   -0.083
    item20|t1         0.641    0.063   10.109    0.000    0.641    0.472
    item21|t1         0.268    0.040    6.797    0.000    0.268    0.262
    item22|t1         0.853    0.052   16.444    0.000    0.853    0.787
    item23|t1         0.690    0.059   11.726    0.000    0.690    0.571
    item24|t1         0.558    0.051   10.915    0.000    0.558    0.480
    item25|t1         0.537    0.054    9.898    0.000    0.537    0.444
    item26|t1         0.676    0.061   11.023    0.000    0.676    0.537
    item27|t1         0.180    0.044    4.071    0.000    0.180    0.157
    item28|t1         0.389    0.056    7.001    0.000    0.389    0.295
    item29|t1         0.795    0.047   16.808    0.000    0.795    0.756
    item30|t1         0.573    0.047   12.089    0.000    0.573    0.513

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            1.000                               1.000    0.471
   .item12            1.000                               1.000    0.914
   .item13            1.000                               1.000    0.545
   .item14            1.000                               1.000    0.685
   .item15            1.000                               1.000    0.780
   .item16            1.000                               1.000    0.605
   .item17            1.000                               1.000    0.605
   .item18            1.000                               1.000    0.497
   .item19            1.000                               1.000    0.465
   .item20            1.000                               1.000    0.542
   .item21            1.000                               1.000    0.951
   .item22            1.000                               1.000    0.851
   .item23            1.000                               1.000    0.685
   .item24            1.000                               1.000    0.740
   .item25            1.000                               1.000    0.684
   .item26            1.000                               1.000    0.631
   .item27            1.000                               1.000    0.758
   .item28            1.000                               1.000    0.576
   .item29            1.000                               1.000    0.904
   .item30            1.000                               1.000    0.801
    theta1            1.000                               1.000    1.000
    theta2            1.000                               1.000    1.000
    theta3            1.000                               1.000    1.000
    theta4            1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11            0.686                               0.686    1.000
    item12            0.956                               0.956    1.000
    item13            0.738                               0.738    1.000
    item14            0.828                               0.828    1.000
    item15            0.883                               0.883    1.000
    item16            0.778                               0.778    1.000
    item17            0.778                               0.778    1.000
    item18            0.705                               0.705    1.000
    item19            0.682                               0.682    1.000
    item20            0.736                               0.736    1.000
    item21            0.975                               0.975    1.000
    item22            0.922                               0.922    1.000
    item23            0.827                               0.827    1.000
    item24            0.860                               0.860    1.000
    item25            0.827                               0.827    1.000
    item26            0.795                               0.795    1.000
    item27            0.871                               0.871    1.000
    item28            0.759                               0.759    1.000
    item29            0.951                               0.951    1.000
    item30            0.895                               0.895    1.000

Multidimensional Model Path Diagram

semPlot::semPaths(multidimensionalModel, 
                  sizeMan = 2.5, 
                  style = "mx", 
                  intercepts = FALSE, 
                  thresholds = FALSE)

Model Score Comparisons

multidimensionalScores = lavPredict(multidimensionalModel)

allScores = data.frame(cbind(unidimensionalScores, multidimensionalScores))
names(allScores) = c("uTheta", paste0("mTheta", 1:4))

plot(allScores, main =  "Unidimensional Score vs. Multidimensional Scores")

cor(allScores)
           uTheta   mTheta1   mTheta2   mTheta3   mTheta4
uTheta  1.0000000 0.9763872 0.9734620 0.8953982 0.9324452
mTheta1 0.9763872 1.0000000 0.9249558 0.8119392 0.9400688
mTheta2 0.9734620 0.9249558 1.0000000 0.8657125 0.8361691
mTheta3 0.8953982 0.8119392 0.8657125 1.0000000 0.8101180
mTheta4 0.9324452 0.9400688 0.8361691 0.8101180 1.0000000

Model Fit Comparison

Which model fits the data better? Chi-square difference test:

Note: Comparison is only unidimensional IRT model vs. Multidimensional IRT model

  • Sumscore-based MCFA model not comparable as likelihood is on different scale
    • Observed variables Bernoulli distributed in IRT
    • Observed variables normally distributed in CFA
anova(unidimensionalModel, multidimensionalModel)

Scaled Chi-Squared Difference Test (method = "satorra.2000")

lavaan NOTE:
    The "Chisq" column contains standard test statistics, not the
    robust test that should be reported per model. A robust difference
    test is a function of two standard (not robust) statistics.
 
                       Df AIC BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
multidimensionalModel 164         233.93                                  
unidimensionalModel   170         419.00      146.5       6  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The MIRT model fits better than the unidimensional model

  • So, if reporting both types of scores, discrepancies can arise
    • Differing models may have competing information
  • Which score is more accurate?
    • Both cannot be correct

Option 2: Summed Multidimensional Model Scores

Another option for reporting subscores and an overall score is to:

  • Estimate subscores from the MIRT model
  • Create the total score with the sum of each of the latent variable estimates from the MIRT model:
totalMIRTScores = rowSums(multidimensionalScores)
plot(x = unidimensionalScores, y = totalMIRTScores, 
     main = "Unidimensional Score vs. Sum of Multidimensional Scores")

cor(x = unidimensionalScores, y = totalMIRTScores)
           [,1]
theta 0.9973215

Evaluating Option 2

Option 2 is closer to what is needed in that it uses MIRT to form a total score

  • But, what is the model that Option 2 implies?

\[ \begin{array}{c} \theta_{p1} = \mu_1 + \lambda F + e_{p1}; e \sim N(0, \psi^2) \\ \theta_{p2} = \mu_2 + \lambda F + e_{p2}; e \sim N(0, \psi^2) \\ \theta_{p3} = \mu_3 + \lambda F + e_{p3}; e \sim N(0, \psi^2) \\ \theta_{p4} = \mu_4 + \lambda F + e_{p4}; e \sim N(0, \psi^2) \\ \end{array} \]

Where \(F \sim N(0, 1)\)

Testing if Summed MIRT Score Model Fits Data

summedMIRT_syntax = "

# constrain all loadings to be equal
total =~ L1*theta1 + L1*theta2 + L1*theta3 + L1*theta4

# set the unique variances to be equal
theta1 ~~ U1*theta1; theta2 ~~ U1*theta2; theta3 ~~ U1*theta3; theta4 ~~ U1*theta4;


"

summedMIRTModel = cfa(
  model = summedMIRT_syntax, 
  data = multidimensionalScores, 
  estimator = "MLR",
  std.lv = TRUE, 
)

summary(summedMIRTModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.15 ended normally after 10 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         8
  Number of equality constraints                     6

  Number of observations                          1099

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                              1240.195    1493.422
  Degrees of freedom                                 8           8
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.830
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              6334.409    8515.633
  Degrees of freedom                                 6           6
  P-value                                        0.000       0.000
  Scaling correction factor                                  0.744

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.805       0.825
  Tucker-Lewis Index (TLI)                       0.854       0.869
                                                                  
  Robust Comparative Fit Index (CFI)                         0.805
  Robust Tucker-Lewis Index (TLI)                            0.854

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -2772.002   -2772.002
  Scaling correction factor                                  0.303
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -2151.905   -2151.905
  Scaling correction factor                                  0.907
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                5548.005    5548.005
  Bayesian (BIC)                              5558.009    5558.009
  Sample-size adjusted Bayesian (SABIC)       5551.657    5551.657

Root Mean Square Error of Approximation:

  RMSEA                                          0.374       0.411
  90 Percent confidence interval - lower         0.357       0.392
  90 Percent confidence interval - upper         0.392       0.430
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    1.000       1.000
                                                                  
  Robust RMSEA                                               0.375
  90 Percent confidence interval - lower                     0.359
  90 Percent confidence interval - upper                     0.391
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         1.000

Standardized Root Mean Square Residual:

  SRMR                                           0.128       0.128

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  total =~                                                              
    theta1    (L1)    0.757    0.019   40.075    0.000    0.757    0.929
    theta2    (L1)    0.757    0.019   40.075    0.000    0.757    0.929
    theta3    (L1)    0.757    0.019   40.075    0.000    0.757    0.929
    theta4    (L1)    0.757    0.019   40.075    0.000    0.757    0.929

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .theta1    (U1)    0.091    0.002   37.596    0.000    0.091    0.138
   .theta2    (U1)    0.091    0.002   37.596    0.000    0.091    0.138
   .theta3    (U1)    0.091    0.002   37.596    0.000    0.091    0.138
   .theta4    (U1)    0.091    0.002   37.596    0.000    0.091    0.138
    total             1.000                               1.000    1.000

Demonstrating Equivalence (Scalar) with Summed MIRT Scores

summedMIRTScores = lavPredict(summedMIRTModel)
plot(x = summedMIRTScores, y = totalMIRTScores, 
     main = "Summed MIRT Score vs. Sum of Multidimensional Scores")

Option #3: Bifactor Model

A bifactor model is a multidimensional model where:

  • Each item loads on a general factor and a specific factor
  • The general factor is uncorrelated with the specific factors
  • The specific factors can be uncorrelated with each other (as a method factor) or correlated with each other (as a multidimensional model)

Bifactor Model Notation

The bifactor model is:

Subscore 1:

\[ \begin{array}{c} \text{logit}\left( P\left( Y_{p1} = 1 \mid \theta_{p1}, g_p \right) \right) = \mu_1 + \lambda_{11} \theta_{p1} + \lambda_{1g} g_p \\ \text{logit}\left( P\left( Y_{p2} = 1 \mid \theta_{p2}, g_p \right) \right) = \mu_2 + \lambda_{21} \theta_{p1} + \lambda_{2g} g_p \\ \vdots \\ \text{logit}\left( P\left( Y_{p5} = 1 \mid \theta_{p5}, g_p \right) \right) = \mu_5 + \lambda_{51} \theta_{p1} + \lambda_{5g} g_p \\ \end{array} \]

Subscore 2:

\[ \begin{array}{c} \text{logit}\left( P\left( Y_{p6} = 1 \mid \theta_{p6}, g_p \right) \right) = \mu_6 + \lambda_{61} \theta_{p2} + \lambda_{6g} g_p \\ \text{logit}\left( P\left( Y_{p7} = 1 \mid \theta_{p7}, g_p \right) \right) = \mu_7 + \lambda_{71} \theta_{p2} + \lambda_{7g} g_p \\ \vdots \\ \text{logit}\left( P\left( Y_{p10} = 1 \mid \theta_{p10}, g_p \right) \right) = \mu_{10} + \lambda_{101} \theta_{p2} + \lambda_{10g} g_p \\ \end{array} \]

Bifactor Model in lavaan

bifactorModel_syntax = "

g =~ item11 + item12 + item13 + item14 + item15 + 
     item16 + item17 + item18 + item19 + item20 + 
     item21 + item22 + item23 + item24 + item25 + 
     item26 + item27 + item28 + item29 + item30
         
theta1 =~ item11 + item12 + item13 + item14 + item15
theta2 =~ item16 + item17 + item18 + item19 + item20
theta3 =~ item21 + item22 + item23 + item24 + item25
theta4 =~ item26 + item27 + item28 + item29 + item30

g ~~ 0*theta1
g ~~ 0*theta2
g ~~ 0*theta3
g ~~ 0*theta4


"

bifactorModel = cfa(
  model = bifactorModel_syntax, 
  data = responseMatrix, 
  estimator = "WLSMV", 
  ordered = paste0("item", 11:30), 
  std.lv = TRUE, 
  parameterization = "theta"
)



summary(bifactorModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.15 ended normally after 85 iterations

  Estimator                                       DWLS
  Optimization method                           NLMINB
  Number of model parameters                        66

                                                  Used       Total
  Number of observations                          1099        2541

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               122.416     169.422
  Degrees of freedom                               144         144
  P-value (Chi-square)                           0.904       0.073
  Scaling correction factor                                  0.787
  Shift parameter                                           13.922
    simple second-order correction                                

Model Test Baseline Model:

  Test statistic                              5341.853    3322.839
  Degrees of freedom                               190         190
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.644

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    1.000       0.992
  Tucker-Lewis Index (TLI)                       1.006       0.989
                                                                  
  Robust Comparative Fit Index (CFI)                         0.977
  Robust Tucker-Lewis Index (TLI)                            0.969

Root Mean Square Error of Approximation:

  RMSEA                                          0.000       0.013
  90 Percent confidence interval - lower         0.000       0.000
  90 Percent confidence interval - upper         0.006       0.020
  P-value H_0: RMSEA <= 0.050                    1.000       1.000
  P-value H_0: RMSEA >= 0.080                    0.000       0.000
                                                                  
  Robust RMSEA                                               0.027
  90 Percent confidence interval - lower                     0.005
  90 Percent confidence interval - upper                     0.040
  P-value H_0: Robust RMSEA <= 0.050                         0.999
  P-value H_0: Robust RMSEA >= 0.080                         0.000

Standardized Root Mean Square Residual:

  SRMR                                           0.037       0.037

Parameter Estimates:

  Standard errors                           Robust.sem
  Information                                 Expected
  Information saturated (h1) model        Unstructured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  g =~                                                                  
    item11            0.746    0.098    7.627    0.000    0.746    0.505
    item12            0.364    0.071    5.161    0.000    0.364    0.342
    item13            0.615    0.083    7.454    0.000    0.615    0.439
    item14            0.495    0.067    7.333    0.000    0.495    0.410
    item15            0.416    0.060    6.956    0.000    0.416    0.369
    item16            0.291    0.082    3.557    0.000    0.291    0.201
    item17            0.396    0.068    5.803    0.000    0.396    0.304
    item18            0.524    0.078    6.715    0.000    0.524    0.369
    item19            0.551    0.083    6.664    0.000    0.551    0.375
    item20            0.683    0.083    8.276    0.000    0.683    0.519
    item21            0.213    0.056    3.835    0.000    0.213    0.208
    item22            0.409    0.077    5.279    0.000    0.409    0.378
    item23            0.470    0.077    6.098    0.000    0.470    0.396
    item24            0.351    0.101    3.482    0.000    0.351    0.242
    item25            0.457    0.075    6.137    0.000    0.457    0.382
    item26            0.755    0.094    8.064    0.000    0.755    0.597
    item27            0.396    0.074    5.346    0.000    0.396    0.327
    item28            0.727    0.171    4.245    0.000    0.727    0.439
    item29            0.402    0.079    5.056    0.000    0.402    0.372
    item30            0.527    0.074    7.148    0.000    0.527    0.466
  theta1 =~                                                             
    item11            0.792    0.133    5.943    0.000    0.792    0.536
    item12            0.020    0.078    0.260    0.795    0.020    0.019
    item13            0.762    0.119    6.389    0.000    0.762    0.544
    item14            0.460    0.088    5.216    0.000    0.460    0.381
    item15            0.315    0.078    4.063    0.000    0.315    0.279
  theta2 =~                                                             
    item16            1.003    0.126    7.941    0.000    1.003    0.694
    item17            0.736    0.087    8.432    0.000    0.736    0.565
    item18            0.860    0.101    8.533    0.000    0.860    0.606
    item19            0.926    0.108    8.558    0.000    0.926    0.630
    item20            0.517    0.087    5.965    0.000    0.517    0.392
  theta3 =~                                                             
    item21            0.070    0.065    1.069    0.285    0.070    0.068
    item22            0.039    0.077    0.498    0.618    0.039    0.036
    item23            0.435    0.095    4.590    0.000    0.435    0.367
    item24            0.991    0.250    3.973    0.000    0.991    0.683
    item25            0.477    0.097    4.917    0.000    0.477    0.398
  theta4 =~                                                             
    item26            0.171    0.100    1.709    0.087    0.171    0.135
    item27            0.557    0.130    4.283    0.000    0.557    0.460
    item28            1.100    0.374    2.939    0.003    1.100    0.665
    item29           -0.072    0.090   -0.792    0.428   -0.072   -0.066
    item30            0.040    0.093    0.429    0.668    0.040    0.035

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  g ~~                                                                  
    theta1            0.000                               0.000    0.000
    theta2            0.000                               0.000    0.000
    theta3            0.000                               0.000    0.000
    theta4            0.000                               0.000    0.000
  theta1 ~~                                                             
    theta2            0.619    0.065    9.571    0.000    0.619    0.619
    theta3            0.018    0.114    0.161    0.872    0.018    0.018
    theta4            0.430    0.111    3.880    0.000    0.430    0.430
  theta2 ~~                                                             
    theta3            0.419    0.074    5.702    0.000    0.419    0.419
    theta4            0.275    0.090    3.072    0.002    0.275    0.275
  theta3 ~~                                                             
    theta4           -0.068    0.114   -0.599    0.549   -0.068   -0.068

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            0.000                               0.000    0.000
   .item12            0.000                               0.000    0.000
   .item13            0.000                               0.000    0.000
   .item14            0.000                               0.000    0.000
   .item15            0.000                               0.000    0.000
   .item16            0.000                               0.000    0.000
   .item17            0.000                               0.000    0.000
   .item18            0.000                               0.000    0.000
   .item19            0.000                               0.000    0.000
   .item20            0.000                               0.000    0.000
   .item21            0.000                               0.000    0.000
   .item22            0.000                               0.000    0.000
   .item23            0.000                               0.000    0.000
   .item24            0.000                               0.000    0.000
   .item25            0.000                               0.000    0.000
   .item26            0.000                               0.000    0.000
   .item27            0.000                               0.000    0.000
   .item28            0.000                               0.000    0.000
   .item29            0.000                               0.000    0.000
   .item30            0.000                               0.000    0.000
    g                 0.000                               0.000    0.000
    theta1            0.000                               0.000    0.000
    theta2            0.000                               0.000    0.000
    theta3            0.000                               0.000    0.000
    theta4            0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11|t1         0.514    0.067    7.644    0.000    0.514    0.348
    item12|t1         0.660    0.046   14.349    0.000    0.660    0.620
    item13|t1         0.142    0.054    2.631    0.009    0.142    0.102
    item14|t1         0.137    0.046    2.957    0.003    0.137    0.113
    item15|t1         0.084    0.043    1.954    0.051    0.084    0.074
    item16|t1        -0.167    0.055   -3.029    0.002   -0.167   -0.115
    item17|t1        -0.040    0.049   -0.815    0.415   -0.040   -0.031
    item18|t1        -0.047    0.054   -0.876    0.381   -0.047   -0.033
    item19|t1        -0.123    0.056   -2.207    0.027   -0.123   -0.083
    item20|t1         0.621    0.059   10.475    0.000    0.621    0.472
    item21|t1         0.268    0.039    6.804    0.000    0.268    0.262
    item22|t1         0.851    0.052   16.506    0.000    0.851    0.787
    item23|t1         0.679    0.056   12.119    0.000    0.679    0.571
    item24|t1         0.696    0.108    6.468    0.000    0.696    0.480
    item25|t1         0.532    0.053   10.035    0.000    0.532    0.444
    item26|t1         0.679    0.062   11.017    0.000    0.679    0.537
    item27|t1         0.190    0.047    4.008    0.000    0.190    0.157
    item28|t1         0.488    0.113    4.334    0.000    0.488    0.295
    item29|t1         0.817    0.052   15.670    0.000    0.817    0.756
    item30|t1         0.580    0.049   11.860    0.000    0.580    0.513

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            1.000                               1.000    0.458
   .item12            1.000                               1.000    0.882
   .item13            1.000                               1.000    0.511
   .item14            1.000                               1.000    0.687
   .item15            1.000                               1.000    0.786
   .item16            1.000                               1.000    0.478
   .item17            1.000                               1.000    0.589
   .item18            1.000                               1.000    0.497
   .item19            1.000                               1.000    0.463
   .item20            1.000                               1.000    0.577
   .item21            1.000                               1.000    0.952
   .item22            1.000                               1.000    0.856
   .item23            1.000                               1.000    0.709
   .item24            1.000                               1.000    0.475
   .item25            1.000                               1.000    0.696
   .item26            1.000                               1.000    0.626
   .item27            1.000                               1.000    0.682
   .item28            1.000                               1.000    0.365
   .item29            1.000                               1.000    0.857
   .item30            1.000                               1.000    0.782
    g                 1.000                               1.000    1.000
    theta1            1.000                               1.000    1.000
    theta2            1.000                               1.000    1.000
    theta3            1.000                               1.000    1.000
    theta4            1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11            0.677                               0.677    1.000
    item12            0.939                               0.939    1.000
    item13            0.715                               0.715    1.000
    item14            0.829                               0.829    1.000
    item15            0.887                               0.887    1.000
    item16            0.692                               0.692    1.000
    item17            0.767                               0.767    1.000
    item18            0.705                               0.705    1.000
    item19            0.680                               0.680    1.000
    item20            0.759                               0.759    1.000
    item21            0.976                               0.976    1.000
    item22            0.925                               0.925    1.000
    item23            0.842                               0.842    1.000
    item24            0.689                               0.689    1.000
    item25            0.834                               0.834    1.000
    item26            0.791                               0.791    1.000
    item27            0.826                               0.826    1.000
    item28            0.604                               0.604    1.000
    item29            0.926                               0.926    1.000
    item30            0.884                               0.884    1.000

Bifactor Model Path Diagram

semPlot::semPaths(bifactorModel, sizeMan = 2.5, style = "mx", intercepts = FALSE, thresholds = FALSE)

Note: as rendered when this lecture was constructed, the plot has correlations between \(g\) and the \(\theta\), which are not present in the model

Bifactor Model Score Comparisons: Unidimensional IRT model \(\theta\) vs. Bifactor IRT model \(g\)

bifactorScores = lavPredict(bifactorModel)

plot(x = unidimensionalScores, y = bifactorScores[, "g"], 
     main = "Unidimensional Score vs. Bifactor Score")

Bifactor Model Score Comparisons: Standards

par(mfrow = c(2,2))
plot(x = multidimensionalScores[, 1], y = bifactorScores[, "theta1"],
     main = "Multidimensional Score vs. Bifactor Score for Theta 1")
plot(x = multidimensionalScores[, 2], y = bifactorScores[, "theta2"],
     main = "Multidimensional Score vs. Bifactor Score for Theta 1")
plot(x = multidimensionalScores[, 3], y = bifactorScores[, "theta3"],
     main = "Multidimensional Score vs. Bifactor Score for Theta 1")
plot(x = multidimensionalScores[, 4], y = bifactorScores[, "theta4"],
     main = "Multidimensional Score vs. Bifactor Score for Theta 1")

par(mfrow = c(1,1))

From Score Plot: Scores are Not Same

The bifactor model scores are not the same as the multidimensional model scores

  • The general factor is not the same as total score in the unidimensional model
    • Rather, it is the score of the domain that does not include the subdomains
    • Put another way: It is everything left over in algebra after controlling for a person’s ability in the algebra standards
    • Sometimes considered a residual

Model Fit Comparison

But…the bifactor model nearly always fits better than a similar multidimensional model

anova(unidimensionalModel, multidimensionalModel, bifactorModel)

Scaled Chi-Squared Difference Test (method = "satorra.2000")

lavaan NOTE:
    The "Chisq" column contains standard test statistics, not the
    robust test that should be reported per model. A robust difference
    test is a function of two standard (not robust) statistics.
 
                       Df AIC BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
bifactorModel         144         122.42                                  
multidimensionalModel 164         233.93     110.74      20  1.442e-14 ***
unidimensionalModel   170         419.00     146.50       6  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Option #4: Higher Order Model

A higher order model is a multidimensional model where:

  • Each item loads onto its subdomain factor, identically with the multidimensional model (MIRT)
  • Each factor then loads onto a general factor

Higher Order Model Notation

Subscore 1:

\[ \begin{array}{c} \text{logit}\left( P\left( Y_{p1} = 1 \mid \theta_{p1} \right) \right) = \mu_1 + \lambda_{11} \theta_{p1} \\ \text{logit}\left( P\left( Y_{p2} = 1 \mid \theta_{p2} \right) \right) = \mu_2 + \lambda_{21} \theta_{p1} \\ \vdots \\ \text{logit}\left( P\left( Y_{p5} = 1 \mid \theta_{p5} \right) \right) = \mu_5 + \lambda_{51} \theta_{p1} \\ \end{array} \]

Subscore 2:

\[ \begin{array}{c} \text{logit}\left( P\left( Y_{p6} = 1 \mid \theta_{p6} \right) \right) = \mu_6 + \lambda_{61} \theta_{p2} \\ \text{logit}\left( P\left( Y_{p7} = 1 \mid \theta_{p7} \right) \right) = \mu_7 + \lambda_{71} \theta_{p2} \\ \vdots \\ \text{logit}\left( P\left( Y_{p10} = 1 \mid \theta_{p10} \right) \right) = \mu_{10} + \lambda_{101} \theta_{p2} \\ \end{array} \]

Structural Model – a unidimensional CFA model for the subdomains:

\[ \begin{array}{c} \theta_{p1} = \mu_1 + \lambda_{1} F + e_{p1}; e_{p1} \sim N(0, \psi^2_1) \\ \theta_{p2} = \mu_2 + \lambda_{2} F + e_{p2}; e_{p2} \sim N(0, \psi^2_2) \\ \theta_{p3} = \mu_3 + \lambda_{3} F + e_{p3}; e_{p3} \sim N(0, \psi^2_3) \\ \theta_{p4} = \mu_4 + \lambda_{4} F + e_{p4}; e_{p4} \sim N(0, \psi^2_4) \\ \end{array} \]

Model-Implied Covariance Matrix of Subdomain Latent Variables

\[ \begin{bmatrix} \theta_{p1} \\ \theta_{p2} \\ \theta_{p3} \\ \theta_{p4} \\ \end{bmatrix} \sim N \left(\boldsymbol{0}, \boldsymbol{\Sigma}_{M} \right) \]

Where:

\[ \mathbf{\Sigma}_{M} = \mathbf{\Lambda} \mathbf{\Phi} \mathbf{\Lambda}^T + \boldsymbol{\Psi} \]

So, the higher order model is the MIRT model with a more restricted structure on the covariance matrix of the subdomain latent variables

Higher Order Model in lavaan

higherOrderModel_syntax = "

theta1 =~ item11 + item12 + item13 + item14 + item15
theta2 =~ item16 + item17 + item18 + item19 + item20
theta3 =~ item21 + item22 + item23 + item24 + item25
theta4 =~ item26 + item27 + item28 + item29 + item30

algebra =~ theta1 + theta2 + theta3 + theta4

"

higherOrderModel = cfa(
  model = higherOrderModel_syntax, 
  data = responseMatrix, 
  estimator = "WLSMV", 
  ordered = paste0("item", 11:30), 
  std.lv = TRUE, 
  parameterization = "theta"
)

summary(higherOrderModel, fit.measures = TRUE, standardized = TRUE)
lavaan 0.6.15 ended normally after 47 iterations

  Estimator                                       DWLS
  Optimization method                           NLMINB
  Number of model parameters                        44

                                                  Used       Total
  Number of observations                          1099        2541

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               252.420     317.925
  Degrees of freedom                               166         166
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  0.843
  Shift parameter                                           18.646
    simple second-order correction                                

Model Test Baseline Model:

  Test statistic                              5341.853    3322.839
  Degrees of freedom                               190         190
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.644

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.983       0.952
  Tucker-Lewis Index (TLI)                       0.981       0.944
                                                                  
  Robust Comparative Fit Index (CFI)                         0.907
  Robust Tucker-Lewis Index (TLI)                            0.894

Root Mean Square Error of Approximation:

  RMSEA                                          0.022       0.029
  90 Percent confidence interval - lower         0.016       0.024
  90 Percent confidence interval - upper         0.027       0.034
  P-value H_0: RMSEA <= 0.050                    1.000       1.000
  P-value H_0: RMSEA >= 0.080                    0.000       0.000
                                                                  
  Robust RMSEA                                               0.050
  90 Percent confidence interval - lower                     0.040
  90 Percent confidence interval - upper                     0.059
  P-value H_0: Robust RMSEA <= 0.050                         0.501
  P-value H_0: Robust RMSEA >= 0.080                         0.000

Standardized Root Mean Square Residual:

  SRMR                                           0.053       0.053

Parameter Estimates:

  Standard errors                           Robust.sem
  Information                                 Expected
  Information saturated (h1) model        Unstructured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  theta1 =~                                                             
    item11            0.425    0.102    4.153    0.000    1.057    0.726
    item12            0.124    0.034    3.692    0.000    0.309    0.295
    item13            0.367    0.086    4.282    0.000    0.913    0.674
    item14            0.272    0.063    4.315    0.000    0.675    0.560
    item15            0.215    0.050    4.287    0.000    0.534    0.471
  theta2 =~                                                             
    item16            0.463    0.054    8.583    0.000    0.808    0.628
    item17            0.464    0.055    8.394    0.000    0.809    0.629
    item18            0.575    0.070    8.195    0.000    1.003    0.708
    item19            0.614    0.074    8.326    0.000    1.071    0.731
    item20            0.529    0.072    7.300    0.000    0.922    0.678
  theta3 =~                                                             
    item21            0.168    0.043    3.946    0.000    0.229    0.223
    item22            0.312    0.059    5.306    0.000    0.426    0.392
    item23            0.498    0.076    6.551    0.000    0.680    0.563
    item24            0.424    0.062    6.847    0.000    0.579    0.501
    item25            0.499    0.074    6.769    0.000    0.681    0.563
  theta4 =~                                                             
    item26            0.485    0.074    6.591    0.000    0.768    0.609
    item27            0.356    0.047    7.504    0.000    0.563    0.491
    item28            0.544    0.075    7.231    0.000    0.860    0.652
    item29            0.205    0.045    4.533    0.000    0.324    0.308
    item30            0.314    0.048    6.545    0.000    0.496    0.444
  algebra =~                                                            
    theta1            2.276    0.539    4.225    0.000    0.916    0.916
    theta2            1.429    0.167    8.557    0.000    0.819    0.819
    theta3            0.929    0.122    7.601    0.000    0.681    0.681
    theta4            1.225    0.159    7.692    0.000    0.775    0.775

Intercepts:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            0.000                               0.000    0.000
   .item12            0.000                               0.000    0.000
   .item13            0.000                               0.000    0.000
   .item14            0.000                               0.000    0.000
   .item15            0.000                               0.000    0.000
   .item16            0.000                               0.000    0.000
   .item17            0.000                               0.000    0.000
   .item18            0.000                               0.000    0.000
   .item19            0.000                               0.000    0.000
   .item20            0.000                               0.000    0.000
   .item21            0.000                               0.000    0.000
   .item22            0.000                               0.000    0.000
   .item23            0.000                               0.000    0.000
   .item24            0.000                               0.000    0.000
   .item25            0.000                               0.000    0.000
   .item26            0.000                               0.000    0.000
   .item27            0.000                               0.000    0.000
   .item28            0.000                               0.000    0.000
   .item29            0.000                               0.000    0.000
   .item30            0.000                               0.000    0.000
   .theta1            0.000                               0.000    0.000
   .theta2            0.000                               0.000    0.000
   .theta3            0.000                               0.000    0.000
   .theta4            0.000                               0.000    0.000
    algebra           0.000                               0.000    0.000

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11|t1         0.506    0.065    7.821    0.000    0.506    0.348
    item12|t1         0.649    0.044   14.879    0.000    0.649    0.620
    item13|t1         0.138    0.052    2.639    0.008    0.138    0.102
    item14|t1         0.137    0.046    2.956    0.003    0.137    0.113
    item15|t1         0.084    0.043    1.953    0.051    0.084    0.074
    item16|t1        -0.148    0.049   -3.060    0.002   -0.148   -0.115
    item17|t1        -0.040    0.049   -0.816    0.415   -0.040   -0.031
    item18|t1        -0.047    0.053   -0.877    0.381   -0.047   -0.033
    item19|t1        -0.122    0.055   -2.215    0.027   -0.122   -0.083
    item20|t1         0.642    0.064   10.093    0.000    0.642    0.472
    item21|t1         0.269    0.040    6.795    0.000    0.269    0.262
    item22|t1         0.855    0.052   16.352    0.000    0.855    0.787
    item23|t1         0.691    0.059   11.691    0.000    0.691    0.571
    item24|t1         0.554    0.051   10.964    0.000    0.554    0.480
    item25|t1         0.537    0.054    9.881    0.000    0.537    0.444
    item26|t1         0.677    0.062   10.991    0.000    0.677    0.537
    item27|t1         0.180    0.044    4.071    0.000    0.180    0.157
    item28|t1         0.389    0.056    6.990    0.000    0.389    0.295
    item29|t1         0.795    0.047   16.813    0.000    0.795    0.756
    item30|t1         0.573    0.047   12.091    0.000    0.573    0.513

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .item11            1.000                               1.000    0.472
   .item12            1.000                               1.000    0.913
   .item13            1.000                               1.000    0.545
   .item14            1.000                               1.000    0.687
   .item15            1.000                               1.000    0.778
   .item16            1.000                               1.000    0.605
   .item17            1.000                               1.000    0.604
   .item18            1.000                               1.000    0.499
   .item19            1.000                               1.000    0.466
   .item20            1.000                               1.000    0.540
   .item21            1.000                               1.000    0.950
   .item22            1.000                               1.000    0.847
   .item23            1.000                               1.000    0.684
   .item24            1.000                               1.000    0.749
   .item25            1.000                               1.000    0.683
   .item26            1.000                               1.000    0.629
   .item27            1.000                               1.000    0.759
   .item28            1.000                               1.000    0.575
   .item29            1.000                               1.000    0.905
   .item30            1.000                               1.000    0.803
   .theta1            1.000                               0.162    0.162
   .theta2            1.000                               0.329    0.329
   .theta3            1.000                               0.537    0.537
   .theta4            1.000                               0.400    0.400
    algebra           1.000                               1.000    1.000

Scales y*:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    item11            0.687                               0.687    1.000
    item12            0.955                               0.955    1.000
    item13            0.738                               0.738    1.000
    item14            0.829                               0.829    1.000
    item15            0.882                               0.882    1.000
    item16            0.778                               0.778    1.000
    item17            0.777                               0.777    1.000
    item18            0.706                               0.706    1.000
    item19            0.683                               0.683    1.000
    item20            0.735                               0.735    1.000
    item21            0.975                               0.975    1.000
    item22            0.920                               0.920    1.000
    item23            0.827                               0.827    1.000
    item24            0.865                               0.865    1.000
    item25            0.826                               0.826    1.000
    item26            0.793                               0.793    1.000
    item27            0.871                               0.871    1.000
    item28            0.758                               0.758    1.000
    item29            0.951                               0.951    1.000
    item30            0.896                               0.896    1.000

Higher Order Model Path Diagram

semPlot::semPaths(higherOrderModel, sizeMan = 2.5, style = "mx", intercepts = FALSE, thresholds = FALSE)

Higher Order Model Score Comparisons: Unidimensional IRT model \(\theta\) vs. Higher Order IRT model \(F\)

higherOrderScores = lavPredict(higherOrderModel)

plot(x = unidimensionalScores, y = higherOrderScores[, "algebra"], 
     main = "Unidimensional Score vs. Higher Order Score")

Higher Order Model Score Comparisons: Standards

par(mfrow = c(2,2))

plot(x = multidimensionalScores[, 1], y = higherOrderScores[, "theta1"],
     main = "Multidimensional Score vs. Higher Order Score for Theta 1")
plot(x = multidimensionalScores[, 2], y = higherOrderScores[, "theta2"],
      main = "Multidimensional Score vs. Higher Order Score for Theta 2")
plot(x = multidimensionalScores[, 3], y = higherOrderScores[, "theta3"],
      main = "Multidimensional Score vs. Higher Order Score for Theta 3")
plot(x = multidimensionalScores[, 4], y = higherOrderScores[, "theta4"],
      main = "Multidimensional Score vs. Higher Order Score for Theta 4")

par(mfrow = c(1,1))

Model Fit Comparison

anova(unidimensionalModel, multidimensionalModel, higherOrderModel)

Scaled Chi-Squared Difference Test (method = "satorra.2000")

lavaan NOTE:
    The "Chisq" column contains standard test statistics, not the
    robust test that should be reported per model. A robust difference
    test is a function of two standard (not robust) statistics.
 
                       Df AIC BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
multidimensionalModel 164         233.93                                  
higherOrderModel      166         252.42     13.261       2    0.00132 ** 
unidimensionalModel   170         419.00    141.738       4    < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

So, the higher order model is really what is needed…but, what if it does not fit? * We can use CFA-based tools (modification indices) to help make the model fit better

Historical Issues with Bifactor and Higher Order Models

Historically, bifactor and higher order models have been used to create subscores

  • In some cases, the models are related

Schmid and Leiman (1957) showed how, in an EFA context, a bifactor model could be transformed into a higher order model

  • Assumed loadings of general to subfactors were proportional within a subfactor
    • Testable assumption
    • Not really valid for measurement purposes, however

Summary

Today we investigated a classic educational measurement problem: The need for having both subscores and a total score

  • We showed that the subscores and total score are incompatible models
  • We showed how several models were not valid for reporting both subscores and a total score
  • We showed how a higher order model was the best model for reporting both subscores and a total score