Hello
I have X, an n-by-n matrix and want to convert it to Y, an
n(n-1)/2 -by- n matrix such that each row of Y
corresponds to an element of the upper diagonal
of X. Say row k of Y corresponds to [i,j] with i\neq j.
Then Y[i,k] = X[i,j] and Y[j,k] = X[j,i].
and Y[-c(i,j),k] = NA.
How to do this vectorizedly?
Example follows:
> X
[,1] [,2] [,3] [,4]
[1,] NA 10 8 7
[2,] 10 NA 7 12
[3,] 12 13 NA 8
[4,] 13 8 12 NA
> Y
[,1] [,2] [,3] [,4]
[1,] 10 10 NA NA
[2,] 12 NA 8 NA
[3,] 13 NA NA 7
[4,] NA 13 7 NA
[5,] NA 8 NA 12
[6,] NA NA 12 8
>
[matrix X corresponds to an all-play-all competition amongst 4
individuals,
entry [i,j] corresponding to the number of times individual "i" won
when competing against individual "j". Thus individual 2 beat
individual
3 seven times and individual 3 beat individual 2 thirteen times.
Note X[i,j] + X[j,i]=20 as there were 20 trials for each pair]
Pitiful nonvectorized code follows.
n <- nrow(X)
Y <- matrix(NA,n*(n-1)/2,n)
k <- 1
for(i in 1:(n-1)){
for(j in (i+1):n){
if( !(i==j)){
print(c(i,j,k))
Y[k,i] <- X[i,j]
Y[k,j] <- X[j,i]
}
k <- k+1
}
}
--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
vectorize a matrix conversion
3 messages · robin hankin, Dimitris Rizopoulos, Charles C. Berry
you could try the following: n <- nrow(X) k <- n * (n - 1) / 2 Y <- matrix(NA, k, n) ind.up <- which(upper.tri(X), arr.ind = TRUE) ind.lo <- which(lower.tri(X), arr.ind = TRUE) Y[cbind(1:k, ind.lo[, 1])] <- X[ind.up] Y[cbind(1:k, ind.lo[, 2])] <- X[ind.lo] Y I hope it helps. Best, Dimitris ---- Dimitris Rizopoulos Ph.D. Student Biostatistical Centre School of Public Health Catholic University of Leuven Address: Kapucijnenvoer 35, Leuven, Belgium Tel: +32/(0)16/336899 Fax: +32/(0)16/337015 Web: http://med.kuleuven.be/biostat/ http://www.student.kuleuven.be/~m0390867/dimitris.htm ----- Original Message ----- From: "Robin Hankin" <r.hankin at noc.soton.ac.uk> To: "R program" <R-help at r-project.org> Sent: Wednesday, September 12, 2007 4:32 PM Subject: [R] vectorize a matrix conversion
Hello I have X, an n-by-n matrix and want to convert it to Y, an n(n-1)/2 -by- n matrix such that each row of Y corresponds to an element of the upper diagonal of X. Say row k of Y corresponds to [i,j] with i\neq j. Then Y[i,k] = X[i,j] and Y[j,k] = X[j,i]. and Y[-c(i,j),k] = NA. How to do this vectorizedly? Example follows:
X
[,1] [,2] [,3] [,4] [1,] NA 10 8 7 [2,] 10 NA 7 12 [3,] 12 13 NA 8 [4,] 13 8 12 NA
Y
[,1] [,2] [,3] [,4] [1,] 10 10 NA NA [2,] 12 NA 8 NA [3,] 13 NA NA 7 [4,] NA 13 7 NA [5,] NA 8 NA 12 [6,] NA NA 12 8
[matrix X corresponds to an all-play-all competition amongst 4
individuals,
entry [i,j] corresponding to the number of times individual "i" won
when competing against individual "j". Thus individual 2 beat
individual
3 seven times and individual 3 beat individual 2 thirteen times.
Note X[i,j] + X[j,i]=20 as there were 20 trials for each pair]
Pitiful nonvectorized code follows.
n <- nrow(X)
Y <- matrix(NA,n*(n-1)/2,n)
k <- 1
for(i in 1:(n-1)){
for(j in (i+1):n){
if( !(i==j)){
print(c(i,j,k))
Y[k,i] <- X[i,j]
Y[k,j] <- X[j,i]
}
k <- k+1
}
}
--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
On Wed, 12 Sep 2007, Robin Hankin wrote:
Hello I have X, an n-by-n matrix and want to convert it to Y, an n(n-1)/2 -by- n matrix such that each row of Y corresponds to an element of the upper diagonal of X. Say row k of Y corresponds to [i,j] with i\neq j. Then Y[i,k] = X[i,j] and Y[j,k] = X[j,i]. and Y[-c(i,j),k] = NA. How to do this vectorizedly?
If I follow you: upper.indexes <- which( lower.tri( X ), arr.ind=TRUE ) from.mat <- rbind( upper.indexes, upper.indexes[ , 2:1 ] ) to.mat <- cbind( rep( 1:nrow(upper.indexes), 2 ), as.vector( upper.indexes[, 2:1] ) ) Y[ to.mat ] <- X[ from.mat ] HTH, Chuck
Example follows:
X
[,1] [,2] [,3] [,4] [1,] NA 10 8 7 [2,] 10 NA 7 12 [3,] 12 13 NA 8 [4,] 13 8 12 NA
Y
[,1] [,2] [,3] [,4] [1,] 10 10 NA NA [2,] 12 NA 8 NA [3,] 13 NA NA 7 [4,] NA 13 7 NA [5,] NA 8 NA 12 [6,] NA NA 12 8
[matrix X corresponds to an all-play-all competition amongst 4
individuals,
entry [i,j] corresponding to the number of times individual "i" won
when competing against individual "j". Thus individual 2 beat
individual
3 seven times and individual 3 beat individual 2 thirteen times.
Note X[i,j] + X[j,i]=20 as there were 20 trials for each pair]
Pitiful nonvectorized code follows.
n <- nrow(X)
Y <- matrix(NA,n*(n-1)/2,n)
k <- 1
for(i in 1:(n-1)){
for(j in (i+1):n){
if( !(i==j)){
print(c(i,j,k))
Y[k,i] <- X[i,j]
Y[k,j] <- X[j,i]
}
k <- k+1
}
}
--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Charles C. Berry (858) 534-2098
Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu UC San Diego
http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901