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
1 change: 0 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

- Documentation
- [ ] DESCRIPTION file version is bumped by the appropriate increment (major, minor, patch)
- [ ] Date in DESCRIPTION is correct
- [ ] Longer functions are commented inline or broken down into helper functions to help debugging
- PR form
- [ ] Title indicates expected version number
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: manynet
Title: Many Ways to Make, Manipulate, and Modify Myriad Networks
Version: 2.1.2
Version: 2.1.3
Description: Many tools for making, manipulating, and modifying many different types of networks.
All functions operate with matrices, edge lists, and 'igraph', 'network', and 'tidygraph' objects,
on directed, multiplex, multimodal, signed, and other networks.
Expand Down
17 changes: 17 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# manynet 2.1.3

## Class

- Fixed stocnet validation test issue

## Describing

- Fixed `mode_names.stocnet()` and `layer_names.stocnet()` to look up correct info names

## Manipulating

- Improved `add_info()`
- `add_info(.data)` (so no further arguments) now checks to see whether metadata may be added and prompts the user to add it if so
- `add_info(.data, optional = TRUE)` extends this to further, optional metadata
- This includes prompting the user by layer for multiplex networks

# manynet 2.1.2

## Package
Expand Down
147 changes: 113 additions & 34 deletions R/manip_info.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#' @description
#' These functions allow users to add and edit information about the network
#' itself.
#' This includes the name, year, and mode of collection of the network,
#' as well as definitions of the nodes and ties in the network.
#' Where available, this information is printed for tidygraph-class objects,
#' and can be used for printing a grand table in the `{grand}` package.
#'
Expand All @@ -18,11 +16,28 @@
#' @eval detail_avail(".*_info")
#' @template fam_manip
#' @param ... Named attributes. The following are currently recognised:
#' "name", "year", and "doi" of the network,
#' "collection" or "mode" of the network
#' ("survey", "interview","sensor","observation","archival", or "simulation"),
#' "nodes" (a vector of the names of the nodes) or "vertex1"/"vertex2",
#' "ties" or "edge.pos"/"edge.neg" for defining the ties.
#' - "name" is the name of the network
#' - "modes" is the name(s) of the nodeset(s)
#' - "layers" is the name(s) of the tie type(s)
#' - "directed" is a logical vector indicating whether each layer is directed
#' - "source" is the source of the network ("empirical" or "synthetic")
#' - "method" is the method of data collection or model used
#' (e.g. "survey", "interview","sensor","observation","archival", or "simulation")
#' - "location" is the geographic, institutional, or digital location of the network
#' - "date" is the date of data collection or model run
#' - "boundary" is the boundary specification of the network ("ego", "roster", or "snowball")
#' - "observation" is the observation type of the network ("cross-sectional",
#' "panel", or "event")
#' - "update" is the update type of the network ("increment" or "replacement")
#' - "max_degree" is the maximum degree of the network
#' - "min_degree" is the minimum degree of the network
#' - "doi" is the DOI or URL of the network
#'
#' If no arguments are used,
#' the function will check for missing information and prompt the user to add it.
#' If `optional = TRUE` is specified, the function will also prompt for optional information.
#' @seealso \href{https://grand-statement.org}{GRAND statement} for more
#' information on the Guidelines for Reporting About Network Data (GRAND).
#' @examples
#' add_info(ison_algebra, name = "Algebra")
#' @export
Expand All @@ -42,7 +57,9 @@ add_info.igraph <- function(.data, ...){
}

info <- list(...)
if(length(info)==0) return(.check_info(.data))
optional <- info$optional %||% FALSE
info$optional <- NULL
if(length(info)==0) return(.check_info(.data, optional = optional))

