this is a documentation-only topic ("?netify_workflows") that
indexes the standard pipelines netify users actually run, with
the function calls in order. new users opening ?netify see the
constructor; opening this topic sees the recipes.
from a friendship edgelist
library(netify)
net <- netify(friends, actor1 = "from", actor2 = "to",
symmetric = TRUE, nodal_data = people)
summary(net)
plot(net, node_color_by = "gender")a ready-to-run worked example ships with the package:
from a bipartite (two-mode) edgelist
a bipartite edgelist links two different kinds of things
(e.g. companies and jurisdictions, movies and actors, students and
classes). build with mode = "bipartite" and pass row-mode /
col-mode covariates separately.
net <- netify(filings, actor1 = "company", actor2 = "jurisdiction",
mode = "bipartite", weight = "n_filings")
net <- add_node_vars(net, company_meta,
actor = "company",
node_vars = c("industry", "hq"))
net <- add_node_vars(net, jurisdiction_meta,
actor = "jurisdiction",
node_vars = "tax_haven")
plot(net, style = "heatmap")from a longitudinal dyadic event dataset (icews-style)
net <- netify(icews, actor1 = "i", actor2 = "j", time = "year",
symmetric = FALSE, weight = "verbCoop")
net <- add_node_vars(net, country_panel,
actor = "actor", time = "year",
node_vars = c("polity", "gdp_log"))
s <- summary(net)
plot(s)multilayer (one call per layer)
# build one netify per layer, then combine with layer_netify()
channels <- sort(unique(slack_long$channel))
nets <- lapply(channels, function(ch) {
netify(slack_long[slack_long$channel == ch, ],
actor1 = "from", actor2 = "to",
time = "month", weight = "n_messages")
})
ml <- layer_netify(setNames(nets, channels))to ergm (statnet)
ntwk <- to_statnet(net)
library(ergm)
fit <- ergm(ntwk ~ edges + nodematch("gender") + nodecov("gpa"))
summary(fit)to longitudinal ergm (tergm 4.x)
nl <- to_statnet(longit_net) # network.list
library(tergm)
fit <- tergm(nl ~ form(~ edges + nodematch("gender")) +
persist(~ edges + mutual),
estimate = "cmle", times = seq_along(nl))to ame (binary bipartite + als + bootstrap uncertainty)
# fast point estimate + parametric bootstrap cis in one call
lm_in <- to_lame(net_bp, fit_method = "als", bootstrap = 200)
library(lame)
fit <- lame::ame_als(y = lm_in$y, mode = "bipartite",
family = "binary", bootstrap = 200l)
confint(fit) # bootstrap cis
pred <- from_lame_fit(fit, value = "prob")
plot(pred, style = "heatmap")
NULL-model hypothesis test
# is observed transitivity surprising vs erdos-renyi at this density?
compare_to_null(net,
fn = function(n) c(transitivity = summary(n)$transitivity),
n_sim = 200, model = "erdos_renyi", seed = 1)bootstrap any custom statistic
my_stat <- function(net) {
sa <- summary_actor(net, stats = "all")
c(max_betw = max(sa$betweenness, na.rm = TRUE))
}
bootstrap_netlet(net, fn = my_stat, n_boot = 200, seed = 1)very large n (~10k+ actors)
netify stores adjacencies densely, so an n x n matrix consumes 8 * n^2 bytes (1.7 gb at n = 15k, 20 gb at n = 50k) per snapshot. the recipes below avoid the dense bottleneck where possible.
# 1. build directly from an edgelist data.frame -- skip any
# pre-built sparse / dense matrix intermediate.
net <- netify(edges, actor1 = "from", actor2 = "to",
weight = "n", symmetric = FALSE)
# 2. use the fast actor-summary path -- skips closeness /
# betweenness / eigen / hits, which dominate wall-clock at
# large n. netify auto-promotes at n >= netify.fast_threshold
# (default 1500); tune via options(netify.fast_threshold = ...).
sa <- summary_actor(net) # auto-promotes
# 3. for community detection / shortest paths / clustering, hand
# off to igraph. its c backend handles 50k+ nodes comfortably.
ig <- to_igraph(net)
cl <- igraph::cluster_louvain(ig)
# 4. when you need a sparse object for downstream code (e.g.
# spectral methods, irlba, glmnet), exit via to_igraph() and
# grab the sparse adjacency from there.
ig <- to_igraph(net)
m <- igraph::as_adjacency_matrix(ig, sparse = TRUE) # requires matrix
# 5. if you must accept a pre-built sparse matrix, density < 1
# with n > 5,000 aborts to protect against accidental
# gigabyte allocations -- pass force_dense = TRUE to override.
net <- netify(m_sparse, force_dense = TRUE)stacking
# combine two cross-sec into a 2-period longit
combined <- bind_netifies(n_2020, n_2021, names = c("2020", "2021"))See also
netify() for the constructor; summary.netify() for
graph-level stats; plot.netify() for visualization;
to_statnet() / to_amen() / to_lame() / to_igraph() for
handoff to modeling packages; bootstrap_netlet() /
compare_to_null() / simulate.netify() for inference; and
bind_netifies() for combining.