Conclusions


library(igraph)
#setwd("~/Downloads/Vizards Fall 2025")
load("data/answers to.rda") 
load("data/informs.rda") 
load("data/negative sentiment.rda") 
load("data/positive sentiment.rda") 
load("data/sentiment.rda")

To prepare, pick out the largest weak component ————————

answer <- decompose(answer_to)[[1]]

V(answer)$tribe
V(answer)$color <- V(answer)$tribe

V(answer)$color <- gsub("atreides", "darkgreen", V(answer)$color) 
V(answer)$color <-  gsub("fremen", "tan", V(answer)$color) 
V(answer)$color <-  gsub("bene gesserit", "darkslateblue", V(answer)$color) 
V(answer)$color <-  gsub("harkonnen", "darkred", V(answer)$color) 
V(answer)$color <-  gsub("empire", "goldenrod", V(answer)$color)
par(mar=rep(0,4))
plot.igraph(answer, layout=layout_nicely(answer), vertex.label.cex=0.75)

Finding Cutpoints

#assigns shapes the the articulation points
V(answer)$shape <- V(answer)$tribe
V(answer)$shape <- ifelse(V(answer) %in%
                          articulation_points(answer),
                        "csquare", "circle")

#prints the names of the cutpoints
answer %>%
  articulation_points() %>%
  as.list() %>%
  names() %>%
  as.data.frame() %>%
  `colnames<-`("Cut Points")

Finding Bi-Components

summary(bc)
                    Length Class     Mode   
no                  1      -none-    numeric
tree_edges          8      -none-    list   
component_edges     8      -none-    list   
components          8      -none-    list   
articulation_points 6      igraph.vs numeric
biconnected_components(answer)$components
[[1]]
+ 2/17 vertices, named, from 87c4a61:
[1] Jamis   Stilgar

[[2]]
+ 2/17 vertices, named, from 87c4a61:
[1] Maker Keeper Jessica     

[[3]]
+ 2/17 vertices, named, from 87c4a61:
[1] Watermaster             Reverend Mother Ramallo

[[4]]
+ 2/17 vertices, named, from 87c4a61:
[1] Jessica                 Reverend Mother Ramallo

[[5]]
+ 6/17 vertices, named, from 87c4a61:
[1] Chani          Gurney Halleck Shishakli      Stilgar        Jessica        Paul Atreides 

[[6]]
+ 2/17 vertices, named, from 87c4a61:
[1] Beast Rabban    Baron Harkonnen

[[7]]
+ 6/17 vertices, named, from 87c4a61:
[1] Feyd-Rautha            Baron Harkonnen        Princess Irulan        Reverend Mother Mohiam Lady Margot Fenring   
[6] Emperor               

[[8]]
+ 2/17 vertices, named, from 87c4a61:
[1] Emperor       Paul Atreides


largest_component <- lapply(biconnected_components(answer)$components, 
                            length) %>% which.max()
# largest_component

V(answer)$color <- ifelse(V(answer) %in%
                    biconnected_components(answer)$components[[largest_component]],
                    "salmon","lightblue")

par(mar=rep(0,4))
plot.igraph(answer, layout=layout_nicely(answer))

The largest Bicomponent here is highlighted in Salmon.

Calculating Reach Centrality

# Function for 2-step reach


reach2 <- function(x){
    r=vector(length=vcount(x))
    for (i in 1:vcount(x)){
    n=neighborhood(x,2, nodes = i)
    ni=unlist(n)
    l=length(ni)
    r[i]=(l)}
    r}

# Function for 3-step reach
reach3 <- function(x){
    r=vector(length=vcount(x))
    for (i in 1:vcount(x)){
    n=neighborhood(x,3, nodes = i)
    ni=unlist(n)
    l=length(ni)
    r[i]=(l)}
    r}
# 
# # Now, run the calculations.
Reach_2 <- reach2(answer)    # Note the differences between the object
Error in neighborhood(x, 2, nodes = i) : unused argument (nodes = i)

This Function would not run for me, after spending a decently long time trying to troubleshoot

Weak Ties

Reach_2 - degree(answer)
Error: object 'Reach_2' not found

