Model types

spifa() can fit five model types that are determined automatically from formula and the class of data (see ?spifa):

  • Non-spatial:
    • eifa: Exploratory IFA
    • cifa: Confirmatory IFA
    • cifa_pred: CIFA with predictors
  • Spatial:
    • spifa: Spatial IFA
    • spifa_pred: SPIFA with predictors

The model type is determined based on the following:

  1. Exploratory structure (eifa) is used when no constraints are provided.
  2. Models with predictors (cifa_pred/spifa_pred) are activated if terms are included on the right-hand side of formula.
  3. Spatial models (spifa/spifa_pred) are only activated when the data is geo-referenced as an sf object, otherwise the non-spatial models are activated.
  4. Setting ngp = 0 forces the model to be non-spatial (eifa/cifa/cifa_pred).

We will showcase the five model types using the ipixuna data.

library(spifa)

data(ipixuna)
nitems <- ncol(ipixuna$items)

Exploratory item factor analysis (EIFA)

The simplest case is the eifa model, the user does not need to provide constraints neither a spatial data. The constraints will be internally defined as a lower-triangular matrix; and in case data is an sf object, the spatial functionality can be dropped using ngp = 0:

set.seed(123)
samples <- spifa(items ~ 1, data = ipixuna, nfactors = 2, ngp = 0, niter = 500)
samples
#> Item factor analysis model: eifa
#> Formula: items ~ 1
#> Dimensions: 100 respondents, 10 items, 2 latent factors, 0 spatial processes
#> MCMC: 1 chain, iter = 500, thin = 1, samples = 500
#> 
#> Item model parameters:
#>           mean median   sd     q10     q90 ess_bulk rhat
#> c[1]    -0.396 -0.393 0.15 -0.5764 -0.2043     75.9  1.0
#> c[2]    -0.518 -0.506 0.20 -0.7757 -0.2745     38.8  1.0
#> c[3]    -0.554 -0.553 0.24 -0.8527 -0.2580     31.0  1.0
#> c[4]    -0.316 -0.316 0.16 -0.5271 -0.1102     94.1  1.0
#> c[5]    -0.311 -0.292 0.24 -0.6408 -0.0086      7.3  1.1
#> c[6]     0.072  0.069 0.26 -0.2506  0.3731     25.4  1.0
#> c[7]     0.273  0.268 0.18  0.0454  0.4960     68.0  1.0
#> c[8]     0.201  0.202 0.17  0.0082  0.4032     77.7  1.0
#> c[9]     0.681  0.671 0.24  0.3968  0.9696     42.8  1.0
#> c[10]    0.496  0.486 0.24  0.1993  0.7943     25.1  1.0
#> A[1,1]   0.548  0.516 0.24  0.2597  0.8658      6.0  1.2
#> A[2,1]   0.767  0.716 0.35  0.3762  1.1924     14.7  1.1
#> A[3,1]   1.159  1.168 0.32  0.7743  1.5596     27.1  1.0
#> A[4,1]   0.731  0.713 0.30  0.4213  1.1538     29.7  1.0
#> A[5,1]  -0.325 -0.343 0.44 -0.9079  0.2494      5.0  1.2
#> A[6,1]  -0.438 -0.424 0.43 -1.0187  0.1151      4.5  1.2
#> A[7,1]   0.361  0.339 0.33 -0.0285  0.7999      9.8  1.1
#> A[8,1]   0.887  0.883 0.30  0.5286  1.2671     13.0  1.0
#> A[9,1]   0.918  0.925 0.40  0.3898  1.4541     13.6  1.1
#> A[10,1]  0.704  0.761 0.35  0.1872  1.1177     20.1  1.0
#> A[2,2]   0.563  0.559 0.24  0.2788  0.8568      5.7  1.1
#> A[3,2]   0.509  0.509 0.28  0.1369  0.8838      5.4  1.1
#> A[4,2]   0.127  0.137 0.25 -0.1728  0.4225     14.7  1.0
#> A[5,2]   1.708  1.683 0.47  1.1479  2.3277     17.7  1.1
#> A[6,2]   1.544  1.543 0.53  0.8674  2.2147     11.2  1.2
#> A[7,2]   1.174  1.164 0.33  0.7694  1.5600     14.7  1.1
#> A[8,2]   0.368  0.349 0.30  0.0546  0.7562      9.7  1.1
#> A[9,2]   1.222  1.193 0.36  0.7797  1.7185      5.8  1.2
#> A[10,2]  1.578  1.608 0.42  1.0197  2.0818      7.9  1.1
#> 
#> ess_bulk is the bulk effective sample size; rhat is the potential
#> scale reduction factor on split chains (Rhat = 1 at convergence).
#> Use summary() for the full set of statistics (incl. ess_tail).

