How to generate an individual adjacency matrix from a group adjacency matrix, in r

I have an adjacency matrix representing species by species interactions (a tri-trophic chain):

mat = matrix(c(0,1,0,
               0,0,1,
               0,0,0), nrow=3, byrow = T,
             dimnames = list(c("sp1","sp2","sp3"),
                             c("sp1","sp2","sp3")))

and a dataframe that contains the species' abundances:

comm = t(data.frame(sp1=100,
                    sp2=20,
                    sp3=5))

Using the above, is there an efficient way to create an individual based adjacency matrix?

in.mat = matrix(0, nrow = sum(comm),
               ncol = sum(comm),
            byrow = T,
            dimnames = list(c(rep("sp1",100),rep("sp2",20),rep("sp3",5)),
                            c(rep("sp1",100),rep("sp2",20),rep("sp3",5))))

So that all individuals of sp3 are connected with all individuals from sp2 and those with all individuals of sp1. I would appreciate any pointers, I have not managed to find similar questions, perhaps because I am not using the appropriate terms.


To illustrate we will use a smaller example shown in the Note at the end but the same code would work with the example in the question. No packages are used except as indicated.

1) Expand the names into nms and then use subscripting.

nms <- rep(rownames(comm), comm)
mat[nms, nms]
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
##  [1,]    0    0    1    1    1    0    0    0    0
##  [2,]    0    0    1    1    1    0    0    0    0
##  [3,]    0    0    0    0    0    1    1    1    1
##  [4,]    0    0    0    0    0    1    1    1    1
##  [5,]    0    0    0    0    0    1    1    1    1
##  [6,]    0    0    0    0    0    0    0    0    0
##  [7,]    0    0    0    0    0    0    0    0    0
##  [8,]    0    0    0    0    0    0    0    0    0
##  [9,]    0    0    0    0    0    0    0    0    0

2) Another approach using nms as above is to use one of these:

outer(nms, nms, function(x, y) mat[cbind(x, y)])

outer(nms, nms, Vectorize(function(x, y) mat[x, y]))

sapply(nms, function(y) sapply(nms, function(x) mat[x, y]))

library(listcompr)
gen.matrix(mat[x, y], x = nms, y = nms)

The eList or comprehenr packages could also be used.

Note

# input
sp <- paste0("sp", 1:3)
mat <- matrix(c(0,0,0,1,0,0,0,1,0), 3, dimnames = list(sp, sp))
comm <- matrix(2:4, 3, dimnames = list(sp, NULL))

mat
##     sp1 sp2 sp3
## sp1   0   1   0
## sp2   0   0   1
## sp3   0   0   0

comm
##     [,1]
## sp1    2
## sp2    3
## sp3    4