Failed due to the function above not being able to run

Edge Betweeness

par(mar=rep(0,4))

E(answer)$width <- edge_betweenness(answer)


plot.igraph(answer,
            edge.width = igraph::edge.betweenness(answer)+1,              # The "+1" was added to make edgewidths non-zero.
            edge.color = heat.colors(igraph::edge.betweenness(answer)+1), # The "+1" was added to make edgewidths non-zero.
            vertex.shape="sphere",  # Here, we are using sphere because it looks cool.
            vertex.size=20,
            vertex.label.font=2,    # Here, we are using bold font.
            vertex.color="lightgreen")

Burt’s Constraint

const <- constraint(answer)
invConstraint <- 1.125 - const  # (Inverse constraint = brokerage potential)

round(invConstraint, 3)
          Paul Atreides                   Chani                 Jessica 
                  0.804                   0.656                   0.809 
                Stilgar          Gurney Halleck             Feyd-Rautha 
                  0.769                   0.544                   0.656 
        Princess Irulan            Beast Rabban                 Emperor 
                  0.321                   0.125                   0.782 
    Lady Margot Fenring         Baron Harkonnen  Reverend Mother Mohiam 
                  0.625                   0.656                   0.604 
              Shishakli                   Jamis            Maker Keeper 
                  0.374                   0.125                   0.125 
Reverend Mother Ramallo             Watermaster 
                  0.625                   0.125 

Brokerage Roles

library(intergraph)
library(statnet)

net <- asNetwork(answer)  # Convert igraph network into an sna object

The brokerage function in sna / statnet produces a lot of information. The only part of that information that we want in this case is the table that lists the number of times each node fulfills a particular type of brokerage role. For whatever reason, that table is called “raw.nli”.

The brokerage function in sna requires just two inputs: the name of the network (formatted for the sna package); and information about where to find the attribute (denoted as cl).

In the code below, we extract the attribute using get.vertex.attribute(net, "party") and use it for the cl argument. On the outside of the argument parentheses, we include $raw.nli to identify just the part of the output that we want.

brokerage(net, cl=get.vertex.attribute(net, "tribe"))$raw.nli

use function ?brokerage to see more info for interpreting this table

