Last week, I came across two interesting posts by Romain François and Petr Simecek:
As coincidence would have it, I also came across an older introductory post about social network analysis (Grey’s Anatomy Network of Sexual Relations) which could actually complement quite well the two posts above.
Using the igraph package, it is very easy to use the Girvan-Newman algorithm to automatically detect your groups/clusters of friends. The code below show how to display the names of your friends on the plot.
Here is the full code to create the chart above:
require(igraph) | |
require(RCurl) | |
require(rjson) | |
# Insert your own token | |
access_token <- '****' | |
# Romain François's function to connect to Facebook Graph API | |
facebook <- function( path = "me", access_token = token, options) { | |
if( !missing(options) ){ | |
options <- sprintf( "?%s", paste( names(options), "=", unlist(options), collapse = "&", sep = "" ) ) | |
} else { | |
options <- "" | |
} | |
data <- getURL( sprintf( "https://graph.facebook.com/%s%s&access_token=%s", path, options, access_token ) ) | |
fromJSON( data ) | |
} | |
# Petr Simecek's code to retrieve friends' relationships | |
# scrape the list of friends | |
friends <- facebook( path="me/friends" , access_token=access_token) | |
# extract Facebook IDs | |
friends.id <- sapply(friends$data, function(x) x$id) | |
# extract names | |
friends.name <- sapply(friends$data, function(x) iconv(x$name,"UTF-8","ASCII//TRANSLIT")) | |
# short names to initials | |
initials <- function(x) paste(substr(x,1,1), collapse="") | |
friends.initial <- sapply(strsplit(friends.name," "), initials) | |
# friendship relation matrix | |
N <- length(friends.id) | |
friendship.matrix <- matrix(0,N,N,dimnames=list(friends.id, friends.id)) | |
for (i in 1:N) { | |
tmp <- facebook( path=paste("me/mutualfriends", friends.id[i], sep="/") , access_token=access_token) | |
mutualfriends <- sapply(tmp$data, function(x) x$id) | |
friendship.matrix[i,friends.id %in% mutualfriends] <- 1 | |
} | |
ga.data <- do.call(rbind, lapply(1:N, function(i) { | |
do.call(rbind, lapply(1:N, function(j) { | |
if(friendship.matrix[i,j]==1) return(data.frame(from=friends.name[i], to=friends.name[j])) | |
})) | |
})) | |
# Gary's code for social network analysis and clustering | |
g <- graph.data.frame(ga.data, directed=FALSE) | |
gnc <- edge.betweenness.community(g, directed=FALSE) | |
m <- vector() | |
for (s in 0:nrow(gnc$merges) ) { | |
memb <- community.to.membership(g,gnc$merge,steps=s)$membership | |
m <- c(m,modularity (g, memb, weights=NULL)) | |
} | |
ideal <- steps <- which(m==max(m)) - 1 | |
gn.groups <- community.to.membership(g,gnc$merge, steps=ideal <- steps)$membership | |
V(g)$color <- gn.groups | |
#V(g)$label <- V(g)$name # this is to show the friends' name on the plot | |
V(g)$label <- NA | |
V(g)$size <- 3 | |
png('friendscluster.png') | |
plot(g) | |
dev.off() |
Enjoy