Skip to content

Commit

Permalink
Merge pull request #275 from snlab-ch/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
jhollway authored Oct 4, 2023
2 parents 088e17f + 42fda70 commit dde0d1d
Show file tree
Hide file tree
Showing 36 changed files with 263 additions and 111 deletions.
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: migraph
Title: Multimodal Network Analysis and More
Version: 1.0.1
Date: 2023-07-20
Version: 1.1.0
Date: 2023-10-03
Description: A set of tools for analysing multimodal networks.
It includes functions for measuring
centrality, centralization, cohesion, closure, constraint and diversity,
Expand All @@ -26,7 +26,7 @@ Imports:
dplyr (>= 1.1.0),
generics,
ggplot2,
igraph,
igraph (>= 1.5.0),
network,
future,
furrr,
Expand Down
8 changes: 8 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,15 @@ export(network_dyad_census)
export(network_eigenvector)
export(network_equivalency)
export(network_factions)
export(network_harmonic)
export(network_heterophily)
export(network_homophily)
export(network_indegree)
export(network_length)
export(network_mixed_census)
export(network_modularity)
export(network_outdegree)
export(network_reach)
export(network_reciprocity)
export(network_reg)
export(network_richness)
Expand All @@ -149,16 +153,20 @@ export(node_effsize)
export(node_eigenvector)
export(node_equivalence)
export(node_fast_greedy)
export(node_harmonic)
export(node_heterophily)
export(node_hierarchy)
export(node_homophily)
export(node_indegree)
export(node_is_core)
export(node_is_cutpoint)
export(node_is_isolate)
export(node_is_max)
export(node_is_min)
export(node_is_random)
export(node_kernighanlin)
export(node_outdegree)
export(node_pagerank)
export(node_path_census)
export(node_power)
export(node_quad_census)
Expand Down
19 changes: 19 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# migraph 1.1.0

## Package

- Added Macports option to the README (closes #274, thank you @barracuda156)
- Updates to the Centrality tutorial

## Measures

- Added `node_outdegree()`, `node_indegree()`, `network_outdegee()`, and `network_indegree()` wrappers
- Added `network_reach()`
- Added `node_harmonic()` and `network_harmonic()`
- Added `node_pagerank()`
- `plot.node_measure()` now returns a single plot for one-mode networks with a frequency histogram and a density overlay

## Data

- Upgraded all old igraph data to work with most recent version

# migraph 1.0.1

## Measures
Expand Down
15 changes: 8 additions & 7 deletions R/class_measures.R
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,20 @@ plot.node_measure <- function(x, type = c("h", "d"), ...) {
start = 0.7, end = 0.4)
}
} else {
if (type == "h") {
# if (type == "h") {
p <- ggplot2::ggplot(data = data) +
ggplot2::geom_histogram(ggplot2::aes(x = .data$Score),
binwidth = ifelse(max(data$Score) > 1, 1,
ifelse(max(data$Score) > .1,
.1,
.01))) +
ggplot2::ylab("Frequency")
} else {
p <- ggplot2::ggplot(data = data) +
ggplot2::geom_density(ggplot2::aes(x = .data$Score)) +
ggplot2::ylab("Density")
}
# ggplot2::ylab("Frequency")
# } else {
# p <- ggplot2::ggplot(data = data) +
ggplot2::geom_density(ggplot2::aes(x = .data$Score), col = 2) +
ggplot2::scale_y_continuous("Frequency",
sec.axis = ggplot2::sec_axis(~ ., breaks = c(0,1), name = "Density"))
# }
}
p + ggplot2::theme_classic() +
ggplot2::theme(panel.grid.major = ggplot2::element_line(colour = "grey90"))
Expand Down
99 changes: 89 additions & 10 deletions R/measure_centrality.R
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ node_degree <- function (.data, normalized = TRUE, alpha = 0,
out
}

#' @describeIn degree_centrality Wraps node_degree(..., direction = "out")
#' @export
node_outdegree <- function (.data, normalized = TRUE, alpha = 0){
node_degree(.data, normalized = normalized, alpha = alpha, direction = "out")
}

