I recently thought about ways to visualize medications and their co-occurences in a group of children. As long as you want to visualize up to 4 different medications you can simply use Venn diagrams. There is a very nice R-package to generate these kind of graphics for you (for a description see: Chen and Boutros, 2011). But this is of little help here.

The problem I faced involved 29 different medications and 50 children. So my data was stored in a table with 29 columns – one for each medication – and 50 rows – one for each child, so that the cells indicate whether or not the child took the medication.

M <- matrix(sample(0:1, 1450, replace=TRUE, prob=c(0.9,0.1)), nc=29)

### The Solution – Social Network Analysis

There are a several R-packages to analyze and visualize social network data – I will focus on “igraph” in this post. The problem I had was that I was not – and probably I am still not – familiar with the concepts and nomenclature of this field. The key to using the data described above in terms of network analysis was understanding that such data is called an **affiliation matrix**, where individuals are affiliated with certain events. As “igraph” likes **adjacency matrices**, where every column and row represents a different node – in our case a medication. The diagonal gives the number of times a medication was given (more information can be found on Daizaburo Shizuka site).

We transform an affilition matrix into an adjacency matrix in R simply by:

adj=M%*%t(M)

Now we can make a first bare-minimum plot:

require(igraph)

g=graph.adjacency(adj,mode=”undirected”, weighted=TRUE,diag=FALSE)

summary(g)

plot(g, main=”The bare minimum”)

### Adding information and spicing it up a notch

In all likelihood You want to add at least three kinds of information:

- Labels for the nodes
- Size of the nodes to represent the total number of events, aka medications
- Size of the links to represent the overlap between medications

name<-sample(c(LETTERS, letters, 1:99), 29, replace=TRUE)

number<-diag(adj)*5+5

width<-(E(g)$weight/2)+1

plot(g, main=”A little more information”, vertex.size=number,vertex.label=name,edge.width=width)

The “igraph” package lets you adopt quite a few parameters so you should consult with the manual. I only changed some of the colors, layout, fonts, etc.

plot(g, main=”Spice it up a notch”, vertex.size=number, vertex.label=name, edge.width=width, layout=layout.lgl, vertex.color=”red”, edge.color=”darkgrey”, vertex.label.family =”sans”, vertex.label.color=”black”)

Here is just the code:

^{?}View Code RSPLUS

require(igraph) setwd("~/Desktop/") # Generate example data M <- matrix(sample(0:1, 1450, replace=TRUE, prob=c(0.9,0.1)), nc=29) # Transform matrices adj=M%*%t(M) # Make a simple plot g<-graph.adjacency(adj,mode="undirected", weighted=TRUE,diag=FALSE) summary(g) plot(g, main="The bare minimum") # Add more information name<-sample(c(LETTERS, letters, 1:99), 29, replace=TRUE) number<-diag(adj)*5+5 width<-(E(g)$weight/2)+1 plot(g, main="A little more information", vertex.size=number,vertex.label=name,edge.width=width) # Adjust some plotting parameters plot(g, main="Spice it up a notch", vertex.size=number, vertex.label=name, edge.width=width, layout=layout.lgl, vertex.color="red", edge.color="darkgrey", vertex.label.family ="sans", vertex.label.color="black") |

efriqueVenn diagrams exist for more than four variables:

http://en.wikipedia.org/wiki/Venn_diagram

gives 3 different examples of 5-variable ones and two 6-variable ones.

Nathan VanHoudnosInstead of defining a relationship between drugs as a single co-occurrence, you might consider estimating the conditional independence structure with log linear graphical models. This will give you simpler, more interpret-able visualizations.

A useful book by the people who developed the gRim package for R. A free preview of a relevant chapter of the book. See section 2.4 Model Selection, for an example of the kinds of thing this approach is good for.

EvanZMy personal preference would be to calculate a correlation matrix and plug it into the heatmap() function. With the network diagram, especially one with so many edges, there’s no practical way to actually investigate the connections between individual nodes. With the heatmap/dendrogram approach, your eyes are able to quickly pick up important relationships between variables.

EvanZI should amend my comment to say, for small networks this approach makes sense if you want to see two variables (i.e. node and edge weights). Can’t do that with the heatmap approach (afaik).

gerhiPost authorHi,

just found a small typo. The correct adjacency matrix for medications is generated with:

adj=t(M)%*%M.

The one in the script, i.e. adj=M%*%t(M), generates a matrix for the participants.