1. My network

Twelve people from my family and my Navy service, in three circles: my immediate family, the in-laws who joined it through marriage, and two Navy best friends. My husband and I met in the Navy, so the circles overlap rather than sitting side by side.

nodes <- tribble(
  ~name,          ~circle,    ~birth_month,
  "Me",           "Me",       "January",
  "Husband",      "Family",   "April",
  "Sis 1",        "Family",   "September",
  "Sis 2",        "Family",   "July",
  "Brother",      "Family",   "May",
  "SIL (bro)",    "In-law",   "February",
  "SIL (hus)",    "In-law",   "October",
  "SIL (class)",  "In-law",   "January",
  "BIL 1",        "In-law",   "May",
  "BIL 2",        "In-law",   "June",
  "Best friend 1","Navy",     "February",
  "Best friend 2","Navy",     "December"
)

SIL (bro) is my brother’s wife, SIL (hus) my husband’s sister, SIL (class) my high school classmate who later became Sis 2’s sister-in-law, BIL 1 Sis 1’s husband, and BIL 2 Sis 2’s husband.

The connections follow four patterns: my core family all know each other; the in-laws who married into my side know that whole core family; the Navy group includes my husband, my brother, and both best friends, who have also met Sis 1, my husband’s sister, and my brother’s wife; and two ties cross circles, since SIL (class) was my classmate before she was family and also knows Sis 1 through a shared interest in BTS.

edges <- tribble(
  ~from,           ~to,
  # Core family
  "Me", "Husband", "Me", "Sis 1", "Me", "Sis 2", "Me", "Brother",
  "Husband", "Sis 1", "Husband", "Sis 2", "Husband", "Brother",
  "Sis 1", "Sis 2", "Sis 1", "Brother", "Sis 2", "Brother",
  # In-laws who married into my side
  "BIL 1", "Me", "BIL 1", "Husband", "BIL 1", "Sis 1",
  "BIL 1", "Sis 2", "BIL 1", "Brother",
  "BIL 2", "Me", "BIL 2", "Husband", "BIL 2", "Sis 1",
  "BIL 2", "Sis 2", "BIL 2", "Brother",
  "SIL (bro)", "Me", "SIL (bro)", "Husband", "SIL (bro)", "Sis 1",
  "SIL (bro)", "Sis 2", "SIL (bro)", "Brother",
  # My husband's sister
  "SIL (hus)", "Husband", "SIL (hus)", "Me",
  "SIL (hus)", "Sis 1", "SIL (hus)", "Brother",
  # My classmate, now Sis 2's sister-in-law
  "SIL (class)", "Me", "SIL (class)", "Sis 2", "SIL (class)", "BIL 2",
  "SIL (class)", "Husband", "SIL (class)", "Sis 1",
  # Navy
  "Best friend 1", "Best friend 2",
  "Best friend 1", "Me", "Best friend 1", "Husband",
  "Best friend 1", "Sis 1", "Best friend 1", "Brother",
  "Best friend 1", "SIL (hus)", "Best friend 1", "SIL (bro)",
  "Best friend 2", "Me", "Best friend 2", "Husband",
  "Best friend 2", "Sis 1", "Best friend 2", "Brother",
  "Best friend 2", "SIL (hus)", "Best friend 2", "SIL (bro)"
)

my_net <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE)
A <- as_adjacency_matrix(my_net, sparse = FALSE)
my_net
## IGRAPH 1e270b2 UN-- 12 47 -- 
## + attr: name (v/c), circle (v/c), birth_month (v/c)
## + edges from 1e270b2 (vertex names):
##  [1] Me     --Husband   Me     --Sis 1     Me     --Sis 2     Me     --Brother  
##  [5] Husband--Sis 1     Husband--Sis 2     Husband--Brother   Sis 1  --Sis 2    
##  [9] Sis 1  --Brother   Sis 2  --Brother   Me     --BIL 1     Husband--BIL 1    
## [13] Sis 1  --BIL 1     Sis 2  --BIL 1     Brother--BIL 1     Me     --BIL 2    
## [17] Husband--BIL 2     Sis 1  --BIL 2     Sis 2  --BIL 2     Brother--BIL 2    
## [21] Me     --SIL (bro) Husband--SIL (bro) Sis 1  --SIL (bro) Sis 2  --SIL (bro)
## [25] Brother--SIL (bro) Husband--SIL (hus) Me     --SIL (hus) Sis 1  --SIL (hus)
## [29] Brother--SIL (hus)
## + ... omitted several edges

2. Network diagram

pal <- c(Me = "#E76F51", Family = "#2A9D8F",
         `In-law` = "#E9C46A", Navy = "pink")
V(my_net)$color <- pal[V(my_net)$circle]

set.seed(123)
plot(my_net,
     layout             = layout_with_fr(my_net),
     vertex.size        = 10 + degree(my_net) * 2,
     vertex.label.color = "black",
     vertex.label.cex   = 0.8,
     vertex.frame.color = "white",
     edge.color         = "grey70",
     main               = "My family and Navy network")
legend("bottomleft", legend = names(pal), pt.bg = pal, pch = 21,
       pt.cex = 1.6, bty = "n", cex = 0.85)

3. Network measures