#' @describeIn degree_centrality Wraps node_degree(..., direction = "in")
#' @export
node_indegree <- function (.data, normalized = TRUE, alpha = 0){
node_degree(.data, normalized = normalized, alpha = alpha, direction = "in")
}

#' @describeIn degree_centrality Calculate the degree centrality of edges in a network
#' @examples
#' tie_degree(ison_adolescents)
Expand Down Expand Up @@ -166,6 +178,18 @@ network_degree <- function(.data, normalized = TRUE,
out
}

#' @describeIn degree_centrality Wraps network_degree(..., direction = "out")
#' @export
network_outdegree <- function(.data, normalized = TRUE){
network_degree(.data, normalized = normalized, direction = "out")
}

#' @describeIn degree_centrality Wraps network_degree(..., direction = "out")
#' @export
network_indegree <- function(.data, normalized = TRUE){
network_degree(.data, normalized = normalized, direction = "in")
}

# Betweenness-like centralities ####

#' Measures of betweenness-like centrality and centralisation
Expand Down Expand Up @@ -222,8 +246,8 @@ node_betweenness <- function(.data, normalized = TRUE,
#' @examples
#' (tb <- tie_betweenness(ison_adolescents))
#' plot(tb)
#' ison_adolescents %>% mutate_ties(weight = tb) %>%
#' autographr()
#' #ison_adolescents %>% mutate_ties(weight = tb) %>%
#' # autographr()
#' @export
tie_betweenness <- function(.data, normalized = TRUE){
if(missing(.data)) {expect_nodes(); .data <- .G()}
Expand Down Expand Up @@ -341,20 +365,39 @@ node_closeness <- function(.data, normalized = TRUE,
#' @export
node_reach <- function(.data, normalized = TRUE, k = 2){
if(missing(.data)) {expect_nodes(); .data <- .G()}
out <- rowSums(node_path_census(.data)==k)
out <- rowSums(node_path_census(.data)<=k)
if(normalized) out <- out/(manynet::network_nodes(.data)-1)
out <- make_node_measure(out, .data)
out
}

#' @describeIn close_centrality Calculate nodes' harmonic centrality or valued centrality.
#' This is thought to behave better than reach centrality for disconnected networks.
#' @references
#' Marchiori, M, and V Latora. 2000.
#' "Harmony in the small-world".
#' _Physica A_ 285: 539-546.
#'
#' Dekker, Anthony. 2005.
#' "Conceptual distance in social network analysis".
#' _Journal of Social Structure_ 6(3).
#' @export
node_harmonic <- function(.data, normalized = TRUE, k = -1){
if(missing(.data)) {expect_nodes(); .data <- .G()}
out <- igraph::harmonic_centrality(as_igraph(.data), # weighted if present
normalized = normalized, cutoff = k)
out <- make_node_measure(out, .data)
out
}

#' @describeIn close_centrality Calculate the closeness of each edge to each other edge
#' in the network.
#' @examples
#' (ec <- tie_closeness(ison_adolescents))
#' plot(ec)
#' ison_adolescents %>%
#' activate(edges) %>% mutate(weight = ec) %>%
#' autographr()
#' #ison_adolescents %>%
#' # activate(edges) %>% mutate(weight = ec) %>%
#' # autographr()
#' @export
tie_closeness <- function(.data, normalized = TRUE){
if(missing(.data)) {expect_nodes(); .data <- .G()}
Expand All @@ -365,7 +408,7 @@ tie_closeness <- function(.data, normalized = TRUE){
out
}

#' @describeIn close_centrality Calculate the closeness centralization for a graph
#' @describeIn close_centrality Calculate a network's closeness centralization
#' @examples
#' network_closeness(ison_southern_women, direction = "in")
#' @export
Expand Down Expand Up @@ -430,6 +473,26 @@ network_closeness <- function(.data, normalized = TRUE,
out
}

#' @describeIn close_centrality Calculate a network's reach centralization
#' @export
network_reach <- function(.data, normalized = TRUE, k = 2){
if(missing(.data)) {expect_nodes(); .data <- .G()}
reaches <- node_reach(.data, normalized = FALSE, k = k)
out <- sum(max(reaches) - reaches)
if(normalized) out <- out / sum(manynet::network_nodes(.data) - reaches)
make_network_measure(out, .data)
}

#' @describeIn close_centrality Calculate a network's harmonic centralization
#' @export
network_harmonic <- function(.data, normalized = TRUE, k = 2){
if(missing(.data)) {expect_nodes(); .data <- .G()}
harm <- node_harmonic(.data, normalized = FALSE, k = k)
out <- sum(max(harm) - harm)
if(normalized) out <- out / sum(manynet::network_nodes(.data) - harm)
make_network_measure(out, .data)
}

# Eigenvector-like centralities ####

#' Measures of eigenvector-like centrality and centralisation
Expand All @@ -450,6 +513,9 @@ NULL
#' Rather than performing this iteration,
#' most routines solve the eigenvector equation \eqn{Ax = \lambda x}.
#' @param scale Logical scalar, whether to rescale the vector so the maximum score is 1.
#' @details
#' We use `{igraph}` routines behind the scenes here for consistency and because they are often faster.
#' For example, `igraph::eigencentrality()` is approximately 25% faster than `sna::evcent()`.
#' @references
#' Bonacich, Phillip. 1991.
#' “Simultaneous Group and Individual Centralities.”
Expand All @@ -467,6 +533,9 @@ node_eigenvector <- function(.data, normalized = TRUE, scale = FALSE){
manynet::tie_weights(.data), NA)
graph <- manynet::as_igraph(.data)

if(!manynet::is_connected(.data))
warning("Unconnected networks will only allow nodes from one component have non-zero eigenvector scores.")

# Do the calculations
if (!manynet::is_twomode(graph)){
out <- igraph::eigen_centrality(graph = graph,
Expand All @@ -491,7 +560,7 @@ node_eigenvector <- function(.data, normalized = TRUE, scale = FALSE){
out
}

#' @describeIn eigenv_centrality Calculate the power centrality of nodes in a network
#' @describeIn eigenv_centrality Calculate the Bonacich, beta, or power centrality of nodes in a network
#' @param exponent Decay rate for the Bonacich power centrality score.
#' @section Power centrality:
#' Power or beta (or Bonacich) centrality
Expand Down Expand Up @@ -574,14 +643,25 @@ node_alpha <- function(.data, alpha = 0.85){
alpha = alpha),
.data)
}

#' @describeIn eigenv_centrality Calculate the pagerank centrality of nodes in a network
#' @references
#' Brin, Sergey and Page, Larry. 1998.
#' "The anatomy of a large-scale hypertextual web search engine".
#' _Proceedings of the 7th World-Wide Web Conference_. Brisbane, Australia.
#' @export
node_pagerank <- function(.data){
if(missing(.data)) {expect_nodes(); .data <- .G()}
make_node_measure(igraph::page_rank(manynet::as_igraph(.data)),
.data)
}

#' @describeIn eigenv_centrality Calculate the eigenvector centralization for a network
#' @examples
#' network_eigenvector(mpn_elite_mex)
#' network_eigenvector(ison_southern_women)
#' @export
network_eigenvector <- function(.data, normalized = TRUE){
if(missing(.data)) {expect_nodes(); .data <- .G()}
if (is_twomode(.data)) {
out <- c(igraph::centr_eigen(manynet::as_igraph(manynet::to_mode1(.data)),
normalized = normalized)$centralization,
Expand Down Expand Up @@ -609,4 +689,3 @@ tie_eigenvector <- function(.data, normalized = TRUE){
}



8 changes: 4 additions & 4 deletions R/member_core.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#' “A Fast Algorithm for the Discrete Core/Periphery Bipartitioning Problem.”
#' \doi{10.48550/arXiv.1102.5511}
#' @examples
#' mpn_elite_usa_advice %>% as_tidygraph %>%
#' mutate(corep = node_core(mpn_elite_usa_advice)) %>%
#' autographr(node_color = "corep")
#' #mpn_elite_usa_advice %>% as_tidygraph %>%
#' # mutate(corep = node_core(mpn_elite_usa_advice)) %>%
#' # autographr(node_color = "corep")
#' network_core(mpn_elite_usa_advice)
#' @export
node_core <- function(.data){
Expand All @@ -47,4 +47,4 @@ node_core <- function(.data){
1,2)
if(manynet::is_labelled(.data)) names(out) <- manynet::node_names(.data)
make_node_member(out, .data)
}
}
8 changes: 5 additions & 3 deletions R/model_play.R
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,11 @@ play_learning <- function(.data,
#' startValues[sample(seq_len(100), round(100*0.2))] <- NA
#' latticeEg <- manynet::create_lattice(100)
#' latticeEg <- manynet::add_node_attribute(latticeEg, "startValues", startValues)
#' manynet::autographr(latticeEg, node_color = "startValues", node_size = 5)
#' manynet::autographr(play_segregation(latticeEg, "startValues", 0.5),
#' node_color = "startValues", node_size = 5)
#' latticeEg
#' play_segregation(latticeEg, "startValues", 0.5)
#' #manynet::autographr(latticeEg, node_color = "startValues", node_size = 5)
#' #manynet::autographr(play_segregation(latticeEg, "startValues", 0.5),
#' # node_color = "startValues", node_size = 5)
#' @export
play_segregation <- function(.data,
attribute,
Expand Down
6 changes: 1 addition & 5 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ but also SIS, SIR, SIRS, SIER, and SIERS.
### Stable

The easiest way to install the latest stable version of `{migraph}` is via CRAN.
Simply open the R console and enter:
Simply open the R console and enter:^[Macs with Macports installed may also install from the command line [using Macports](https://ports.macports.org/port/R-migraph/).]

`install.packages('migraph')`

Expand All @@ -175,10 +175,6 @@ You can then begin to use `{migraph}` by loading the package:
`library(migraph)`

This will load any required packages and make the data contained within the package available.
The version from CRAN also has all the vignettes built and included.
You can check them out with:

`vignettes(package = "migraph")`

### Development

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ SIS, SIR, SIRS, SIER, and SIERS.
### Stable

The easiest way to install the latest stable version of `{migraph}` is
via CRAN. Simply open the R console and enter:
via CRAN. Simply open the R console and enter:[^1]

`install.packages('migraph')`

Expand All @@ -182,10 +182,7 @@ You can then begin to use `{migraph}` by loading the package:
`library(migraph)`

This will load any required packages and make the data contained within
the package available. The version from CRAN also has all the vignettes
built and included. You can check them out with:

`vignettes(package = "migraph")`
the package available.

### Development

Expand Down Expand Up @@ -258,3 +255,6 @@ Most work on this package has been funded by the Swiss National Science
Foundation (SNSF) [Grant Number
188976](https://data.snf.ch/grants/grant/188976): “Power and Networks
and the Rate of Change in Institutional Complexes” (PANARCHIC).

[^1]: Macs with Macports installed may also install from the command
line [using Macports](https://ports.macports.org/port/R-migraph/).
2 changes: 0 additions & 2 deletions cran-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@
## R CMD check results

0 errors | 0 warnings | 0 notes

- The Depends on `manynet` is required to offer full functionality to users
Binary file modified data/mpn_DE_1990.rda
Binary file not shown.
Binary file modified data/mpn_DE_2008.rda
Binary file not shown.
Binary file modified data/mpn_DemSxP.rda
Binary file not shown.
Binary file modified data/mpn_IT_1990.rda
Binary file not shown.
Binary file modified data/mpn_IT_2008.rda
Binary file not shown.
Binary file modified data/mpn_OverSxP.rda
Binary file not shown.
Binary file modified data/mpn_RepSxP.rda
Binary file not shown.
Binary file modified data/mpn_UK_1990.rda
Binary file not shown.
Binary file modified data/mpn_UK_2008.rda
Binary file not shown.
Binary file modified data/mpn_bristol.rda
Binary file not shown.
Binary file modified data/mpn_cow_igo.rda
Binary file not shown.
Binary file modified data/mpn_cow_trade.rda
Binary file not shown.
Binary file modified data/mpn_elite_mex.rda
Binary file not shown.
Binary file modified data/mpn_elite_usa_advice.rda
Binary file not shown.
Binary file modified data/mpn_elite_usa_money.rda
Binary file not shown.
Binary file modified data/mpn_ryanair.rda
Binary file not shown.
Loading

0 comments on commit dde0d1d

Please sign in to comment.