Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
Package: netrics
Title: Many Ways to Measure and Classify Membership for Networks, Nodes, and Ties
Version: 0.2.3
Date: 2026-04-25
Version: 0.3.0
Description: Many tools for calculating network, node, or tie
marks, measures, motifs and memberships of many different types of networks.
Marks identify structural positions, measures quantify network properties,
Expand All @@ -14,10 +13,9 @@ License: MIT + file LICENSE
Language: en-GB
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.3.3
Depends:
R (>= 3.6.0),
manynet
R (>= 4.1.0),
manynet (>= 2.0.0)
Imports:
dplyr,
igraph (>= 2.1.0)
Expand Down Expand Up @@ -45,3 +43,4 @@ Config/Needs/website:
Config/testthat/parallel: true
Config/testthat/edition: 3
Config/testthat/start-first: measure_net
Config/roxygen2/version: 8.0.0
6 changes: 4 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Generated by roxygen2: do not edit by hand

export("%>%")
export(cluster_concor)
Comment thread
jhollway marked this conversation as resolved.
export(cluster_cosine)
export(cluster_hierarchical)
Expand Down Expand Up @@ -178,7 +177,10 @@ export(tie_is_simmelian)
export(tie_is_transitive)
export(tie_is_triangular)
export(tie_is_triplet)
importFrom(dplyr,"%>%")
importFrom(dplyr,filter)
importFrom(dplyr,group_by)
importFrom(dplyr,mutate)
importFrom(dplyr,select)
Comment thread
jhollway marked this conversation as resolved.
importFrom(igraph,V)
importFrom(igraph,adhesion)
importFrom(igraph,all_shortest_paths)
Expand Down
22 changes: 22 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# netrics 0.3.0

## Package

- Improved docs/examples to use base R pipe (|>) instead of magrittr's %>%
- Improved dependency requirements (R >= 4.1.0)
- Improved startup messages to be more succinct

## Measures

- Fixed `node_by_homophily()` to work when attribute is provided as a vector (e.g., a membership vector)
- Improved `node_by_homophily()` to avoid calling `as_igraph()` multiple times

## Motifs

- Fixed `net_x_hazard()` to use `diff_model$t` for naming the returned data frame columns, rather than the deprecated `diff_model$time`

## Tutorials

- Updated topology tutorial to use base R pipe (|>) instead of magrittr's %>%
- Updated centrality tutorial to use base R pipe (|>) instead of magrittr's %>%

# netrics 0.2.3

## Tutorials
Expand Down
4 changes: 0 additions & 4 deletions R/class_metrics.R
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,3 @@ make_network_motif <- function(out, .data) {
attr(out, "call") <- deparse(sys.calls())
out
}

