Les scripts pour réaliser une interface web qui vous permet de représenter votre réseau facebook ? Voir l’article en anglais…

This post follows this post and this other post that, respectively, described how to extract your friendship network from facebook and how to create a Graphical User Interface with **R** and the package **shiny**. In this, I simply provide a graphical user interface made with **shiny** to display your facebook network, with different options for representing the nodes (color, size…). The initial function commented on this post to collect information from your facebook network was re-written due to a recent change in the facebook graph API.

An example of how the application works is provided in this movie:

and the application may be testable here (where it is hosted by rstudio but I don’t know for sure how the application might react to many simultaneous connections because gathering the information from facebook takes several minutes at each time so you’d better be patient…).

## Installing necessary packages

In this example, I am using several packages: **shiny** (now available on CRAN repositories), **igraph** to manipulate networks, **RCurl** and **rjson** to import and extract data from facebook and finally, **RColorBrewer** to better handle colors.

`ui.R`

The file `ui.R`

contains the description of the interface: mine is made of a left hand side panel where the options are set by the user (the access token pasted from the facebook graph API explorer and the meaning of node color, size and label) and of a right hand side panel where the results are displayed. The main functions used in this panel are:

`textInput`

to obtain a character string from the user (here, the facebook access token);`selectInput`

to make the user select an option from a list (here, meaning of the node color, size and label);`checkboxInput`

to display a checkbox clickable by the user;`p`

,`br()`

and`HTML`

for various HTML tags that can be used to print free text.

The interface also contains a right hand side panel, which is the main panel where the results are displayed. Thanks to the function `conditionalPanel`

, this panel displays a short user guide until an access token is given. Then, the main panel is divided into two tabs to organize outputs in a graphical part (where the network is displayed) and a statistical parts (where simple facts about the network are summarized). The outputs are displayed by using the functions `plotOutput`

(that displays a graph coming from the `server.R`

script and referenced by a name, here `graph`

) and `tableOutput`

(that displays a data frame coming from the `server.R`

script and referenced by a name, here `stats`

).

The full script is given below:

```
shinyUI(pageWithSidebar(
# Title of the application
headerPanel("Visualize your facebook network..."),
# Left hand side panel
sidebarPanel(
textInput("token",strong("Copy your access token here:"), ""),
selectInput("ncol", "Node color represents:",choices = c("community","betweenness","degree","uniform")),
selectInput("nsize", "Node size represents:",choices = c("degree","betweenness","uniform")),
selectInput("nname","Node names are:",choices=c("initials","facebook id","names")),
checkboxInput("lcc"," Only the largest connected component is displayed.",TRUE),
br(),
p(HTML("Script sources and explanations can be found on my blog.")),
p(HTML("This application is kindly provided by
```**tuxette** ;-)"))
),
# Right hand side panel
mainPanel(
# If the "token" text area is empty
conditionalPanel(
condition = "input.token == '' ",
h4("Basic user guide"),
p("To visualize your facebook network, please go to ", a("the facebook graph API Explorer", href="https://developers.facebook.com/tools/explorer")," to generate a token and copy it in the field on the left hand side panel. Do not forget to select proper permissions to give you access to your friends' data."),
p("You may wait for a long time for the first network to be displayed (until all your data are collected from facebook) and then you can change the way the network is displayed by selecting various options for the node colors, size and label.")
),
# If the "token" text area is not empty
conditionalPanel(
condition = "input.token != '' ",
tabsetPanel(
tabPanel("Chart",p(HTML("Wait a few minutes... I'm working...")),plotOutput("chart")),
tabPanel("Statistics",tableOutput("stats"))
)
)
)
))

`server.R`

The `server.R`

script reacts to changes in the input collected in the `ui.R`

(each referenced by a label and useable with `input$LABEL`

in the `server.R`

script) and calculates outputs that can be numerical values, data frames, charts… This script is made of 5 main functions:

`facebook`

is the generic function to collect information through the facebook graph API;`fb.friends`

uses`facebook`

and the access token provided by the user to collect the list of friends. It is a reactive function, i.e., a function that reats to changes in the user’s input options;`mainnet`

uses`facebook`

and the access token provided by the user to collect the information about mutual friendship among your friends. It is also a reactive function;`output$chart`

uses the two functions`fb.friends`

and`mainnet`

to define a network and then to display it accordingly to the options specified by the user. It uses the package**igraph**to manipulate networks and it is also a reactive function that reacts to changes in the options chosen for representing the network;`output$stats`

uses the two functions`fb.friends`

and`mainnet`

to define a network and then to calculate simple statistics. Mine told me that my network contains 150 friends among which**Sabrina**is the one who is the most connected.

The full script is given below:

```
library(RCurl)
library(rjson)
library(igraph)
library(RColorBrewer)
# Generic function that collects data from facebook through the 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 ) )
print(sprintf( "https://graph.facebook.com/%s%s/?access_token=%s",
path, options, access_token ))
fromJSON( data )
}
# Shiny ouputs calculation
shinyServer(function(input, output) {
# Collect information about the friends on facebook
fb.friends = reactive(function(){
friends = facebook( path="me/friends" , access_token=input$token)
friends.id = sapply(friends$data, function(x) x$id)
friends.name = sapply(friends$data, function(x) iconv(x$name,"UTF-8","ASCII//TRANSLIT"))
initials = function(x) paste(substr(x,3,3), collapse=" ")
friends.initial = sapply(strsplit(friends.name," "), initials)
list("initials"=friends.initial,"name"=friends.name,"fbid"=friends.id)
})
# Collect mutual friendship information on facebook
mainnet = reactive(function() {
the.friends = fb.friends()
N = length(the.friends$initials)
friendship.matrix = matrix(0,N,N)
for (i in 1:N) {
tmp = facebook( path=paste("me/mutualfriends", the.friends$fbid[i], sep="/") , access_token=input$token)
mutualfriends = sapply(tmp$data, function(x) x$id)
friendship.matrix[i,the.friends$fbid %in% mutualfriends] = 1
}
colnames(friendship.matrix) = the.friends$name
rownames(friendship.matrix) = the.friends$name
friendship.matrix
})
# Display the network
output$chart = reactivePlot(function() {
the.friends = fb.friends()
adj = mainnet()
the.full.graph = graph.adjacency(adj,mode="undirected")
V(the.full.graph)$initials = the.friends$initials
V(the.full.graph)$fbid = the.friends$fbid
if (input$lcc) {
the.clusters = clusters(the.full.graph)
the.graph = induced.subgraph(the.full.graph,which(the.clusters$membership==which.max(the.clusters$csize)))
} else {
the.graph = the.full.graph
}
if (input$ncol=="uniform") {
V(the.graph)$color = rep("seagreen",vcount(the.graph))
} else if (input$ncol=="degree") {
dclust = cut(degree(the.graph),9,label=F)
V(the.graph)$color = brewer.pal(9,"YlOrRd")[dclust]
} else if (input$ncol=="betweenness") {
bclust = cut(betweenness(the.graph),9,label=F)
V(the.graph)$color = brewer.pal(9,"YlOrRd")[bclust]
} else if (input$ncol=="community") {
all.cc = clusters(the.graph)
lcc = induced.subgraph(the.graph,which(all.cc$membership==which.max(all.cc$csize)))
clust = multilevel.community(lcc)
V(the.graph)$color = rep("yellow",vcount(the.graph))
V(the.graph)$color[match(clust$names,V(the.graph)$name)] = brewer.pal(12,"Paired")[clust$membership]
}
if (input$nsize=="degree") {
vsize = degree(the.graph)/max(degree(the.graph))*8
} else if (input$nsize=="betweenness") {
vsize = betweenness(the.graph)/max(betweenness(the.graph))*8
} else if (input$nsize=="uniform") {
vsize = rep(5,vcount(the.graph))
}
if (input$nname=="names") {
vname = V(the.graph)$name
} else if (input$nname=="facebook id") {
vname = V(the.graph)$fbid
} else if (input$nname=="initials") {
vname = V(the.graph)$initials
}
par(mar=rep(0,4))
set.seed(21121444)
plot(the.graph,layout=layout.auto,vertex.label=vname,vertex.label.font=1,vertex.label.color="black",vertex.color=V(the.graph)$color, vertex.frame.color=V(the.graph)$color,vertex.size=vsize)
})
# Calculate basic statistics
output$stats = reactiveTable(function() {
the.friends = fb.friends()
adj = mainnet()
the.full.graph = graph.adjacency(adj,mode="undirected")
deg = degree(the.full.graph)
the.bet = betweenness(the.full.graph)
data.frame(
Statistics = c("Number of friends", "Density", "Transitivity", "Average degree", "Max degree", "Average betweenness", "Max betweenness", "Best degree", "Best betweenness"),
Values = as.character(c(vcount(the.full.graph), paste(round(graph.density(the.full.graph)*100,0),"%",collapse=" "), paste(round(transitivity(the.full.graph)*100,0),"%",collapse=" "), round(mean(deg),1), max(deg), round(mean(the.bet),0), round(max(the.bet),0), names(which.max(deg)), names(which.max(the.bet)))),
stringsAsFactors=FALSE)
})
})
```

In case your would like to use and/or modify this application on your own computer (without the need to rely on the rstudio server), make sure all the necessary packages are installed, then copy/paste the two scripts `ui.R`

and `server.R`

in given directory (for instance, “DIR”) and, in **R**, run

```
library(shiny)
runApp("PATH2DIR/DIR")
```

where “PATH2DIR” is the path from your working directory to “DIR”.