Notice how the constraints have been defined internally:

attr(samples, "fit_args")$constrain_L
#>       [,1] [,2]
#>  [1,]    1    0
#>  [2,]    1    1
#>  [3,]    1    1
#>  [4,]    1    1
#>  [5,]    1    1
#>  [6,]    1    1
#>  [7,]    1    1
#>  [8,]    1    1
#>  [9,]    1    1
#> [10,]    1    1

EIFA also never estimates the correlation between the latent factors, so only the easiness (c) and discrimination (A) parameters are estimated.

Confirmatory item factor analysis (CIFA)

Supplying your own discrimination constraints leads to a cifa model:

nfactors <- 3
A <- matrix(1, nitems, nfactors)
A[c(4, 8), 1] <- 0
A[c(4, 5, 6, 7, 8, 10), 2] <- 0
A[c(5, 6), 3] <- 0

samples <- spifa(
  items ~ 1, data = ipixuna, nfactors = nfactors, ngp = 0, niter = 500,
  constraints = list(discrimination = A)
)
samples
#> Item factor analysis model: cifa
#> Formula: items ~ 1
#> Dimensions: 100 respondents, 10 items, 3 latent factors, 0 spatial processes
#> MCMC: 1 chain, iter = 500, thin = 1, samples = 500
#> 
#> Item model parameters:
#>           mean median   sd    q10    q90 ess_bulk rhat
#> c[1]    -0.741 -0.664 0.34 -1.130 -0.407     21.8  1.0
#> c[2]    -0.546 -0.552 0.18 -0.784 -0.307     49.7  1.0
#> c[3]    -0.696 -0.680 0.28 -1.104 -0.347     21.1  1.0
#> c[4]    -0.335 -0.327 0.16 -0.555 -0.131    128.4  1.0
#> c[5]    -0.370 -0.360 0.22 -0.661 -0.094     20.8  1.0
#> c[6]     0.031  0.026 0.20 -0.223  0.290     16.7  1.0
#> c[7]     0.192  0.206 0.21 -0.098  0.426     29.2  1.0
#> c[8]     0.183  0.173 0.21 -0.066  0.462     34.7  1.0
#> c[9]     0.754  0.756 0.24  0.442  1.078     37.3  1.0
#> c[10]    0.465  0.506 0.33  0.016  0.847     14.3  1.0
#> A[1,1]   0.568  0.568 0.27  0.234  0.888     29.2  1.0
#> A[2,1]   0.525  0.512 0.22  0.228  0.814      6.1  1.2
#> A[3,1]   0.322  0.317 0.26 -0.010  0.673     22.0  1.0
#> A[5,1]   1.595  1.564 0.40  1.141  2.097     18.1  1.0
#> A[6,1]   1.196  1.174 0.29  0.853  1.573     26.8  1.0
#> A[7,1]   1.083  1.035 0.36  0.672  1.564     10.9  1.1
#> A[9,1]   1.414  1.413 0.36  0.952  1.873      2.6  1.4
#> A[10,1]  1.713  1.635 0.43  1.256  2.318      5.4  1.2
#> A[1,2]   1.945  1.943 0.68  1.049  2.884     15.7  1.0
#> A[2,2]   0.770  0.745 0.25  0.478  1.139     52.7  1.0
#> A[3,2]   0.784  0.745 0.34  0.377  1.243     26.0  1.0
#> A[9,2]   1.218  1.247 0.40  0.671  1.700      9.3  1.1
#> A[1,3]  -0.275 -0.215 0.47 -0.988  0.314      1.9  1.5
#> A[2,3]   0.395  0.416 0.27  0.010  0.749      4.6  1.2
#> A[3,3]   1.134  1.130 0.36  0.669  1.619     17.9  1.0
#> A[4,3]   0.949  0.945 0.31  0.569  1.367     41.1  1.0
#> A[7,3]   0.575  0.569 0.23  0.302  0.852     26.8  1.1
#> A[8,3]   1.489  1.479 0.56  0.817  2.262      2.9  1.3
#> A[9,3]   0.580  0.628 0.44 -0.021  1.104      3.2  1.3
#> A[10,3]  1.366  1.377 0.48  0.771  1.981      5.3  1.2
#> 
#> Factor model parameters:
#>             mean median   sd    q10    q90 ess_bulk rhat
#> Corr[2,1] -0.199 -0.205 0.15 -0.393 -0.026      2.6  1.4
#> Corr[3,1]  0.046  0.055 0.11 -0.081  0.171     24.1  1.0
#> Corr[3,2]  0.204  0.181 0.22 -0.072  0.551      1.5  1.9
#> 
#> ess_bulk is the bulk effective sample size; rhat is the potential
#> scale reduction factor on split chains (Rhat = 1 at convergence).
#> Use summary() for the full set of statistics (incl. ess_tail).