#' @importFrom dplyr %>%
#' @export
dplyr::`%>%`
55 changes: 28 additions & 27 deletions R/mark_nodes.R
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,10 @@ node_is_latent <- function(.data, time = 0){
.data <- manynet::expect_nodes(.data)
if(manynet::is_changing(.data)){
t <- time
latent <- manynet::as_changelist(.data) %>%
dplyr::filter(time <= t & value %in% c("E", "I")) %>%
dplyr::group_by(node) %>%
dplyr::mutate(n = dplyr::n()) %>%
latent <- manynet::as_changelist(.data) |>
dplyr::filter(time <= t & value %in% c("E", "I")) |>
dplyr::group_by(node) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1 & value == "E")
if (manynet::is_labelled(.data)) {
out <- seq_len(manynet::net_nodes(.data)) %in% latent$node
Expand All @@ -253,10 +253,10 @@ node_is_latent <- function(.data, time = 0){
}
make_node_mark(out, .data)
} else if(inherits(.data, "diff_model")){
latent <- summary(.data) %>%
dplyr::filter(t <= time & event %in% c("E", "I")) %>%
dplyr::group_by(nodes) %>%
dplyr::mutate(n = dplyr::n()) %>%
latent <- summary(.data) |>
dplyr::filter(t <= time & event %in% c("E", "I")) |>
dplyr::group_by(nodes) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1 & event == "E")
net <- attr(.data, "network")
if (manynet::is_labelled(net)) {
Expand All @@ -283,10 +283,10 @@ node_is_infected <- function(.data, time = 0) {
.data <- manynet::expect_nodes(.data)
if(manynet::is_changing(.data)){
t <- time
infected <- manynet::as_changelist(.data) %>%
dplyr::filter(time <= t & value %in% c("I", "R")) %>%
dplyr::group_by(node) %>%
dplyr::mutate(n = dplyr::n()) %>%
infected <- manynet::as_changelist(.data) |>
dplyr::filter(time <= t & value %in% c("I", "R")) |>
dplyr::group_by(node) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1 & value == "I")
if (manynet::is_labelled(.data)) {
out <- seq_len(manynet::net_nodes(.data)) %in% infected$node
Expand All @@ -296,10 +296,10 @@ node_is_infected <- function(.data, time = 0) {
}
make_node_mark(out, .data)
} else if(inherits(.data, "diff_model")){
infected <- summary(.data) %>%
dplyr::filter(t <= time & event %in% c("I", "R")) %>%
dplyr::group_by(nodes) %>%
dplyr::mutate(n = dplyr::n()) %>%
infected <- summary(.data) |>
dplyr::filter(t <= time & event %in% c("I", "R")) |>
dplyr::group_by(nodes) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1 & event == "I")
net <- attr(.data, "network")
if (manynet::is_labelled(net)) {
Expand All @@ -325,10 +325,10 @@ node_is_recovered <- function(.data, time = 0){
.data <- manynet::expect_nodes(.data)
if(manynet::is_changing(.data)){
t <- time
recovered <- manynet::as_changelist(.data) %>%
dplyr::filter(time <= t & value %in% c("R")) %>%
dplyr::group_by(node) %>%
dplyr::mutate(n = dplyr::n()) %>%
recovered <- manynet::as_changelist(.data) |>
dplyr::filter(time <= t & value %in% c("R")) |>
dplyr::group_by(node) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1 & value == "R")
if (manynet::is_labelled(.data)) {
out <- seq_len(manynet::net_nodes(.data)) %in% recovered$node
Expand All @@ -338,10 +338,10 @@ node_is_recovered <- function(.data, time = 0){
}
make_node_mark(out, .data)
} else if(inherits(.data, "diff_model")){
recovered <- summary(.data) %>%
dplyr::filter(t <= time & event == "R") %>%
dplyr::group_by(nodes) %>%
dplyr::mutate(n = dplyr::n()) %>%
recovered <- summary(.data) |>
dplyr::filter(t <= time & event == "R") |>
dplyr::group_by(nodes) |>
dplyr::mutate(n = dplyr::n()) |>
dplyr::filter(n == 1)
net <- attr(.data, "network")
if (manynet::is_labelled(net)) {
Expand Down Expand Up @@ -372,6 +372,7 @@ node_is_recovered <- function(.data, time = 0){
#' then the function will return nodes exposure to the seed nodes
#' in that diffusion.
#' @param mark vector denoting which nodes are infected
#' @importFrom dplyr filter select group_by mutate
#' @examples
#' # To mark which nodes are currently exposed
#' (expos <- node_is_exposed(manynet::create_tree(14), mark = c(1,3)))
Expand All @@ -384,9 +385,9 @@ node_is_exposed <- function(.data, mark, time = 0){
t <- time
return(make_node_mark(node_by_adopt_exposure(.data, time = t)>0, .data))
} else if(inherits(.data, "diff_model")){
mark <- summary(.data) %>%
dplyr::filter(t == 0 & event == "I") %>%
dplyr::select(nodes) %>% unlist()
mark <- summary(.data) |>
dplyr::filter(t == 0 & event == "I") |>
dplyr::select(nodes) |> unlist()
.data <- attr(.data, "network")
}
}
Expand Down
16 changes: 8 additions & 8 deletions R/mark_ties.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ tie_is_bridge <- function(.data){
#' By default FALSE, sampling just a single path.
#' @importFrom igraph all_shortest_paths
#' @examples
#' ison_adolescents %>%
#' ison_adolescents |>
#' mutate_ties(route = tie_is_path(from = "Jane", to = 7))
#' @export
tie_is_path <- function(.data, from, to, all_paths = FALSE){
Expand Down Expand Up @@ -141,7 +141,7 @@ NULL
#' @rdname mark_triangles
#' @importFrom igraph triangles
#' @examples
#' ison_monks %>% to_uniplex("like") %>%
#' ison_monks |> to_uniplex("like") |>
#' mutate_ties(tri = tie_is_triangular())
#' @export
tie_is_triangular <- function(.data){
Expand All @@ -161,7 +161,7 @@ tie_is_triangular <- function(.data){

#' @rdname mark_triangles
#' @examples
#' ison_adolescents %>% to_directed() %>%
#' ison_adolescents |> to_directed() |>
#' mutate_ties(trans = tie_is_transitive())
#' @export
tie_is_transitive <- function(.data){
Expand All @@ -177,7 +177,7 @@ tie_is_transitive <- function(.data){

#' @rdname mark_triangles
#' @examples
#' ison_adolescents %>% to_directed() %>%
#' ison_adolescents |> to_directed() |>
#' mutate_ties(trip = tie_is_triplet())
#' @export
tie_is_triplet <- function(.data){
Expand All @@ -198,7 +198,7 @@ tie_is_triplet <- function(.data){

#' @rdname mark_triangles
#' @examples
#' ison_adolescents %>% to_directed() %>%
#' ison_adolescents |> to_directed() |>
#' mutate_ties(cyc = tie_is_cyclical())
#' @export
tie_is_cyclical <- function(.data){
Expand All @@ -214,7 +214,7 @@ tie_is_cyclical <- function(.data){

#' @rdname mark_triangles
#' @examples
#' ison_monks %>% to_uniplex("like") %>%
#' ison_monks |> to_uniplex("like") |>
#' mutate_ties(simmel = tie_is_simmelian())
#' @export
tie_is_simmelian <- function(.data){
Expand All @@ -229,7 +229,7 @@ tie_is_simmelian <- function(.data){

# #' @rdname mark_triangles
# #' @examples
# #' generate_random(8, directed = TRUE) %>%
# #' generate_random(8, directed = TRUE) |>
# #' mutate_ties(forbid = tie_is_forbidden())
# #' @export
# tie_is_forbidden <- function(.data){
Expand Down Expand Up @@ -262,7 +262,7 @@ tie_is_simmelian <- function(.data){

#' @rdname mark_triangles
#' @examples
#' fict_marvel %>% to_uniplex("relationship") %>% tie_is_imbalanced()
#' fict_marvel |> to_uniplex("relationship") |> tie_is_imbalanced()
#' @export
tie_is_imbalanced <- function(.data){
.data <- manynet::expect_ties(.data)
Expand Down
2 changes: 1 addition & 1 deletion R/measure_centrality_between.R
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ NULL
#' @importFrom igraph edge_betweenness
#' @examples
#' (tb <- tie_by_betweenness(ison_adolescents))
#' ison_adolescents %>% mutate_ties(weight = tb)
#' ison_adolescents |> mutate_ties(weight = tb)
#' @export
tie_by_betweenness <- function(.data, normalized = TRUE){
.data <- manynet::expect_ties(.data)
Expand Down
2 changes: 1 addition & 1 deletion R/measure_centrality_closeness.R
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ NULL
#' @rdname measure_centralities_close
#' @examples
#' (ec <- tie_by_closeness(ison_adolescents))
#' ison_adolescents %>% mutate_ties(weight = ec)
#' ison_adolescents |> mutate_ties(weight = ec)
#' @export
tie_by_closeness <- function(.data, normalized = TRUE){
.data <- manynet::expect_ties(.data)
Expand Down
20 changes: 10 additions & 10 deletions R/measure_diffusion.R
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ node_by_adopt_time <- function(.data){

if(inherits(.data, "diff_model")){
net <- attr(.data, "network")
out <- summary(.data) %>% dplyr::filter(event == "I") %>%
dplyr::distinct(nodes, .keep_all = TRUE) %>%
out <- summary(.data) |> dplyr::filter(event == "I") |>
dplyr::distinct(nodes, .keep_all = TRUE) |>
dplyr::select(nodes,t)
if(!manynet::is_labelled(net))
out <- dplyr::arrange(out, nodes) else if (is.numeric(out$nodes))
Expand All @@ -323,8 +323,8 @@ node_by_adopt_time <- function(.data){
}
} else {
net <- .data
out <- manynet::as_changelist(.data) %>% dplyr::filter(value == "I") %>%
dplyr::distinct(node, .keep_all = TRUE) %>%
out <- manynet::as_changelist(.data) |> dplyr::filter(value == "I") |>
dplyr::distinct(node, .keep_all = TRUE) |>
dplyr::select(node,time)
if(!manynet::is_labelled(net))
out <- dplyr::arrange(out, node) else if (is.numeric(out$node))
Expand Down Expand Up @@ -379,9 +379,9 @@ node_by_adopt_threshold <- function(.data, normalized = TRUE, lag = 1){
}
}
if(any(out$event == "E"))
out <- out %>% dplyr::filter(event == "E") else
out <- out %>% dplyr::filter(event == "I")
out <- out %>% dplyr::distinct(nodes, .keep_all = TRUE) %>%
out <- out |> dplyr::filter(event == "E") else
out <- out |> dplyr::filter(event == "I")
out <- out |> dplyr::distinct(nodes, .keep_all = TRUE) |>
dplyr::select(nodes, exposure)
if(manynet::is_labelled(net))
out <- stats::setNames(out$exposure, manynet::node_names(net)[out$nodes]) else
Expand All @@ -398,9 +398,9 @@ node_by_adopt_threshold <- function(.data, normalized = TRUE, lag = 1){
}
}
if(any(out$value == "E"))
out <- out %>% dplyr::filter(value == "E") else
out <- out %>% dplyr::filter(value == "I")
out <- out %>% dplyr::distinct(node, .keep_all = TRUE) %>%
out <- out |> dplyr::filter(value == "E") else
out <- out |> dplyr::filter(value == "I")
out <- out |> dplyr::distinct(node, .keep_all = TRUE) |>
dplyr::select(node, exposure)
if(manynet::is_labelled(net))
out <- stats::setNames(out$exposure, manynet::node_names(net)[out$node]) else
Expand Down
13 changes: 9 additions & 4 deletions R/measure_heterogeneity.R
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,15 @@ node_by_homophily <- function(.data, attribute,
manynet::snet_info("Using {.val ie} index instead.")
assortativity <- "ie"
}
out <- vapply(igraph::ego(manynet::as_igraph(.data)),
function(x) net_by_homophily(
igraph::induced_subgraph(manynet::as_igraph(.data), x),
attribute, assortativity = assortativity),
idat <- manynet::as_igraph(.data)
out <- vapply(igraph::ego(idat),
function(x) {
subattr <- if (length(attribute) == 1 && is.character(attribute))
attribute else attribute[as.integer(x)]
net_by_homophily(
igraph::induced_subgraph(idat, x),
subattr, assortativity = assortativity)
},
FUN.VALUE = numeric(1))
make_node_measure(out, .data)
}
Expand Down
2 changes: 1 addition & 1 deletion R/member_components.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ NULL
#' @rdname member_components
#' @importFrom igraph components
#' @examples
#' ison_monks %>% to_uniplex("esteem") %>%
#' ison_monks |> to_uniplex("esteem") |>
#' mutate_nodes(comp = node_in_component())
#' @export
node_in_component <- function(.data){
Expand Down
2 changes: 1 addition & 1 deletion R/member_core.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ NULL
#' \doi{10.48550/arXiv.1102.5511}
#' @examples
#' node_is_core(ison_adolescents)
#' ison_adolescents %>%
#' ison_adolescents |>
#' mutate(corep = node_is_core())
#' @export
node_is_core <- function(.data, centrality = c("degree", "eigenvector")){
Expand Down
Loading
Loading