Given a data frame as following:
v1 v2 v3 v4 v5
tom A pinky A 3
ben B hugo C 2
lily A tom A 1
...
Which denotes that v1
from group v2
has mentioned v3
from group v4
for v5
times. For instance, tom from group A has mentioned pinky from group A for 3 times. Now I'd like to plot a social network, each user denoted by a point and its size is proportional to the times he or she has been mentioned totally. And there is a line linkage two points if they have mentioned each other mutually or unilaterally.
As I look into the ggplot document, I can not find any function to do it.
Do you have any idea? Thanks in advance!
EDIT:
Here is the graph I get so far:
library(igraph)
library(dplyr)
# create example dataset
dt = data.frame(v1 = c("tom", "ben", "lilly", "mark"),
v2 = c("A","B","A","C"),
v3 = c("pinky", "hugo", "tom", "pinky"),
v4 = c("A","D","A","A"),
v5 = c(20,10,15,15),
stringsAsFactors = F)
dt
# v1 v2 v3 v4 v5
# 1 tom A pinky A 20
# 2 ben B hugo D 10
# 3 lilly A tom A 15
# 4 mark C pinky A 15
# select columns of names to use for the graph
dt_graph = dt %>% select(v1,v3)
# create the graph
g = graph.data.frame(dt_graph)
# count number of times names were mentioned
dt_times_mentioned =
dt %>%
group_by(v3) %>%
summarise(times = sum(v5))
dt_times_mentioned
# v3 times
# (chr) (dbl)
# 1 hugo 10
# 2 pinky 35
# 3 tom 15
# join back to the vertex names to include names in the graph that were not mentioned
dt_weights =
data.frame(names = names(V(g)), stringsAsFactors = F) %>%
left_join(dt_times_mentioned, by=c("names"="v3")) %>%
mutate(times = ifelse(is.na(times), 0, times))
dt_weights
# names times
# 1 tom 15
# 2 ben 0
# 3 lilly 0
# 4 mark 0
# 5 pinky 35
# 6 hugo 10
# create two datasets based on 1st and 2nd column of names
dt1 = dt %>% select(names=v1, group=v2)
dt2 = dt %>% select(names=v3, group=v4)
# get distinct names and their group values
dt_group =
dt1 %>% rbind(dt2) %>% distinct() %>%
mutate(color = colors()[as.numeric(factor(group))+5]) # get colours from group values
#(note that the +5 above is an arbitrary value for this example in order to get colors easy to distinguish. this is not really needed. if you don't have many groups you can manually set the colors)
dt_group
# names group color
# 1 tom A antiquewhite3
# 2 ben B antiquewhite4
# 3 lilly A antiquewhite3
# 4 mark C aquamarine
# 5 pinky A antiquewhite3
# 6 hugo D aquamarine1
# plot the graph
plot(g, vertex.size = dt_weights$times, vertex.color = dt_group$color)
# add legend
legend(1.5, 1.5,
legend=unique(dt_group$group),
pch=19,
col=unique(dt_group$color),
title = "Colors - Groups")