Stan
Stan

Reputation: 1247

Reshape array into distance matrix (in R)

I've got an array that was generated by flattening of a bottom triangle of a symmetrical square matrix (i.e distance matrix). I'm looking to reverse that process and generate the full square matrix from the array.

Let's say the original matrix was:

0 1 2 4
1 0 3 5
2 3 0 6
4 5 6 0

The lower triangle is:

1
2 3
4 5 6

...which was then flattened and recorded as array

1 2 3 4 5 6

I want to take that array and convert it back to the original matrix. I was hoping that it'd be as simple as

as.matrix(as.dist(ar)) +  t(as.matrix(as.dist(ar)))

...but as.dist(...) actually goes on calculate distances in various ways, instead of simply filling in the values from the array. There's probably a simple alternative, right?

Upvotes: 2

Views: 536

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 270195

Let n1 be such that 1+2+3+...+n1 is the length of x and let n = n1 + 1. Then m is an n x n matrix so:

ar <- 1:6

n <- which(cumsum(seq_along(ar)) == length(ar)) + 1

m <- matrix(0, n, n)
as.dist(t(replace(m, upper.tri(m), ar)))

giving:

  1 2 3
2 1    
3 2 3  
4 4 5 6

Upvotes: 2

Julius Vainora
Julius Vainora

Reputation: 48241

ar <- 1:6
d <- (1 + sqrt(1 + 8 * length(ar))) / 2
x <- matrix(0, d, d)
x[upper.tri(x)] <- ar
x[lower.tri(x)] <- t(x)[lower.tri(x)]
x
#      [,1] [,2] [,3] [,4]
# [1,]    0    1    2    4
# [2,]    1    0    3    5
# [3,]    2    3    0    6
# [4,]    4    5    6    0

Upvotes: 2

Related Questions