1

I have a network of friendships and I'm trying to plot each ego network that shows only to out nominations of each ego. When I plot the ego network, it includes arrows directed towards ego and edges connecting alters to each other. I'd like to conditionally remove edges not coming from ego. Sample data and code below:

df<-read.table(text="student_id friendid_1    friendid_2    friendid_3    friendid_4
1          3             NA            NA            NA
2          5             2             3             NA
3          2             4             5             NA
4          1             6             NA            3
5          1             NA            6             2
6          5             NA            2             1
7          8             NA            NA            NA
8          NA            9             NA            NA
9          8             7             NA            NA
10         7             9             NA            NA
11         19            15            NA            12
12         20            NA            19            11
13         15            19            11            NA
14         16            NA            12            18
15         17            20            17            NA
16         14            19            20            13
17         20            18            13            14
18         13            NA            19            17
19         17            NA            16            11
20         13            17            11            14", header = TRUE) %>%
           pivot_longer(., 
                        cols = friendid_1:friendid_4) %>%
           select(student_id, alter = value) %>%
           na.omit()


egonet_3 <- graph_from_data_frame(d = df, directed = TRUE) %>% 
            make_ego_graph(., order = 1,  nodes = V(.) %in% c("3"), mode = "out")


as_tbl_graph(egonet_3[[1]]) %>%
  create_layout(., layout = 'fr') %>%
  ggraph(.) + 
  geom_edge_link(color = "black", alpha = 0.7,
                 arrow = arrow(type = "closed",
                              angle = 25,
                              length = unit(1.5, 'mm')),
                 end_cap = circle(2, 'mm'), 
                 width = 0.5, show.legend = FALSE) +        
  geom_node_point(size = 4) +
  geom_node_label(aes(label = name), repel = TRUE) + 
  theme_graph() +
  theme(legend.position = "none")  

This code gives me this image:

enter image description here

However, I want to look like this:

enter image description here

Is there a way to conditionally remove edges not coming from ego? I have a number of plots to make, so removing individual edges by hand is not ideal.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
L. Tucker
  • 523
  • 2
  • 12

1 Answers1

1

Update

If you have multiple egos, and would like to put all the ego networks within the same graph, you can try the code below

egoid <- c("3", "7", "12", "15", "20")

egonet <- graph_from_edgelist(
  do.call(
    rbind,
    lapply(
      egoid,
      function(x) {
        cbind(
          x,
          subset(names(V(g)), distances(g, v = x, mode = "out") == 1)
        )
      }
    )
  )
)

which gives

enter image description here

Otherwise, you can save each ego networks in a list, e.g.,

egonetlst <- lapply(
  egoid,
  function(x) {
    graph_from_edgelist(
      cbind(
        x,
        subset(names(V(g)), distances(g, v = x, mode = "out") == 1)
      )
    )
  }
)

which gives

> egonetlst
[[1]]
IGRAPH 9ca6dac DN-- 4 3 --
+ attr: name (v/c)
+ edges from 9ca6dac (vertex names):
[1] 3->2 3->4 3->5

[[2]]
IGRAPH 9ca7dd3 DN-- 2 1 --
+ attr: name (v/c)
+ edge from 9ca7dd3 (vertex names):
[1] 7->8

[[3]]
IGRAPH 9ca7dd3 DN-- 4 3 --
+ attr: name (v/c)
+ edges from 9ca7dd3 (vertex names):
[1] 12->11 12->19 12->20

[[4]]
IGRAPH 9ca7dd3 DN-- 3 2 --
+ attr: name (v/c)
+ edges from 9ca7dd3 (vertex names):
[1] 15->17 15->20

[[5]]
IGRAPH 9ca7dd3 DN-- 5 4 --
+ attr: name (v/c)
+ edges from 9ca7dd3 (vertex names):
[1] 20->11 20->13 20->14 20->17

I guess you can use distance instead of make_ego_graph

g <- graph_from_data_frame(d = df, directed = TRUE)
egonet_3 <- graph_from_edgelist(
  cbind(
    "3",
    subset(names(V(g)), distances(g, v = "3", mode = "out") == 1)
  )
)

and plot(egonet_3) shows

enter image description here

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81