Re: [R] R code for var-cov matrix given variances and correlations

2004-12-21 Thread Peter Dalgaard
Haynes, Maurice (NIH/NICHD) [EMAIL PROTECTED] writes:

 If the vector of variances were
 var.vec - c(14, 12, 7) 
 and the vector of correlations were 
 cor.vec - c(.4, .2, .5), 
 then the vector of covariances would be:
  covAB(c(.4, .2, .5),c(14, 14, 12), c(12, 7, 7))
 [1] 5.184593 1.979899 4.582576
 
 and the variance-covariance matrix with covariances rounded to 
 the first decimal place would be:
  vmat - matrix(c(14, 5.2, 2.0, 5.2, 12, 4.6, 2.0, 4.6, 7),
 + nrow=3)
  vmat
  [,1] [,2] [,3]
 [1,] 14.0  5.2  2.0
 [2,]  5.2 12.0  4.6
 [3,]  2.0  4.6  7.0
  


# First fill in the correlation matrix:

V - matrix(NA,3,3)
diag(V) - 1
V[lower.tri(V)] -  c(.4, .2, .5)
V[upper.tri(V)] - t(V)[upper.tri(V)]

# then scale rows and columns

D - diag(sqrt( c(14, 12, 7)))
D %*% V %*% D

# or, more efficiently

s - sqrt( c(14, 12, 7))
sweep(sweep(V,1,s,*),2,s,*)




-- 
   O__   Peter Dalgaard Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics 2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark  Ph: (+45) 35327918
~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907

__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] R code for var-cov matrix given variances and correlations

2004-12-21 Thread David Firth
On 21 Dec, 2004, at 13:09, Haynes, Maurice (NIH/NICHD) wrote:
Dear list members,
Where can I find code for computing the p*p variance-covariance
matrix given a vector of p variances (ordered varA, varB, ...,
varp) and a vector of all possible correlations (ordered corAB,
corAC, ..., corp-1,p)?
Something like this (not tested):
sd.vec - sqrt(var.vec)
n - length(sd.vec)
cor.mat - matrix(1, n, n)
for (i in 2:n){
for (j in 1:i-1){
cor.mat[i,j] - cor.vec[(i-1)*(i-2)/2 + j]
cor.mat[j,i] - cor.mat[i,j]}}
cov.mat - cor.mat * outer(sd.vec, sd.vec)
I hope that helps.
David

I know that the covariance between 2 variables is equal to the
product of their correlation and their standard deviations:
corAB * varA^.5 * varB^.5
and so:
covAB - function(corAB, varA, varB) {
corAB * varA^.5 * varB^.5
}
If the vector of variances were
var.vec - c(14, 12, 7)
and the vector of correlations were
cor.vec - c(.4, .2, .5),
then the vector of covariances would be:
covAB(c(.4, .2, .5),c(14, 14, 12), c(12, 7, 7))
[1] 5.184593 1.979899 4.582576

and the variance-covariance matrix with covariances rounded to
the first decimal place would be:
vmat - matrix(c(14, 5.2, 2.0, 5.2, 12, 4.6, 2.0, 4.6, 7),
+ nrow=3)
vmat
 [,1] [,2] [,3]
[1,] 14.0  5.2  2.0
[2,]  5.2 12.0  4.6
[3,]  2.0  4.6  7.0

