Search code examples
igraphsocial-networkingadjacency-matrixbipartitenetwork-analysis

How to create a one-mode network (adjacency matrix) based on matches from two-mode network


I'm working with a survey data (row=respondents; col=opinion) and trying to create a one-mode adjacency matrix among respondents that measures the number of times they gave the same answers for each dyad network. Specifically,

affiliation_matrix <- matrix(c(
  0,1,0,
  1,0,0,
  0,1,1
)
,nrow=3
,ncol=3,
byrow=TRUE)

dimnames(affiliation_matrix) <- list(
  c("Alyssa", "Brad", "Carla"),
  c("opinion1", "opinion2", "opinion3")
)

affiliation_matrix

In the above example of 3x3 matrix, I'd like to create a matrix that looks like

ideal_matrix <- matrix(c(
  1,1,2,
  1,1,0,
  2,0,2
)
,nrow=3
,ncol=3,
byrow=TRUE)

dimnames(ideal_matrix) <- list(
  c("Alyssa", "Brad", "Carla"),
  c("Alyssa", "Brad", "Carla")
)

So between Alyssa and Carla, their connection gets a 2 because they both answered the same for opinion1 and opinion2. Similarly, the connection between Alyssa and Brad gets a 1 because they both answered 0 in opinion3.

I was looking up the code get.adjacency() and bipartite.projection but this one seems to only deal with person-event network where only the value of 1 is treated as a match. Is there an R package that lets me do this, or do I need to create my own loop manually (if so... how??)?

Thanks!!


Solution

  • There might be an off-the-shelve solution I am not aware of. However, in this particular (binary) case one could recode the matrix, multiply each by its transpose and finally add them together:

    affiliation_matrix_recoded <- affiliation_matrix
    affiliation_matrix_recoded[] <- ifelse(affiliation_matrix_recoded > 0, 0, 1)
    
    a <- tcrossprod(affiliation_matrix)
    b <- tcrossprod(affiliation_matrix_recoded )
    
    r <- a + b
    diag(r) <- 0
    r
    

    Resulting in this:

           Alyssa Brad Carla
    Alyssa      0    1     2
    Brad        1    0     0
    Carla       2    0     0