# Normalized, rounded to 2 digits
round(brokerage(net, cl=get.vertex.attribute(net, "tribe"))$z.nli, 2) 
LS0tCnRpdGxlOiAiQnJva2VyYWdlIFByYWN0aWN1bSA5LzYvMjUgLSBUaW0gTGluayIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiA5MAotLS0KCiMjIENvbmNsdXNpb25zCgotICAgV2hvIGFyZSB0aGUgYnJva2VycyBpbiB0aGlzIG5ldHdvcmssIGFzIGluZGljYXRlZCBieSB5b3VyIGFuYWx5c2lzPwogICAgLSAgIFBhdWwsIEplc3NpY2EsIGFuZCB0aGUgRW1wZXJvciBoYXZlIHRoZSAzIGhpZ2hlc3Qgc2NvcmVzIG9uIHRoZSBpbnZlcnRlZCBidXJ0cwogICAgICAgIGNvbnN0cmFpbnQsIGluZGljYXRpbmcgdGhhdCB0aGV5IGhhdmUgYSBzdHJvbmcgYnJva2VyYWdlIHBvc2l0aW9uLgogICAgLSAgIFRoZXNlIHNhbWUgMyBwZW9wbGUgYWx3YXlzIGFwcGVhciB2aXN1YWxseSBpbiBhIHN0cm9uZyBicm9rZXJhZ2UgcG9zaXRpb24gaW4gdGhlCiAgICAgICAgZWRnZSBiZXR3ZWVuZXNzIHZpc3VhbGl6YXRpb24uCiAgICAtICAgRnVydGhlcm1vcmUgdGhlc2UgcGVvcGxlIGFyZSBhbHNvIGN1dHBvaW50cywgaW5kaWNhdGluZyB0aGF0IGVhY2ggb2YgdGhlbSBoYXMgdGhlCiAgICAgICAgcG90ZW50aWFsIHRvIGNvbnRyb2wgdGhlIGZsb3cgb2YgaW5mb3JtYXRpb24sIG9yIGlmIHRoZXkgd2VyZSByZW1vdmVkIChraWxsZWQpCiAgICAgICAgdGhhdCBmbG93IHdvdWxkIGRpc3J1cHRlZC4KLSAgIEdpdmVuIHdoYXQgeW91IGtub3cgYWJvdXQgdGhlIG1vdmllLCB3aGF0IGRvZXMgdGhpcyB0ZWxsIHlvdSBhYm91dCB0aGUgY2hhcmFjdGVycyBpbgogICAgdGhlIG1vdmllIG5ldHdvcms/CiAgICAtICAgTXkgaW50ZXJwcmV0YXRpb24gaXMgdGhhdCB0aGUgcGVvcGxlIGF0IHRoZSB0b3Agb2YgdGhlIGhpZXJhcmNoeSAoUGF1bCwgSmVzc2ljYSwKICAgICAgICBFbXBlcm9yKSBkZWFsIHdpdGggZWFjaCBvdGhlciBhbmQgdGhlbiByZWxheSB0aGF0IGluZm9ybWF0aW9uIHRvIHRoZSBwZW9wbGUgdGhleQogICAgICAgIGNvbnRyb2wuIFRoZSB1bmRlcmxpbmdzIHRvIGRvIG5vdCBoYXZlIHRoZSBmcmVlZG9tIHRvIGludGVyYWN0IHdpdGggb3RoZXIgZ3JvdXBzCiAgICAgICAgd2l0aG91dCB0aGUgY29uc2VudCBvciBwcmVzZW5jZSBvZiB0aGUgbGVhZGVyc2hpcC4gVGhpcyBpbnRlbnRpb25hbGx5IGNlbnRlcnMgdGhlCiAgICAgICAgcGVvcGxlIGF0IHRoZSB0b3AsIHdoaWNoIG1ha2VzIHNlbnNlIGFzIHRoZXkgYXJlIHF1aXRlIHRoZSBwYXJhbm9pZCBidW5jaCAoZm9yCiAgICAgICAgZ29vZCByZWFzb24pLgoKYGBge3IgU2V0dGluZyBVcH0KCmxpYnJhcnkoaWdyYXBoKQojc2V0d2QoIn4vRG93bmxvYWRzL1ZpemFyZHMgRmFsbCAyMDI1IikKYGBgCgpgYGB7ciBMb2FkaW5nIERhdGF9CmxvYWQoImRhdGEvYW5zd2VycyB0by5yZGEiKSAKbG9hZCgiZGF0YS9pbmZvcm1zLnJkYSIpIApsb2FkKCJkYXRhL25lZ2F0aXZlIHNlbnRpbWVudC5yZGEiKSAKbG9hZCgiZGF0YS9wb3NpdGl2ZSBzZW50aW1lbnQucmRhIikgCmxvYWQoImRhdGEvc2VudGltZW50LnJkYSIpCmBgYAoKVG8gcHJlcGFyZSwgcGljayBvdXQgdGhlIGxhcmdlc3Qgd2VhayBjb21wb25lbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KYW5zd2VyIDwtIGRlY29tcG9zZShhbnN3ZXJfdG8pW1sxXV0KClYoYW5zd2VyKSR0cmliZQpWKGFuc3dlcikkY29sb3IgPC0gVihhbnN3ZXIpJHRyaWJlCgpWKGFuc3dlcikkY29sb3IgPC0gZ3N1YigiYXRyZWlkZXMiLCAiZGFya2dyZWVuIiwgVihhbnN3ZXIpJGNvbG9yKSAKVihhbnN3ZXIpJGNvbG9yIDwtICBnc3ViKCJmcmVtZW4iLCAidGFuIiwgVihhbnN3ZXIpJGNvbG9yKSAKVihhbnN3ZXIpJGNvbG9yIDwtICBnc3ViKCJiZW5lIGdlc3Nlcml0IiwgImRhcmtzbGF0ZWJsdWUiLCBWKGFuc3dlcikkY29sb3IpIApWKGFuc3dlcikkY29sb3IgPC0gIGdzdWIoImhhcmtvbm5lbiIsICJkYXJrcmVkIiwgVihhbnN3ZXIpJGNvbG9yKSAKVihhbnN3ZXIpJGNvbG9yIDwtICBnc3ViKCJlbXBpcmUiLCAiZ29sZGVucm9kIiwgVihhbnN3ZXIpJGNvbG9yKQpgYGAKCmBgYHtyIFRlc3QgdGhlIFBsb3Qgd2l0aCBjb2xvcnN9CnBhcihtYXI9cmVwKDAsNCkpCnBsb3QuaWdyYXBoKGFuc3dlciwgbGF5b3V0PWxheW91dF9uaWNlbHkoYW5zd2VyKSwgdmVydGV4LmxhYmVsLmNleD0wLjc1KQpgYGAKCiMjIEZpbmRpbmcgQ3V0cG9pbnRzCgpgYGB7cn0KI2Fzc2lnbnMgc2hhcGVzIHRoZSB0aGUgYXJ0aWN1bGF0aW9uIHBvaW50cwpWKGFuc3dlcikkc2hhcGUgPC0gVihhbnN3ZXIpJHRyaWJlClYoYW5zd2VyKSRzaGFwZSA8LSBpZmVsc2UoVihhbnN3ZXIpICVpbiUKICAgICAgICAgICAgICAgICAgICAgICAgICBhcnRpY3VsYXRpb25fcG9pbnRzKGFuc3dlciksCiAgICAgICAgICAgICAgICAgICAgICAgICJjc3F1YXJlIiwgImNpcmNsZSIpCgojcHJpbnRzIHRoZSBuYW1lcyBvZiB0aGUgY3V0cG9pbnRzCmFuc3dlciAlPiUKICBhcnRpY3VsYXRpb25fcG9pbnRzKCkgJT4lCiAgYXMubGlzdCgpICU+JQogIG5hbWVzKCkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIGBjb2xuYW1lczwtYCgiQ3V0IFBvaW50cyIpCmBgYAoKIyMgRmluZGluZyBCaS1Db21wb25lbnRzCgpgYGB7cn0KYmMgPC0gYmljb25uZWN0ZWRfY29tcG9uZW50cyhhbnN3ZXIpCnN1bW1hcnkoYmMpCmBgYAoKYGBge3J9CmJpY29ubmVjdGVkX2NvbXBvbmVudHMoYW5zd2VyKSRjb21wb25lbnRzCmBgYAoKYGBge3J9CgoKbGFyZ2VzdF9jb21wb25lbnQgPC0gbGFwcGx5KGJpY29ubmVjdGVkX2NvbXBvbmVudHMoYW5zd2VyKSRjb21wb25lbnRzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCkgJT4lIHdoaWNoLm1heCgpCiMgbGFyZ2VzdF9jb21wb25lbnQKClYoYW5zd2VyKSRjb2xvciA8LSBpZmVsc2UoVihhbnN3ZXIpICVpbiUKICAgICAgICAgICAgICAgICAgICBiaWNvbm5lY3RlZF9jb21wb25lbnRzKGFuc3dlcikkY29tcG9uZW50c1tbbGFyZ2VzdF9jb21wb25lbnRdXSwKICAgICAgICAgICAgICAgICAgICAic2FsbW9uIiwibGlnaHRibHVlIikKCnBhcihtYXI9cmVwKDAsNCkpCnBsb3QuaWdyYXBoKGFuc3dlciwgbGF5b3V0PWxheW91dF9uaWNlbHkoYW5zd2VyKSkKYGBgCgpUaGUgbGFyZ2VzdCBCaWNvbXBvbmVudCBoZXJlIGlzIGhpZ2hsaWdodGVkIGluIFNhbG1vbi4KCiMjIENhbGN1bGF0aW5nIFJlYWNoIENlbnRyYWxpdHkKCmBgYHtyfQojIEZ1bmN0aW9uIGZvciAyLXN0ZXAgcmVhY2gKCgpyZWFjaDIgPC0gZnVuY3Rpb24oeCl7CiAgICByPXZlY3RvcihsZW5ndGg9dmNvdW50KHgpKQogICAgZm9yIChpIGluIDE6dmNvdW50KHgpKXsKICAgIG49bmVpZ2hib3Job29kKHgsMiwgbm9kZXMgPSBpKQogICAgbmk9dW5saXN0KG4pCiAgICBsPWxlbmd0aChuaSkKICAgIHJbaV09KGwpfQogICAgcn0KCiMgRnVuY3Rpb24gZm9yIDMtc3RlcCByZWFjaApyZWFjaDMgPC0gZnVuY3Rpb24oeCl7CiAgICByPXZlY3RvcihsZW5ndGg9dmNvdW50KHgpKQogICAgZm9yIChpIGluIDE6dmNvdW50KHgpKXsKICAgIG49bmVpZ2hib3Job29kKHgsMywgbm9kZXMgPSBpKQogICAgbmk9dW5saXN0KG4pCiAgICBsPWxlbmd0aChuaSkKICAgIHJbaV09KGwpfQogICAgcn0KIyAKIyAjIE5vdywgcnVuIHRoZSBjYWxjdWxhdGlvbnMuClJlYWNoXzIgPC0gcmVhY2gyKGFuc3dlcikgICAgIyBOb3RlIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBvYmplY3QKUmVhY2hfMyA8LSByZWFjaDMoYW5zd2VyKSAgICAjICAgbmFtZXMgYW5kIHRoZSBmdW5jdGlvbiBuYW1lcyEKYGBgCgpUaGlzIEZ1bmN0aW9uIHdvdWxkIG5vdCBydW4gZm9yIG1lLCBhZnRlciBzcGVuZGluZyBhIGRlY2VudGx5IGxvbmcgdGltZSB0cnlpbmcgdG8KdHJvdWJsZXNob290CgojIyBXZWFrIFRpZXMKCmBgYHtyfQpSZWFjaF8yIC0gZGVncmVlKGFuc3dlcikKCmBgYAoKRmFpbGVkIGR1ZSB0byB0aGUgZnVuY3Rpb24gYWJvdmUgbm90IGJlaW5nIGFibGUgdG8gcnVuCgojIyBFZGdlIEJldHdlZW5lc3MKCmBgYHtyfQpwYXIobWFyPXJlcCgwLDQpKQoKRShhbnN3ZXIpJHdpZHRoIDwtIGVkZ2VfYmV0d2Vlbm5lc3MoYW5zd2VyKQoKCnBsb3QuaWdyYXBoKGFuc3dlciwKICAgICAgICAgICAgZWRnZS53aWR0aCA9IGlncmFwaDo6ZWRnZS5iZXR3ZWVubmVzcyhhbnN3ZXIpKzEsICAgICAgICAgICAgICAjIFRoZSAiKzEiIHdhcyBhZGRlZCB0byBtYWtlIGVkZ2V3aWR0aHMgbm9uLXplcm8uCiAgICAgICAgICAgIGVkZ2UuY29sb3IgPSBoZWF0LmNvbG9ycyhpZ3JhcGg6OmVkZ2UuYmV0d2Vlbm5lc3MoYW5zd2VyKSsxKSwgIyBUaGUgIisxIiB3YXMgYWRkZWQgdG8gbWFrZSBlZGdld2lkdGhzIG5vbi16ZXJvLgogICAgICAgICAgICB2ZXJ0ZXguc2hhcGU9InNwaGVyZSIsICAjIEhlcmUsIHdlIGFyZSB1c2luZyBzcGhlcmUgYmVjYXVzZSBpdCBsb29rcyBjb29sLgogICAgICAgICAgICB2ZXJ0ZXguc2l6ZT0yMCwKICAgICAgICAgICAgdmVydGV4LmxhYmVsLmZvbnQ9MiwgICAgIyBIZXJlLCB3ZSBhcmUgdXNpbmcgYm9sZCBmb250LgogICAgICAgICAgICB2ZXJ0ZXguY29sb3I9ImxpZ2h0Z3JlZW4iKQpgYGAKCiMjIEJ1cnQncyBDb25zdHJhaW50CgpgYGB7cn0KY29uc3QgPC0gY29uc3RyYWludChhbnN3ZXIpCmludkNvbnN0cmFpbnQgPC0gMS4xMjUgLSBjb25zdCAgIyAoSW52ZXJzZSBjb25zdHJhaW50ID0gYnJva2VyYWdlIHBvdGVudGlhbCkKCnJvdW5kKGludkNvbnN0cmFpbnQsIDMpCgpgYGAKCiMjIEJyb2tlcmFnZSBSb2xlcwoKYGBge3J9CmxpYnJhcnkoaW50ZXJncmFwaCkKbGlicmFyeShzdGF0bmV0KQoKbmV0IDwtIGFzTmV0d29yayhhbnN3ZXIpICAjIENvbnZlcnQgaWdyYXBoIG5ldHdvcmsgaW50byBhbiBzbmEgb2JqZWN0CmBgYAoKVGhlIGBicm9rZXJhZ2VgIGZ1bmN0aW9uIGluICpzbmEqIC8gKnN0YXRuZXQqIHByb2R1Y2VzIGEgbG90IG9mIGluZm9ybWF0aW9uLiBUaGUgb25seSBwYXJ0Cm9mIHRoYXQgaW5mb3JtYXRpb24gdGhhdCB3ZSB3YW50IGluIHRoaXMgY2FzZSBpcyB0aGUgdGFibGUgdGhhdCBsaXN0cyB0aGUgbnVtYmVyIG9mIHRpbWVzCmVhY2ggbm9kZSBmdWxmaWxscyBhIHBhcnRpY3VsYXIgdHlwZSBvZiBicm9rZXJhZ2Ugcm9sZS4gRm9yIHdoYXRldmVyIHJlYXNvbiwgdGhhdCB0YWJsZSBpcwpjYWxsZWQg4oCcKipyYXcubmxpKirigJ0uCgpUaGUgYGJyb2tlcmFnZWAgZnVuY3Rpb24gaW4gKnNuYSogcmVxdWlyZXMganVzdCB0d28gaW5wdXRzOiB0aGUgbmFtZSBvZiB0aGUgbmV0d29yawooZm9ybWF0dGVkIGZvciB0aGUgc25hIHBhY2thZ2UpOyBhbmQgaW5mb3JtYXRpb24gYWJvdXQgd2hlcmUgdG8gZmluZCB0aGUgYXR0cmlidXRlCihkZW5vdGVkIGFzIGBjbGApLgoKSW4gdGhlIGNvZGUgYmVsb3csIHdlIGV4dHJhY3QgdGhlIGF0dHJpYnV0ZSB1c2luZyBgZ2V0LnZlcnRleC5hdHRyaWJ1dGUobmV0LCAicGFydHkiKWAgYW5kCnVzZSBpdCBmb3IgdGhlIGBjbGAgYXJndW1lbnQuIE9uIHRoZSBvdXRzaWRlIG9mIHRoZSBhcmd1bWVudCBwYXJlbnRoZXNlcywgd2UgaW5jbHVkZQpgJHJhdy5ubGlgIHRvIGlkZW50aWZ5IGp1c3QgdGhlIHBhcnQgb2YgdGhlIG91dHB1dCB0aGF0IHdlIHdhbnQuCgpgYGB7cn0KYnJva2VyYWdlKG5ldCwgY2w9Z2V0LnZlcnRleC5hdHRyaWJ1dGUobmV0LCAidHJpYmUiKSkkcmF3Lm5saQpgYGAKCnVzZSBmdW5jdGlvbiBgP2Jyb2tlcmFnZWAgdG8gc2VlIG1vcmUgaW5mbyBmb3IgaW50ZXJwcmV0aW5nIHRoaXMgdGFibGUKCmBgYHtyfQojIE5vcm1hbGl6ZWQsIHJvdW5kZWQgdG8gMiBkaWdpdHMKcm91bmQoYnJva2VyYWdlKG5ldCwgY2w9Z2V0LnZlcnRleC5hdHRyaWJ1dGUobmV0LCAidHJpYmUiKSkkei5ubGksIDIpIApgYGAK