diff --git a/DESCRIPTION b/DESCRIPTION index f1dc3465b..10c19cfc0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: migraph Title: Inferential Methods for Multimodal and Other Networks -Version: 1.5.7 -Date: 2026-02-18 +Version: 1.6.0 +Date: 2026-04-04 Description: A set of tools for testing networks. It includes functions for univariate and multivariate conditional uniform graph and quadratic assignment procedure testing, @@ -22,17 +22,22 @@ RoxygenNote: 7.3.3 Depends: R (>= 3.6.0), manynet (>= 1.0.5), - autograph (>= 0.4.0) + autograph (>= 0.4.0), + netrics Imports: dplyr (>= 1.1.0), ergm, future, furrr, generics, + knitr, + learnr, purrr Suggests: covr, + rmarkdown, roxygen2, + shiny, testthat (>= 3.0.0) Authors@R: c(person(given = "James", @@ -58,4 +63,4 @@ Authors@R: Roxygen: list(markdown = TRUE, roclets = c("namespace", "rd")) Config/testthat/parallel: true Config/testthat/edition: 3 -Config/testthat/start-first: helper-functions +Config/testthat/start-first: tutorials_manynet diff --git a/NAMESPACE b/NAMESPACE index 6ae921317..df07aa527 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -12,13 +12,13 @@ S3method(print,netlogit) S3method(print,network_test) S3method(print,over_memb) S3method(summary,diffs_model) -S3method(summary,ergm) S3method(summary,sienaFit) S3method(tidy,ergm) S3method(tidy,netlm) S3method(tidy,netlogit) S3method(tidy,sienaFit) export("%>%") +export(extract_tute) export(glance) export(net_regression) export(network_reg) @@ -26,17 +26,23 @@ export(over_membership) export(over_time) export(over_waves) export(play_diffusions) +export(run_tute) export(test_configuration) export(test_distribution) export(test_fit) export(test_gof) export(test_permutation) export(test_random) +export(test_tutorials) export(tidy) importFrom(autograph,ag_base) +importFrom(dplyr,"%>%") importFrom(dplyr,`%>%`) +importFrom(dplyr,as_tibble) importFrom(dplyr,bind_cols) importFrom(dplyr,left_join) +importFrom(dplyr,select) +importFrom(dplyr,tibble) importFrom(ergm,as.rlebdm) importFrom(furrr,furrr_options) importFrom(furrr,future_map_dfr) @@ -50,6 +56,7 @@ importFrom(manynet,is_complex) importFrom(manynet,is_directed) importFrom(manynet,play_diffusion) importFrom(manynet,to_subgraph) +importFrom(netrics,net_by_heterophily) importFrom(purrr,flatten) importFrom(stats,as.formula) importFrom(stats,binomial) diff --git a/NEWS.md b/NEWS.md index 6c583a040..b095cbd7d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,10 +1,33 @@ -# migraph 1.5.7 +# migraph 1.6.0 + +2026-04-04 + +## Package + +- Updated logo +- Now Depends on `{netrics}` +- Fixed generic arguments and rely on `dplyr::tibble()` instead of `tibble::tibble()` internally + +## Testing + +- Fixed `test_permutation()` to use `netrics::net_by_density()` +- Fixed `net_regression()` to use `manynet::to_permuted()` + +## Tutorials + +- Moved `run_tute()` and `extract_tute()` from `{manynet}` to here +- Fixed `fict_marvel` example +- Fixed diversity tutorial to work with `fict_marvel` +- Fixed ergm tutorial to work with `{netrics}` +- Moved tutorial0/data from `{manynet}` +- Added tutorial testing, with a quiet option +- Tutorials are highlighted in the README -2026-02-18 +# migraph 1.5.7 -- Using fict_marvel in tests -- Added tidy(), glance(), and summary() methods for sienaFit class objects -- Added summary.ergm() +- Using `fict_marvel` in tests +- Added `tidy()`, `glance()`, and `summary()` methods for sienaFit class objects +- Added `summary.ergm()` # migraph 1.5.6 diff --git a/R/class_models.R b/R/class_models.R index b8e9f3576..d5644813e 100644 --- a/R/class_models.R +++ b/R/class_models.R @@ -98,14 +98,15 @@ tidy.ergm <- function( } #' @method tidy sienaFit +#' @importFrom dplyr tibble #' @export -tidy.sienaFit <- function(ans){ - tibble::tibble( - dv = ans$effects$name, - term = ans$effects$effectName, - estimate = ans$theta, - se = ans$se, - tstat = ans$theta/ans$se +tidy.sienaFit <- function(x, ...){ + dplyr::tibble( + dv = x$effects$name, + term = x$effects$effectName, + estimate = x$theta, + std.error = x$se, + statistic = x$theta/x$se ) } @@ -252,10 +253,10 @@ glance.ergm <- function(x, deviance = FALSE, mcmc = FALSE, ...) { #' @method glance sienaFit #' @export -glance.sienaFit <- function(ans){ - tibble::tibble( - tmax = ans$tmax, - tconv.max = ans$tconv.max[,1] +glance.sienaFit <- function(x, ...){ + dplyr::tibble( + tmax = x$tmax, + tconv.max = x$tconv.max[,1] ) } @@ -275,20 +276,21 @@ print.netlogit <- function(x, ...){ print(glance(x)) } -#' @export -summary.ergm <- function(x, ...){ - cat("# Fitted model results\n") - print(tidy(x)) - cat("\n# Model summary statistics\n") - print(glance(x)) -} +# Unused because infinite recursion through summary.ergm() in tidy.ergm() +# #' @export +# summary.ergm <- function(x, ...){ +# cat("# Fitted model results\n") +# print(tidy(x)) +# cat("\n# Model summary statistics\n") +# print(glance(x)) +# } #' @export -summary.sienaFit <- function(x, ...){ +summary.sienaFit <- function(object, ...){ cat("# Fitted model results\n") - print(tidy(x)) + print(tidy(object)) cat("\n# Model summary statistics\n") - print(glance(x)) + print(glance(object)) } diff --git a/R/migraph-package.R b/R/migraph-package.R index e261fff0b..162473cc6 100644 --- a/R/migraph-package.R +++ b/R/migraph-package.R @@ -20,15 +20,18 @@ thisRequires <- function(pkgname){ } # defining global variables more centrally -utils::globalVariables(c(".data", "obs", "fin","n","sim","time","value","conf.low","conf.high")) +utils::globalVariables(c(".data", "obs", "fin","n","sim","time","value","conf.low","conf.high", + "name")) # Suppress R CMD check note # Namespace in Imports field not imported from: PKG # All declared Imports should be used. #' @importFrom autograph ag_base +#' @importFrom netrics net_by_heterophily ignore_unused_imports <- function() { # This function exists only to reference autograph::ag_base and suppress R CMD check notes about unused imports. autograph::ag_base + netrics::net_by_heterophily NULL } diff --git a/R/model_regression.R b/R/model_regression.R index 09afd7d48..0af2110fc 100644 --- a/R/model_regression.R +++ b/R/model_regression.R @@ -171,14 +171,14 @@ net_regression <- function(formula, .data, on.exit(future::plan(oplan), add = TRUE) if(valued){ repdist <- furrr::future_map_dfr(1:times, function(j){ - nlmfit(c(list(manynet::generate_permutation(g[[1]], with_attr = FALSE)), + nlmfit(c(list(manynet::to_permuted(g[[1]], with_attr = FALSE)), g[2:(nx+1)]), directed = directed, diag = diag, rety = FALSE) }, .progress = verbose, .options = furrr::furrr_options(seed = T)) } else { repdist <- furrr::future_map_dfr(1:times, function(j){ - repfit <- nlgfit(c(list(manynet::generate_permutation(g[[1]], with_attr = FALSE)), + repfit <- nlgfit(c(list(manynet::to_permuted(g[[1]], with_attr = FALSE)), g[2:(nx+1)]), directed = directed, diag = diag) repfit$coef/sqrt(diag(chol2inv(repfit$qr$qr))) @@ -207,14 +207,14 @@ net_regression <- function(formula, .data, if(valued){ repdist[,i] <- furrr::future_map_dbl(1:times, function(j){ nlmfit(c(g[-(1 + i)], - list(manynet::generate_permutation(xres, with_attr = FALSE))), + list(manynet::to_permuted(xres, with_attr = FALSE))), directed = directed, diag = diag, rety = FALSE)[nx] }, .progress = verbose, .options = furrr::furrr_options(seed = T)) } else { repdist[,i] <- furrr::future_map_dbl(1:times, function(j){ repfit <- nlgfit(c(g[-(1 + i)], - list(manynet::generate_permutation(xres, with_attr = FALSE))), + list(manynet::to_permuted(xres, with_attr = FALSE))), directed = directed, diag = diag) repfit$coef[nx]/sqrt(diag(chol2inv(repfit$qr$qr)))[nx] }, .progress = verbose, .options = furrr::furrr_options(seed = T)) diff --git a/R/model_tests.R b/R/model_tests.R index f77d96d90..f7ebf75f2 100644 --- a/R/model_tests.R +++ b/R/model_tests.R @@ -23,10 +23,10 @@ NULL #' @rdname tests #' @importFrom manynet generate_random bind_node_attributes is_directed is_complex #' @examples -#' marvel_friends <- to_unsigned(ison_marvel_relationships) -#' marvel_friends <- to_giant(marvel_friends) %>% +#' marvel_friends <- fict_marvel %>% to_uniplex("relationship") %>% +#' to_unsigned() %>% to_giant() %>% #' to_subgraph(PowerOrigin == "Human") -#' (cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", +#' (cugtest <- test_random(marvel_friends, net_by_heterophily, attribute = "Attractive", #' times = 200)) #' # plot(cugtest) #' @export @@ -119,7 +119,7 @@ test_configuration <- function(.data, FUN, ..., #' @rdname tests #' @examples #' # (qaptest <- test_permutation(marvel_friends, -#' # manynet::net_heterophily, attribute = "Attractive", +#' # net_by_heterophily, attribute = "Attractive", #' # times = 200)) #' # plot(qaptest) #' @export @@ -134,7 +134,7 @@ test_permutation <- function(.data, FUN, ..., obsd <- FUN(.data) } n <- manynet::net_dims(.data) - d <- manynet::net_density(.data) + d <- netrics::net_by_density(.data) oplan <- future::plan(strategy) on.exit(future::plan(oplan), add = TRUE) rands <- furrr::future_map(1:times, diff --git a/R/tutorial_run.R b/R/tutorial_run.R new file mode 100644 index 000000000..3c1af167c --- /dev/null +++ b/R/tutorial_run.R @@ -0,0 +1,92 @@ +# Tutorials overview #### + +#' Open and extract code from tutorials +#' +#' @description +#' These functions make it easy to use the tutorials +#' in the `{manynet}` and `{migraph}` packages: +#' +#' - `run_tute()` runs a `{learnr}` tutorial from +#' either the `{manynet}` or `{migraph}` packages, +#' wraps `learnr::run_tutorial()` with some convenience. +#' - `extract_tute()` extracts and opens just the solution code +#' from a `{manynet}` or `{migraph}` tutorial, +#' saving the .R script to the current working directory. +#' +#' @param tute String, name of the tutorial (e.g. "tutorial2"). +#' @importFrom dplyr %>% as_tibble select tibble +#' @name tutorials +NULL + +stocnet <- c("manynet", "migraph", "autograph") + +#' @rdname tutorials +#' @export +run_tute <- function(tute) { + thisRequires("learnr") + avail_pkgs <- stocnet[suppressWarnings(unlist(lapply(stocnet, + function(x) nzchar(system.file(package = x)))))] + if (missing(tute)) { + tutelist <- lapply(manynet::snet_progress_along(avail_pkgs, + name = "Checking tutorials in stocnet packages"), + function(p){ + dplyr::as_tibble(learnr::available_tutorials(package = avail_pkgs[p]), + silent = TRUE) %>% dplyr::select(1:3) + }) + dplyr::bind_rows(tutelist) %>% dplyr::arrange(name) %>% print() + manynet::snet_info("You can run a tutorial by typing e.g `run_tute('tutorial1')` or `run_tute('Data')` into the console.") + } else { + try(learnr::run_tutorial(tute, "manynet"), silent = TRUE) + try(learnr::run_tutorial(tute, "migraph"), silent = TRUE) + try(learnr::run_tutorial(tute, "autograph"), silent = TRUE) + manynet::snet_info("Didn't find a direct match, so looking for close matches...") + tutelist <- lapply(manynet::snet_progress_along(avail_pkgs, + name = "Checking tutorials in stocnet packages"), function(p){ + dplyr::as_tibble(learnr::available_tutorials(package = avail_pkgs[p]), + silent = TRUE) %>% dplyr::select(1:3) + }) + avails <- dplyr::bind_rows(tutelist) + inftit <- grepl(tute, avails$title, ignore.case = TRUE) + if(!any(inftit) | sum(inftit)>1) + inftit <- which.min(utils::adist(tute, avails$title, ignore.case = TRUE, + costs = list(ins=0, del=1, sub=1))) + if(any(inftit) & sum(inftit)==1){ + manynet::snet_success("And found one!") + try(learnr::run_tutorial(avails$name[inftit], avails$package[inftit]), silent = TRUE) + } else{ + manynet::snet_warn("...and couldn't find which one you meant. Please specify one of these titles:\n") + print(avails) + } + } +} + +#' @rdname tutorials +#' @export +extract_tute <- function(tute) { + if (missing(tute)) { + thisRequires("learnr") + avail_pkgs <- stocnet[suppressWarnings(unlist(lapply(stocnet, function(x) nzchar(system.file(package = x)))))] + tutelist <- lapply(manynet::snet_progress_along(avail_pkgs, + name = "Checking tutorials in stocnet packages"), function(p){ + dplyr::as_tibble(learnr::available_tutorials(package = avail_pkgs[p]), + silent = TRUE) %>% dplyr::select(1:3) + }) + dplyr::bind_rows(tutelist) %>% dplyr::arrange(name) %>% print() + manynet::snet_info("You can extract the code from one of these tutorials by typing e.g `extract_tute('tutorial1')` into the console.") + } else { + thisRequires("knitr") + pth <- file.path(path.package("manynet"), "tutorials", tute) + if(!dir.exists(pth)) { + thisRequires("autograph") + pth <- gsub("manynet", "autograph", pth) + } + if(!dir.exists(pth)) { + thisRequires("migraph") + pth <- gsub("autograph", "migraph", pth) + } + knitr::purl(file.path(pth, list.files(pth, pattern = "*.Rmd")), + documentation = 1) + utils::file.edit(gsub(".Rmd", ".R", list.files(pth, pattern = "*.Rmd"))) + } +} + diff --git a/R/tutorial_test.R b/R/tutorial_test.R new file mode 100644 index 000000000..0af38efc7 --- /dev/null +++ b/R/tutorial_test.R @@ -0,0 +1,34 @@ +#' Test tutorials +#' +#' @description +#' For our purposes, "testing" a tutorial means being able to +#' (successfully) run `render()` on it. +#' This function renders the tutorial provided in `path`. +#' There is no check to see if the rendered file looks OK. +#' If a tutorial fails to render, then an error will be generated which will +#' propagate to the caller. +#' @param path Character vector of the paths to the tutorials to be knitted. +#' @param quiet Logical, whether to suppress messages from `render()`. +#' @returns No return value, called for side effects. +#' @author David Kane, see tutorial.helpers +#' @export +test_tutorials <- function(path, quiet = TRUE){ + + stopifnot(all(file.exists(path))) + + for(i in path){ + if(!quiet) message("Rendering: ", basename(i)) + tryCatch({ + rmarkdown::render(input = i, + output_dir = tempdir(), + intermediates_dir = tempdir(), quiet = quiet) + # Note that the Debian setup on CRAN does not allow for writing files to any + # location other than the temporary directory, which is why we must specify + # tempdir() in the two dir arguments. + if(!quiet) message("Successfully rendered: ", basename(i)) + }, error = function(e) { + stop("Failed to render ", i, ": ", e$message, call. = FALSE) + }) + } + invisible(NULL) +} \ No newline at end of file diff --git a/README.Rmd b/README.Rmd index 50b7ab01e..8e832dce6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -103,7 +103,9 @@ for two-mode networks as well as one-mode networks. ## Tutorials -Together with `{manynet}`, this package makes available interactive `{learnr}` tutorials. +This package makes available interactive `{learnr}` tutorials to help new and +experienced users learn how they can conduct social network analysis using the +stocnet packages. The easiest way to access the tutorials is via `run_tute()`. If no tutorial name is provided, the function will return a list of tutorials currently available in either package: diff --git a/README.md b/README.md index fbf80af2e..c905d7ab6 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,8 @@ conditional uniform graph (CUG) or quadratic assignment procedure (QAP) distributions using: - `test_configuration()`, `test_distribution()`, `test_fit()`, - `test_gof()`, `test_permutation()`, `test_random()` + `test_gof()`, `test_permutation()`, `test_random()`, + `test_tutorials()` Plot showing the results of a QAP test @@ -98,28 +99,31 @@ two-mode networks as well as one-mode networks. ## Tutorials -Together with `{manynet}`, this package makes available interactive -`{learnr}` tutorials. The easiest way to access the tutorials is via -`run_tute()`. If no tutorial name is provided, the function will return -a list of tutorials currently available in either package: +This package makes available interactive `{learnr}` tutorials to help +new and experienced users learn how they can conduct social network +analysis using the stocnet packages. The easiest way to access the +tutorials is via `run_tute()`. If no tutorial name is provided, the +function will return a list of tutorials currently available in either +package: ``` r library(migraph) run_tute() -#> Checking tutorials in stocnet packages ■■■■■■■■■■■■■■■■ 50% | … -#> # A tibble: 9 × 3 -#> package name title -#> -#> 1 manynet tutorial0 Intro to R -#> 2 manynet tutorial1 Data -#> 3 manynet tutorial2 Visualisation -#> 4 manynet tutorial3 Centrality -#> 5 manynet tutorial4 Cohesion and Community -#> 6 manynet tutorial5 Position and Equivalence -#> 7 manynet tutorial6 Topology and Resilience -#> 8 manynet tutorial7 Diffusion and Learning -#> 9 migraph tutorial8 Diversity and Regression -#> ℹ You can run one of these tutorials by typing e.g `run_tute('tutorial1')` or `run_tute('Data')` into the console. +#> Checking tutorials in stocnet packages ■■■■■■■■■■■ 33% | … +#> # A tibble: 10 × 3 +#> package name title +#> +#> 1 manynet tutorial0 Intro to R +#> 2 manynet tutorial1 Data +#> 3 autograph tutorial2 Visualisation +#> 4 manynet tutorial3 Centrality +#> 5 manynet tutorial4 Cohesion and Community +#> 6 manynet tutorial5 Position and Equivalence +#> 7 manynet tutorial6 Topology and Resilience +#> 8 migraph tutorial7 Diffusion and Learning +#> 9 migraph tutorial8 Diversity and Regression +#> 10 migraph tutorial9 Modelling with ERGMs +#> ℹ You can run a tutorial by typing e.g `run_tute('tutorial1')` or `run_tute('Data')` into the console. # run_tute("tutorial5") ``` diff --git a/cran-comments.md b/cran-comments.md index 4631e4d7a..8d0c3374d 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -9,4 +9,4 @@ 0 errors | 0 warnings | 0 notes -- This release is required to avoid a reverse dependency issue because of renaming some data in the manynet package +- Updates to bring autograph into line with latest version of manynet (> v2.0.0) diff --git a/inst/migraph.pdf b/inst/migraph.pdf new file mode 100644 index 000000000..438bc645f Binary files /dev/null and b/inst/migraph.pdf differ diff --git a/inst/migraph.png b/inst/migraph.png deleted file mode 100644 index 13092a832..000000000 Binary files a/inst/migraph.png and /dev/null differ diff --git a/inst/migraph_logo.png b/inst/migraph_logo.png deleted file mode 100644 index 3b2f31414..000000000 Binary files a/inst/migraph_logo.png and /dev/null differ diff --git a/inst/migraph_old.png b/inst/migraph_old.png index 80fc85e57..3b2f31414 100644 Binary files a/inst/migraph_old.png and b/inst/migraph_old.png differ diff --git a/inst/migraph_older.png b/inst/migraph_older.png new file mode 100644 index 000000000..80fc85e57 Binary files /dev/null and b/inst/migraph_older.png differ diff --git a/inst/tutorials/tutorial0/.gitignore b/inst/tutorials/tutorial0/.gitignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/inst/tutorials/tutorial0/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/inst/tutorials/tutorial0/tutorial0.Rmd b/inst/tutorials/tutorial0/tutorial0.Rmd new file mode 100644 index 000000000..a1af70dd0 --- /dev/null +++ b/inst/tutorials/tutorial0/tutorial0.Rmd @@ -0,0 +1,426 @@ +--- +title: "Intro to R" +author: "by James Hollway" +output: + learnr::tutorial: + theme: bootstrap +runtime: shiny_prerendered +description: > + The aim of this tutorial is to offer a very, very short introduction to R + including objects, functions, and data structures in R. +--- + +```{r setup, include=FALSE} +library(learnr) +knitr::opts_chunk$set(echo = FALSE) +``` + +## Aims + +This is not a course to learn R. +The aim of this tutorial is to offer a very, very short introduction +so that you have a basic introduction as we move forward. +In this tutorial, we will introduce: + +- objects in R +- functions in R +- data structures in R + +If you would like to develop your skills further (not such a bad idea) +there are plenty of excellent online courses and resources available. +Recommended elsewhere are the following: + +- https://cran.r-project.org/doc/manuals/R-intro.html#Introduction-and-preliminaries +- https://www.datacamp.com/community/open-courses/r-programming-with-swirl +- http://www.burns-stat.com/pages/Tutor/hints_R_begin.html +- http://data.princeton.edu/R/gettingStarted.html +- http://www.ats.ucla.edu/stat/R/sk/ +- http://www.statmethods.net/ +- https://www.r-bloggers.com/2022/05/best-books-to-learn-r-programming-2/ + +These sites will help you learn or refresh your memory. +But you can also expect to return to Google often as you go and type "R ..." as a query. +That's fine, and totally normal. +You will find as you do so that answers to most questions are available +on fora pages such as [StackOverflow](https://stackoverflow.com/questions/tagged/r) +and [CrossValidated](https://stats.stackexchange.com/?tags=r). + +## Software + +For this course, you will need to download and install two software, +R and RStudio, to your system. +Since you are completing this tutorial, we assume you have already done so, +but here we briefly explain the purpose of each. + +### What is R? + +R logo + +[R](http://www.r-project.org/) is a programming language and environment for statistical computing and graphics. +R is available as Free Software under the terms of the Free Software Foundation's +GNU General Public License, +and provides a wide variety of statistical (linear and nonlinear modelling, +classical statistical tests, time-series analysis, classification, ...) +and graphical techniques, and is highly extensible. +This means that anybody can write extensions to R and make them publicly available, +such as in the [stocnet](https://github.com/stocnet) group of packages... + +### What is RStudio? + +RStudio logo + +[RStudio](https://posit.co/products/open-source/rstudio/) is an integrated development environment (IDE) for R and Python, +enabling researchers to interact with R (and/or Python) through a fully-functional editor +with syntax highlighting, direct code execution, autocomplete, +and various tools for plotting, history, debugging, package development, and workspace management. + +In the end, although you will need to make sure R has been downloaded and installed +correctly on the system you are using, +in practice you will never open it directly. +Instead you will be using RStudio to interact with R. +Think of R as the internals of the calculator, but RStudio as the case. +Let's start the calculator but opening the 'calculator case' app, RStudio. + +## Getting started + +### RStudio and R scripts + +If we open and take a look around RStudio, we should see a window of four (4) panes. +Among them there should be a **console**: +this is where RStudio executes commands in R. +You can type commands yourself (RStudio may help by suggesting autocompletions), +but we usually write code in an R script instead, +and then tell RStudio when to execute one or more lines from the script. +There are basically three reasons for using a script: editing, repetition, sharing. +You can run a command in RStudio by moving the cursor to the line or lines you want to run +and then press Cmd-Enter (Mac) or Ctrl-Enter (Windows). +You can try this with the following lines: + +```{r printing-results, exercise = TRUE} +1 + 5 # This will print the result +105 * 99 + 6 # An asterisk is used for multiplication +``` + +Note that R won't execute anything after a comment `#`. +Remove the hash symbol at the start of this line to run it: + +```{r comments, exercise = TRUE} +# 1/5 # this will still be commented... +``` + +In an R script you can toggle commenting for one or more lines using Cmd-Shift-C/Ctrl-Shift-C. +If you try to run a commented out line, it will continue until it finds the next command. + +### Beyond a calculator + +Ok, wow, R is a calculator! +But it is also much, much more than that... +Try the following command: + +```{r hello-world, exercise = TRUE} +print("Hello World") +``` + +You've told R to print a string of text (identified by the quotation marks) to the console. +Much more flexible than a high school calculator! + +It is important to note that R is case-sensitive, +i.e. `Print("Hello World")` will not work. Try it! + +```{r Print-hello-world, exercise = TRUE} +Print("Hello World") +``` + +```{r case-sensitivity-question, purl=FALSE} +question("Why does Print('Hello World') cause an error?", + answer("Because print is spelled with a capital P", + correct = TRUE), + answer("Because the print function has already been used"), + answer("Because the print function has been lost"), + answer("Because of face insensitivity"), + random_answer_order = TRUE, + allow_retry = TRUE +) +``` + + +This means that `james` is not the same as `JAMES` (and `Hollway` is not the same as `Holloway`...). +In R, we can write such logical statements as: + +```{r equivalence, exercise = TRUE} +"James"=="james" # Try also "James"!="james" +# Other logical statements include: ">", ">=", "<=", "<". +# 1 < 5 # Try also "1 <= 5" +``` + +Logical values are always either `TRUE` or `FALSE`, +but can be abbreviated as `T` or `F` respectively. +Why do we have to use two equals signs and quotation marks? +Quotation marks tells R you are referring to a string of text and not a named _object_. + +## Objects + +### Values + +An object is a placeholder R uses for one or more numbers, strings, or other things. +You can assign such things to an object using one `=` sign, +but it's better to use `<-` to avoid mistakes related to `=` use also in logical statements. + +```{r assignment, exercise = TRUE} +surname <- "Hollway" +y.chromosome <- T # or TRUE +siblings <- 1 +age <- NA # This is used for missing information +# Note that these objects then appear in RStudio's environment pane (by default the top right) +``` + +You can then recover this information by simply calling these objects: + +```{r calling, exercise = TRUE, exercise.setup = "assignment"} +surname +y.chromosome +siblings +age +``` + +And even operate on them: + +```{r mult, exercise = TRUE, exercise.setup = "assignment"} +siblings*3 +# Try multiplying the other objects by 3 +``` + +### Vectors + +We can also concatenate multiple values together using the function `c()`: + +```{r concatenation, exercise = TRUE} +lived <- c("New Zealand", "UK", "New Zealand", "Germany", "UK", "Switzerland") +``` + +And recall them. Where was the fourth place I lived? +We use square brackets `[ ]` for indexing: + +```{r indexing, exercise = TRUE, exercise.setup = "concatenation"} +lived[4] +``` + +There are several shortcuts for making a series of values. +For example, consecutive numbers can be produced with: + +```{r series, exercise = TRUE} +teenageyrs <- 13:19 +teenageqrtrs <- seq(13, 19.99, by = 0.25) +# We can recall every third value from this object using a repeating vector +teenageqrtrs +teenageqrtrs[c(FALSE, FALSE, TRUE)] +# teenageqrtrs[c(F, F, T)] # Also works but it is best practice to write out the logic. +``` + +So R can help us store and recall values and even vectors of values, +but the key is being able to relate values and vectors together. +For that we use objects of more complex _classes_. + +## Classes + +### Matrices + +Data can be aggregated in R into different formats, such as data frames and lists +but the most common one used for network research is the matrix format. +Matrices are created by populating a given number of rows and columns with data +Assigning, `<-`, doesn't print any output unless you wrap the line in parentheses: + +```{r assign-print, exercise = TRUE} +(my.matrix <- matrix(data = 1:9, nrow = 6, ncol = 6)) +``` + +If you look in the help file, +which you can access by putting a `?` before the command/function name, +you will see matrix sets `byrow = F` by default. + +```{r help, exercise = TRUE} +?matrix # Forgot the exact name of the function? Use ?? for search... +``` + +This means that it populates the matrix with the data by column by default, +but we can populate it by row instead by adding an extra 'argument': + +```{r byrow, exercise = TRUE} +(my.2nd.matrix <- matrix(1:9, 6, 6, byrow = T)) +``` + +We can index cells of a matrix using square brackets with a comma `[ , ]` + +```{r index-cells, exercise = TRUE, exercise.setup = "byrow"} +my.2nd.matrix[2, 2] +``` + +Left of the comma is the row, right of the comma is the column. +We can even overwrite particular cells of the matrix by assigning a new value +to those indexed cells: + +```{r cell-assign, exercise = TRUE, exercise.setup = "byrow"} +my.2nd.matrix[my.2nd.matrix == 6] <- 600 +my.2nd.matrix +``` + +### Data frames + +Data frames are like matrices, but can hold different types of variables at once, +such as logical, numeric/integer, or string/character variables. +Replace the missing data (the NAs) with your details: + +```{r df-own-values, exercise = TRUE} +mydf <- data.frame(Surname = c("Hollway", NA), + Born = c("New Zealand", NA), + Siblings = c(1, NA)) +``` + +You can even add new variables by simply writing a new variable name: + +```{r df-add-variable, exercise = TRUE, exercise.setup="df-own-values"} +mydf$Dept <- c("IRPS", NA) +``` + +Can you call the data frame and print to the console? + +```{r df-test, exercise = TRUE, exercise.setup="df-add-variable"} + +``` + +```{r df-test-solution} +mydf +``` + +We can recall an observation (row) or variable (column) of the data frame +in the same way that we indexed the matrix above, e.g. `mydf[2,2]`, +but we can also call a named variable using the `$` sign: + +```{r df-call-var, exercise = TRUE, exercise.setup="df-add-variable"} +mydf$Surname +``` + +This can be very handy when "subsetting" the data: + +```{r df-subset, exercise = TRUE, exercise.setup="df-add-variable"} +james <- mydf[mydf$Surname == "Hollway", ] +james +``` + +Note, however, that data frames must have variables of equal length. + +### Lists + +Lists are a more flexible generalisation of data frames. + +```{r list-init, exercise = TRUE} +mylist <- list() # Here we are initialising an empty list +``` + +List items can also be named, like data frame variables, but don't have to be: + +```{r list-names, exercise = TRUE, exercise.setup="list-init"} +mylist$Surname <- c("Hollway", NA) +mylist$Siblings <- c(1, NA) # Now you can add the others from above +``` + +You can also add lists to a list: + +```{r list-nest, exercise = TRUE, exercise.setup="list-names"} +mylist$Lived <- list(c("New Zealand", "UK", "New Zealand", "Germany", "UK", "Switzerland"), NA) +``` + +Note that we've been using parentheses, `()`, here and not brackets, `[]`, +as we did when we were indexing. +Parentheses are used for _functions_. + +## Functions + +Functions are sets of actions or algorithms that are applied to values, vectors, or objects. + +```{r functions, exercise = TRUE} +exp(0.09855) +mean(c(1, 5, 8, 7, 6, 4, 22, 1, 0.9)) +``` + +### Arguments + +Usually every function must be followed by `()`. +Some functions work without any "arguments" though; +that is, with empty parentheses. + +```{r functions-empty, exercise = TRUE} +ls() # This tells you what objects are in your environment +getwd() # This tells you the directory on your computer R is working in/on +list.files() # This tells you what files are in your working directory +# setwd("...") # You can set the working directory with this function +# (or under session in RStudio) +``` + +Compare the above with functions like the following, +which enables you to write an object out of R to some path on your hard-drive that you specify: + +```{r function-write, exercise = TRUE} +write.csv(x = mydf, file = "~/Desktop/jamesdf.csv") +``` + +Two arguments are specified for this function `write.csv()`: +`x` and `file`. +But the function can accept other arguments as might be necessary +for more complex data, for less common outputs, or in edge cases. +See `?write.csv` for a list of the different arguments the function will accept. +Usually functions include defaults so that they work even if you do not +specify all the possible arguments though. +In fact, we don't need to write `x = `, just `write.csv(mydf, file = "~/Desktop/jamesdf.csv`. +That is because the function is expecting the object to be written +to be specified as the first argument, +so it is only where you want to be explicit or use a different ordering of the arguments +that you might need to spell that out. +It is good practice to be explicit whereever possible though to avoid unexpected results. + +### Pipes + +When working with multiple functions on the same object, +we can use pipe operators `%>%` or `|>` to chain consecutive functions +and avoid nesting multiple functions in the code. +Pipes take the result of the code on the left of the pipe operator +and uses it in whatever function is on the right or next line of the pipe operator. +Note that when piping over multiple lines should, +the pipe operator(s) should be used at the end of each line. + +```{r pipes, exercise = TRUE} +example.vector <- c(1, 5, 8, 7, 6, 4, 22, 1, 0.9) +pipe.result.1 <- example.vector |> + mean() +pipe.result.1 + +# library(dplyr) +# pipe.result.2 <- example.vector %>% + # mean() +# both pipe operators give the same result +# pipe.result.1 == pipe.result.2 +``` + +While `|>`is the native pipe operator since R v4.0.0, +those using earlier versions of R may wish to use `%>%` +from either the `{magrittr}` or `{dplyr}` packages. +Note that in that case, the package would need to be loaded first +before you can use the operator. + +## Tasks + +1. Create and fill in a matrix of "whom you already know" in the class: +There are other ways to do this, +but for this unit test I'd like you to do it in R. +You can follow my example below (copy to a new script and uncomment): + +```{r egonet-eg, exercise = TRUE} +mynetwork <- matrix(0,2,2) # this creates an empty network of 2 people +# Next I'm going to name the matrix rows and columns: +rownames(mynetwork) <- c("James Hollway","Korakot Janteerasakul") +colnames(mynetwork) <- c("James Hollway","Korakot Janteerasakul") +mynetwork[1,2] <- 1 # this means I know Korakot already +mynetwork[2,1] <- 1 # I think I can say Korakot knows me already too... +mynetwork["James Hollway","Korakot Janteerasakul"] <- 1 # I could also do this by name +# mynetwork[mynetwork > 0] <- 0 # Just in case you make a mistake, this wipes it! +``` diff --git a/inst/tutorials/tutorial8/diversity.Rmd b/inst/tutorials/tutorial8/diversity.Rmd index ff475492f..d15e1ed20 100644 --- a/inst/tutorials/tutorial8/diversity.Rmd +++ b/inst/tutorials/tutorial8/diversity.Rmd @@ -50,7 +50,7 @@ learnr::random_phrases_add(language = "en", "Bravo!", "Super!"), encouragement = c("Bon effort")) -marvel_friends <- to_unsigned(ison_marvel_relationships, keep = "positive") +marvel_friends <- to_unsigned(to_uniplex(fict_marvel, "relationship"), keep = "positive") marvel_friends <- to_giant(marvel_friends) marvel_friends <- marvel_friends %>% to_subgraph(Appearances >= mean(Appearances)) ``` @@ -73,11 +73,12 @@ By the end of this tutorial, you will be able to: ## Initial visualisation For this session, we'll explore a couple of different datasets. -First, let's examine homogeneity/`r gloss("heterogeneity")` in the Marvel relationships dataset from `{manynet}`, -`ison_marvel_relationships`. +First, let's examine homogeneity/`r gloss("heterogeneity")` in the Marvel dataset from `{manynet}`, +`fict_marvel`. The dataset is quite complicated, so to make this simpler, let's concentrate on: +- just the relationships part of the network - just the positive (friendship) ties and not the negative (enmity) ties - the main (giant) component without any isolates - just those characters that appear in the comics more than average @@ -90,24 +91,23 @@ and can be seen in the following chunk in order: ``` ```{r friends-hint-1, purl = FALSE} +to_uniplex(____, "relationship") +``` + +```{r friends-hint-2, purl = FALSE} # since the dataset is a 'signed' graph, we want to get just the # positively signed ties to get the friendship graph # (and lose the enmity relations) to_unsigned(____, keep = "positive") ``` -```{r friends-hint-2, purl = FALSE} +```{r friends-hint-3, purl = FALSE} # to_giant() is a quick easy way to get the giant/main component to_giant(____) ``` -```{r friends-hint-3, purl = FALSE} -to_subgraph(____, Appearances >= mean(Appearances)) -``` - ```{r friends-hint-4, purl = FALSE} -# don't forget to assign the results! -marvel_friends <- ____ +to_subgraph(____, Appearances >= mean(Appearances)) ``` ```{r friends-hint-5, purl = FALSE} diff --git a/inst/tutorials/tutorial9/ergm.Rmd b/inst/tutorials/tutorial9/ergm.Rmd index bc8ed4eb9..87c77ba39 100644 --- a/inst/tutorials/tutorial9/ergm.Rmd +++ b/inst/tutorials/tutorial9/ergm.Rmd @@ -17,6 +17,7 @@ library(ergm) ```{r setup, include = FALSE, purl=FALSE, eval=TRUE} library(manynet) +library(netrics) library(autograph) library(migraph) library(ergm) @@ -89,7 +90,7 @@ What attributes are attached to the nodes of this network that we might use in modelling? ```{r density, exercise=TRUE, exercise.setup = "ergm-data"} -net_density(flomarriage) +net_by_density(flomarriage) net_node_attributes(flomarriage) net_tie_attributes(flomarriage) ``` @@ -106,7 +107,7 @@ What do you observe? Describe the network in terms of configurations. ```{r vis-flomarriage, exercise=TRUE, exercise.setup = "ergm-data", fig.width=8} graphr(flomarriage, node_size = "wealth") -as_tidygraph(flomarriage) %>% mutate_nodes(Degree = node_deg()) %>% +as_tidygraph(flomarriage) %>% mutate_nodes(Degree = node_by_deg()) %>% mutate_ties(Triangles = tie_is_triangular()) %>% graphr(node_size = "Degree", edge_color = "Triangles") ``` @@ -391,7 +392,7 @@ We need additional modelling! ## Markov model ```{r visflo2, echo=FALSE, purl = FALSE, fig.width=9, setup = "flom-gof"} -p1 <- as_tidygraph(flomarriage) %>% mutate_nodes(Degree = node_deg()) %>% +p1 <- as_tidygraph(flomarriage) %>% mutate_nodes(Degree = node_by_deg()) %>% mutate_ties(Triangles = tie_is_triangular()) %>% graphr(node_size = "Degree", edge_color = "Triangles") + ggplot2::theme(legend.position = 'none') diff --git a/man/figures/logo.png b/man/figures/logo.png index 13092a832..0c58f72ec 100644 Binary files a/man/figures/logo.png and b/man/figures/logo.png differ diff --git a/man/figures/logo_old.png b/man/figures/logo_old.png index a21b608a5..13092a832 100644 Binary files a/man/figures/logo_old.png and b/man/figures/logo_old.png differ diff --git a/man/figures/logo_older.png b/man/figures/logo_older.png new file mode 100644 index 000000000..a21b608a5 Binary files /dev/null and b/man/figures/logo_older.png differ diff --git a/man/mpn_bristol.Rd b/man/mpn_bristol.Rd index ef00ec304..06ac33437 100644 --- a/man/mpn_bristol.Rd +++ b/man/mpn_bristol.Rd @@ -6,8 +6,8 @@ \title{Multimodal (3) Bristol protest events, 1990-2002 (Diani and Bison 2004)} \format{ \if{html}{\out{
}}\preformatted{#> -- # Bristol protest event network --------------------------------------------- -#> # A labelled, two-mode network of 150 individuals and 1496 affiliation and -#> participation ties +#> # A labelled, two-mode network of 150 individuals and 114 individuals and 1496 +#> affiliation and participation ties #> #> -- Nodes #> # A tibble: 264 x 3 diff --git a/man/mpn_cow.Rd b/man/mpn_cow.Rd index af0933f4e..67456e528 100644 --- a/man/mpn_cow.Rd +++ b/man/mpn_cow.Rd @@ -35,7 +35,7 @@ #> }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 152 nodes and 839 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 112 nodes and 40 nodes and 839 ties #> #> -- Nodes #> # A tibble: 152 x 3 diff --git a/man/mpn_elite_usa.Rd b/man/mpn_elite_usa.Rd index 6fbed695d..27dca211b 100644 --- a/man/mpn_elite_usa.Rd +++ b/man/mpn_elite_usa.Rd @@ -7,7 +7,7 @@ \alias{mpn_elite_usa_money} \title{Two-mode and three-mode American power elite database (Domhoff 2016)} \format{ -\if{html}{\out{
}}\preformatted{#> # A labelled, two-mode network of 34 nodes and 46 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, two-mode network of 14 nodes and 20 nodes and 46 ties #> #> -- Nodes #> # A tibble: 34 x 2 @@ -35,7 +35,7 @@ #> }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{#> # A labelled, two-mode network of 38 nodes and 103 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, two-mode network of 26 nodes and 12 nodes and 103 ties #> #> -- Nodes #> # A tibble: 38 x 2 diff --git a/man/mpn_senate112.Rd b/man/mpn_senate112.Rd index 784acebb7..2c44b358e 100644 --- a/man/mpn_senate112.Rd +++ b/man/mpn_senate112.Rd @@ -8,7 +8,7 @@ \alias{mpn_senate_over} \title{Two-mode 112th Congress Senate Voting (Knoke et al. 2021)} \format{ -\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 114 nodes and 2791 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 51 nodes and 63 nodes and 2791 ties #> #> -- Nodes #> # A tibble: 114 x 2 @@ -36,7 +36,7 @@ #> }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 134 nodes and 3675 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 62 nodes and 72 nodes and 3675 ties #> #> -- Nodes #> # A tibble: 134 x 2 @@ -64,7 +64,7 @@ #> }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 52 nodes and 614 ties +\if{html}{\out{
}}\preformatted{#> # A labelled, weighted, two-mode network of 20 nodes and 32 nodes and 614 ties #> #> -- Nodes #> # A tibble: 52 x 2 diff --git a/man/test_tutorials.Rd b/man/test_tutorials.Rd new file mode 100644 index 000000000..2e36367df --- /dev/null +++ b/man/test_tutorials.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tutorial_test.R +\name{test_tutorials} +\alias{test_tutorials} +\title{Test tutorials} +\usage{ +test_tutorials(path, quiet = TRUE) +} +\arguments{ +\item{path}{Character vector of the paths to the tutorials to be knitted.} + +\item{quiet}{Logical, whether to suppress messages from \code{render()}.} +} +\value{ +No return value, called for side effects. +} +\description{ +For our purposes, "testing" a tutorial means being able to +(successfully) run \code{render()} on it. +This function renders the tutorial provided in \code{path}. +There is no check to see if the rendered file looks OK. +If a tutorial fails to render, then an error will be generated which will +propagate to the caller. +} +\author{ +David Kane, see tutorial.helpers +} diff --git a/man/tests.Rd b/man/tests.Rd index ae5196096..d882795d8 100644 --- a/man/tests.Rd +++ b/man/tests.Rd @@ -75,14 +75,14 @@ of the original network. } } \examples{ -marvel_friends <- to_unsigned(ison_marvel_relationships) -marvel_friends <- to_giant(marvel_friends) \%>\% +marvel_friends <- fict_marvel \%>\% to_uniplex("relationship") \%>\% + to_unsigned() \%>\% to_giant() \%>\% to_subgraph(PowerOrigin == "Human") -(cugtest <- test_random(marvel_friends, manynet::net_heterophily, attribute = "Attractive", +(cugtest <- test_random(marvel_friends, net_by_heterophily, attribute = "Attractive", times = 200)) # plot(cugtest) # (qaptest <- test_permutation(marvel_friends, -# manynet::net_heterophily, attribute = "Attractive", +# net_by_heterophily, attribute = "Attractive", # times = 200)) # plot(qaptest) } diff --git a/man/tutorials.Rd b/man/tutorials.Rd new file mode 100644 index 000000000..f85734157 --- /dev/null +++ b/man/tutorials.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tutorial_run.R +\name{tutorials} +\alias{tutorials} +\alias{run_tute} +\alias{extract_tute} +\title{Open and extract code from tutorials} +\usage{ +run_tute(tute) + +extract_tute(tute) +} +\arguments{ +\item{tute}{String, name of the tutorial (e.g. "tutorial2").} +} +\description{ +These functions make it easy to use the tutorials +in the \code{{manynet}} and \code{{migraph}} packages: +\itemize{ +\item \code{run_tute()} runs a \code{{learnr}} tutorial from +either the \code{{manynet}} or \code{{migraph}} packages, +wraps \code{learnr::run_tutorial()} with some convenience. +\item \code{extract_tute()} extracts and opens just the solution code +from a \code{{manynet}} or \code{{migraph}} tutorial, +saving the .R script to the current working directory. +} +} diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index 770f53ab2..31d85b188 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -52,9 +52,18 @@ reference: - starts_with("test") - regression - predict - - title: "Data" + + - title: "Practicing" + - subtitle: "Learning" + desc: | + Functions for loading and extracting code from tutorials. + contents: + - tutorials + - subtitle: "Data" desc: | The package contains multimodal, multilevel, and multiplex network data, used in the book _Multimodal Political Networks_ (prefixed with `mpn_`). contents: - starts_with("mpn_") + + diff --git a/tests/testthat/helper-functions.R b/tests/testthat/helper-functions.R index 5abaf2d2a..414f5a875 100644 --- a/tests/testthat/helper-functions.R +++ b/tests/testthat/helper-functions.R @@ -1,3 +1,5 @@ +knitr::opts_chunk$set(message = FALSE) + top3 <- function(res, dec = 4){ if(is.numeric(res)){ unname(round(res, dec))[1:3] diff --git a/tests/testthat/test-measure_over.R b/tests/testthat/test-measure_over.R index c758ee89d..6684d7c93 100644 --- a/tests/testthat/test-measure_over.R +++ b/tests/testthat/test-measure_over.R @@ -1,10 +1,10 @@ test_that("over_waves works", { - res <- over_waves(manynet::fict_potter, manynet::net_components) + res <- over_waves(manynet::fict_potter, netrics::net_by_components) # expect_equal(unname(unlist(c(res))), c(48,52,57,43,54,64)) }) test_that("over_membership works", { - res <- over_membership(fict_potter, manynet::net_assortativity, - membership = node_in_regular(fict_potter)) + res <- over_membership(fict_potter, netrics::net_by_assortativity, + membership = netrics::node_in_regular(fict_potter)) expect_equal(unname(unlist(c(res))), c(0.490201713,NaN)) }) diff --git a/tests/testthat/test-model_tests.R b/tests/testthat/test-model_tests.R index a7ebee70d..426e7f372 100644 --- a/tests/testthat/test-model_tests.R +++ b/tests/testthat/test-model_tests.R @@ -3,14 +3,14 @@ marvel_friends <- manynet::to_uniplex(manynet::fict_marvel, "relationship") %>% manynet::to_giant() %>% manynet::to_unsigned() %>% manynet::to_subgraph(PowerOrigin == "Human") cugtest <- test_random(marvel_friends, - manynet::net_heterophily, + netrics::net_by_heterophily, attribute = "Attractive", times = 200) cugtest2 <- test_random(marvel_friends, - manynet::net_betweenness, + netrics::net_by_betweenness, times = 200) cugtest3 <- test_random(ison_southern_women, - manynet::net_equivalency, + netrics::net_by_equivalency, times = 200) test_that("test_random works", { @@ -40,7 +40,7 @@ test_that("test_random works", { # Set the qaptest up qaptest <- test_permutation(marvel_friends, - manynet::net_heterophily, + netrics::net_by_heterophily, attribute = "Attractive", times = 200) @@ -57,7 +57,7 @@ test_that("test_permutation works", { test_that("test_configuration works", { testthat::skip_on_os("linux") configtest <- test_configuration(marvel_friends, - manynet::net_heterophily, + netrics::net_by_heterophily, attribute = "Attractive", times = 200) expect_s3_class(configtest, "network_test") diff --git a/tests/testthat/test-tutorials_autograph.R b/tests/testthat/test-tutorials_autograph.R new file mode 100644 index 000000000..2b5aeb9e2 --- /dev/null +++ b/tests/testthat/test-tutorials_autograph.R @@ -0,0 +1,8 @@ +test_that("autograph tutorials work", { + for(tute.dir in list.dirs(system.file("tutorials", package = "autograph"), + recursive = F)){ + tute.file <- list.files(tute.dir, pattern = "*.Rmd", full.names = T) + expect_null(test_tutorials(tute.file)) + } +}) + diff --git a/tests/testthat/test-tutorials_manynet.R b/tests/testthat/test-tutorials_manynet.R new file mode 100644 index 000000000..d2f6e55ea --- /dev/null +++ b/tests/testthat/test-tutorials_manynet.R @@ -0,0 +1,7 @@ +test_that("manynet tutorials work", { + for(tute.dir in list.dirs(system.file("tutorials", package = "manynet"), + recursive = F)){ + tute.file <- list.files(tute.dir, pattern = "*.Rmd", full.names = T) + expect_null(test_tutorials(tute.file)) + } +}) \ No newline at end of file diff --git a/tests/testthat/test-tutorials_migraph.R b/tests/testthat/test-tutorials_migraph.R new file mode 100644 index 000000000..1087eeab5 --- /dev/null +++ b/tests/testthat/test-tutorials_migraph.R @@ -0,0 +1,7 @@ +test_that("migraph tutorials work", { + for(tute.dir in list.dirs(system.file("tutorials", package = "migraph"), + recursive = F)){ + tute.file <- list.files(tute.dir, pattern = "*.Rmd", full.names = T) + expect_null(test_tutorials(tute.file)) + } +}) \ No newline at end of file