4

I want to show the connections between a number of people, organizations or whatever:

   Var1 Var2 Freq
1     F    A    5
2     F    B   38
3     B    C   10
4     E    C   28
5     A    D    8
6     B    D   21
7     A    E   50
8     A    F   34
9     D    F   50
10    E    F   14

enter image description here

I couldn't find any examples for this kind of plot, so I started from scratch. However, I'm struggling with the labels for the frequency values. Any ideas how to fix that?

MWE:

### Sample data ###

# Gerate names
names <- LETTERS[1:6]

# Generate all possible permutations
df = expand.grid(rep(list(names), 2))
rownames(df) <- NULL

# Drop some of the permutations
df <- df[df$Var1 != df$Var2, ]
df <- df[-sample(1:nrow(df), nrow(df) * 2/3), ]

# Add a column with random frequency values
df$Freq <- sample(1:50, nrow(df), replace=T)

### Prepare sample data for ggplot ####

# Add a column with the row numbers (used for grouping)
df$Pair <- 1:nrow(df)

# Convert data frame to long format
df.from <- df[, -which(names(df) %in% c("Var2"))]
df.from$Type <- "From"
colnames(df.from) <- c("Name", "Freq", "Pair", "Type")

df.to <- df[, -which(names(df) %in% c("Var1"))]
df.to$Type <- "To"
colnames(df.to) <- c("Name", "Freq", "Pair", "Type")

df2 <- rbind(df.from, df.to)

### Plot ###

library(ggplot2)
library(scales)

p <- ggplot()
p <- p + geom_text(aes(x = "From", y = names, label = names), hjust = 1, vjust = 0.5)
p <- p + geom_text(aes(x = "To", y = names, label = names), hjust = 0, vjust = 0.5)
p <- p + geom_line(data = df2, aes(x = Type, y = Name, group = Pair))
p <- p + geom_text(data = df2[df2$Type == "To", ], aes(x = Type, y = Name, group = Pair, label = Freq), hjust = 3, vjust = 0.5)
p <- p + scale_y_discrete(name = "", limits = rev(factor(names, levels = sort(names))))
p <- p + scale_x_discrete(name = "", limits = c("From", "To"))
p
not_a_number
  • 305
  • 1
  • 6
  • 18
  • 1
    You might find useful these three resources regarding so-called Tufte bump charts or slopegraphs:(1) http://charliepark.org/a-slopegraph-update/ (2) http://learnr.wordpress.com/2009/05/06/ggplot2-bump-chart/; (3) http://stackoverflow.com/questions/25781284/simplest-way-to-plot-changes-in-ranking-between-two-ordered-lists-in-r : – lawyeR Jun 06 '15 at 09:39
  • Not going to be easy without calculating the positions of each label, storing them in df2, finding the collisions, and moving them apart. I suspect you wanted to avoid that. – Mike Wise Jun 06 '15 at 10:32
  • Sorry, but this isn't really a duplicate question. It's related, yes, but it doesn't answer how to properly add the labels. – not_a_number Jun 06 '15 at 21:51

1 Answers1

3

to me the request:

to show the connections between a number of people, organizations or whatever

sounds like a desire to graph the the network plot. Using the network package:

#Construct a sparse graph
m<-matrix(rbinom(100,1,1.5/9),10)
diag(m)<-0
g<-network(m)
#Plot the graph
plot(g)

You could get the following Sample network plot

Alternatively, this may be more relevant to your problem, you may consider making use of the qgraph package. For example the code below:

require(qgraph)
set.seed(1)
adj = matrix(sample(0:1, 10^2, TRUE, prob = c(0.8, 0.2)), nrow = 10, ncol = 10)
qgraph(adj)
title("Unweighted and directed graphs", line = 2.5)

Would return this beautiful network graph: qgrapph example

If you are you looking for more examples just refer to this excellent page by Sacha Epskam on how to use qgraph.

Konrad
  • 17,740
  • 16
  • 106
  • 167