--- title: "Introduction to GRAND" author: "Zachary Neal, Michigan State University, zpneal@msu.edu" output: rmarkdown::html_vignette: toc: true bibliography: grand_bib.bib link-citations: yes vignette: > %\VignetteIndexEntry{Introduction to GRAND} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") knitr::opts_knit$set(global.par = TRUE) ``` # Table of Contents {#toc} [](https://www.zacharyneal.com/backbone) 1. [Introduction](#introduction) a. [Welcome](#welcome) b. [What is GRAND?](#grand) b. [Loading the package](#loading) c. [Package overview](#overview) 2. [Adding GRAND attributes](#attributes) a. [Interactively](#interactive) a. [Not Interactively](#noninteractive) 3. [Generating a GRAND narrative](#narrative) 4. [Generating a GRAND table](#table) 5. [More examples](#examples) a. [Bipartite](#bipartite) b. [Signed](#signed) 6. [Utility functions](#utility) a. [`scan2()`](#scan) b. [`menu2()`](#menu) # Introduction {#introduction} ## Welcome {#welcome} Thank you for your interest in the `grand` package! This vignette illustrates how to use this package to describe a network following the **G**uidelines for **R**eporting **A**bout **N**etwork **D**ata (GRAND). The `grand` package can be cited as: **Neal, Z. P. (2023). grand: An R package for using the Guidelines for Reporting About Network Data. GitHub. *GitHub*. [https://github.com/zpneal/grand/](https://github.com/zpneal/grand/)** If you have questions about the grand package, please contact the maintainer Zachary Neal by email ([zpneal\@msu.edu](mailto:zpneal@msu.edu)) or via Mastodon ([\@zpneal@mastodon.social](https://mastodon.social/@zpneal)). Please report bugs in the backbone package at [https://github.com/zpneal/grand/issues](https://github.com/zpneal/grand/issues). ## What is GRAND? {#grand} Networks can represent a wide range of social and natural phenomena at many different scales, and so network data is often quite diverse. Additionally, methods for analyzing networks have evolved over several decades across multiple disciplines. As a result, different researchers, from different disciplinary backgrounds, studying networks representing different things, often describe their network data in very different (and sometimes incomplete) ways. The **G**uidelines for **R**eporting **A**bout **N**etwork **D**ata (GRAND) are an attempt to establish some basic reporting standards that can help facilitate consistent and complete description of networks in research publications, presentations, and data repositories. GRAND aims to be neutral with respect to discipline, method, and content, and therefore focuses only on a limited number of fundamental characteristics that are relevant for all networks: *What* does it represent? *When* and *where* did it come from? *How* is it measured? ## Loading the package {#loading} The backbone package can be loaded in the usual way: ```{r setup} library(grand) ``` Upon successful loading, a startup message will display that shows the version number, citation, ways to get help, and ways to contact us. ## Package overview {#overview} The package offers three basic functions: * `grand()` interactively queries the user about a network, and saves the responses as graph attributes. * `grand.text()` writes a uniform narrative description of the network. * `grand.table()` plots a uniform tabular description of the network, in the style of a US Nutrition Label. Because the goal of GRAND is to bring consistency and uniformity to the description of network data, these functions offer relatively few options. They are designed to provide a minimal uniform description that is suitable for any network and any context, which users can supplement with additional network-specific and context-specific details. [back to Table of Contents](#toc) # Adding GRAND attributes {#attributes} ## Interactively {#interactive} The `grand()` function applies GRAND to a network stored as an igraph object. It offers in *interactive* mode that guides the user through GRAND by asking a series of questions, and a *non-interactive* mode that allows the user to directly specify GRAND attributes. This section illustrates `grand()` with the example `airport` data, which is a weighted and directed network of passenger air traffic in the United States in 2019, and which can be loaded using: ```{r} data(airport) ``` To interactively add GRAND attributes, use: ``` airport <- grand(airport) This graph already contains a GRAND attribute. Do you want to overwrite (Y/N)? 1: Y What is the name of this network (enter NA if unnamed)? 1: US Air Traffic Network What DOI is associated with this network (enter NA if unnamed)? 1: 10.1371/journal.pone.0269137 How were these data collected or generated? 1: Survey 2: Interview 3: Sensor 4: Observation 5: Archival 6: Simulation 7: Other Selection: 5 In what year were these data collected? 1: 2019 This network contains 382 nodes. What type of entity do these represent (e.g., people)? 1: Airports ``` This code block illustrates the first several questions, and appropriate responses, and they would appear in the interactive mode. The first set of interactive questions ask about the **data** as a whole: * _name_ - What is the name of the network? This should usually be specified ending with the word "network" or "data" (e.g. "Florentine Families Network" or "Airline Traffic Data"). * _doi_ - What is the DOI associated with the network? This could be a DOI for the data itself (e.g., if it is available online), or could be the DOI for a manuscript describing the data. * Data collection _mode_ - How were these data collected or generated. Chose one of the available options (Survey, Interview, Sensor, Observation, Archival, or Simulation) or choose `Other` to enter something else. * _year_ - In what year were the data collected? The second set of interactive questions ask about the **nodes** or vertices: * _vertex1_ (and in bipartite graphs, _vertex2_) - What type of entity do the nodes/vertices represent? This should be specified as a plural noun (e.g., "People"). * _vertex1.total_ (and in bipartite graphs, _vertex2.total_) - Networks often have an externally-defined boundary that determines which nodes/vertices should be included, even if some are missing from the network. If the network has a boundary: How many entities are included in the network's boundary. This is used to compute rates of missingness (e.g. a classroom contained 20 children, but only 18 provided network data; 10% node missingness). The third set of interactive questions ask about the **edges**: * _edge.pos_ (and in signed graphs, _edge.neg_) - What type of relationship do the edges represent? This should be specified as a plural noun (e.g., "Friendships"). * _weight_ - What do the edge weights represent? There are four default options: Frequency (how often), Intensity (how strong), Multiplexity (how many), or Valence (positive or negative). Choosing `Other` prompts to enter another option. * _measure_ - How are the edge weights measured? There are four defauly options:Continuous, Count, Ordinal, or Categorical. Choosing `Other` prompts to enter another option. The final interactive question asks about relevant **topological** characteristics. Some topological characteristics are reported by default (depending on the type of network), however it is possible to request that additional topological characteristics are also reported. The available topological characteristics include: * _clustering coefficient_ - Computed using `transitivity(G, type = "localaverage")` * _degree centralization_ - Computed using `centr_degree(G)$centralization` * _degree distribution_ - Computed using `fit_power_law(degree(G), implementation = "plfit")` * _density_ - Computed using `edge_density(G)` * _diameter_ - Computed using `diameter(G)` * _efficiency_ - Computed using `global_efficiency(G)` * _mean degree_ - Computed using `mean(degree(G))` * _modularity_ - Computed from a partition generated by `cluster_leiden(G, objective_function = "modularity")` * _number of communities_ - Computed from a partition generated by `cluster_leiden(G, objective_function = "modularity")` * _number of components_ - Computed using `count_components(G)` * _transitivity_ - Computed using `transitivity(G, type = "global")` * _structural balance_ - Computed using the triangle index ## Not Interactively {#noninteractive} It is also possible to add GRAND attributes directly, using: ```{r} airport <- grand(airport, interactive = FALSE, #Apply GRAND non-interactively name = "US Air Traffic Network", doi = "10.1371/journal.pone.0269137", vertex1 = "Airports", vertex1.total = 382, edge.pos = "Routes", weight = "Passengers", measure = "Count", mode = "Archival", year = "2019", topology = c("clustering coefficient", "mean path length", "degree distribution")) ``` Using the non-interactive mode requires knowing which parameters to specify given the type of network and knowing what values to supply each parameter. For example, here we specify the `vertex1` parameter but not the `vertex2` parameter because this is a unipartite network with only one type of node. Similarly, we supply `"Archival"` as the value for the `mode` parameter because this parameter records the mode of data collection. These issues are automated in the interactive mode, however the non-interactive mode offers greater flexibility and the ability to add GRAND attributes when running R scripts. [back to Table of Contents](#toc) # Generating a GRAND narrative {#narrative} The `grand.text()` function writes a complete and uniform narrative description of the network. For example: ```{r} grand.text(airport) ``` [back to Table of Contents](#toc) # Generating a GRAND table {#table} The `grand.table()` function plots writes a complete and uniform tabular description of the network, in the style of a US Nutrition Label. For example: ```{r, fig.width=3.5, fig.height=4} grand.table(airport) ``` A table can be exported for use in a paper or presentation using a graphics device. For example: ``` pdf("grand.pdf", width = 3.5, height = 4) grand.table(airport) dev.off() ``` [back to Table of Contents](#toc) # More examples {#examples} ## A bipartite network {#bipartite} The example `cosponsor` data is a bipartite network representing US Senators' (co-)sponsorship of Senate Bills during the 116th session (2019-2020). It can be loaded, and narrative and tabular summaries can be obtained, using: ```{r, fig.width=3.5, fig.height=4} data(cosponsor) grand.text(cosponsor) grand.table(cosponsor) ``` [back to Table of Contents](#toc) ## A signed network {#signed} The example `senate` data is a signed network representing US Senators' representing US Senators' alliances and antagonisms during the 116th session (2019-2020). It can be loaded, and narrative and tabular summaries can be obtained, using: ```{r, fig.width=3.5, fig.height=4} data(senate) grand.text(senate) grand.table(senate) ``` [back to Table of Contents](#toc) # Utility functions {#utility} The `grand` package includes a couple exported utility functions that are extensions of user input functions in base `R`. These functions are used by `grand()` to interactively query the user about the supplied `igraph` object. ## `scan2()` {#scan} The `scan2()` function is an extension of `scan()` that allows the specification of a required input format using the `type` parameter. Currently four input types are allowed: `character`, `numeric`, `integer`, or a vector of allowable responses. For example: ``` #Requiring an integer input scan2(prompt = "Enter an integer", type = "integer") Enter an integer 1: q Please enter an integer. 1: 2.5 Please enter an integer. 1: 1 [1] 1 #Requiring an input from a vector of possibilities > scan2(prompt = "Do you like this function (Y/N)?", type = c("Y", "N", "y", "n")) Do you like this function (Y/N)? 1: 3 Please enter one of these options: Y N y n 1: yes Please enter one of these options: Y N y n 1: Y [1] "Y" ``` ## `menu2()` {#menu} The `menu2()` function is an extension of `utils::menu()` that returns the text of the selected choice as a string, and allows looping so that the user can make multiple choices. For example: ``` #Allowing a single choice menu2(choices = c("A", "B", "C"), title = "Choose an option", loop = FALSE) Choose an option 1: A 2: B 3: C Selection: 1 [1] "A" #Allowing multiple choices menu2(choices = c("A", "B", "C"), title = "Choose an option", loop = TRUE) Choose an option 1: A 2: B 3: C Selection: 2 Choose an option 1: A 2: C Selection: 1 Choose an option 1: C Selection: 0 [1] "B" "A" ``` [back to Table of Contents](#toc)