views:

456

answers:

2

A few years back I used UCINET for some social network analysis. Theese days I'd like to use SNA again - but this time I prefer a unified analysis framework - which for me is R.

I have looked at the sna and statnet documentation but am a bit overwhelmed.

What I'd like to do: First: Load an bipartite/incidence matrix pulled directly from e.g. a websurvey (often valued). Convert this matrix to two adjacency matrix' (affiliatoin by affiliation and cases by cases). It could also be a directed, valued cases by cases matrix.

Second: Load a file (also from e.g. websurvey data) of vertice attributes.

Third: Then plot the graph with e.g. vertice size according to some centrality measure, colored and labeled by some vertice attributes, with only edges with value over a certain threshold being drawn.

This is a mini incidence matrix:

data <- structure(list(this = c(0, 1, 0, 1, 1, 2, 0, 1, 3), 
 that = c(1, 1, 3, 0, 0, 0, 2, 1, 0), 
 phat = c(0, 0, 2, 1, 0, 0, 1, 2, 0)), 
 .Names = c("this", "that", "phat"), 
 row.names = c("a", "b", "c", "d", "e", "f", "g", "h", "i"), 
 class = "data.frame")

with som attribute data:

att <-structure(list(sex = structure(c(1L, 1L, 2L, 2L, 1L, 2L, 1L, 
1L, 1L), .Label = c("F", "M"), class = "factor"), agegr = c(1L, 
1L, 3L, 1L, 3L, 1L, 1L, 3L, 1L), place = structure(c(1L, 2L, 
1L, 1L, 1L, 1L, 2L, 2L, 1L), .Label = c("Lower", "Upper"), 
class = "factor")), .Names  = c("sex", 
"agegr", "place"), row.names = c(NA, -9L), class = "data.frame")

p.s. maybe SNA would be a good tag for this post? I just don't have the nescassary SO goodwill :-)

+2  A: 

This doesn't directly answer your question, but I strongly recommend watching Drew Conway's presentation on SNA in R if you haven't already seen it.

Shane
+5  A: 

This is a good question, and provides some opportunity for further exploration of SNA in R. I am more familiar with the igraph package, so I will answer your question using the the functions in that library.

The first part of your question has a fairly straightforward solution:

# Convert data frame to graph using incidence matrix
G<-graph.incidence(as.matrix(data),weighted=TRUE,directed=FALSE)
summary(G)
# Vertices: 12 
# Edges: 30 
# Directed: TRUE 
# No graph attributes.
# Vertex attributes: type, name.
# Edge attributes: weight.

This returns a graph object with undirected and weighted edges from the incidence matrix. To generate the affiliations graphs from the bipartite graph you have two options. The quick and easy one is this:

proj<-bipartite.projection(G)

This will return a list with each projection indexed as $proj1 and proj2, the unfortunate thing is that these projects do not contain the edge weights that you would normally want when performing this manipulation. To do this the best solution is to simply perform the matrix multiplication yourself.

# Create the matrices, and set diagonals to zero
M<-as.matrix(data)
affil.matrix<-M%*%t(M)
diag(affil.matrix)<-0
cases.matrix<-t(M)%*%M
diag(cases.matrix)<-0
# Create graph objects from matrices
affil.graph<-graph.incidence(affil.matrix,weighted=TRUE)
cases.graph<-graph.incidence(cases.matrix,weighted=TRUE)

Generating the plots with the attribute data is a bit trickier and requires more coding, but I recommend looking through some of the igraph examples, or even some of my own as there is plenty there to get you started. Good luck!

DrewConway