Unlike eifa, the cifa model estimates the correlation (Corr) between the latent factors.

CIFA model with predictors

Adding predictor terms to the right-hand side of formula generates a cifa_pred, which models the latent factors in terms of the predictor terms:

samples <- spifa(
  items ~ poly(wealth, 2), data = ipixuna, nfactors = nfactors, ngp = 0, niter = 500,
  constraints = list(discrimination = A)
)
samples
#> Item factor analysis model: cifa_pred
#> Formula: items ~ poly(wealth, 2)
#> Dimensions: 100 respondents, 10 items, 3 latent factors, 0 spatial processes
#> MCMC: 1 chain, iter = 500, thin = 1, samples = 500
#> 
#> Item model parameters:
#>            mean median   sd    q10    q90 ess_bulk rhat
#> c[1]    -0.4405 -0.441 0.16 -0.652 -0.234     94.8  1.0
#> c[2]    -0.4609 -0.458 0.16 -0.656 -0.257    102.8  1.0
#> c[3]    -0.4569 -0.454 0.16 -0.656 -0.255    137.3  1.0
#> c[4]    -0.2846 -0.283 0.14 -0.469 -0.106    168.7  1.0
#> c[5]    -0.2574 -0.249 0.17 -0.484 -0.041     98.2  1.0
#> c[6]     0.0428  0.032 0.15 -0.143  0.229    123.4  1.0
#> c[7]     0.2192  0.208 0.17  0.006  0.442    116.9  1.0
#> c[8]     0.1636  0.161 0.15 -0.015  0.359    132.5  1.0
#> c[9]     0.5276  0.524 0.17  0.315  0.767     89.7  1.0
#> c[10]    0.3613  0.378 0.19  0.115  0.609     86.6  1.0
#> A[1,1]   0.3554  0.348 0.18  0.140  0.603     74.1  1.0
#> A[2,1]   0.2742  0.267 0.27 -0.067  0.652     36.1  1.1
#> A[3,1]   0.2701  0.266 0.26 -0.052  0.566     63.5  1.0
#> A[5,1]   1.0655  1.067 0.24  0.749  1.355     66.0  1.0
#> A[6,1]   0.9376  0.922 0.23  0.652  1.253     47.7  1.0
#> A[7,1]   0.8031  0.782 0.25  0.507  1.129     71.3  1.0
#> A[9,1]   0.6692  0.658 0.28  0.314  1.040     35.9  1.0
#> A[10,1]  0.9313  0.928 0.24  0.602  1.236     50.9  1.0
#> A[1,2]   0.1571  0.350 0.68 -0.840  0.919      1.5  1.9
#> A[2,2]   0.2982  0.324 0.23 -0.036  0.559      2.1  1.4
#> A[3,2]   0.0082  0.019 0.38 -0.491  0.523      1.9  1.5
#> A[9,2]   0.0218  0.024 0.39 -0.500  0.525      2.0  1.5
#> A[1,3]   0.2885  0.304 0.24 -0.023  0.584     34.8  1.0
#> A[2,3]   0.5672  0.570 0.28  0.184  0.942     38.9  1.0
#> A[3,3]   0.5483  0.551 0.15  0.349  0.740    139.8  1.0
#> A[4,3]   0.5220  0.507 0.18  0.298  0.755     53.0  1.0
#> A[7,3]   0.4387  0.422 0.21  0.181  0.698     81.6  1.0
#> A[8,3]   0.7184  0.701 0.23  0.437  1.039     19.7  1.1
#> A[9,3]   0.6897  0.694 0.24  0.391  0.967     37.4  1.0
#> A[10,3]  0.6648  0.658 0.20  0.420  0.934     75.3  1.0
#> 
#> Factor model parameters:
#>            mean median   sd    q10   q90 ess_bulk rhat
#> B[1,1]    -5.64 -5.605 1.12 -7.062 -4.19     67.0  1.0
#> B[2,1]     0.18  0.088 1.29 -1.429  1.92     38.4  1.0
#> B[1,2]     1.50  3.038 5.02 -5.749  7.08      1.8  1.5
#> B[2,2]     0.37  0.508 1.85 -2.223  2.57      8.8  1.1
#> B[1,3]    -3.43 -3.258 1.61 -5.368 -1.58     36.1  1.0
#> B[2,3]    -0.63 -0.599 1.26 -2.334  1.03     99.9  1.0
#> Corr[2,1] -0.14 -0.185 0.45 -0.700  0.59      4.5  1.4
#> Corr[3,1]  0.30  0.278 0.16  0.082  0.49      4.3  1.2
#> Corr[3,2] -0.30 -0.263 0.16 -0.513 -0.13      4.9  1.1
#> 
#> ess_bulk is the bulk effective sample size; rhat is the potential
#> scale reduction factor on split chains (Rhat = 1 at convergence).
#> Use summary() for the full set of statistics (incl. ess_tail).

