0
votes

I am working on a social network analysis assignment and need to create a network from a matrix. I'm trying to create a matrix that shows what classes people have in common.

My original data looks something like this:

Last.Name <- c("A", "B", "C", "D")
email <- c("abdn@gmail.com", "anfgd@gmail.com", "ahdg@gmail.com", "resd@gmail.com)
Class.1 <- c("ABC101", "ABC364", "ABC103", "ABC354")
Class.2 <- c("ABC201", "ABC204", "ABC207", "ABC624")
Class.3 <- c("ABC223", "ABC267", "ABC103", "ABC354")

I have wrangled the original data into a matrix and need to transpose it but get the following error:

Error in M1 %*% t(M1) : requires numeric/complex matrix/vector arguments

This is what I have done so far:

library(tidyr)
D1$classes <- 1
D2<- D1 %>% gather(Class.1:Class.6, key = "number", value = "class-names")
D3<- spread(D2, key= "class-names", value= "classes")
D3$email <- NULL 
M1 <- as.matrix(D3)
M1[is.na(M1)] <- 0
M2 <- t(M1)
M3 <- M1 %*% t(M1)

A previous SO question/answer R error message when using t()%*% “requires numeric/complex matrix/vector arguments suggested the following code but I get the same error message.

df2 %>% mutate_if(is.factor, as.character) -> df2
m <- as.matrix(df2)
m2 <- t(m) %*% m 

Any suggestions for where I went wrong and how to resolve this error to get to a correct matrix that shows students connected by classes would be appreciated. Thanks!

1
What are you trying to do with %*% exactly? That's the matrix multiplication operator. You seem to have all text values. Kind of hard to multiply strings. What exactly is the output you desire?MrFlick
I wonder if outer was the intended function, although that would have required specifying a function to handle the two vectors.IRTFM

1 Answers

0
votes

So if you need a matrix showing individuals with shared classes - you can make use of the igraph package, creating a two-mode network of individuals-classes, then projecting it to two one-mode networks of (i)class that share participants and (ii) individuals sharing classes.

Creating the dataframe (I am just using the last names to identify individuals)

library(tidyr) library(igraph)

DF<-cbind(Last.Name,Class.1,Class.2,Class.3)%>%as.data.frame(.,stringsAsFactors=FALSE) D2<- DF %>% gather(Class.1:Class.3, key = "number", value = "class-names")

I disregard the class number (I'm not sure what role the number plays in your problem) and focus on the class code:

D2$number<-NULL

From this dataframe, we can then create the two-mode class-individual network:

g<- graph_from_data_frame(D2, directed=FALSE) plot(g) g2<-simplify(g, remove.multiple = TRUE, remove.loops = TRUE)

The simplify command removes duplicated ties and loops.

We then identify the node types (class/individuals):

V(g2)$type<-V(g2)$name %in% unique(DF$Last.Name)

We can then project this two-mode network into two one-mode networks:

PROJECTION<-bipartite.projection(g2) #two-mode CLASSnet<-PROJECTION[[1]] #one-mode INDnet<-PROJECTION[[2]]#one-mode

We can then extract the matrix from the network of individuals that share classes using: INDmat<-as_adjacency_matrix(INDnet) INDmat<-as.matrix(INDmat)