A beginning section loads the necessary packages and defines the starting directory.
pacman::p_load(dplyr, networktools, ggplot2, BGGM,
emojifont, fontawesome)
Data and models can be found on the Open Science Framework at https://osf.io/42ueg/. Rather than re-running models, we will load them here.
t1 <- read.csv(here::here("DATA", "t1.csv"))
t2 <- read.csv(here::here("DATA", "t2.csv"))
Load the pre-created {BGGM}
models. (When running the code to replicate analyses, you may set models_loaded
to false
in the preamble at the top of this document if planning to knit, or run all chunks manually, if you would like to generate the models anew.)
load(here::here("DATA", "models", "C1.Rdata"))
load(here::here("DATA", "models", "C2.Rdata"))
load(here::here("DATA", "models", "C3.Rdata"))
load(here::here("DATA", "models", "E1.Rdata"))
load(here::here("DATA", "models", "E2.Rdata"))
load(here::here("DATA", "models", "E3.Rdata"))
Source the make_adj_plot()
function and the add_neg_edges()
function
# load code for plot functions
# including modified functions originally
# by Josue Rodriguez, as well as
# the helper function insertLayer() for adding layers
# to ggplots
source(here::here("R Syntax", "network_plots.R"))
# set colors
pal <- c("#1b9e77", "#d95f02", "#7570b3")
node_font_color <- "white"
end_network_activity_game <- t1 %>%
dplyr::select(end_phone:end_time,
home_exercise:work_outside_home)
end_network_activity_game$id <- NULL
end_network_dep <- t1 %>%
dplyr::select(end_phone:end_time,
PHQ.8_1:PHQ.8_8)
end_network_dep$id <- NULL
act_network_dep <- t1 %>%
dplyr::select(home_exercise:work_outside_home,
PHQ.8_1:PHQ.8_8)
act_network_dep$id <- NULL
First, construct the activites & game network
if(! params$models_loaded) {
set.seed(NULL) # needed for knitr to play well with BGGM
explore_network1 <- BGGM::explore(end_network_activity_game,
type = "mixed",
iter = 5000,
seed = 1)
E1 <- BGGM::select(explore_network1,
alternative = "exhaustive",
bf_cut = 3)
}
Plot using the {BGGM} plotting:
# plot(E1, edge_magnify = 5, ci_width = 0.95)
if(pacman::p_isloaded("BGGM")) {
allp <- plot(E1, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allp)
}
Retain positive partial correlations from the real-life/game variables. Define names for nodes and communities.
partial_cors_pos <- E1$pcor_mat * E1$pos_mat
partial_cors_neg <- E1$pcor_mat * E1$neg_mat
#vector for nodenames
node_names <- colnames(end_network_activity_game)
#node_names <- colnames(confirm_E1)
#create communities
comms <- c(rep("Game Activity", 9), rep("Real Activity", 21))
# rename columns with node names
dimnames(partial_cors_pos) <- list(node_names, node_names)
dimnames(partial_cors_neg) <- list(node_names, node_names)
Calculate bridge strength. comms
is a vector specifying the community for each node. We will use the top 10% in bridge strength as bridge nodes.
bridge_strengths_pos <- networktools::bridge(partial_cors_pos, communities = comms)$`Bridge Strength`
bridge_strengths_neg <- networktools::bridge(partial_cors_neg, communities = comms)$`Bridge Strength`
# bridge nodes:
bridge_strength_cutoff <- quantile(bridge_strengths_pos, 0.9)
bridge_strengths_pos[bridge_strengths_pos > bridge_strength_cutoff]
## end_phone end_drink work_outside_home
## 0.810 0.632 0.591
bridge_strength_cutoff2 <- quantile(bridge_strengths_neg, 0.9)
bridge_strengths_neg[bridge_strengths_neg > bridge_strength_cutoff2]
## end_phone end_exercise knit
## 0.363 0.389 0.590
Create the confirmatory network.
confirm_E1 <- t2 %>%
dplyr::select(end_phone:end_time,
home_exercise:work_outside_home)
confirm_E1$id <- NULL
if(! params$models_loaded) {
confirm_network1 <- BGGM::explore(confirm_E1,
type = "mixed",
iter = 5000,
seed = 1)
C1 <- BGGM::select(confirm_network1, bf_cut = 3)
}
Plot using the BGGM base plotting:
if(pacman::p_isloaded("BGGM")) {
allp_C1 <- plot(C1, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allp_C1)
}
Note that some variations of the plot may cause some dashed lines to print with only minor spaces, and thus appear to be solid. They seem to work best when perfectly circular.
The first plot highlights the bridge nodes. First we’ll prepare the names, then plot it.
# we previously defined the node_names1:
# node_names1 <- colnames(end_network_activity_game)
# let's give them more descriptive names
node_names1 <- c("Gphone", "Gcomp", "Galco", "Gtv", "Gexer",
"Gcook", "GhobbN", "GhobbO", "Gtime",
"RexerH", "RexerO", "Rgym", "Rcook",
"Rvol", "Rtv", "Rvg", "Rknit", "Rread",
"RhobbN", "Ralco", "Rmj", "Rsubs", "Rreas",
"Rsmed", "Ryoga", "Rwrit", "Rmus", "Rzoom",
"Rwfh", "Roffic")
# provide descriptors
captions1 <- c("in-game phone use", "in-game time on computer",
"in-game drinking alcohol", "in-game TV use",
"in-game exercise", "in-game cooking",
"in-game new hobby", "in-game old hobby",
"time spent in-game", "real-life in-home exercise",
"real-life outdoor exercise", "real-life gym",
"real-life baking and cooking",
"real-life volunteering",
"real-life TV use", "real-life videogames",
"real-life knitting", "real-life reading",
"real-life new hobbies", "real-life drinking alcohol",
"real-life marijuana use",
"real-life substance use (other)",
"real-life reassurance-seeking",
"real-life social media use", "real-life yoga",
"real-life writing", "real-life playing music",
"real-life video calls with friends",
"real-life working from homew",
"real-life working outside the home")
# create key-value pairs for referencing:
captions1 <- tibble(captions1, node_names1)
equivalencies <- setNames(as.list(node_names1), colnames(end_network_activity_game))
# rename communities (especially for legend)
comms1 <- c(rep("Game Activity", 9), rep("Real Activity", 21))
# bridge names by direction:
posnames <- names(bridge_strengths_pos[bridge_strengths_pos > bridge_strength_cutoff])
negnames <- names(bridge_strengths_neg[bridge_strengths_neg > bridge_strength_cutoff2])
posnames <- equivalencies[posnames] %>% unlist()
negnames <- equivalencies[negnames] %>% unlist()
bridgenames <- c(posnames, negnames[! negnames %in% posnames])
fadenames <- node_names1[! node_names1 %in% bridgenames]
Plot using make_adj_plot()
from sourced functions. Add on the negative layer using add_neg_edges()
from same. A wrapping function create_net_plot()
is sourced from the create_plot.R; it simply adds on themes to the make_adj_plot()
function.
source(here::here("R syntax", "create_plot.R"))
plot_cd_E <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E1$pos_mat, adj_neg = E1$neg_mat,
node_labels = node_names1,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = bridgenames, bridges_neg = negnames,
fade = fadenames,
model_parcors = E1$pcor_mat,
type = "cd",
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = FALSE)
}
# save the legend for use later
# legend_E1 <- add_legend(plot_cd_E())
plot_cd_E(fontsize = 7)
Print captions:
captions1 <- captions1 %>%
rowwise() %>%
mutate(combined = paste0(c(node_names1, captions1), collapse=": ")) %>%
pull(combined)
cat(captions1, sep = "\n")
## Gphone: in-game phone use
## Gcomp: in-game time on computer
## Galco: in-game drinking alcohol
## Gtv: in-game TV use
## Gexer: in-game exercise
## Gcook: in-game cooking
## GhobbN: in-game new hobby
## GhobbO: in-game old hobby
## Gtime: time spent in-game
## RexerH: real-life in-home exercise
## RexerO: real-life outdoor exercise
## Rgym: real-life gym
## Rcook: real-life baking and cooking
## Rvol: real-life volunteering
## Rtv: real-life TV use
## Rvg: real-life videogames
## Rknit: real-life knitting
## Rread: real-life reading
## RhobbN: real-life new hobbies
## Ralco: real-life drinking alcohol
## Rmj: real-life marijuana use
## Rsubs: real-life substance use (other)
## Rreas: real-life reassurance-seeking
## Rsmed: real-life social media use
## Ryoga: real-life yoga
## Rwrit: real-life writing
## Rmus: real-life playing music
## Rzoom: real-life video calls with friends
## Rwfh: real-life working from homew
## Roffic: real-life working outside the home
We found an icon-based plot to be much more straightforward to read. The plot is created below; it should be identical to the above plot except with icons based on Font Awesome and using the {emojifont}
package.
If you save your plot to a PDF, you may need to embed the fonts as well, using grDevices::embedFonts
or extrafont::embed_fonts
. However, the plot saves to png without issue.
load.fontawesome()
node_names1FAname <- c("fa-mobile", # game phone use
"fa-laptop", # game computer
"fa-beer", # game drinking
"fa-tv", # game tv
"fa-heartbeat", # game exercise
"fa-cutlery", # cooking
"fa-random", # new hobby
"fa-object-group", # hobby old
"fa-clock-o", # end game time
"fa-bicycle", # home exercise
"fa-futbol-o", # outside exercise
"fa-hashtag", # gym
"fa-cutlery", # cooking
"fa-handshake-o", # volunteering
"fa-tv", # tv
"fa-gamepad", # videogames
"fa-connectdevelop", # knitting
"fa-book", # reading
"fa-modx", # new hobbies
"fa-glass", # alcohol
"fa-leaf", # marijuana
"fa-flask", # other substances fa-eye-slash?
"fa-hand-peace-o", # reassurance
"fa-twitter", # social media
"fa-sun-o", # yoga # refresh?
"fa-pencil", # writing
"fa-music", # music playing
"fa-skype", # videocalls with friends
"fa-window-restore", # working from home
"fa-building-o" # working from the office
)
# convert to icons
node_names1FA <- fontawesome(node_names1FAname)
# provide descriptors
captions1FA <- c("in-game phone use", "in-game time on computer",
"in-game drinking alcohol", "in-game TV use",
"in-game exercise", "in-game cooking",
"in-game new hobby", "in-game old hobby",
"time spent in-game", "real-life in-home exercise",
"real-life outdoor exercise", "real-life gym",
"real-life baking and cooking",
"real-life volunteering",
"real-life TV use", "real-life videogames",
"real-life knitting", "real-life reading",
"real-life new hobbies",
"real-life drinking alcohol",
"real-life marijuana use",
"real-life substance use (other)",
"real-life reassurance-seeking",
"real-life social media use", "real-life yoga",
"real-life writing", "real-life playing music",
"real-life video calls with friends",
"real-life working from homew",
"real-life working outside the home")
# create key-value pairs:
equivalenciesFA <- setNames(as.list(node_names1FA),
colnames(end_network_activity_game))
comms1 <- c(rep("Game Activity", 9), rep("Real Activity", 21))
# bridge names:
posnamesFA <- names(bridge_strengths_pos[bridge_strengths_pos > bridge_strength_cutoff])
negnamesFA <- names(bridge_strengths_neg[bridge_strengths_neg >
bridge_strength_cutoff2])
posnamesFA <- equivalenciesFA[posnamesFA] %>% unlist()
negnamesFA <- equivalenciesFA[negnamesFA] %>% unlist()
bridgenamesFA <- c(posnamesFA, negnamesFA[! negnamesFA %in% posnamesFA])
fadenamesFA <- node_names1FA[! node_names1FA %in% bridgenamesFA]
Make the plot:
plot_cd_EFA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E1$pos_mat, adj_neg = E1$neg_mat,
node_labels = node_names1FA,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = bridgenamesFA, bridges_neg = negnamesFA,
fade = fadenamesFA,
model_parcors = E1$pcor_mat,
type = "cd",
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_EFA(fontsize = 12)
In game:
Real-life:
The second plot shows the community-independent plot (CI).
plot_ci_E <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E1$pos_mat, adj_neg = E1$neg_mat,
node_labels = node_names1,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = NULL, bridges_neg = NULL,
fade = NULL,
model_parcors = E1$pcor_mat,
type = "ci",
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = FALSE)
}
plot_ci_E(fontsize = 7)
The same bridge nodes are highlighted as in the exploratory network, regardless of whether those nodes are in fact bridge nodes in the confirmatory network.
Using a bit of code borrowed from BGGM::plot.select()
, we adjusted the make_adj_plot()
so that if we set confirmatory = TRUE
, it will change edges to dashed if they have negative weights. This works with fontawesome = TRUE
, as well.
plot_C1 <- C1$pcor_mat * C1$Adj_10 # instead of C1$pcor_mat_zero
plot_cd_C1 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C1,
node_labels = node_names1,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = bridgenames,
fade = fadenames,
model_parcors = C1$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = FALSE)
}
plot_cd_C1(fontsize = 7)
We can run this with the FontAwesome icons, too:
# plot_C1 <- C1$pcor_mat * C1$Adj_10 # instead of C1$pcor_mat_zero
plot_cd_C1_FA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C1,
node_labels = node_names1FA,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = bridgenamesFA,
fade = fadenamesFA,
model_parcors = C1$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C1_FA(fontsize = 12)
The following plots don’t mask the within-community edges, by using the variant within = TRUE
in the create_net_plot()
function, and therefore include_within = TRUE
to the make_adj_plot()
function. This pairs with confirmatory = TRUE
and also fontawesome = TRUE
.
plot_cd_C1_FA_within_edges <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = TRUE,
adj_limits = adj_limits,
adj_pos = plot_C1,
node_labels = node_names1FA,
node_label_col = node_font_color,
communities = comms1,
bridges_pos = bridgenamesFA,
fade = fadenamesFA,
model_parcors = C1$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"Real-Life Activities"),
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C1_FA_within_edges(fontsize = 12)
if(! params$models_loaded) {
set.seed(NULL) # needed for knitr to play well with BGGM
explore_network2 <- BGGM::explore(end_network_dep,
type = "continuous",
iter = 5000,
seed = 1)
E2 <- BGGM::select(explore_network2,
alternative = "exhaustive",
bf_cut = 3)
}
if(pacman::p_isloaded("BGGM")) {
allp2 <- plot(E2, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allp2)
}
# retain positive & negative partial correlations from the PHQ/game variables
partial_cors_pos2 <- E2$pcor_mat * E2$pos_mat
partial_cors_neg2 <- E2$pcor_mat * E2$neg_mat
#vector for nodenames
node_names2 <- colnames(end_network_dep)
node_names2 <- colnames(end_network_dep)
#create communities
comms2 <- c(rep("Game Activity", 9), rep("PHQ", 8))
# rename columns with node names
dimnames(partial_cors_pos2) <- list(node_names2, node_names2)
dimnames(partial_cors_neg2) <- list(node_names2, node_names2)
# calculate bridge strength. comms is a vector specifying
# the community for each node
bridge_strengths_pos2 <- networktools::bridge(partial_cors_pos2, communities = comms2)$`Bridge Strength`
bridge_strengths_neg2 <- networktools::bridge(partial_cors_neg2, communities = comms2)$`Bridge Strength`
# we use the top 10% in bridge strength as bridge nodes
bridge_strength_cutoff.b <- quantile(bridge_strengths_pos2, 0.9)
bridge_strengths_pos2[bridge_strengths_pos2 > bridge_strength_cutoff.b]
## end_cook PHQ.8_1
## 0.254 0.247
bridge_strength_cutoff2.b <- quantile(bridge_strengths_neg2, 0.9)
bridge_strengths_neg2[bridge_strengths_neg2 > bridge_strength_cutoff2.b]
## PHQ.8_2 PHQ.8_5
## 0.245 0.275
confirm_E2 <- t2 %>%
dplyr::select(end_phone:end_time, PHQ.8_1:PHQ.8_8)
confirm_E2$id <- NULL
if(! params$models_loaded) {
confirm_network2 <- BGGM::explore(confirm_E2,
type = "continuous",
iter = 5000,
seed = 1)
C2 <- BGGM::select(confirm_network2)
}
if(pacman::p_isloaded("BGGM")) {
allC2 <- plot(C2, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allC2, ncol = 2)
}
Since these are smaller networks, node size can be larger. (Probably 33 for saving and 30 in-document.)
node_size <- node_size + 5 - ifelse(params$save_all_plots, 2, 0)
node_names2 <- c("Gphone", "Gcomp", "Galco", "Gtv", "Gexer",
"Gcook", "GhobbN", "GhobbO", "Gtime",
"PHQ-1", "PHQ-2", "PHQ-3", "PHQ-4",
"PHQ-5", "PHQ-6", "PHQ-7", "PHQ-8")
# provide descriptors
captions2 <- c("in-game phone use", "in-game time on computer",
"in-game drinking alcohol", "in-game TV use",
"in-game exercise", "in-game cooking",
"in-game new hobby", "in-game old hobby",
"time spent in-game", "PHQ-1: little interest",
"PHQ-2: feeling down", "PHQ-3: sleep trouble",
"PHQ-4: low energy", "PHQ-5: appetite",
"PHQ-6: failure", "PHQ-7: concentration",
"PHQ-8: psychomotor")
# create key-value pairs:
captions2 <- tibble(captions2, node_names2)
equivalencies2 <- setNames(as.list(node_names2), colnames(end_network_dep))
comms2 <- c(rep("Game Activity", 9), rep("PHQ-8", 8))
# bridge names:
posnames2 <- names(bridge_strengths_pos2[bridge_strengths_pos2 > bridge_strength_cutoff.b])
negnames2 <- names(bridge_strengths_neg2[bridge_strengths_neg2 > bridge_strength_cutoff2.b])
posnames2 <- equivalencies2[posnames2] %>% unlist()
negnames2 <- equivalencies2[negnames2] %>% unlist()
bridgenames2 <- c(posnames2, negnames2[! negnames2 %in% posnames2])
fadenames2 <- node_names2[! node_names2 %in% bridgenames2]
Plot using make_adj_plot()
from sourced functions. Add on the negative layer using add_neg_edges()
from same.
plot_cd_E2 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E2$pos_mat, adj_neg = E2$neg_mat,
node_labels = node_names2,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = bridgenames2, bridges_neg = negnames2,
fade = fadenames2,
model_parcors = E2$pcor_mat,
type = "cd",
confirmatory = FALSE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_cd_E2(fontsize = 7)
Add the captions:
captions2 <- captions2 %>%
rowwise() %>%
mutate(combined = paste0(c(node_names2, captions2), collapse=": ")) %>%
pull(combined)
cat(captions2, sep = "\n")
## Gphone: in-game phone use
## Gcomp: in-game time on computer
## Galco: in-game drinking alcohol
## Gtv: in-game TV use
## Gexer: in-game exercise
## Gcook: in-game cooking
## GhobbN: in-game new hobby
## GhobbO: in-game old hobby
## Gtime: time spent in-game
## PHQ-1: PHQ-1: little interest
## PHQ-2: PHQ-2: feeling down
## PHQ-3: PHQ-3: sleep trouble
## PHQ-4: PHQ-4: low energy
## PHQ-5: PHQ-5: appetite
## PHQ-6: PHQ-6: failure
## PHQ-7: PHQ-7: concentration
## PHQ-8: PHQ-8: psychomotor
As above, these plots use Font Awesome to replace names with images.
load.fontawesome()
node_names2FAname <- c("fa-mobile", # game phone use
"fa-laptop", # game computer
"fa-beer", # game drinking
"fa-tv", # game tv
"fa-heartbeat", # game exercise
"fa-cutlery", # cooking
"fa-random", # new hobby
"fa-object-group", # hobby old
"fa-clock-o", # end game time
"fa-remove", # "PHQ-1: little interest"
"fa-hand-o-down", # "PHQ-2: feeling down"
"fa-bed", # "PHQ-3: sleep trouble"
"fa-battery-1", # "PHQ-4: low energy"
"fa-spoon", # "PHQ-5: appetite"
"fa-warning", # "PHQ-6: failure"
"fa-joomla", # "PHQ-7: concentration"
"fa-ellipsis-h" # "PHQ-8: psychomotor agitation/slowing"
)
# convert to icons
node_names2FA <- fontawesome(node_names2FAname)
# provide descriptors
captions2FA <- c("in-game phone use", "in-game time on computer",
"in-game drinking alcohol", "in-game TV use",
"in-game exercise", "in-game cooking",
"in-game new hobby", "in-game old hobby",
"time spent in-game", "PHQ-1: little interest",
"PHQ-2: feeling down", "PHQ-3: sleep trouble",
"PHQ-4: low energy", "PHQ-5: appetite",
"PHQ-6: failure", "PHQ-7: concentration",
"PHQ-8: psychomotor")
# create key-value pairs:
equivalencies2FA <- setNames(as.list(node_names2FA),
colnames(end_network_dep))
comms2 <- c(rep("Game Activity", 9), rep("PHQ-8", 8))
# bridge names:
posnames2FA <- names(bridge_strengths_pos2[bridge_strengths_pos2 > bridge_strength_cutoff.b])
negnames2FA <- names(bridge_strengths_neg2[bridge_strengths_neg2 > bridge_strength_cutoff2.b])
posnames2FA <- equivalencies2FA[posnames2FA] %>% unlist()
negnames2FA <- equivalencies2FA[negnames2FA] %>% unlist()
bridgenames2FA <- c(posnames2FA, negnames2FA[! negnames2FA %in% posnames2FA])
fadenames2FA <- node_names2FA[! node_names2FA %in% bridgenames2FA]
Make the plot:
plot_cd_E2FA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E2$pos_mat, adj_neg = E2$neg_mat,
node_labels = node_names2FA,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = bridgenames2FA,
bridges_neg = negnames2FA,
fade = fadenames2FA,
model_parcors = E2$pcor_mat,
type = "cd",
confirmatory = FALSE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_E2FA(fontsize = 12)
In game:
PHQ-8:
The second set of plots show the community-independent plot (CI).
plot_ci_E2 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E2$pos_mat, adj_neg = E2$neg_mat,
node_labels = node_names2,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = NULL, bridges_neg = NULL,
fade = NULL,
model_parcors = E2$pcor_mat,
type = "ci",
confirmatory = FALSE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_ci_E2(fontsize = 7)
plot_C2 <- C2$pcor_mat * C2$Adj_10 # instead of C2$pcor_mat_zero
plot_cd_C2 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C2,
node_labels = node_names2,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = bridgenames2,
fade = fadenames2,
model_parcors = C2$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_cd_C2(fontsize = 7)
We can run this with the FontAwesome icons, too:
# plot_C2 <- C2$pcor_mat * C2$Adj_10 # instead of C2$pcor_mat_zero
plot_cd_C2_FA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C2,
node_labels = node_names2FA,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = bridgenames2FA,
fade = fadenames2FA,
model_parcors = C2$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C2_FA(fontsize = 12)
As above in C1
, we can include a community-dependent plot which doesn’t mask the within-community edges, by using the variant type = "keep_within_edges"
to the make_adj_plot()
function. We’ll keep it for the FA plot.
plot_cd_C2_FA_within_edges <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = TRUE,
adj_limits = adj_limits,
adj_pos = plot_C2,
node_labels = node_names2FA,
node_label_col = node_font_color,
communities = comms2,
bridges_pos = bridgenames2FA,
fade = fadenames2FA,
model_parcors = C2$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("Game Endings",
"PHQ-8"),
node_colors = pal[c(1,3)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C2_FA_within_edges(fontsize = 12)
if(! params$models_loaded) {
explore_network3 <- BGGM::explore(act_network_dep,
type = "mixed",
iter = 5000,
seed = 1)
E3 <- BGGM::select(explore_network3,
alternative = "exhaustive",
bf_cut = 3)
}
if(pacman::p_isloaded("BGGM")) {
allp3 <- plot(E3, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allp3)
}
# retain positive & negative partial correlations from the PHQ/activity variables
partial_cors_pos3 <- E3$pcor_mat * E3$pos_mat
partial_cors_neg3 <- E3$pcor_mat * E3$neg_mat
#vector for nodenames
node_names3 <- colnames(act_network_dep)
#create communities
comms3 <- c(rep("Real Activity", 21), rep("PHQ", 8))
# rename columns with node names
dimnames(partial_cors_pos3) <- list(node_names3, node_names3)
dimnames(partial_cors_neg3) <- list(node_names3, node_names3)
# calculate bridge strength. comms is a vector specifying
# the community for each node
bridge_strengths_pos3 <- networktools::bridge(partial_cors_pos3, communities = comms3)$`Bridge Strength`
bridge_strengths_neg3 <- networktools::bridge(partial_cors_neg3, communities = comms3)$`Bridge Strength`
# we use the top 10% in bridge strength as bridge nodes
bridge_strength_cutoff.c <- quantile(bridge_strengths_pos3, 0.9)
bridge_strengths_pos3[bridge_strengths_pos3 > bridge_strength_cutoff.c]
## writing PHQ.8_5
## 0.307 0.284
bridge_strength_cutoff2.c <- quantile(bridge_strengths_neg3, 0.9)
bridge_strengths_neg3[bridge_strengths_neg3 > bridge_strength_cutoff2.c]
## work_outside_home PHQ.8_1 PHQ.8_3
## 0.304 0.440 0.401
Create the confirmatory network.
confirm_E3 <- t2 %>% select(home_exercise:work_outside_home, PHQ.8_1:PHQ.8_8)
confirm_E3$id <- NULL
if(! params$models_loaded) {
confirm_network3 <- BGGM::explore(confirm_E3,
type = "mixed",
iter = 5000,
seed = 1)
C3 <- BGGM::select(confirm_network3)
}
if(pacman::p_isloaded("BGGM")) {
allpc3 <- plot(C3, edge_magnify = 5, ci_width = 0.95)
gridExtra::grid.arrange(grobs = allpc3, ncol = 2)
}
Since these are larger networks, node size should return to the first size of 25 for knitting and 30 for saving.
node_size <- node_size - 5 + ifelse(params$save_all_plots, 2, 0)
# node_names3
node_names3 <- c("RexerH", "RexerO", "Rgym", "Rcook",
"Rvol", "Rtv", "Rvg", "Rknit", "Rread",
"RhobbN", "Ralco", "Rmj", "Rsubs", "Rreas",
"Rsmed", "Ryoga", "Rwrit", "Rmus", "Rzoom",
"Rwfh", "Roffic", "PHQ-1", "PHQ-2", "PHQ-3", "PHQ-4",
"PHQ-5", "PHQ-6", "PHQ-7", "PHQ-8")
# provide descriptors
captions3 <- c("real-life in-home exercise",
"real-life outdoor exercise", "real-life gym",
"real-life baking and cooking",
"real-life volunteering",
"real-life TV use", "real-life videogames",
"real-life knitting", "real-life reading",
"real-life new hobbies", "real-life drinking alcohol",
"real-life marijuana use",
"real-life substance use (other)",
"real-life reassurance-seeking",
"real-life social media use", "real-life yoga",
"real-life writing", "real-life playing music",
"real-life video calls with friends",
"real-life working from homew",
"real-life working outside the home",
"PHQ-1: little interest",
"PHQ-2: feeling down", "PHQ-3: sleep trouble",
"PHQ-4: low energy", "PHQ-5: appetite",
"PHQ-6: failure", "PHQ-7: concentration",
"PHQ-8: psychomotor")
# create key-value pairs:
captions3 <- tibble(captions3, node_names3)
equivalencies3 <- setNames(as.list(node_names3), colnames(act_network_dep))
comms3 <- c(rep("Real-Life Activities", 21), rep("PHQ-8", 8))
# bridge names:
posnames3 <- names(bridge_strengths_pos3[bridge_strengths_pos3 > bridge_strength_cutoff.c])
negnames3 <- names(bridge_strengths_neg3[bridge_strengths_neg3 > bridge_strength_cutoff2.c])
posnames3 <- equivalencies3[posnames3] %>% unlist()
negnames3 <- equivalencies3[negnames3] %>% unlist()
bridgenames3 <- c(posnames3, negnames3[! negnames3 %in% posnames3])
fadenames3 <- node_names3[! node_names3 %in% bridgenames3]
Plot using make_adj_plot()
from sourced functions. Add on the negative layer using add_neg_edges()
from same.
plot_cd_E3 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E3$pos_mat, adj_neg = E3$neg_mat,
node_labels = node_names3,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = bridgenames3, bridges_neg = negnames3,
fade = fadenames3,
model_parcors = E3$pcor_mat,
type = "cd",
scale_labels = c("PHQ-8",
"Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_cd_E3(fontsize = 7)
Add the captions:
captions3 <- captions3 %>%
rowwise() %>%
mutate(combined = paste0(c(node_names3, captions3), collapse=": ")) %>%
pull(combined)
cat(captions3, sep = "\n")
## RexerH: real-life in-home exercise
## RexerO: real-life outdoor exercise
## Rgym: real-life gym
## Rcook: real-life baking and cooking
## Rvol: real-life volunteering
## Rtv: real-life TV use
## Rvg: real-life videogames
## Rknit: real-life knitting
## Rread: real-life reading
## RhobbN: real-life new hobbies
## Ralco: real-life drinking alcohol
## Rmj: real-life marijuana use
## Rsubs: real-life substance use (other)
## Rreas: real-life reassurance-seeking
## Rsmed: real-life social media use
## Ryoga: real-life yoga
## Rwrit: real-life writing
## Rmus: real-life playing music
## Rzoom: real-life video calls with friends
## Rwfh: real-life working from homew
## Roffic: real-life working outside the home
## PHQ-1: PHQ-1: little interest
## PHQ-2: PHQ-2: feeling down
## PHQ-3: PHQ-3: sleep trouble
## PHQ-4: PHQ-4: low energy
## PHQ-5: PHQ-5: appetite
## PHQ-6: PHQ-6: failure
## PHQ-7: PHQ-7: concentration
## PHQ-8: PHQ-8: psychomotor
As above, these plots use Font Awesome to replace names with images.
load.fontawesome()
node_names3FAname <- c("fa-bicycle", # home exercise
"fa-futbol-o", # outside exercise
"fa-hashtag", # gym
"fa-cutlery", # cooking
"fa-handshake-o", # volunteering
"fa-tv", # tv
"fa-gamepad", # videogames
"fa-connectdevelop", # knitting
"fa-book", # reading
"fa-modx", # new hobbies
"fa-glass", # alcohol
"fa-leaf", # marijuana
"fa-flask", # other substances fa-eye-slash?
"fa-hand-peace-o", # reassurance
"fa-twitter", # social media
"fa-sun-o", # yoga # refresh?
"fa-pencil", # writing
"fa-music", # music playing
"fa-skype", # videocalls with friends
"fa-window-restore", # working from home
"fa-building-o", # working from the office
"fa-remove", # "PHQ-1: little interest"
"fa-hand-o-down", # "PHQ-2: feeling down"
"fa-bed", # "PHQ-3: sleep trouble"
"fa-battery-1", # "PHQ-4: low energy"
"fa-spoon", # "PHQ-5: appetite"
"fa-warning", # "PHQ-6: failure"
"fa-joomla", # "PHQ-7: concentration"
"fa-ellipsis-h" # "PHQ-8: psychomotor agitation/slowing"
)
# convert to icons
node_names3FA <- fontawesome(node_names3FAname)
# provide descriptors
captions3FA <- c(
"real-life outdoor exercise", "real-life gym",
"real-life baking and cooking",
"real-life volunteering",
"real-life TV use", "real-life videogames",
"real-life knitting", "real-life reading",
"real-life new hobbies",
"real-life drinking alcohol",
"real-life marijuana use",
"real-life substance use (other)",
"real-life reassurance-seeking",
"real-life social media use", "real-life yoga",
"real-life writing", "real-life playing music",
"real-life video calls with friends",
"real-life working from homew",
"real-life working outside the home",
"PHQ-1: little interest",
"PHQ-2: feeling down", "PHQ-3: sleep trouble",
"PHQ-4: low energy", "PHQ-5: appetite",
"PHQ-6: failure", "PHQ-7: concentration",
"PHQ-8: psychomotor"
)
# create key-value pairs:
equivalencies3FA <- setNames(as.list(node_names3FA),
colnames(act_network_dep))
comms3 <- c(rep("Real Activity", 21), rep("PHQ-8", 8))
# bridge names:
posnames3FA <- names(bridge_strengths_pos3[bridge_strengths_pos3 > bridge_strength_cutoff.c])
negnames3FA <- names(bridge_strengths_neg3[bridge_strengths_neg3 >
bridge_strength_cutoff2.c])
posnames3FA <- equivalencies3FA[posnames3FA] %>% unlist()
negnames3FA <- equivalencies3FA[negnames3FA] %>% unlist()
bridgenames3FA <- c(posnames3FA, negnames3FA[! negnames3FA %in% posnames3FA])
fadenames3FA <- node_names3FA[! node_names3FA %in% bridgenames3FA]
Make the plot:
plot_cd_E3FA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E3$pos_mat, adj_neg = E3$neg_mat,
node_labels = node_names3FA,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = bridgenames3FA,
bridges_neg = negnames3FA,
fade = fadenames3FA,
model_parcors = E3$pcor_mat,
type = "cd",
scale_labels = c("PHQ-8",
"Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_E3FA(fontsize = 12)
Real-life activities:
PHQ-8:
These plots show the community-independent plot (CI).
plot_ci_E3 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = E3$pos_mat, adj_neg = E3$neg_mat,
node_labels = node_names3,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = NULL, bridges_neg = NULL,
fade = NULL,
model_parcors = E3$pcor_mat,
type = "ci",
confirmatory = FALSE,
scale_labels = c("PHQ-8", "Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_ci_E3(fontsize = 7)
plot_C3 <- C3$pcor_mat * C3$Adj_10 # instead of C3$pcor_mat_zero
plot_cd_C3 <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C3,
node_labels = node_names3,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = bridgenames3,
fade = fadenames3,
model_parcors = C3$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("PHQ-8", "Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = FALSE)
}
plot_cd_C3(fontsize = 7)
We can run this with the FontAwesome icons, too:
# plot_C3 <- C3$pcor_mat * C3$Adj_10 # instead of C3$pcor_mat_zero
plot_cd_C3_FA <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = FALSE,
adj_limits = adj_limits,
adj_pos = plot_C3,
node_labels = node_names3FA,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = bridgenames3FA,
fade = fadenames3FA,
model_parcors = C3$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("PHQ-8", "Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C3_FA(fontsize = 12)
As above in C1
and C2
, we can include a community-dependent plot which doesn’t mask the within-community edges, by using the variant within = TRUE"
to the make_adj_plot()
function. We’ll keep it for the FA plot.
plot_cd_C3_FA_within_edges <- function(plot_node_size = node_size,
adj_limits = .1, fontsize = 15
) {
create_net_plot(plot_node_size = plot_node_size,
within = TRUE,
adj_limits = adj_limits,
adj_pos = plot_C3,
node_labels = node_names3FA,
node_label_col = node_font_color,
communities = comms3,
bridges_pos = bridgenames3FA,
fade = fadenames3FA,
model_parcors = C3$pcor_mat,
type = "cd",
confirmatory = TRUE,
scale_labels = c("PHQ-8", "Real-Life Activities"),
node_colors = pal[c(3, 2)],
fontsize = fontsize,
fontawesome = TRUE)
}
plot_cd_C3_FA_within_edges(fontsize = 12)
The following code creates the arranged plots used in the manuscript. They are combinations of plots printed above.
pacman::p_load(cowplot)
legend_1 <- ggplot(tibble(x = c(3, 12), y = 1, z = c("A", "B")),
aes(x, y, color = z)) +
geom_point(size = 30) +
scale_color_manual(values = c("#1b9e77", "#d95f02")) +
scale_x_continuous(limits = c(0, 15)) +
scale_y_continuous(limits = c(.8, 1.2)) +
theme_void() + theme(legend.position = "none") +
annotate("text", x = 3, y = .88, size = 35,
label = "Game Endings") +
annotate("text", x = 12, y = .88, size = 35,
label = "Real-Life Activities")
network1_plot <- cowplot::plot_grid(
plot_cd_EFA(plot_node_size = 35,
fontsize = 45,
adj_limits = 0),
#cowplot::get_legend(add_legend(plot_cd_EFA(), textsize = 70)),
cowplot::plot_grid(legend_1),
plot_cd_C1_FA_within_edges(plot_node_size = 35,
fontsize = 45,
adj_limits = 0),
rel_heights = c(1, .2, 1),
rel_widths = c(1, .7, 1),
axis = "ltrb", align = "hv",
ncol = 1,
labels = c('A', '', 'B'),
label_x = 0.2,
label_size = 100
)
legend_2_3 <- ggplot(tibble(x = c(3, 12, 21), y = 1,
z = c("A", "B", "C")),
aes(x, y, color = z)) +
geom_point(size = 30) +
scale_color_manual(values = c("#1b9e77", "#d95f02", "#7570b3")) +
scale_x_continuous(limits = c(0, 24)) +
scale_y_continuous(limits = c(.8, 1.2)) +
theme_void() + theme(legend.position = "none") +
annotate("text", x = 3, y = .88, size = 35,
label = "Game Endings") +
annotate("text", x = 12, y = .88, size = 35,
label = "Real-Life Activities") +
annotate("text", x = 21, y = .88, size = 35,
label = "PHQ-8")
# legend_3 <- ggplot(tibble(x = c(3, 12), y = 1, z = c("A", "B")),
# aes(x, y, color = z)) +
# geom_point(size = 30) +
# scale_color_manual(values = c("#7570b3", "#d95f02")) +
# scale_x_continuous(limits = c(0, 15)) +
# scale_y_continuous(limits = c(.8, 1.2)) +
# theme_void() + theme(legend.position = "none") +
# annotate("text", x = 3, y = .88, size = 35,
# label = "PHQ-8") +
# annotate("text", x = 12, y = .88, size = 35,
# label = "Real-Life Activities")
networks2_3_plot <- cowplot::plot_grid(
cowplot::plot_grid(# network 2
plot_cd_E2FA(plot_node_size = 40,
fontsize = 50,
adj_limits = .05),
plot_cd_C2_FA_within_edges(plot_node_size = 40,
fontsize = 50,
adj_limits = .05),
ncol = 2,
labels = c('A', 'B'),
label_x = 0.2, label_size = 100
),
cowplot::plot_grid(NULL, legend_2_3, NULL, nrow = 1,
rel_widths = c(.6, 1, .6)),
cowplot::plot_grid(# network 3
plot_cd_E3FA(plot_node_size = 35,
fontsize = 45,
adj_limits = 0),
plot_cd_C3_FA_within_edges(plot_node_size = 35,
fontsize = 45,
adj_limits = 0),
ncol = 2,
labels = c('C', 'D'),
label_x = 0.2, label_size = 100
),
# cowplot::plot_grid(NULL, legend_3, NULL, nrow = 1,
# rel_widths = c(.6, 1, .6)),
# specs
byrow = TRUE,
rel_heights = c(1, .2, 1),
nrow = 3
)