fungibleR | R Documentation |
Generate fungible correlation matrices. For a given vector of standardized regression coefficients, Beta, and a user-define R-squared value, Rsq, find predictor correlation matrices, R, such that Beta' R Beta = Rsq. The size of the smallest eigenvalue (Lp) of R can be defined.
fungibleR(R, Beta, Lp = 0, eps = 1e-08, Print.Warnings = TRUE)
R |
A p x p predictor correlation matrix. |
Beta |
A p x 1 vector of standardized regression coefficients. |
Lp |
Controls the size of the smallest eigenvalue of RstarLp. |
eps |
Convergence criterion. |
Print.Warnings |
Logical, default = TRUE. When TRUE, convergence failures are printed. |
R |
Any input correlation matrix that satisfies Beta' R Beta = Rsq. |
Beta |
Input vector of std reg coefficients. |
Rstar |
A random fungible correlation matrix. |
RstarLp |
A fungible correlation matrix with a fixed minimum eigenvalue (RstarLp can be PD, PSD, or ID). |
s |
Scaling constant for Rstar. |
sLp |
Scaling constant for RstarLp. |
Delta |
Vector in the null space of vecp(Beta Beta'). |
Q |
Left null space of Beta. |
FrobNorm |
Frobenius norm ||R - Rstar||_F. |
FrobNormLp |
Frobenius norm ||R - RstarLp||_F given random Delta. |
converged |
An integer code. 0 indicates successful completion. |
Niels Waller
Waller, N. (2016). Fungible Correlation Matrices: A method for generating nonsingular, singular, and improper correlation matrices for Monte Carlo research. Multivariate Behavioral Research.
library(fungible)
## ===== Example 1 =====
## Generate 5 random PD fungible R matrices
## that are consistent with a user-defined predictive
## structure: B' Rxx B = .30
set.seed(246)
## Create a 5 x 5 correlation matrix, R, with all r_ij = .25
R.ex1 <- matrix(.25, 5, 5)
diag(R.ex1) <- 1
## create a 5 x 1 vector of standardized regression coefficients,
## Beta.ex1
Beta.ex1 <- c(-.4, -.2, 0, .2, .4)
cat("\nModel Rsq = ", t(Beta.ex1) %*% R.ex1 %*% Beta.ex1)
## Generate fungible correlation matrices, Rstar, with smallest
## eigenvalues > 0.
Rstar.list <- list(rep(99,5))
i <- 0
while(i <= 5){
out <- fungibleR(R = R.ex1, Beta = Beta.ex1, Lp = 1e-8, eps = 1e-8,
Print.Warnings = TRUE)
if(out$converged==0){
i <- i + 1
Rstar.list[[i]] <- out$Rstar
}
}
## Check Results
cat("\n *** Check Results ***")
for(i in 1:5){
cat("\n\n\n+++++++++++++++++++++++++++++++++++++++++++++++++")
cat("\nRstar", i,"\n")
print(round(Rstar.list[[i]], 2),)
cat("\neigenvalues of Rstar", i,"\n")
print(eigen(Rstar.list[[i]])$values)
cat("\nBeta' Rstar",i, "Beta = ",
t(Beta.ex1) %*% Rstar.list[[i]] %*% Beta.ex1)
}
## ===== Example 2 =====
## Generate a PD fungible R matrix with a fixed smallest
## eigenvalue (Lp).
## Create a 5 x 5 correlation matrix, R, with all r_ij = .5
R <- matrix(.5, 5, 5)
diag(R) <- 1
## create a 5 x 1 vector of standardized regression coefficients, Beta,
## such that Beta_i = .1 for all i
Beta <- rep(.1, 5)
## Generate fungible correlation matrices (a) Rstar and (b) RstarLp.
## Set Lp = 0.12345678 so that the smallest eigenvalue (Lp) of RstarLp
## = 0.12345678
out <- fungibleR(R, Beta, Lp = 0.12345678, eps = 1e-10, Print.Warnings = TRUE)
## print R
cat("\nR: a user-specified seed matrix")
print(round(out$R,3))
## Rstar
cat("\nRstar: A random fungible correlation matrix for R")
print(round(out$Rstar,3))
cat("\nCoefficient of determination when using R\n")
print( t(Beta) %*% R %*% Beta )
cat("\nCoefficient of determination when using Rstar\n")
print( t(Beta) %*% out$Rstar %*% Beta)
## Eigenvalues of R
cat("\nEigenvalues of R\n")
print(round(eigen(out$R)$values, 9))
## Eigenvalues of Rstar
cat("\nEigenvalues of Rstar\n")
print(round(eigen(out$Rstar)$values, 9))
## What is the Frobenius norm (Euclidean distance) between
## R and Rstar
cat("\nFrobenious norm ||R - Rstar||\n")
print( out$FrobNorm)
## RstarLp is a random fungible correlation matrix with
## a fixed smallest eigenvalue of 0.12345678
cat("\nRstarLp: a random fungible correlation matrix with a user-defined
smallest eigenvalue\n")
print(round(out$RstarLp, 3))
## Eigenvalues of RstarLp
cat("\nEigenvalues of RstarLp")
print(eigen(out$RstarLp)$values, digits = 9)
cat("\nCoefficient of determination when using RstarLp\n")
print( t(Beta) %*% out$RstarLp %*% Beta)
## Check function convergence
if(out$converged) print("Falied to converge")
## ===== Example 3 =====
## This examples demonstrates how fungibleR can be used
## to generate improper correlation matrices (i.e., pseudo
## correlation matrices with negative eigenvalues).
library(fungible)
## We desire an improper correlation matrix that
## is close to a user-supplied seed matrix. Create an
## interesting seed matrix that reflects a Big Five
## factor structure.
set.seed(123)
minCrossLoading <- -.2
maxCrossLoading <- .2
F1 <- c(rep(.6,5),runif(20,minCrossLoading, maxCrossLoading))
F2 <- c(runif(5,minCrossLoading, maxCrossLoading), rep(.6,5),
runif(15,minCrossLoading, maxCrossLoading))
F3 <- c(runif(10,minCrossLoading,maxCrossLoading), rep(.6,5),
runif(10,minCrossLoading,maxCrossLoading) )
F4 <- c(runif(15,minCrossLoading,maxCrossLoading), rep(.6,5),
runif(5,minCrossLoading,maxCrossLoading))
F5 <- c(runif(20,minCrossLoading,maxCrossLoading), rep(.6,5))
FacMat <- cbind(F1,F2,F3,F4,F5)
R.bfi <- FacMat %*% t(FacMat)
diag(R.bfi) <- 1
## Set Beta to a null vector to inform fungibleR that we are
## not interested in placing constraints on the predictive structure
## of the fungible R matrices.
Beta <- rep(0, 25)
## We seek a NPD fungible R matrix that is close to the bfi seed matrix.
## To find a suitable matrix we generate a large number (e.g., 50000)
## fungible R matrices. For illustration purposes I will set Nmatrices
## to a smaller number: 10.
Nmatrices<-10
## Initialize a list to contain the Nmatrices fungible R objects
RstarLp.list <- as.list( rep(0, Nmatrices ) )
## Initialize a vector for the Nmatrices Frobeius norms ||R - RstarLp||
FrobLp.vec <- rep(0, Nmatrices)
## Constraint the smallest eigenvalue of RStarLp by setting
## Lp = -.1 (or any suitably chosen user-defined value).
## Generate Nmatrices fungibleR matrices and identify the NPD correlation
## matrix that is "closest" (has the smallest Frobenious norm) to the bfi
## seed matrix.
BestR.i <- 0
BestFrob <- 99
i <- 0
set.seed(1)
while(i < Nmatrices){
out<-fungibleR(R = R.bfi, Beta, Lp = -.1, eps=1e-10)
## retain solution if algorithm converged
if(out$converged == 0)
{
i<- i + 1
## print progress
cat("\nGenerating matrix ", i, " Current minimum ||R - RstarLp|| = ",BestFrob)
tmp <- FrobLp.vec[i] <- out$FrobNormLp #Frobenious Norm ||R - RstarLp||
RstarLp.list[[i]]<-out$RstarLp
if( tmp < BestFrob )
{
BestR.i <- i # matrix with lowest ||R - RstarLp||
BestFrob <- tmp # value of lowest ||R - RstarLp||
}
}
}
# CloseR is an improper correlation matrix that is close to the seed matrix.
CloseR<-RstarLp.list[[BestR.i]]
plot(1:25, eigen(R.bfi)$values,
type = "b",
lwd = 2,
main = "Scree Plots for R and RstarLp",
cex.main = 1.5,
ylim = c(-.2,6),
ylab = "Eigenvalues",
xlab = "Dimensions")
points(1:25,eigen(CloseR)$values,
type = "b",
lty = 2,
lwd = 2,
col = "red")
abline(h = 0, col = "grey")
legend(legend=c(expression(paste(lambda[i]~" of R",sep = "")),
expression(paste(lambda[i]~" of RstarLp",sep = ""))),
lty=c(1,2),
x = 17,y = 5.75,
cex = 1.5,
col=c("black","red"),
text.width = 5.5,
lwd = 2)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.