0

I am working with an undirected graph. I am looking to plot the graph, and colour those nodes that satisfy some criteria.

I have a dataframe containing edges that are bad and good. Good edges I set the column color = darkgrey, bad edgeds color = red

My edgelist looks like:

      from     to    color
1    54770  54771 darkgrey
2    54770  54775 darkgrey
3    54770  54776 darkgrey
4    54770  54774 darkgrey
5    54771  54775 darkgrey
6    54771  54776 darkgrey
7    54771  54774      red
8    54775  54776 darkgrey
9    54775  54774 darkgrey
10   54776  54774 darkgrey
11  110780 110781      red

(to do this I run the following line on a column dob_diff):

df$color <- with(df, ifelse(dob_diff <= 168), "red", "darkgrey"))

I can plot the graph:

g = graph.data.frame(df, directed=FALSE)
plot(graph)

enter image description here

I can return a list of the index of those edges that are bad by doing:

a <- which(df$colour == "red") 
> a
 [1]   7  11

How can I take these edges and then colour those nodes which are connected to the bad edges?

This question here indicates you can access a node colour by its number

V(g)$color[6] <- "red" 

How can I tell igraph to take a list of edges?

Edit: For example:

I can return a list of those nodes that are incorrect:

> from <- cluster_data_updated_illegal_combined[c("from")][cluster_data_updated_illegal_combined$illegal_dob == 1,]
> to <- cluster_data_updated_illegal_combined[c("to")][cluster_data_updated_illegal_combined$illegal_dob == 1,]

> from
 [1] "54771"  "110780" "20285"  "83962"  "88825"  "19695"  "33343"  "89446"  "90175"  "98032"  "115768"
[12] "1982"   "71327"  "75017"  "75018"  "89315"  "89316"  "106277" "106956" "111140" "32841"  "72276" 
[23] "111062" "111074" "1904"   "12148"  "17325"  "17412"  "18238"  "18368"  "19681"  "28041"  "30755" 
[34] "31915"  "32825"  "43791"  "54806"  "54808"  "87075"  "94814"  "97877"  "101124" "102311" "107659"
[45] "108778" "108906" "112029" "120840" "127396" "33371"  "90150"  "111095" "122230"
> to
 [1] "54774"  "110781" "20693"  "83961"  "88565"  "20338"  "33340"  "91043"  "90171"  "98035"  "115771"
[12] "1976"   "71439"  "75019"  "75020"  "89929"  "89929"  "106279" "107489" "111139" "32993"  "72272" 
[23] "111060" "111071" "2697"   "12090"  "17323"  "17413"  "20300"  "18561"  "20025"  "28046"  "30744" 
[34] "31587"  "33113"  "44067"  "54799"  "54803"  "87073"  "94816"  "97872"  "101122" "103480" "107679"
[45] "109013" "109256" "112246" "120842" "127401" "32679"  "90259"  "111028" "122228"

I then try to colour the graph red for those nodes but I get an error:

> V(gg)[from]$color<-"red"
Error in unclass(x)[i] : invalid subscript type 'closure'
> V(gg)[to]$color<-"red"
Error in unclass(x)[i] : invalid subscript type 'closure'
Chuck
  • 3,664
  • 7
  • 42
  • 76
  • Side note: In future posts, I suggest you to #1 provide your data using `dput` or `read.table` (see my answer) or something similar, which makes it convenient for readers to reproduce your problem; #2 cut out the fat (less text/more to the point, remove everything that is not relevant for the question, like all the `plot` arguments, ...). – lukeA Nov 24 '17 at 09:59

1 Answers1

1

What you got:

Your edgelist looks like this:

df <- read.table(header=T, text=" from     to    color
1    54770  54771 darkgrey
2    54770  54775 darkgrey
3    54770  54776 darkgrey
4    54770  54774 darkgrey
5    54771  54775 darkgrey
6    54771  54776 darkgrey
7    54771  54774      red
8    54775  54776 darkgrey
9    54775  54774 darkgrey
10   54776  54774 darkgrey
11  110780 110781      red")

This is the graph:

library(igraph)
g = graph.data.frame(df, directed=FALSE)
plot(g)

These are the indices of red ("bad") edges in your data frame:

which(df$color == "red") 
# [1]   7  11

Your questions:

How can I take these edges and then colour those nodes which are connected to the bad edges?

Here's one way to color the nodes, which are connected to the red edges:

vertices <- union(
  head_of(g, which(E(g)$color == "red")), 
  tail_of(g, which(E(g)$color == "red"))
)
plot(g, vertex.color = ifelse(V(g) %in% vertices, 6, 1))

enter image description here

See e.g. ?head_of. There might be other/better ways.

Is there another column I can create with a different name that igraph can use to auto colour the nodes?

You can assign a color attribute to vertices V(g)as well as to edges E(g):

V(g)$color <- (V(g) %in% vertices) + 1L
plot(g)

enter image description here

lukeA
  • 53,097
  • 5
  • 97
  • 100
  • Thank you lukeA. This is perfect. I appreciate your bearing with the jumbled-ness of the original Q. – Chuck Nov 24 '17 at 10:26
  • @Chuck It's short for `as.integer(V(g) %in% vertices) + 1L`. `V(g) %in% vertices` gives a logical vector (TRUE/FALSE values), which is not suitable for color coding. When converting to numeric, FALSE gives 0, which is white (or transparent) in the default palette from igraph. 1, the standard, is orange, and 2 is blue. Adding 1 just prevents white vertices. The `L` indicates integer, `1` alone would be numeric. – lukeA Nov 24 '17 at 12:01
  • Thanks Luke. Appreciate it. – Chuck Nov 24 '17 at 12:10