1

The question R DataFrame into square (symmetric) matrix is about transforming a data frame into a symmetric matrix given the following example:

# data
x <- structure(c(1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), 
                 .Dim = c(3L,5L), 
                 .Dimnames = list(c("X", "Y", "Z"), c("A", "B", "C", "D", "E")))

x
#  A B C D E
#X 1 1 0 0 0
#Y 1 1 0 0 0
#Z 0 0 0 1 0

# transformation
x <- x %*% t(x)
diag(x) <- 1

x
#  X Y Z
#X 1 2 0
#Y 2 1 0
#Z 0 0 1

Now, I'm trying to keep the columns c("A", "B", "C", "D", "E") in the matrix, like this:

#  X Y Z A B C D E
#X 1 0 0 1 1 0 0 0
#Y 0 1 0 1 1 0 0 0
#Z 0 0 1 0 0 0 1 0
#A 1 1 0 1 0 0 0 0
#B 1 1 0 0 1 0 0 0
#C 0 0 0 0 0 1 0 0
#D 0 0 1 0 0 0 1 0
#E 0 0 0 0 0 0 0 1

I'm pretty sure there's an easy way to do it similar to the first transformation including each case. Can anyone suggest a solution?

Thank you in advance!

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
alex_555
  • 1,092
  • 1
  • 14
  • 27

2 Answers2

3

This is just an augmentation, isn't it?

X <- as.matrix(x)
rbind(cbind(diag(nrow(X)), X), cbind(t(X), diag(ncol(X))))
Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
  • use this from by code: `colnames(m) = rownames(m) = c(rownames(x),colnames(x))` – Andre Elrico Aug 01 '18 at 09:50
  • Great and very short, thanks! Works pretty well! You're right, it's just augmentation. I really overthought the problem, which confused me a bit. Problem solved! – alex_555 Aug 01 '18 at 10:31
1

build it step by step: thanks to @李哲源 for pointing out m <- diag(sum(dim(x))).

m <- diag(sum(dim(x)))
colnames(m) = rownames(m) = c(rownames(x),colnames(x))
m[dimnames(x)[[1]],dimnames(x)[[2]]] <- x
m[dimnames(x)[[2]],dimnames(x)[[1]]] <- t(x)

#  X Y Z A B C D E
#X 1 0 0 1 1 0 0 0
#Y 0 1 0 1 1 0 0 0
#Z 0 0 1 0 0 0 1 0
#A 1 1 0 1 0 0 0 0
#B 1 1 0 0 1 0 0 0
#C 0 0 0 0 0 1 0 0
#D 0 0 1 0 0 0 1 0
#E 0 0 0 0 0 0 0 1

You can wrap it into a function and then call it:

makeSymMat <-function(x) {
    x <- as.matrix(x)
    m <- diag(sum(dim(x)))
    colnames(m) = rownames(m) = c(rownames(x),colnames(x))
    m[dimnames(x)[[1]],dimnames(x)[[2]]] <- x
    m[dimnames(x)[[2]],dimnames(x)[[1]]] <- t(x)
    return(m)
}

makeSymMat(x)
Andre Elrico
  • 10,956
  • 6
  • 50
  • 69