R: Prepare data for Network Analysis

Viewed 161

I have data with 2 columns: transaction ID and Salesperson Name, where a row represents a transaction and the salesperson who worked on it. Most transactions have more than 1 salesperson so in that case, the transaction ID repeats to list all the salespersons.

I want to create a network viz using the network package in r but am getting stuck on how to format the data. I can get the nodes from doing a unique sort on the names, but not sure how to transform the data to get an edge list. The network is undirected.

My data looks like this:

Trans_ID | Name
--------------------
1        | Andy
1        | Ben
1        | Cindy
2        | David
2        | Eric
3        | Fabian
3        | George
4        | Hector

The real data has about 300k rows of data.

2 Answers

You could join the Trans_ID to create the edges:

library(dplyr)
library(visNetwork)

data <- tibble::tribble(~Trans_ID , ~Name,
1       , "Andy",
1        , "Ben",
1        , "Cindy",
2        , "David",
2        , "Eric",
3        , "Fabian",
3        , "George",
4        , "Hector")


nodes <- data %>% select(Name)  %>% unique() %>% mutate(id = Name, label = Name)
edges <- data %>% inner_join(data, by = c("Trans_ID"="Trans_ID")) %>% 
         filter(Name.x < Name.y) %>%
         mutate(from = Name.x, to = Name.y)


vn <- visNetwork(nodes, edges, height = 1200,width = "100%")  %>% visPhysics(stabilization = FALSE,solver='forceAtlas2Based')
vn 

enter image description here

I am not sure which kind of network you are about to illustrate based on the given data frame. Here is an option using igraph:


  • Plot Name associated with Trans_ID
library(igraph)
g <- graph_from_data_frame(df,directed = FALSE)
V(g)$color <- c("light blue","yellow")[V(g)$name %in% df$Trans_ID + 1]
plot(g,vertex.size = 30)

giving

enter image description here


  • Plot Name only (grouped by Trans_ID)
library(igraph)
DF <- as.data.frame(do.call(rbind,
        with(df,tapply(Name, Trans_ID, function(x) if (length(x)==1) t(rep(x,2)) else t(combn(x,2)) ))))
g <- graph_from_data_frame(DF,directed = FALSE)
plot(simplify(g),vertex.size = 30)

giving enter image description here

Related