Я вважаю, що фокус питання полягає не в теоретичній стороні, а більше з практичної сторони, тобто як реалізувати факторний аналіз дихотомічних даних у Р.
Спочатку давайте змоделюємо 200 спостережень із 6 змінних, що походять від 2 ортогональних факторів. Я візьму пару проміжних кроків і почну з багатоваріантних нормальних безперервних даних, які згодом дихотомізую. Таким чином, ми можемо порівняти Пірсонові кореляції з поліхорними кореляціями та порівняти факторні навантаження з безперервних даних з дихотомічними даними та справжніми навантаженнями.
set.seed(1.234)
N <- 200 # number of observations
P <- 6 # number of variables
Q <- 2 # number of factors
# true P x Q loading matrix -> variable-factor correlations
Lambda <- matrix(c(0.7,-0.4, 0.8,0, -0.2,0.9, -0.3,0.4, 0.3,0.7, -0.8,0.1),
nrow=P, ncol=Q, byrow=TRUE)
x = Λ f+ ехΛfе
library(mvtnorm) # for rmvnorm()
FF <- rmvnorm(N, mean=c(5, 15), sigma=diag(Q)) # factor scores (uncorrelated factors)
E <- rmvnorm(N, rep(0, P), diag(P)) # matrix with iid, mean 0, normal errors
X <- FF %*% t(Lambda) + E # matrix with variable values
Xdf <- data.frame(X) # data also as a data frame
Зробіть факторний аналіз для безперервних даних. Орієнтовні навантаження схожі на справжні, якщо ігнорувати нерелевантний знак.
> library(psych) # for fa(), fa.poly(), factor.plot(), fa.diagram(), fa.parallel.poly, vss()
> fa(X, nfactors=2, rotate="varimax")$loadings # factor analysis continuous data
Loadings:
MR2 MR1
[1,] -0.602 -0.125
[2,] -0.450 0.102
[3,] 0.341 0.386
[4,] 0.443 0.251
[5,] -0.156 0.985
[6,] 0.590
Тепер давайте дихотомізуємо дані. Ми збережемо дані у двох форматах: як кадр даних із упорядкованими факторами, і як числова матриця. hetcor()з пакета polycorдає нам поліхорну матрицю кореляції, яку ми згодом використовуватимемо для FA.
# dichotomize variables into a list of ordered factors
Xdi <- lapply(Xdf, function(x) cut(x, breaks=c(-Inf, median(x), Inf), ordered=TRUE))
Xdidf <- do.call("data.frame", Xdi) # combine list into a data frame
XdiNum <- data.matrix(Xdidf) # dichotomized data as a numeric matrix
library(polycor) # for hetcor()
pc <- hetcor(Xdidf, ML=TRUE) # polychoric corr matrix -> component correlations
Тепер використовуйте поліхіричну кореляційну матрицю, щоб зробити звичайну ФА. Зауважимо, що передбачувані навантаження досить схожі на завантажені з безперервних даних.
> faPC <- fa(r=pc$correlations, nfactors=2, n.obs=N, rotate="varimax")
> faPC$loadings
Loadings:
MR2 MR1
X1 -0.706 -0.150
X2 -0.278 0.167
X3 0.482 0.182
X4 0.598 0.226
X5 0.143 0.987
X6 0.571
Ви можете пропустити крок обчислення матриці поліхорної кореляції самостійно та безпосередньо скористатися fa.poly()з пакету psych, який зрештою робить те саме. Ця функція приймає необроблені дихотомічні дані як числову матрицю.
faPCdirect <- fa.poly(XdiNum, nfactors=2, rotate="varimax") # polychoric FA
faPCdirect$fa$loadings # loadings are the same as above ...
РЕДАКТУВАННЯ: Для оцінки факторів дивіться пакет, ltmякий має factor.scores()функцію спеціально для даних політомів результатів. Приклад наведено на цій сторінці -> "Оцінки факторів - Оцінки можливостей".
Ви можете візуалізувати навантаження з факторного аналізу, використовуючи factor.plot()і fa.diagram(), і з пакету psych. Чомусь factor.plot()приймає лише $faкомпонент результату від fa.poly(), а не повний об'єкт.
factor.plot(faPCdirect$fa, cut=0.5)
fa.diagram(faPCdirect)

Паралельний аналіз та аналіз "дуже простої структури" надають допомогу у виборі кількості факторів. Знову пакет psychмає необхідні функції. vss()приймає полігорну кореляційну матрицю як аргумент.
fa.parallel.poly(XdiNum) # parallel analysis for dichotomous data
vss(pc$correlations, n.obs=N, rotate="varimax") # very simple structure
Паралельний аналіз на поліхорну ФА також надається пакетом random.polychor.pa.
library(random.polychor.pa) # for random.polychor.pa()
random.polychor.pa(data.matrix=XdiNum, nrep=5, q.eigen=0.99)

Зауважте, що функції fa()і fa.poly()надають ще багато інших варіантів налаштування FA. Крім того, я відредагував частину результатів, які дають змогу добре перевірити відповідність і т. Д. Документація для цих функцій (і пакет psychвзагалі) є відмінною. Цей приклад тут призначений для початку роботи.