Search code examples
rggraphtidygraph

Adding an attribute column to a tidygraph object


I am trying to figure out how to add attribute data to a tidygraph object specifically for plotting purposes. I can't seem to figure out how take a variable which is associated with a variable level, preserve it when I create a tidygraph object for use later in a plot. So in the reprex below, I'd like to colour by height but the approach escapes me

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tidygraph)
#> 
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(ggraph)
#> Loading required package: ggplot2

starwars_graph <- starwars %>%
  filter(eye_color == "blue") %>% ## trim down the data
  select(species, homeworld,  height) %>%
  na.omit() %>% 
  as_tbl_graph()


ggraph(starwars_graph, layout = "nicely") +
  geom_edge_link() +
  geom_node_label(aes(label = name))


ggraph(starwars_graph, layout = "nicely") +
  geom_edge_link() +
  geom_node_label(aes(label = name, colour = height))
#> Error in FUN(X[[i]], ...): object 'height' not found

Can anyone recommend any good way to add height to this plot?

Created on 2019-03-11 by the reprex package (v0.2.1)


Solution

  • Currently, height is an edge property (a property of each individual person), and in order to create a node property that will apply to the whole species it seems like you'll need to collapse the multiple members of each species down to a single value using the mean:

    sp_heights = starwars %>%
        group_by(species) %>%
        summarise(height = mean(height, na.rm = TRUE))
    
    starwars_graph = starwars_graph %>%
        activate(nodes) %>%
        left_join(sp_heights, by = c("name" = "species"))
    
    ggraph(starwars_graph, layout = "nicely") +
        geom_edge_link() +
        geom_node_label(aes(label = name, colour = height)) +
        scale_color_continuous(na.value = "black")
    

    Output:

    Coloured labels