2

I'd like to convert a size n factor into a n×n binary matrix whose (i, j) element is 1 if i-th and j-th element of factor are same and 0 otherwise.

The following is a naive way to implement what I want to do but this code is quite slow. Is there any more efficient way to do the same thing?

size <- 100
id <- factor(sample(3, size, replace=TRUE))
mat <- matrix(0, nrow=size, ncol=size)

for(i in 1:size){
  for(j in 1:size){
    if(id[i] == id[j]){
      mat[i, j] <- 1
    }
  }
}
2
  • Sorry I mistook copy-and-paste. Commented Jul 17, 2017 at 10:17
  • 2
    And instead of if(...) just do mat[i, j] <- (id[i] == id[j]) + 0L. Commented Jul 17, 2017 at 10:26

2 Answers 2

4

Another alternative, which should be relatively fast

tcrossprod(model.matrix( ~ id + 0))

Similarly to Hong Ooi's answer you can use also sparse matrices

library(Matrix)
tcrossprod(sparse.model.matrix( ~ id + 0)) 
Sign up to request clarification or add additional context in comments.

Comments

3

outer can be used for this.

mat <- outer(id, id, "==")

Since the output is a binary matrix, and O(N^2) objects are kind of large, this is a good use case for sparse matrices:

library(Matrix)
mat <- Matrix(nrow=100, ncol=100)
mat[] <- outer(id, id, "==")  # [] means to assign into the existing 'mat' matrix

2 Comments

It's interesting way to use tensordot. Thanks!
Good answer, but you are not in any way making use of sparse matrices.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.