I'm simulating a multivariate dataset using a modified form of the mvrnorm() function (from the MASS package in R).

The problem is that I'm getting some negative values after the eigenvalue transformation (I assume) because I have many negative correlations and a number of small means.

Is there a special way to deal with this phenomenon? My idea is to just add some factor to all the datapoints (such as the 1st quartile) because I don't care so much what the exact means are, as long as the correlation structure remains intact.

A simple example:

require(MASS)     # For mvrnorm()
require(Matrix) # For nearPD()

corr <- diag(5)
corr[5,1] <- .5
corr[1,5] <- .5
corr[4,2] <- -.5
corr[2,4] <- -.5

mm <- mvrnorm(n=10, mu=rep(1,5), Sigma=nearPD(corr, corr=TRUE)$mat, 

As you can see, mm has nonpositive examples. Since I want to model physical measurements, this makes no sense.

edit2: multivariate sampling from log-normal distribution still results in negative examples:

mvrlnorm <- function (n = 1, mu, Sigma, tol = 1e-06, empirical = TRUE) {
    p <- length(mu)
    if (!all(dim(Sigma) == c(p, p)))
        stop("incompatible arguments")
    eS <- eigen(Sigma, symmetric = TRUE, EISPACK = TRUE)
    ev <- eS$values
    if (!all(ev >= -tol * abs(ev[1L]))) 
        stop("'Sigma' is not positive definite")
      # HERE BE log-normal distribution
    X <- matrix(rlnorm(p * n), nrow=n)
    if (empirical) {
        X <- scale(X, TRUE , FALSE)
        X <- X %*% svd(X, nu = nrow(X), nv = ncol(X))$v
        X <- scale(X, FALSE, TRUE)
    retval <- eS$vectors %*% diag(sqrt(ev), length(ev)) %*% t(eS$vectors)
    retval <- X %*% retval
    retval <- sweep(retval, 2, mu, "+")
    X <- retval

    nm <- names(mu)
    if (is.null(nm) && !is.null(dn <- dimnames(Sigma))) 
        nm <- dn[[1L]]
    dimnames(X) <- list(nm, NULL)
    if (n == 1) 
    else t(X)
  • 4
    $\begingroup$ A reproducible example would help. $\endgroup$
    – chl
    Mar 27, 2012 at 20:19
  • $\begingroup$ To add to chl's remark: it is not clear what you mean by an "eigenvalue transformation"; one cannot tell whether you are referring to negative eigenvalues or negative random values; and--most importantly--the purpose and constraints of the simulation are ambiguous, because if you can arbitrarily add "some factor" to the simulated data--which changes the means--then exactly what statistical characteristics are you attempting to reproduce with this simulation? $\endgroup$
    – whuber
    Mar 28, 2012 at 15:27
  • 1
    $\begingroup$ Added an example... sorry about that. The point of the simulation is to see if a new correlation metric for a certain kind of data can accurately recover the input correlation matrix (hence, the exact value of the means don't matter much). $\endgroup$
    – zzk
    Mar 28, 2012 at 16:32
  • 1
    $\begingroup$ What is the basis for choosing $1$ in rep(1,5) instead of, say, $10$, which would make your problem go away? $\endgroup$
    – whuber
    Mar 28, 2012 at 16:47
  • $\begingroup$ in my actual code, I set the means by sampling from a log-normal distribution (which is a reasonable approx of the actual physical phenomenon - population means of a community of organisms). It's not unusual for the mean of a variable to be close to 1. $\endgroup$
    – zzk
    Mar 28, 2012 at 16:52

1 Answer 1


A multivariate normal distribution on $\mathbb{R}^p$ has its support equal to the whole $\mathbb{R}^p$ unless the covariance matrix does not have full rank. Therefore, there always is a positive probability to observe negative components when generating $$ X \sim \mathcal{N}_p(\mu,\Sigma) $$ Thus, to answer your questions:

  1. The issue has nothing to do with the mvnorm() function. It is doing what it is supposed to do.
  2. If you are imposing positivity on your distribution, you cannot use a normal distribution. Use instead a distribution restricted to $\mathbb{R}_+^p$.
  • $\begingroup$ I've edited the source code and replaced the normal distribution with a log normal and I still observe negative components. Want to see the code? $\endgroup$
    – zzk
    Mar 28, 2012 at 16:55
  • 1
    $\begingroup$ Indeed, I would be most interested in seeing negative log normal realisations! $\endgroup$
    – Xi'an
    Mar 28, 2012 at 16:59
  • $\begingroup$ added to OP. Running with same seed and correlation matrix results in negative realizations. $\endgroup$
    – zzk
    Mar 28, 2012 at 17:04
  • 1
    $\begingroup$ @zzk: your code consists in transforming an iid lognormal vector $X$ by linear transforms, i.e. $Y=\mu+A X$. The resulting vector $Y$ is no longer log-normal, since only the location families like the normal distribution remain invariant under linear transforms. And there is nothing paradoxical in observing some components of $Y$ to be negative. $\endgroup$
    – Xi'an
    Mar 28, 2012 at 17:07
  • 1
    $\begingroup$ @zzk: exactly my point above. While it works for the normal distribution, it does not work for the log-normal distribution! This is of course an interesting problem, how to find a joint distribution on $\mathbb{R}^p_+$ with a given covariance matrix, however I do not know of a closed form solution. $\endgroup$
    – Xi'an
    Mar 29, 2012 at 5:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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