Degree counts direct connections, betweenness measures how often someone bridges two others, PageRank rewards being connected to well-connected people, and triangles counts the closed three-person groups someone belongs to.

tibble(
  person      = V(my_net)$name,
  circle      = V(my_net)$circle,
  degree      = degree(my_net),
  betweenness = round(betweenness(my_net), 2),
  pagerank    = round(page_rank(my_net)$vector, 4),
  triangles   = count_triangles(my_net)
) %>%
  arrange(desc(degree)) %>%
  kable(caption = "Centrality and triangle counts") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Centrality and triangle counts
person circle degree betweenness pagerank triangles
Me Me 11 4.62 0.1133 36
Husband Family 11 4.62 0.1133 36
Sis 1 Family 11 4.62 0.1133 36
Brother Family 10 2.92 0.1035 32
Sis 2 Family 8 1.30 0.0854 22
SIL (bro) In-law 7 0.40 0.0749 19
Best friend 1 Navy 7 0.17 0.0751 20
Best friend 2 Navy 7 0.17 0.0751 20
SIL (hus) In-law 6 0.00 0.0658 15
BIL 2 In-law 6 0.20 0.0664 14
SIL (class) In-law 5 0.00 0.0572 10
BIL 1 In-law 5 0.00 0.0566 10
tibble(
  measure = c("People", "Relationships", "Density", "Diameter",
              "Average path length"),
  value   = c(vcount(my_net), ecount(my_net),
              round(edge_density(my_net), 3),
              diameter(my_net), round(mean_distance(my_net), 3))
) %>%
  kable(caption = "Whole-network summary") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Whole-network summary
measure value
People 12.000
Relationships 47.000
Density 0.712
Diameter 2.000
Average path length 1.288

4. Shared birth months

The tutorial’s “same birthday” analysis, using birth month. I check every possible pair and flag whether the pair is already connected.

pair_matrix <- t(combn(nodes$name, 2))

tibble(person_a = pair_matrix[, 1], person_b = pair_matrix[, 2]) %>%
  left_join(nodes %>% select(name, birth_month), by = c("person_a" = "name")) %>%
  left_join(nodes %>% select(name, birth_month), by = c("person_b" = "name"),
            suffix = c("_a", "_b")) %>%
  filter(birth_month_a == birth_month_b) %>%
  mutate(already_connected = A[cbind(person_a, person_b)] == 1) %>%
  select(person_a, person_b, birth_month = birth_month_a, already_connected) %>%
  kable(caption = "Pairs sharing a birth month") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Pairs sharing a birth month
person_a person_b birth_month already_connected
Me SIL (class) January TRUE
Brother BIL 1 May TRUE
SIL (bro) Best friend 1 February TRUE

5. Friends of friends

Pairs who share a mutual connection but don’t know each other directly — the logic behind “People You May Know.”

shared     <- A %*% A
candidates <- which(upper.tri(shared) & shared > 0 & A == 0, arr.ind = TRUE)

tibble(
  person_a       = rownames(A)[candidates[, "row"]],
  person_b       = colnames(A)[candidates[, "col"]],
  mutual_friends = shared[candidates]
) %>%
  arrange(desc(mutual_friends)) %>%
  kable(caption = "Unconnected pairs with mutual connections") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Unconnected pairs with mutual connections
person_a person_b mutual_friends
SIL (bro) SIL (hus) 6
Brother SIL (class) 5
SIL (bro) BIL 1 5
SIL (bro) BIL 2 5
BIL 1 BIL 2 5
Sis 2 Best friend 1 5
Sis 2 Best friend 2 5
Sis 2 SIL (hus) 4
SIL (bro) SIL (class) 4
SIL (hus) BIL 1 4
SIL (class) BIL 1 4
SIL (hus) BIL 2 4
BIL 1 Best friend 1 4
BIL 2 Best friend 1 4
BIL 1 Best friend 2 4
BIL 2 Best friend 2 4
SIL (hus) SIL (class) 3
SIL (class) Best friend 1 3
SIL (class) Best friend 2 3

6. Interpretation and conclusion

My husband and I are each connected to everyone else in the network. That happened because we met in the Navy alongside my best friends and then married into each other’s families, so his relatives and my service friends met directly instead of through one of us relaying between them.

The result is a network with no bridge person. Density is high, the diameter is small, and betweenness is low for everyone, so any two people here reach each other in a step or two. That is the opposite of the tutorial’s example network, where one person sits on nearly every path.

Degree still separates people whose formal family roles look identical. Sis 1 and Sis 2 have the same standing in the family, but Sis 1 has met both best friends and my husband’s sister and Sis 2 has not, so Sis 1 sits noticeably better connected. Relationship category and network position are not the same thing.

What the analysis didn’t surface is just as telling. Every birth-month match is between people who already know each other, and the friend-of-friend list is short. Both techniques need sparse networks to produce anything useful, and mine is dense. The main limitation is that the network is undirected and unweighted, so a sibling I speak to daily counts the same as an in-law I see once a year; adding edge weights for contact frequency would be the most useful next step.

References

  • Xu, Z. “Jimmy.” Social network analysis using R. RPubs. https://rpubs.com/utjimmyx/network
  • Csardi, G., & Nepusz, T. (2006). The igraph software package for complex network research. InterJournal, Complex Systems, 1695.