Spatial item factor analysis (SPIFA)

If the data is an sf object and no predictor terms are included in formula, the model type is spifa automatically. By default, it includes a spatial term for each factor ngp = nfactors; but custom number of ngp can be provided with a constraints loading matrix (T) of size nfactors x ngp.

T_loading <- matrix(c(1, 1, 0, 0, 0, 1), nfactors, 2)
T_loading
#>      [,1] [,2]
#> [1,]    1    0
#> [2,]    1    0
#> [3,]    0    1

This structure means that 1 GP is shared between factor 1 and 2, and another GP is introduced for factor 3:

samples <- spifa(
  items ~ 1, data = ipixuna, nfactors = nfactors, ngp = 2, niter = 500,
  constraints = list(discrimination = A, loading = T_loading)
)
samples
#> Item factor analysis model: spifa
#> Formula: items ~ 1
#> Dimensions: 100 respondents, 10 items, 3 latent factors, 2 spatial processes
#> MCMC: 1 chain, iter = 500, thin = 1, samples = 500
#> 
#> Item model parameters:
#>           mean median   sd    q10    q90 ess_bulk rhat
#> c[1]    -0.407 -0.410 0.14 -0.587 -0.222    150.8  1.0
#> c[2]    -0.575 -0.566 0.19 -0.816 -0.355     36.5  1.0
#> c[3]    -0.584 -0.585 0.20 -0.834 -0.332     67.0  1.0
#> c[4]    -0.315 -0.304 0.14 -0.498 -0.140    109.0  1.0
#> c[5]    -0.376 -0.360 0.27 -0.736 -0.051     29.0  1.0
#> c[6]     0.028  0.017 0.19 -0.220  0.269     67.0  1.0
#> c[7]     0.154  0.154 0.18 -0.087  0.384     13.5  1.1
#> c[8]     0.134  0.142 0.17 -0.087  0.351     76.2  1.0
#> c[9]     0.564  0.560 0.20  0.314  0.819     37.4  1.0
#> c[10]    0.363  0.371 0.23  0.071  0.654      6.0  1.2
#> A[1,1]   0.481  0.464 0.28  0.137  0.836    127.7  1.0
#> A[2,1]  -0.190 -0.196 0.33 -0.596  0.245     96.8  1.0
#> A[3,1]   0.136  0.114 0.45 -0.381  0.758     70.1  1.0
#> A[5,1]   1.598  1.558 0.53  1.085  2.231      5.4  1.1
#> A[6,1]   1.115  1.109 0.30  0.746  1.509     17.7  1.0
#> A[7,1]   0.978  0.968 0.25  0.667  1.313     44.1  1.0
#> A[9,1]   0.697  0.703 0.49  0.041  1.293     69.8  1.0
#> A[10,1]  1.237  1.221 0.35  0.801  1.705      7.9  1.1
#> A[1,2]  -0.346 -0.342 0.43 -0.898  0.240     56.0  1.0
#> A[2,2]   0.716  0.715 0.33  0.319  1.161    147.4  1.0
#> A[3,2]   0.125  0.132 0.50 -0.514  0.804     62.3  1.0
#> A[9,2]   0.309  0.326 0.59 -0.394  1.091     54.6  1.0
#> A[1,3]   0.460  0.441 0.20  0.217  0.726     50.1  1.0
#> A[2,3]   0.788  0.753 0.27  0.468  1.182     31.3  1.0
#> A[3,3]   1.106  1.113 0.23  0.804  1.396     69.7  1.0
#> A[4,3]   0.673  0.657 0.23  0.391  0.986     30.8  1.0
#> A[7,3]   0.579  0.572 0.21  0.323  0.829     20.2  1.1
#> A[8,3]   1.058  1.042 0.33  0.631  1.484     32.6  1.1
#> A[9,3]   1.097  1.107 0.25  0.775  1.396     58.1  1.1
#> A[10,3]  1.080  1.077 0.28  0.752  1.407     52.5  1.0
#> 
#> Factor model parameters:
#>             mean median     sd    q10     q90 ess_bulk rhat
#> T[1,1]     0.941  0.926 0.0690  0.860  1.0549      8.7  1.1
#> T[2,1]     0.882  0.900 0.0988  0.745  0.9917      2.9  1.3
#> T[3,2]     0.909  0.906 0.0777  0.800  1.0115      7.7  1.1
#> phi[1]     0.050  0.051 0.0047  0.044  0.0562      9.9  1.1
#> phi[2]     0.054  0.055 0.0080  0.043  0.0653     10.4  1.0
#> Corr[2,1]  0.157  0.145 0.2073 -0.075  0.4520      6.3  1.1
#> Corr[3,1] -0.128 -0.085 0.1066 -0.294 -0.0140      5.8  1.2
#> Corr[3,2] -0.257 -0.279 0.1541 -0.416  0.0044      2.5  1.3
#> 
#> ess_bulk is the bulk effective sample size; rhat is the potential
#> scale reduction factor on split chains (Rhat = 1 at convergence).
#> Use summary() for the full set of statistics (incl. ess_tail).

