Skip to contents

Recovers respondent ideal points from an issue-scale response matrix by Poole's (1998) decomposition \(X_0 = \Psi W' + J_n c' + E_0\) over the observed cells. Respondents with fewer than minscale responses are not scaled (their rows are NA). The fit is a native port of the BLACKB routine of basicspace::blackbox: each dimension is started from sign-corrected respondent means (column polarities from the pairwise correlation matrix) and refined by four alternating least squares sweeps on the residuals of the earlier dimensions; up to five joint sweeps follow, stopping once the two half-step error sums of squares differ by less than 0.01; and the fitted \(\Psi W'\) is re-expressed by its singular value decomposition, \(\Psi = U D^{1/2}\), \(W = V D^{1/2}\). The results equal basicspace::blackbox's (which rounds them to three decimals), with or without missing cells; like it, the alternating fit is stopped early, so on weakly structured data it need not be the fully converged least-squares (truncated SVD) solution.

Usage

morie_spatial_voting_blackbox(X, n_dims = 2L, minscale = 8L)

Arguments

X

A respondent-by-issue numeric matrix of responses (NA for missing).

n_dims

Number of dimensions to extract.

minscale

Minimum number of responses for a respondent to be scaled (capped at the number of issues).

Value

A list with ideal_points (\(\Psi\), NA rows for unscaled respondents), stimuli_weights (\(W\)), eigenvalues (squared singular values), singular_values (of the fitted \(\Psi W'\), basicspace's fits$singular), explained_variance (\(1 - SSE/SS\), SS taken about the grand mean of the observed cells: the sum of basicspace's fits$percent over the dimensions, divided by 100), col_means (the issue intercepts \(c\), basicspace's c column), n_dims, and engine ("native").

References

Poole, K. T. (1998); Armstrong et al. (2021).

Examples

set.seed(1)
X <- matrix(rnorm(30 * 2), 30, 2) %*% matrix(rnorm(2 * 8), 2, 8) +
  matrix(rnorm(240, 0, 0.3), 30, 8)
X[sample(240, 10)] <- NA
fit <- morie_spatial_voting_blackbox(X, n_dims = 2)
fit$engine
#> [1] "native"
head(fit$ideal_points)
#>            [,1]        [,2]
#> [1,] -1.0393690 -0.96223469
#> [2,]  0.2901126  0.24491438
#> [3,] -0.7818754 -0.02044986
#> [4,]  1.3506573 -0.15572170
#> [5,]  0.7512586  1.04767730
#> [6,]         NA          NA