RnpdMAP | R Documentation |
Generate a list of Random NPD (pseudo) R matrices with a user-defined fixed minimum eigenvalue from a user-supplied population R using the method of alternating projections.
RnpdMAP(
Rpop,
Lp = NULL,
NNegEigs = 1,
NSmoothPosEigs = 4,
NSubjects = NULL,
NSamples = 0,
MaxIts = 15000,
PRINT = FALSE,
Seed = NULL
)
Rpop |
input (PD or PSD) p x p Population correlation matrix. |
Lp |
desired minimum eigenvalue in the NPD matrices. |
NNegEigs |
number of eigenvalues < 0 in Rnpd. |
NSmoothPosEigs |
number of eigenvalues > 0 to smooth: the smallest NSmoothPosEigs > 0 will be smoothed toward 0. |
NSubjects |
sample size (required when NSamples > 0) parameter used to generate sample correlation matrices. Default = NULL. |
NSamples |
generate NSamples sample R matrices. If NSamples = 0 the program will attempt to find Rnpd such that ||Rpop - Rnpd||_2 is minimized. |
MaxIts |
maximum number of projection iterations. |
PRINT |
(logical) If TRUE the program will print the iteration history for Lp. Default = NULL. |
Seed |
Optional seed for random number generation. |
Rpop |
population (PD) correlation matrix. |
R |
sample correlation matrix. |
Rnpd |
NPD improper (pseudo) correlation matrix. |
Lp |
desired value of minimum eigenvalue. |
minEig |
observed value of minimum eigenvalue of Rnpd. |
convergence |
0 = converged; 1 = not converged in MaxIts iterations of the alternating projections algorithm. |
feasible |
logical) TRUE if max(abs(r_ij)) <= 1. If FALSE then one or more values in Rnpd > 1 in absolute value. |
Seed |
saved seed for random number generator. |
prbs1 |
vector probabilities used to generate eigenvalues < 0. |
prbs2 |
vector of probabilities used to smooth the smallest NSmoothPosEigs towards zero. |
Niels G. Waller
library(MASS)
Nvar = 20
Nfac = 4
NSubj = 2000
Seed = 123
set.seed(Seed)
## Generate a vector of classical item difficulties
p <- runif(Nvar)
cat("\nClassical Item Difficulties:\n")
print(rbind(1:Nvar,round(p,2)) )
summary(p)
## Convert item difficulties to quantiles
b <- qnorm(p)
## fnc to compute root mean squared standard deviation
RMSD <- function(A, B){
sqrt(mean( ( A[lower.tri(A, diag = FALSE)] - B[lower.tri(B, diag = FALSE)] )^2))
}
## Generate vector of eigenvalues with clear factor structure
L <- eigGen(nDimensions = Nvar,
nMajorFactors = Nfac,
PrcntMajor = .60,
threshold = .50)
## Generate a population R matrix with the eigenvalues in L
Rpop <- rGivens(eigs = L)$R
## Generate continuous data that will reproduce Rpop (exactly)
X <- mvrnorm(n = NSubj, mu = rep(0, Nvar),
Sigma = Rpop, empirical = TRUE)
while( any(colSums(X) == 0) ){
warning("One or more variables have zero variance. Generating a new data set.")
X <- mvrnorm(n = NSubj, mu = rep(0, Nvar),
Sigma = Rpop, empirical = TRUE)
}
## Cut X at thresholds given in b to produce binary data U
U <- matrix(0, nrow(X), ncol(X))
for(j in 1:Nvar){
U[X[,j] <= b[j],j] <- 1
}
## Compute tetrachoric correlations
Rtet <- tetcor(U, Smooth = FALSE, PRINT = TRUE)$r
# Calculate eigenvalues of tetrachoric R matrix
Ltet <- eigen(Rtet)$values
if(Ltet[Nvar] >= 0) stop("Rtet is P(S)D")
## Simulate NPD R matrix with minimum eigenvalue equal to
# min(Ltet)
out <- RnpdMAP(Rpop,
Lp = Ltet[Nvar],
NNegEigs = Nvar/5,
NSmoothPosEigs = Nvar/5,
NSubjects = 150,
NSamples = 1,
MaxIts = 15000,
PRINT = FALSE,
Seed = Seed)
## RLp is a NPD pseudo R matrix with min eigenvalue = min(Ltet)
RLp <- out[[1]]$Rnpd
## Calculate eigenvalues of simulated NPD R matrix (Rnpd)
Lnpd <- eigen(RLp, only.values = TRUE)$values
## Scree plots for observed and simulated NPD R matrices.
ytop <- max(c(L,Lnpd,Ltet))
pointSize = .8
plot(1:Nvar, L, typ = "b", col = "darkgrey", lwd=3,
lty=1,
main =
"Eigenvalues of Rpop, Tet R, and Sim Tet R:
\nSimulated vs Observed npd Tetrachoric R Matrices",
ylim = c(-1, ytop),
xlab = "Dimensions",
ylab = "Eigenvalues",
cex = pointSize,cex.main = 1.2)
points(1:Nvar, Lnpd, typ="b",
col = "red", lwd = 3, lty=2, cex=pointSize)
points(1:Nvar, Ltet, typ="b",
col = "darkgreen", lwd = 3, lty = 3, cex= pointSize)
legend("topright",
legend = c("eigs Rpop", "eigs Sim Rnpd", "eigs Emp Rnpd"),
col = c("darkgrey", "red","darkgreen"),
lty = c(1,2,3),
lwd = c(4,4,4), cex = 1.5)
abline(h = 0, col = "grey", lty = 2, lwd = 4)
cat("\nRMSD(Rpop, Rtet) = ", round(rmsd(Rpop, Rtet), 3))
cat("\nRMSD(Rpop, RLp) = ", round(rmsd(Rpop, RLp), 3))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.