Notice that the loading parameter is also available in the samples.

SPIFA model with predictors

A spifa_pred model is simply defined by adding predictor terms to formula.

samples <- spifa(
  items ~ wealth, data = ipixuna, nfactors = nfactors, niter = 500,
  constraints = list(discrimination = A)
)
samples
#> Item factor analysis model: spifa_pred
#> Formula: items ~ wealth
#> Dimensions: 100 respondents, 10 items, 3 latent factors, 3 spatial processes
#> MCMC: 1 chain, iter = 500, thin = 1, samples = 500
#> 
#> Item model parameters:
#>           mean median   sd     q10    q90 ess_bulk rhat
#> c[1]    -0.532 -0.531 0.22 -0.8073 -0.249     48.4  1.0
#> c[2]    -0.528 -0.516 0.19 -0.7766 -0.302     72.7  1.0
#> c[3]    -0.496 -0.495 0.19 -0.7363 -0.248    100.9  1.0
#> c[4]    -0.343 -0.339 0.16 -0.5365 -0.136    103.7  1.0
#> c[5]    -0.289 -0.284 0.19 -0.5286 -0.038     49.7  1.0
#> c[6]     0.036  0.037 0.18 -0.2012  0.274     38.5  1.1
#> c[7]     0.274  0.271 0.20  0.0273  0.530     49.0  1.0
#> c[8]     0.216  0.214 0.17  0.0051  0.427    105.4  1.0
#> c[9]     0.760  0.741 0.26  0.4419  1.125     16.1  1.1
#> c[10]    0.475  0.472 0.20  0.2096  0.710     51.9  1.0
#> A[1,1]   0.401  0.375 0.22  0.1312  0.720     45.9  1.0
#> A[2,1]   0.452  0.441 0.24  0.1634  0.764      7.8  1.1
#> A[3,1]   0.301  0.291 0.22  0.0288  0.599     79.6  1.0
#> A[5,1]   1.522  1.503 0.38  1.1259  2.071     21.2  1.0
#> A[6,1]   1.205  1.209 0.31  0.8209  1.586     46.2  1.0
#> A[7,1]   1.216  1.171 0.32  0.8575  1.642     20.5  1.0
#> A[9,1]   1.116  1.115 0.29  0.7787  1.475     32.4  1.0
#> A[10,1]  1.315  1.264 0.40  0.8853  1.824     16.4  1.0
#> A[1,2]   1.139  1.144 0.37  0.6788  1.626     21.6  1.1
#> A[2,2]   0.801  0.773 0.23  0.5203  1.111     43.3  1.1
#> A[3,2]   0.594  0.575 0.28  0.2576  0.967     53.4  1.0
#> A[9,2]   0.905  0.905 0.31  0.5326  1.293      7.9  1.1
#> A[1,3]   0.025  0.027 0.27 -0.3180  0.372     26.7  1.0
#> A[2,3]   0.532  0.539 0.24  0.2423  0.833     47.5  1.0
#> A[3,3]   0.892  0.893 0.20  0.6174  1.142     65.8  1.0
#> A[4,3]   1.006  0.991 0.32  0.6154  1.440      6.4  1.1
#> A[7,3]   0.693  0.697 0.24  0.3936  1.017     28.5  1.0
#> A[8,3]   1.258  1.216 0.38  0.8021  1.773     20.0  1.0
#> A[9,3]   0.839  0.851 0.36  0.3619  1.317      7.2  1.1
#> A[10,3]  1.053  1.059 0.29  0.6868  1.418     39.7  1.0
#> 
#> Factor model parameters:
#>             mean median     sd    q10    q90 ess_bulk rhat
#> B[1,1]    -0.433 -0.437 0.1266 -0.582 -0.286     64.3  1.0
#> B[1,2]     0.096  0.094 0.1341 -0.067  0.269    206.3  1.0
#> B[1,3]    -0.244 -0.238 0.1147 -0.389 -0.113    230.7  1.0
#> T[1,1]     0.889  0.881 0.0969  0.783  1.029      3.7  1.2
#> T[2,2]     0.920  0.879 0.1378  0.777  1.109     15.7  1.0
#> T[3,3]     0.895  0.869 0.0844  0.812  1.033      6.2  1.2
#> phi[1]     0.050  0.050 0.0082  0.039  0.065     12.6  1.2
#> phi[2]     0.046  0.046 0.0055  0.039  0.053     19.0  1.1
#> phi[3]     0.054  0.052 0.0078  0.044  0.064      3.8  1.3
#> Corr[2,1]  0.087  0.104 0.1250 -0.045  0.201     34.4  1.0
#> Corr[3,1]  0.164  0.133 0.1818 -0.023  0.472     13.9  1.2
#> Corr[3,2]  0.124  0.086 0.1968 -0.122  0.404      7.4  1.1
#> 
#> ess_bulk is the bulk effective sample size; rhat is the potential
#> scale reduction factor on split chains (Rhat = 1 at convergence).
#> Use summary() for the full set of statistics (incl. ess_tail).

Notice that the predictor effects B is now included in the samples.