So the question is: How can I generate a p*p variance-covariance
matrix from a vector of variances and a vector of correlations
without resorting to a construction like:
vmat - matrix(rep(0, p*p), nrow=p)
if (p == 2) {
vmat[1,1] - var[1]
vmat[1,2] - cor[1] * (var[1]^.5 * var[2]^.5)
vmat[2,1] - cor[1] * (var[2]^.5 * var[1]^.5)
vmat[2,2] - var[2]
}
if (p == 3) {
vmat[1,1] - var[1]
vmat[1,2] - cor[1] * (var[1]^.5 * var[2]^.5)
vmat[1,3] - cor[2] * (var[1]^.5 * var[3]^.5)
vmat[2,1] - cor[1] * (var[2]^.5 * var[1]^.5)
vmat[2,2] - var[2]
vmat[2,3] - cor[3] * (var[2]^.5 * var[3]^.5)
vmat[3,1] - cor[2] * (var[3]^.5 * var[1]^.5)
vmat[3,2] - cor[3] * (var[3]^.5 * var[2]^.5)
vmat[3,3] - var[3]
}
and so forth?
Thanks,
Maurice Haynes
National Institute of Child Health and Human Development
Child and Family Research Section
6705 Rockledge Drive, Suite 8030
Bethesda, MD  20892
Voice: 301-496-8180
Fax: 301-496-2766
E-mail: [EMAIL PROTECTED]
__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! 
http://www.R-project.org/posting-guide.html
__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] R code for var-cov matrix given variances and correlations

2004-12-21 Thread Martin Maechler
 PD == Peter Dalgaard [EMAIL PROTECTED]
 on 21 Dec 2004 14:34:59 +0100 writes:

PD Haynes, Maurice (NIH/NICHD) [EMAIL PROTECTED] writes:
 If the vector of variances were
 var.vec - c(14, 12, 7) 
 and the vector of correlations were 
 cor.vec - c(.4, .2, .5), 
 then the vector of covariances would be:
  covAB(c(.4, .2, .5),c(14, 14, 12), c(12, 7, 7))
 [1] 5.184593 1.979899 4.582576
 
 and the variance-covariance matrix with covariances rounded to 
 the first decimal place would be:
  vmat - matrix(c(14, 5.2, 2.0, 5.2, 12, 4.6, 2.0, 4.6, 7),
 + nrow=3)
  vmat
 [,1] [,2] [,3]
 [1,] 14.0  5.2  2.0
 [2,]  5.2 12.0  4.6
 [3,]  2.0  4.6  7.0
  


PD # First fill in the correlation matrix:

PD V - matrix(NA,3,3)
PD diag(V) - 1
PD V[lower.tri(V)] -  c(.4, .2, .5)
PD V[upper.tri(V)] - t(V)[upper.tri(V)]

PD # then scale rows and columns

PD D - diag(sqrt( c(14, 12, 7)))
PD D %*% V %*% D

PD # or, more efficiently

PD s - sqrt( c(14, 12, 7))
PD sweep(sweep(V,1,s,*),2,s,*)

and others give similar answers, not as nice as the sweep one.
While I leave the exact comparisons and even more slick
alternatives to Gabor (:-),
yet another alternative is to look at 
  cov2cor()
which does  Cov |-- Cor, i.e., the inverse of what the original
poster wanted.
The source of that function, e.g. in
https://svn.r-project.org/R/trunk/src/library/stats/R/cor.R
is

cov2cor - function(V)
{
## Purpose: Covariance matrix |-- Correlation matrix -- efficiently
## --
## Arguments: V: a covariance matrix (i.e. symmetric and positive definite)
## --
## Author: Martin Maechler, Date: 12 Jun 2003, 11:50
p - (d - dim(V))[1]
if(!is.numeric(V) || length(d) != 2 || p != d[2])
stop(`V' is not a square numeric matrix)
Is - sqrt(1/diag(V)) # diag( 1/sigma_i )
if(any(!is.finite(Is)))
warning(diagonal has non-finite entries)
r - V # keep dimnames
r[] - Is * V * rep(Is, each = p)
##  == D %*% V %*% D  where D = diag(Is)
r[cbind(1:p,1:p)] - 1 # exact in diagonal
r
}

[ Note that this is the *real source* including comments, 
  contrary to what you get when you just type   'cov2cor' in R ]

What I've wanted to expose here are the lines

Is - sqrt(1/diag(V)) # diag( 1/sigma_i )
..
r - V # keep dimnames
r[] - Is * V * rep(Is, each = p)

which shows ``how to'' compute  Diag %*% Matrix %*% Diag,
efficiently, probably a bit more even than Peter's nice double
use of sweep(.., *)  {and still keeping dimnames}.

Martin

__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html