unrecog <- setdiff(names(info), c("name", "nodes", "ties", "doi",
"source", "method", "location", "date", "system",
Expand Down Expand Up @@ -85,6 +102,12 @@ add_info.igraph <- function(.data, ...){
#' @export
add_info.stocnet <- function(.data, ...){
dots <- list(...)
# if dots contains optional = FALSE/TRUE
optional <- dots$optional %||% FALSE
dots$optional <- NULL
if(length(dots) == 0){
return(.check_info(.data, optional = optional))
}
for(item in names(dots)){
.data$info[[item]] <- dots[[item]]
}
Expand Down Expand Up @@ -130,48 +153,104 @@ net_attributes <- function(.data){
.check_info <- function(.data, optional = FALSE){

out <- .data
read_optional <- function(prompt) {
x <- readline(prompt)
if (x == "") NULL else x
}

# Names
if(is.null(net_name(.data)) || net_name(.data) == ""){
if(is.null(net_name(out)) || net_name(out) == ""){
snet_prompt("This network does not have a name. Please add one.")
out <- add_info(out, name = readline(prompt = "Network name: "))
} else snet_success("Network name: {net_name(out)}")
out <- add_info(out, name = read_optional(prompt = "Network name: "))
}
if(!is.null(net_name(out))) snet_success("Network name: {net_name(out)}")

# Nodes
if(is_twomode(.data) && is.null(mode_names(.data))){
# Nodes ####
if(is.null(mode_names(out))){
if(is_twomode(out)){
snet_prompt("This two-mode network does not have names for the nodesets. Please add one.")
out$nodes <- c(readline(prompt = "Nodeset 1 name: "),
readline(prompt = "Nodeset 2 name: "))
} else if(is_twomode(.data)){
snet_success("Nodesets: {mode_names(out)}")
} else if(!is_twomode(.data) && is.null(mode_names(.data))){
snet_prompt("This network does not have a name for the nodes. Please add one.")
out <- add_info(out, nodes = readline(prompt = "Nodeset name: "))
} else snet_success("Nodeset: {mode_names(out)}")
out$modes <- c(read_optional(prompt = "Nodeset 1 name: "),
read_optional(prompt = "Nodeset 2 name: "))
} else {
snet_prompt("This network does not have a name for the nodeset. Please add one.")
out <- add_info(out, modes = read_optional(prompt = "Nodeset name: "))
}}
if(!is.null(mode_names(out))) snet_success("Modes: {mode_names(out)}")

# Ties ####
if(is.null(layer_names(out))){
snet_prompt("This network does not have a name for the layer/type of tie. Please add one.")
out <- add_info(out, layers = read_optional(prompt = "Layer name: "))
}
if(!is.null(layer_names(out))) snet_success("Layers: {layer_names(out)}")
if(!"directed" %in% net_attributes(out)){
if(net_layers(out) > 1){
snet_prompt("This network has multiple layers. Please specify whether they are directed or undirected.")
for (layer in layer_names(out)) {
directed <- utils::menu(choices = c("Directed", "Undirected"),
title = paste0("Is the layer '", layer, "' directed or undirected?"))
out$info$directed[match(layer, layer_names(out))] <- stats::setNames(directed == 1, layer)
}
} else out <- add_info(out, directed = is_directed(.data))
}
if("directed" %in% net_attributes(out)) snet_success("Directed: {as_infolist(out)$directed}")

# Source & method
# Optionals ####
if(optional){
if(!"source" %in% net_attributes(.data)){
if(!"source" %in% net_attributes(out)){
snet_prompt("This network does not have a source. You may add one.")
source_options <- c("Observed", "Synthetic")
source <- utils::menu(choices = source_options, title = "Is this network observed or synthetic?")
source_options <- c("Empirical", "Synthetic")
source <- utils::menu(choices = source_options, title = "Is this network empirical or synthetic?")
if(source == 1){
method_options <- c("Survey", "Interview", "Sensor", "Archival", "Trace", "Ethnography")
out <- add_info(out, source = source_options[source],
method = utils::menu(choices = source_options, title = "Method: "))
method = utils::menu(choices = method_options, title = "Method: "))
out <- add_info(out, location = read_optional(prompt = "Location: "))
out <- add_info(out, date = read_optional(prompt = "Date: "))
bound_options <- c("Ego", "Roster", "Snowball")
out <- add_info(out, boundary = utils::menu(choices = bound_options, title = "Boundary: "))
} else if(source == 2){
out <- add_info(out, source = source_options[source],
method = readline(prompt = "Model: "))
method = read_optional(prompt = "Model: "))
}
if(!"doi" %in% net_attributes(out)){
out <- add_info(out, doi = read_optional(prompt = "DOI/URL: "))
}
if(!"max_degree" %in% net_attributes(out)){
out <- add_info(out, max_degree = read_optional(prompt = "Maximum degree: "))
}
if(!"min_degree" %in% net_attributes(out)){
out <- add_info(out, min_degree = read_optional(prompt = "Minimum degree: "))
}
} else snet_success("Source: {net_info(out)$source}")
if(!"observation" %in% net_attributes(out)){
obs_options <- c("Cross-sectional", "Panel", "Event")
for (layer in layer_names(out)) {
observation <- utils::menu(choices = obs_options,
title = paste0("The layer '", layer, "' is observed as: "))
out$info$observation[match(layer, layer_names(out))] <- stats::setNames(obs_options[observation], layer)
}
}
if(is_weighted(out) && !"update" %in% net_attributes(out)){
upd_options <- c("Increment", "Replacement")
for (layer in layer_names(out)) {
update <- utils::menu(choices = upd_options,
title = paste0("The layer '", layer, "' is updated by: "))
out$info$update[match(layer, layer_names(out))] <- stats::setNames(upd_options[update], layer)
}
}
}
if("source" %in% net_attributes(out)) snet_success("Source: {as_infolist(out)$source}")
if("method" %in% net_attributes(out)) snet_success("Method/Model: {as_infolist(out)$method}")
if("boundary" %in% net_attributes(out)) snet_success("Boundary: {as_infolist(out)$boundary}")
if("location" %in% net_attributes(out)) snet_success("Location: {as_infolist(out)$location}")
if("observation" %in% net_attributes(out)) snet_success("Observation: {as_infolist(out)$observation}")
if("update" %in% net_attributes(out)) snet_success("Update: {as_infolist(out)$update}")
if("max_degree" %in% net_attributes(out)) snet_success("Max degree: {as_infolist(out)$max_degree}")
if("min_degree" %in% net_attributes(out)) snet_success("Min degree: {as_infolist(out)$min_degree}")
if("date" %in% net_attributes(out)) snet_success("Date: {as_infolist(out)$date}")
if("doi" %in% net_attributes(out)) snet_success("DOI/URL: {as_infolist(out)$doi}")
}

# Ties
if(is.null(layer_names(.data))){
snet_prompt("This network does not have a name for the ties. Please add one.")
out <- add_info(out, ties = readline(prompt = "Ties name: "))
} else snet_success("Ties: {layer_names(out)}")

out
}

4 changes: 2 additions & 2 deletions R/measure_properties.R
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ mode_names.igraph <- function(.data){

#' @export
mode_names.stocnet <- function(.data){
.data$info$nodes
.data$info$modes
}

#' @rdname member_names
Expand Down Expand Up @@ -335,7 +335,7 @@ layer_names.igraph <- function(.data){

#' @export
layer_names.stocnet <- function(.data){
.data$info$ties
.data$info$layers %||% unique(.data$ties$layer)
}

#' @rdname member_names
Expand Down
3 changes: 1 addition & 2 deletions cran-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@

0 errors | 0 warnings | 0 notes

- Fixed README link issue
- Together with parallel submissions of 'netrics' and 'migraph', should pass all reverse dependency checks now too
- Though less than 10 days, this version fixes intermittent validation test error on CRAN
32 changes: 25 additions & 7 deletions man/manip_info.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/testthat/test-class_stocnet.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test_that("stocnet validation", {
reserved_cols(
.data = list(nodes = tibble::tibble(id = 1)),
component = "nodes",
reserved_cols = "label",
column = "label",
class = "character",
aka = c("name", "id")
),
Expand All @@ -17,7 +17,7 @@ test_that("stocnet validation", {
reserved_cols(
.data = list(nodes = tibble::tibble(mode = 1)),
component = "nodes",
reserved_cols = "mode",
column = "mode",
class = "character"
),
"'mode' must be of class 'character'."
Expand All @@ -26,7 +26,7 @@ test_that("stocnet validation", {
required_cols(
.data = list(nodes = tibble::tibble(nabel = 1)),
component = "nodes",
required_cols = "label"
column = "label"
),
"The 'nodes' component of a stocnet object must have the following columns: label."
)
Expand Down
Loading