My setting is, I want to simulate a data set in two conditions, e.g. control and disease. I want them to share mostly the same correlations except some should be different to simulate a "signal" between the two conditions.

So I'm trying to simulate two correlation matrices (i.e. they have to be positive semidefinite, symmetric with ones on the diagonal) which share some equal correlations, e.g. the first 2 rows should have the same correlation between the two, the rest is random/shuffled, like this:

Example of the two correlation matrices

Note how A and B have the same correlation values in both (first two rows and columns are the same), the rest is different.

Is this possible? I can generate a random correlation matrix using the last method described here, but I can't figure out how to change/shuffle a subset of the matrix still keep them positive semidefinite. I tried shuffling the elements of the rows except the diagonal values and make it symmetric again with

cor.mat[lower.tri(cor.mat)] <- t(cor.mat)[lower.tri(cor.mat)]

but then the matrix isn't positive semidefinite anymore.

Any suggestions would be greatly appreciated!


I found this post where the question was to complete a partial matrix to be positive definite one, could this be used in my case? E.g. generate one matrix, delete the rows I want to randomize and fill it up with random values?

Unfortunately I'm no mathematician and I don't really understand the explanations and can't translate the answers into R code, could someone help with this?

  • 1
    $\begingroup$ It's usually possible, but the result is indefinite: please indicate what probability distribution you want the random correlation matrices to have. $\endgroup$
    – whuber
    Commented Dec 5, 2022 at 17:26
  • $\begingroup$ There is no way to create a positive semidefinite matrix with this? I want to use mvrnorm to sample from a multivariate normal distribution, this doesn't work if they are not positive semidefinite. The correlation matrices should be skewed towards -1 and 1. Currently I achieve this using the technique described by @amoeba here $\endgroup$
    – Sinraw
    Commented Dec 6, 2022 at 10:20
  • $\begingroup$ @whuber please also see my new edit, do you think this could work? $\endgroup$
    – Sinraw
    Commented Dec 6, 2022 at 12:05
  • $\begingroup$ Ordinarily a simulation is conducted to explore a set of possible values in a realistic way. Merely completing a partially filled correlation matrix would not be a simulation. Perhaps you could explain why you want to do this -- that might help us suggest solutions that are useful and appropriate. $\endgroup$
    – whuber
    Commented Dec 6, 2022 at 15:36
  • $\begingroup$ BTW, my post at stats.stackexchange.com/a/313138/919 gives the most general possible solution to this problem -- along with demonstration code. stats.stackexchange.com/questions/444039 has a more detailed explanation of why it works. $\endgroup$
    – whuber
    Commented Dec 6, 2022 at 16:01

1 Answer 1


In case anyone also has this problem, I think I found a solution that works for me:

I simulate one correlation matrix, duplicate it and then randomize some values in the duplicate, resulting in the second "condition" matrix. To get this new matrix to be positive semi-definite as well, I use the R function nearPD() in the Matrix package. nearPD() finds the nearest positive semi-definite by adjusting all values slightly till a result is found that fulfills the criteria. This doesn't give me exactly what I wanted (since all values are adjusted in the new matrix, they don't match exactly with the values in the original matrix) but it's close enough to work in my case.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.