3

I want to make a network object for igraph from a event-note data.

For example, I have a data looks like this.

 Event  Person
  1     Obama
  1     Putin
  1     Abe
  1     Cameron 
  2     Putin
  2     Xi
  2     Merkel
  3     Obama
  3     Abe
  3     Xi
  3     Merkel

I assume everybody in same event has connections. Obama, Putin, Abe, and Cameron have connections, because they are all in event 1. Based on this data, Obama and Abe have two times of connection because they are both in event 1 and 3.

With this data, I want to calculate degree / betweenness / closeness centrality. To calculate these centralities, I need to have a graph object. How can I create a graph object or adjacency matrix to calculate three centrality measures?

I am sorry for this basic question, but I am new to using R for network analysis.

Thank you in advance!

user3077008
  • 837
  • 4
  • 13
  • 24

2 Answers2

6

This is a bipartite graph, and what you want is its projection.

txt <- "Event  Person
          1     Obama
          1     Putin
          1     Abe
          1     Cameron 
          2     Putin
          2     Xi
          2     Merkel
          3     Obama
          3     Abe
          3     Xi
          3     Merkel
"

data <- read.table(textConnection(txt), header = TRUE)
BG <- graph.data.frame(data, directed = FALSE)
V(BG)$type <- grepl("^[0-9]+$", V(BG)$name)

bipartite.projection(BG)[[1]]
#> IGRAPH UNW- 6 13 -- 
#> + attr: name (v/c), weight (e/n)
#> + edges (vertex names):
#>  [1] Obama--Putin   Obama--Abe     Obama--Cameron Obama--Xi      Obama--Merkel 
#>  [6] Putin--Abe     Putin--Cameron Putin--Xi      Putin--Merkel  Abe  --Cameron
#> [11] Abe  --Xi      Abe  --Merkel  Xi   --Merkel 
Gabor Csardi
  • 10,705
  • 1
  • 36
  • 53
3

Assuming you read your data into a data.frame named dd, you can get an adjacent matrix with

X <- with(dd, table(Event, Person))
adj <- crossprod(X,X)

#          Person
# Person    Abe Cameron Merkel Obama Putin Xi
#   Abe       2       1      1     2     1  1
#   Cameron   1       1      0     1     1  0
#   Merkel    1       0      2     1     1  2
#   Obama     2       1      1     2     1  1
#   Putin     1       1      1     1     2  1
#   Xi        1       0      2     1     1  2

You have a few options on how you want to turn that into a graph object, but you'd most likely use graph.adjacency. Here's one way

gg<-graph.adjacency(adj, mode="upper", weighted=TRUE, diag=FALSE);
plot(gg,  edge.width=E(gg)$weight)

enter image description here

MrFlick
  • 195,160
  • 17
  • 277
  • 295