Error using rnorm_multi()
peter-hitchcock opened this issue · comments
Womp — sorry, this issue came up due to trying to use the function with a supplied matrix that wasn't positive definite; I ended up using an empirical correlation matrix and that solved it.
When I ran your code, cmat is a tibble that looks like a correlation matrix. If you want to use the full matrix specification, you need to convert this to a matrix with as.matrix()
.
However, it also isn't symmetric (e.g. the correlation between q_sxs_corr_1 and q_sxs_corr_2 in the upper right triangle isn't the same at the correlation between q_sxs_corr_2 and q_sxs_corr_1 in the lower left triangle).
Additionally, you're simulating correlations among the 21 items sampled from a uniform distribution between .25 and .8. That almost certainly means that the pattern of correlations you're creating will be literally impossible (i.e., not positive definite). For example, rnorm_multi(n=100, vars=3, r=c(.25, .8, -.5))
returns an error that the correlation matrix is not positive definite because if A and B correlate .25, and A and C correlate .8, then B and C can only have correlations between -0.38 and +0.78 (see faux::pos_def_limits(.25, .8, NA)
).
With such a large number of intercorrelations, you need to either set all of the values to a smaller random range or use real data (which should have an achievable pattern of correlations).
I can get the following to work (also fixes the asymmetric tibble problem and reduces the questionnaire item correlation range):
GenRow <- function(iter) {
row_without_diag <- c(
# Questionnaire items
runif(21, .25, .5), # reduced 0.8 to 0.5
# Other variable
runif(1, -.43, -.17)
)
row_without_diag[(iter+1):22]. # just return upper right triangle part
}
urtri <- lapply(1:21, function(x) GenRow(x)) %>% unlist()
# convert upper right triangle to full matrix
# not necessary, as the r argument will also take the URT vector,
# but useful for checking what a symmetric matrix looks like
cmat <- faux:::cormat_from_triangle(urtri)
dat <- rnorm_multi(n=100, vars=22, r=cmat, varnames = LETTERS[1:22])
Ack, you edited while I was replying!!
Hi Lisa, Sorry about that, but that still was very useful, so thank you! I had realized the non-symmetry and generally that I'd need to put some thought into creating positive definite matrices, but that helps to see how to use pos_def_limits
and cormat_from_triangle
(given that it's not always desirable to use an empirical correlation matrix as I ended up doing in this case). Thank you!