From ca5207623dccf397aabfe7eb7d81d18a5e93d97c Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Fri, 17 Nov 2023 17:09:36 +0100 Subject: [PATCH 01/27] Add use_memoise helper to memoise chull fct on the fly --- R/fd_fdiv.R | 8 +++++++- R/fd_fric.R | 9 ++++++++- R/use_memoise.R | 4 ++++ R/zzz.R | 10 ---------- 4 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 R/use_memoise.R delete mode 100644 R/zzz.R diff --git a/R/fd_fdiv.R b/R/fd_fdiv.R index 6965675..dc531a3 100644 --- a/R/fd_fdiv.R +++ b/R/fd_fdiv.R @@ -66,6 +66,12 @@ fd_fdiv <- function(traits, sp_com) { site_abundances[site_abundances == 0] <- 1 # Account for site with no species sp_com <- sp_com / site_abundances + f <- if (use_memoise()) { + memoise::memoise(fd_chull) + } else { + fd_chull + } + # Compute Functional Divergence fdiv_site <- future_apply(sp_com, 1, function(sp_site) { @@ -79,7 +85,7 @@ fd_fdiv <- function(traits, sp_com) { # Select traits for species actually in site sub_traits <- traits[names(sub_site),, drop = FALSE] - ch <- fd_chull(sub_traits) + ch <- f(sub_traits) verts <- ch$p[unique(c(ch$hull)),, drop = FALSE] diff --git a/R/fd_fric.R b/R/fd_fric.R index 54dd6b3..366e468 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -100,8 +100,15 @@ fd_fric <- function(traits, sp_com, stand = FALSE) { max_range <- fd_chull(traits)$vol } + f <- if (use_memoise()) { + memoise::memoise(fd_chull) + } else { + fd_chull + } + fric_site <- future_apply(sp_com, 1, function(site_row) { - fd_chull(traits[site_row > 0,, drop = FALSE])$vol + res <- f(traits[site_row > 0, , drop = FALSE]) + return(res$vol) }, future.globals = FALSE) if (any(is.na(fric_site))) { diff --git a/R/use_memoise.R b/R/use_memoise.R new file mode 100644 index 0000000..fe2c4b2 --- /dev/null +++ b/R/use_memoise.R @@ -0,0 +1,4 @@ +use_memoise <- function() { + requireNamespace("memoise", quietly = TRUE) && + isTRUE(getOption("fundiversity.memoise", TRUE)) +} diff --git a/R/zzz.R b/R/zzz.R deleted file mode 100644 index ee33de1..0000000 --- a/R/zzz.R +++ /dev/null @@ -1,10 +0,0 @@ -# Diverse utility functions - -# Memoized version of fd_chull loaded if package is installed -.onLoad <- function(libname, pkgname) { - if (requireNamespace("memoise", quietly = TRUE) && - isTRUE(getOption("fundiversity.memoise", TRUE))) { - fd_chull <<- memoise::memoise(fd_chull) - fd_chull_intersect <<- memoise::memoise(fd_chull_intersect) - } -} From b6f87e4468161ab4f2952c39fc706b1a55a9c662 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Sat, 9 Dec 2023 13:36:01 +0100 Subject: [PATCH 02/27] Memoise once but dispatch on the fly --- R/fd_fdiv.R | 2 +- R/fd_fric.R | 2 +- R/use_memoise.R | 27 +++++++++++++++++++++++++-- R/zzz.R | 5 +++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 R/zzz.R diff --git a/R/fd_fdiv.R b/R/fd_fdiv.R index dc531a3..0edb00c 100644 --- a/R/fd_fdiv.R +++ b/R/fd_fdiv.R @@ -67,7 +67,7 @@ fd_fdiv <- function(traits, sp_com) { sp_com <- sp_com / site_abundances f <- if (use_memoise()) { - memoise::memoise(fd_chull) + fd_chull_memoised } else { fd_chull } diff --git a/R/fd_fric.R b/R/fd_fric.R index 366e468..b9f74f7 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -101,7 +101,7 @@ fd_fric <- function(traits, sp_com, stand = FALSE) { } f <- if (use_memoise()) { - memoise::memoise(fd_chull) + fd_chull_memoised } else { fd_chull } diff --git a/R/use_memoise.R b/R/use_memoise.R index fe2c4b2..87becab 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -1,4 +1,27 @@ +# We respect users' explicit choice and error if we cannot honour it. However, +# by default, without any explicit option set by the user, we use memoise only +# if it was installed when fundiversity was loaded, without any messages. use_memoise <- function() { - requireNamespace("memoise", quietly = TRUE) && - isTRUE(getOption("fundiversity.memoise", TRUE)) + # explicitly set to TRUE by user + if (isTRUE(getOption("fundiversity.memoise"))) { + if (exists("fd_chull_memoised")) { + return(TRUE) + } + stop( + "memoise is not installed", + "or was installed after fundiversity was loaded.", + "Please install memoise and restart R.", + call. = FALSE + ) + } + # explicitly set to FALSE by user + if (isFALSE(getOption("fundiversity.memoise"))) { + return(FALSE) + } + # unspecified / default + if (is.null(getOption("fundiversity.memoise"))) { + # TRUE or FALSE depending on whether memoise was installed when fundiversity + # was loaded + return(exists("fd_chull_memoised")) + } } diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 0000000..68e9a45 --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,5 @@ +.onLoad <- function(libname, pkgname) { + if (requireNamespace("memoise", quietly = TRUE)) { + fd_chull_memoised <<- memoise::memoise(fd_chull) + } +} From a31c964a2729cded887c94462d86013e76195172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 16:25:17 +0100 Subject: [PATCH 03/27] Also memoise first computation --- R/fd_fric.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/fd_fric.R b/R/fd_fric.R index b9f74f7..6c21951 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -96,16 +96,16 @@ fd_fric <- function(traits, sp_com, stand = FALSE) { max_range <- 1 - if (stand) { - max_range <- fd_chull(traits)$vol - } - f <- if (use_memoise()) { fd_chull_memoised } else { fd_chull } + if (stand) { + max_range <- f(traits)$vol + } + fric_site <- future_apply(sp_com, 1, function(site_row) { res <- f(traits[site_row > 0, , drop = FALSE]) return(res$vol) From e47fc0c41f5b750903eeef34ec952e1e8575e790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 17:00:28 +0100 Subject: [PATCH 04/27] Add basic tests for use_memoise() --- R/use_memoise.R | 2 ++ tests/testthat/test-use_memoise.R | 51 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/testthat/test-use_memoise.R diff --git a/R/use_memoise.R b/R/use_memoise.R index 87becab..f68d40f 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -25,3 +25,5 @@ use_memoise <- function() { return(exists("fd_chull_memoised")) } } + +exists <- NULL diff --git a/tests/testthat/test-use_memoise.R b/tests/testthat/test-use_memoise.R new file mode 100644 index 0000000..60791ec --- /dev/null +++ b/tests/testthat/test-use_memoise.R @@ -0,0 +1,51 @@ +test_that("use_memoise() works when memoise is installed", { + + # Pretend fd_chull_memoised() exists = memoise installed before fundiversity + fd_chull_memoised <- NULL + + # If memoise installed & options TRUE + withr::local_options(fundiversity.memoise = TRUE) + expect_true(use_memoise()) + + # If memoise installed & options FALSE + withr::local_options(fundiversity.memoise = FALSE) + expect_false(use_memoise()) + + # If memoise installed & options NULL + withr::local_options(fundiversity.memoise = NULL) + expect_true(use_memoise()) + +}) + + +test_that("use_memoise() sends back FALSE when memoise isn't installed", { + + local_mocked_bindings(exists = function(...) FALSE) + + # If memoise not installed & options TRUE + withr::local_options(fundiversity.memoise = TRUE) + expect_error(use_memoise(), regexp = "memoise is not installedor was installed after fundiversity was loaded.Please install memoise and restart R.", fixed = TRUE) + + # If memoise not installed & options FALSE + withr::local_options(fundiversity.memoise = FALSE) + expect_false(use_memoise()) + + # If memoise not installed & options NULL + withr::local_options(fundiversity.memoise = NULL) + expect_false(use_memoise()) + +}) + + +test_that("use_memoise() sends back FALSE when plan is parallel", { + + # Check both fd_chull() and fd_chull_intersect() + + ## If memoise not installed + # If memoise not installed & options TRUE + + # If memoise not installed & options FALSE + + # If memoise not installed & options NULL + +}) From ec60d07be7a9794b97919a0708e398a2ba59ee29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 17:01:59 +0100 Subject: [PATCH 05/27] Slightly better error message --- R/use_memoise.R | 4 ++-- tests/testthat/test-use_memoise.R | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/R/use_memoise.R b/R/use_memoise.R index f68d40f..9937145 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -8,8 +8,8 @@ use_memoise <- function() { return(TRUE) } stop( - "memoise is not installed", - "or was installed after fundiversity was loaded.", + "memoise is not installed ", + "or was installed after fundiversity was loaded. ", "Please install memoise and restart R.", call. = FALSE ) diff --git a/tests/testthat/test-use_memoise.R b/tests/testthat/test-use_memoise.R index 60791ec..3f86c45 100644 --- a/tests/testthat/test-use_memoise.R +++ b/tests/testthat/test-use_memoise.R @@ -24,7 +24,14 @@ test_that("use_memoise() sends back FALSE when memoise isn't installed", { # If memoise not installed & options TRUE withr::local_options(fundiversity.memoise = TRUE) - expect_error(use_memoise(), regexp = "memoise is not installedor was installed after fundiversity was loaded.Please install memoise and restart R.", fixed = TRUE) + expect_error( + use_memoise(), + regexp = paste0( + "memoise is not installed or was installed after fundiversity was ", + "loaded. Please install memoise and restart R." + ), + fixed = TRUE + ) # If memoise not installed & options FALSE withr::local_options(fundiversity.memoise = FALSE) From 2b7bc376611648623b4b3f3dec150531e1f30914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 17:14:44 +0100 Subject: [PATCH 06/27] Test for non sequential plan --- R/use_memoise.R | 6 ++++++ tests/testthat/test-use_memoise.R | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/R/use_memoise.R b/R/use_memoise.R index 9937145..ddcb764 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -2,6 +2,12 @@ # by default, without any explicit option set by the user, we use memoise only # if it was installed when fundiversity was loaded, without any messages. use_memoise <- function() { + + # Cannot use memoise in parallel settings + if (!inherits(future::plan(), "sequential")) { + return(FALSE) + } + # explicitly set to TRUE by user if (isTRUE(getOption("fundiversity.memoise"))) { if (exists("fd_chull_memoised")) { diff --git a/tests/testthat/test-use_memoise.R b/tests/testthat/test-use_memoise.R index 3f86c45..a06b84d 100644 --- a/tests/testthat/test-use_memoise.R +++ b/tests/testthat/test-use_memoise.R @@ -1,7 +1,7 @@ test_that("use_memoise() works when memoise is installed", { # Pretend fd_chull_memoised() exists = memoise installed before fundiversity - fd_chull_memoised <- NULL + local_mocked_bindings(exists = function(...) TRUE) # If memoise installed & options TRUE withr::local_options(fundiversity.memoise = TRUE) @@ -46,13 +46,18 @@ test_that("use_memoise() sends back FALSE when memoise isn't installed", { test_that("use_memoise() sends back FALSE when plan is parallel", { - # Check both fd_chull() and fd_chull_intersect() + future::plan("multisession") - ## If memoise not installed - # If memoise not installed & options TRUE + withr::local_options(fundiversity.memoise = TRUE) + expect_false(use_memoise()) # If memoise not installed & options FALSE + withr::local_options(fundiversity.memoise = FALSE) + expect_false(use_memoise()) # If memoise not installed & options NULL + withr::local_options(fundiversity.memoise = NULL) + expect_false(use_memoise()) + future::plan("sequential") }) From eb169c15ea8ca6967d9007bfc41094a0f6d2648b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 21:32:06 +0100 Subject: [PATCH 07/27] Add 'withr' as Suggests --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index b990b3a..e7790c7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -36,7 +36,8 @@ Suggests: knitr, memoise, rmarkdown, - testthat (>= 3.0.0) + testthat (>= 3.0.0), + withr URL: https://funecology.github.io/fundiversity/, https://github.com/funecology/fundiversity BugReports: https://github.com/funecology/fundiversity/issues Config/testthat/edition: 3 From d8bc50f19e73018e5daa8dd1b9978043daeae06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 21:46:34 +0100 Subject: [PATCH 08/27] Fix tests for fd_chull() and fd_chull_intersect() --- tests/testthat/test-chull.R | 25 +++++++++---------------- tests/testthat/test-chull_intersect.R | 27 ++++++++------------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/tests/testthat/test-chull.R b/tests/testthat/test-chull.R index ab48c7b..4a2909b 100644 --- a/tests/testthat/test-chull.R +++ b/tests/testthat/test-chull.R @@ -1,20 +1,13 @@ -data("traits_birds") +test_that("fd_chull() gives good value", { -test_that("memoise options works on fd_chull()", { - skip_if_not_installed("memoise") + box_trait <- matrix( + c(-0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5), ncol = 2, + dimnames = list( + species = paste0("sp", 1:4), traits = paste0("trait", 1:2) + ) + ) - if (getOption("fundiversity.memoise", TRUE)) { - expect_true(memoise::is.memoised(fd_chull)) - - ch <- fd_chull(traits_birds) - - expect_true(memoise::has_cache(fd_chull)(traits_birds)) - } else { - expect_false(memoise::is.memoised(fd_chull)) - - ch <- fd_chull(traits_birds) - - expect_false(memoise::has_cache(fd_chull)(traits_birds)) - } + expect_equal(fd_chull(box_trait)$vol, 1) + expect_equal(fd_chull(box_trait)$area, 4) }) diff --git a/tests/testthat/test-chull_intersect.R b/tests/testthat/test-chull_intersect.R index bc2f3e7..64970ce 100644 --- a/tests/testthat/test-chull_intersect.R +++ b/tests/testthat/test-chull_intersect.R @@ -1,24 +1,13 @@ -data("traits_birds") +test_that("fd_chull_intersect() gives good value", { -test_that("memoise options work on fd_chull_intersect()", { - skip_if_not_installed("memoise") - - if (getOption("fundiversity.memoise", TRUE)) { - expect_true(memoise::is.memoised(fd_chull_intersect)) - - ch_i <- fd_chull_intersect(traits_birds, traits_birds) - - expect_true( - memoise::has_cache(fd_chull_intersect)(traits_birds, traits_birds) + box_trait <- matrix( + c(-0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5), ncol = 2, + dimnames = list( + species = paste0("sp", 1:4), traits = paste0("trait", 1:2) ) - } else { - expect_false(memoise::is.memoised(fd_chull_intersect)) + ) - ch_i <- fd_chull_intersect(traits_birds, traits_birds) - - expect_false( - memoise::has_cache(fd_chull_intersect)(traits_birds, traits_birds) - ) - } + expect_equal(fd_chull_intersect(box_trait, box_trait)$vol, 1) + expect_equal(fd_chull_intersect(box_trait, box_trait)$area, 4) }) From a82b8caa191b3ac6ea8de764a58835ab920d47b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 22:11:36 +0100 Subject: [PATCH 09/27] Remove global memoise option in tests --- tests/testthat.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat.R b/tests/testthat.R index afabd8e..8f125b6 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -2,6 +2,5 @@ library(fundiversity) if (requireNamespace("testthat", quietly = TRUE)) { library(testthat) - options(fundiversity.memoise = TRUE) test_check("fundiversity") } From 3e8219bd4e02e7144b364db3799e0278567f9adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 22:15:22 +0100 Subject: [PATCH 10/27] Memoise fd_chull_intersect() as well --- R/fd_fric_intersect.R | 18 +++++++++++++++--- R/zzz.R | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/R/fd_fric_intersect.R b/R/fd_fric_intersect.R index fafc4c5..1aab246 100644 --- a/R/fd_fric_intersect.R +++ b/R/fd_fric_intersect.R @@ -75,8 +75,20 @@ fd_fric_intersect <- function(traits, sp_com, stand = FALSE) { max_range <- 1 + f <- if (use_memoise()) { + fd_chull_memoised + } else { + fd_chull + } + + f_inter <- if (use_memoise()) { + fd_chull_intersect_memoised + } else { + fd_chull_intersect + } + if (stand) { - max_range <- fd_chull(traits)$vol + max_range <- f(traits)$vol } # All pairs of sites (not within themselves) @@ -104,11 +116,11 @@ fd_fric_intersect <- function(traits, sp_com, stand = FALSE) { second_row <- sp_com[site_comb[[2]],, drop = TRUE] second_traits <- traits[second_row > 0,, drop = FALSE] - fd_chull_intersect(first_traits, second_traits)$vol + f_inter(first_traits, second_traits)$vol } else { # Self-intersection (equivalent to regular convex hulls) # way more efficient that compute with fd_chull_inters - fd_chull(first_traits)$vol + f(first_traits)$vol } }, future.globals = FALSE) diff --git a/R/zzz.R b/R/zzz.R index 68e9a45..ff19b05 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,5 +1,6 @@ .onLoad <- function(libname, pkgname) { if (requireNamespace("memoise", quietly = TRUE)) { fd_chull_memoised <<- memoise::memoise(fd_chull) + fd_chull_intersect_memoised <<- memoise::memoise(fd_chull_intersect) } } From 5d902a9d16a3032661f47093f2c108749cd83f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 19 Mar 2024 22:21:10 +0100 Subject: [PATCH 11/27] Update function documentation of memoisation --- DESCRIPTION | 2 +- R/fd_fric.R | 9 +++++++-- man/fd_fdiv.Rd | 9 +++++++-- man/fd_fric.Rd | 9 +++++++-- man/fd_fric_intersect.Rd | 9 +++++++-- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e7790c7..1b3c44a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,7 @@ Language: en Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Depends: R (>= 2.10) Imports: diff --git a/R/fd_fric.R b/R/fd_fric.R index 6c21951..ac2d55a 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -34,11 +34,16 @@ #' @details By default, when loading \pkg{fundiversity}, the functions to #' compute convex hulls are #' [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` -#' package if it is installed. To deactivate this behavior you can set the +#' package if it is installed (their results are cached to avoid recomputing the +#' same functional volume twice). To deactivate this behavior you can set the #' option `fundiversity.memoise` to `FALSE` by running the following line: #' `options(fundiversity.memoise = FALSE)`. If you use it interactively it will #' only affect your current session. Add it to your script(s) or `.Rprofile` -#' file to avoid toggling it each time. +#' file to avoid toggling it each time. By changing the option, the behavior +#' will automatically change the next time you run the function. **Note**: +#' memoisation is only available when the `memoise` package has been installed +#' **and without parallelization**, otherwise `fundiversity` will use unmemoised +#' versions of the functions. #' #' @return a data.frame with two columns: #' * `site` the names of the sites as the row names of the input `sp_com`, diff --git a/man/fd_fdiv.Rd b/man/fd_fdiv.Rd index ff09d57..3f0b59e 100644 --- a/man/fd_fdiv.Rd +++ b/man/fd_fdiv.Rd @@ -36,11 +36,16 @@ there are less traits than species, then FDiv is equal to \code{NaN}. By default, when loading \pkg{fundiversity}, the functions to compute convex hulls are \href{https://en.wikipedia.org/wiki/Memoization}{memoised} through the \code{memoise} -package if it is installed. To deactivate this behavior you can set the +package if it is installed (their results are cached to avoid recomputing the +same functional volume twice). To deactivate this behavior you can set the option \code{fundiversity.memoise} to \code{FALSE} by running the following line: \code{options(fundiversity.memoise = FALSE)}. If you use it interactively it will only affect your current session. Add it to your script(s) or \code{.Rprofile} -file to avoid toggling it each time. +file to avoid toggling it each time. By changing the option, the behavior +will automatically change the next time you run the function. \strong{Note}: +memoisation is only available when the \code{memoise} package has been installed +\strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised +versions of the functions. } \section{Parallelization}{ diff --git a/man/fd_fric.Rd b/man/fd_fric.Rd index c916a69..bdecebe 100644 --- a/man/fd_fric.Rd +++ b/man/fd_fric.Rd @@ -47,11 +47,16 @@ than the number of provided traits. By default, when loading \pkg{fundiversity}, the functions to compute convex hulls are \href{https://en.wikipedia.org/wiki/Memoization}{memoised} through the \code{memoise} -package if it is installed. To deactivate this behavior you can set the +package if it is installed (their results are cached to avoid recomputing the +same functional volume twice). To deactivate this behavior you can set the option \code{fundiversity.memoise} to \code{FALSE} by running the following line: \code{options(fundiversity.memoise = FALSE)}. If you use it interactively it will only affect your current session. Add it to your script(s) or \code{.Rprofile} -file to avoid toggling it each time. +file to avoid toggling it each time. By changing the option, the behavior +will automatically change the next time you run the function. \strong{Note}: +memoisation is only available when the \code{memoise} package has been installed +\strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised +versions of the functions. } \section{Parallelization}{ diff --git a/man/fd_fric_intersect.Rd b/man/fd_fric_intersect.Rd index b1f183f..79b227b 100644 --- a/man/fd_fric_intersect.Rd +++ b/man/fd_fric_intersect.Rd @@ -53,11 +53,16 @@ one of the sites than the number of provided traits. By default, when loading \pkg{fundiversity}, the functions to compute convex hulls are \href{https://en.wikipedia.org/wiki/Memoization}{memoised} through the \code{memoise} -package if it is installed. To deactivate this behavior you can set the +package if it is installed (their results are cached to avoid recomputing the +same functional volume twice). To deactivate this behavior you can set the option \code{fundiversity.memoise} to \code{FALSE} by running the following line: \code{options(fundiversity.memoise = FALSE)}. If you use it interactively it will only affect your current session. Add it to your script(s) or \code{.Rprofile} -file to avoid toggling it each time. +file to avoid toggling it each time. By changing the option, the behavior +will automatically change the next time you run the function. \strong{Note}: +memoisation is only available when the \code{memoise} package has been installed +\strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised +versions of the functions. } \section{Parallelization}{ From 2535ec27f28ac55cb004df5229b1909d86e02689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Wed, 20 Mar 2024 07:37:14 +0100 Subject: [PATCH 12/27] Update vignettes to explain memoisation --- vignettes/_fundiversity_1-parallel.Rmd | 4 +- vignettes/fundiversity.Rmd | 2 +- vignettes/fundiversity_1-parallel.Rmd | 216 ++++++++++++++----------- 3 files changed, 128 insertions(+), 94 deletions(-) diff --git a/vignettes/_fundiversity_1-parallel.Rmd b/vignettes/_fundiversity_1-parallel.Rmd index 8d4e8d7..93ebe5a 100644 --- a/vignettes/_fundiversity_1-parallel.Rmd +++ b/vignettes/_fundiversity_1-parallel.Rmd @@ -27,9 +27,11 @@ Note: This vignette presents some performance tests ran between non-parallel and Within `fundiversity` the computation of most indices can be parallelized using the `future` package. The goal of this vignette is to explain how to toggle and use parallelization in `fundiversity`. The functions that currently support parallelization are summarized in the table below: -```{r child="man/rmdchunks/_fundiversity_functions.Rmd"} +```{r child="../man/rmdchunks/_fundiversity_functions.Rmd"} ``` +Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computation are parallelized, `fundiversity` will use unmemoised version of functions. + The `future` package provides a simple and general framework to allow asynchronous computation depending on the resources available for the user. The [first vignette of `future`](https://cran.r-project.org/package=future) gives a general overview of all its features. The main idea being that the user should write the code once and that it would run seamlessly sequentially, or in parallel on a single computer, or on a cluster, or distributed over several computers. `fundiversity` can thus run on all these different backends following the user's choice. ```{r setup} diff --git a/vignettes/fundiversity.Rmd b/vignettes/fundiversity.Rmd index f7344cd..4f8d051 100644 --- a/vignettes/fundiversity.Rmd +++ b/vignettes/fundiversity.Rmd @@ -132,7 +132,7 @@ Each row gives the standardized FRic values of each site. **Parallelization**. The computation of this function can be parallelized thanks to the `future` package. Refer to the [parallelization vignette](./fundiversity_1-parallel.html) to get more information about how to do so. -**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed. It means that repeated calls to `fd_fric()` with similar arguments won't be recomputed each time but recovered from memory. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. If you use it interactively it will only affect your current session. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. +**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed (their results are cached to avoid recomputing the same functional volume twice). To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. If you use it interactively it will only affect your current session. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. **Note**: memoisation is only available when the `memoise` package has been installed **and without parallelization**, otherwise `fundiversity` will use unmemoised versions of the functions. # Functional volume intersect (FRic_intersect) - `fd_fric_intersect()` diff --git a/vignettes/fundiversity_1-parallel.Rmd b/vignettes/fundiversity_1-parallel.Rmd index e3e4af1..01cd41b 100644 --- a/vignettes/fundiversity_1-parallel.Rmd +++ b/vignettes/fundiversity_1-parallel.Rmd @@ -16,7 +16,22 @@ knitr::knit("vignettes/_fundiversity_1-parallel.Rmd", output = "vignettes/fundiv Note: This vignette presents some performance tests ran between non-parallel and parallel versions of `fundiversity` functions. Note that to avoid the dependency on other packages, this vignette is [**pre-computed**](https://ropensci.org/technotes/2019/12/08/precompute-vignettes/). -Within `fundiversity` the computation of most indices can be parallelized using the `future` package. The indices that currently support parallelization are: **FRic**, **FDis**, **FDiv**, and **FEve**. The goal of this vignette is to explain how to toggle and use parallelization in `fundiversity`. +Within `fundiversity` the computation of most indices can be parallelized using the `future` package. The goal of this vignette is to explain how to toggle and use parallelization in `fundiversity`. The functions that currently support parallelization are summarized in the table below: + + +| Function Name | Index Name | Parallelizable[^1] | Memoizable[^2] | +|:----------------------|:---------------|:------------------:|:--------------:| +| `fd_fric()` | FRic | ✅ | ✅ | +| `fd_fric_intersect()` | FRic_intersect | ✅ | ✅ | +| `fd_fdiv()` | FDiv | ✅ | ✅ | +| `fd_feve()` | FEve | ✅ | ❌ | +| `fd_fdis()` | FDis | ✅ | ❌ | +| `fd_raoq()` | Rao's Q | ❌ | ❌ | + +[^1]: parallelization through the `future` backend please refer to the [parallelization vignette](https://funecology.github.io/fundiversity/articles/fundiversity_1-parallel.html) for details. +[^2]: memoization means that the results of the functions calls are cached and not recomputed when recalled, to toggle it off see the `fundiversity::fd_fric()` [Details section](https://funecology.github.io/fundiversity/reference/fd_fric.html#details). + +Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computation are parallelized, `fundiversity` will use unmemoised version of functions. The `future` package provides a simple and general framework to allow asynchronous computation depending on the resources available for the user. The [first vignette of `future`](https://cran.r-project.org/package=future) gives a general overview of all its features. The main idea being that the user should write the code once and that it would run seamlessly sequentially, or in parallel on a single computer, or on a cluster, or distributed over several computers. `fundiversity` can thus run on all these different backends following the user's choice. @@ -83,9 +98,9 @@ parallel_bench <- microbenchmark::microbenchmark( rbind(non_parallel_bench, parallel_bench) #> Unit: milliseconds -#> expr min lq mean median uq max neval cld -#> non_parallel 8.756378 8.892243 9.841818 9.072241 9.218554 23.9519 20 a -#> parallel 56.374332 167.680385 218.073077 172.888927 185.670312 1247.8534 20 b +#> expr min lq mean median uq max neval cld +#> non_parallel 12.3267 13.3452 15.03753 14.7037 15.84075 20.0802 20 a +#> parallel 178.1048 188.8670 259.66154 211.7129 219.97645 1312.2693 20 b ``` The non parallelized code runs faster than the parallelized one! Indeed, the parallelization in `fundiversity` parallelize the computation across different sites. So parallelization should be used when you have many sites on which you want to compute similar indices. @@ -121,14 +136,11 @@ microbenchmark::microbenchmark( fd_fric(traits_birds, bigger_site) }, times = 20 ) -#> Warning in supportsMulticoreAndRStudio(...): [ONE-TIME WARNING] Forked processing ('multicore') is not supported when running R from RStudio -#> because it is considered unstable. For more details, how to control forked processing or not, and how to silence this warning in future R -#> sessions, see ?parallelly::supportsMulticore #> Unit: seconds -#> expr min lq mean median uq max neval cld -#> seq 15.58688 15.67587 15.97552 15.97047 16.24568 16.54392 20 a -#> multisession 21.17851 21.75313 22.02965 21.88691 22.26971 23.50062 20 b -#> multicore 15.53872 15.75567 16.06103 16.01595 16.35790 16.98102 20 a +#> expr min lq mean median uq max neval cld +#> seq 114.82322 117.47735 149.55998 163.00871 167.59926 184.8759 20 a +#> multisession 54.77985 64.59042 70.99131 67.62465 74.16261 119.5938 20 b +#> multicore 116.11616 160.90286 159.18414 163.86793 166.77678 173.3062 20 a ```
@@ -136,95 +148,115 @@ microbenchmark::microbenchmark( ``` -#> seconds needed to generate this document: 1095.27 sec elapsed -#> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +#> seconds needed to generate this document: 7610.61 sec elapsed +#> ─ Session info ──────────────────────────────────────────────────────────────────── #> setting value -#> version R version 4.2.1 (2022-06-23) -#> os Ubuntu 20.04.5 LTS -#> system x86_64, linux-gnu +#> version R version 4.3.1 (2023-06-16 ucrt) +#> os Windows 11 x64 (build 22631) +#> system x86_64, mingw32 #> ui RStudio #> language (EN) -#> collate en_US.UTF-8 -#> ctype en_US.UTF-8 -#> tz Etc/UTC -#> date 2022-11-15 -#> rstudio 2022.02.0+443 Prairie Trillium (server) -#> pandoc 2.17.1.1 @ /usr/lib/rstudio-server/bin/quarto/bin/ (via rmarkdown) +#> collate French_France.utf8 +#> ctype fr_FR.UTF-8 +#> tz Europe/Paris +#> date 2024-03-20 +#> rstudio 2023.12.1+402 Ocean Storm (desktop) +#> pandoc 3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown) #> -#> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── -#> ! package * version date (UTC) lib source -#> P abind 1.4-5 2016-07-21 [3] CRAN (R 4.2.0) -#> assertthat 0.2.1 2019-03-21 [3] CRAN (R 4.1.3) -#> cachem 1.0.6 2021-08-19 [3] CRAN (R 4.1.3) -#> VP cli 3.4.0 2022-09-23 [?] CRAN (R 4.2.1) (on disk 3.4.1) -#> codetools 0.2-18 2020-11-04 [5] CRAN (R 4.0.3) -#> colorspace 2.0-3 2022-02-21 [1] CRAN (R 4.2.0) -#> crayon 1.5.1 2022-03-26 [1] CRAN (R 4.2.0) -#> DBI 1.1.2 2021-12-20 [3] CRAN (R 4.1.3) -#> P digest 0.6.29 2021-12-01 [3] CRAN (R 4.2.0) -#> dplyr * 1.0.10 2022-09-01 [1] CRAN (R 4.2.1) -#> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.2.0) -#> evaluate 0.18 2022-11-07 [1] CRAN (R 4.2.1) -#> fansi 1.0.3 2022-03-24 [1] CRAN (R 4.2.0) -#> P fastmap 1.1.0 2021-01-25 [3] CRAN (R 4.2.1) -#> fundiversity * 0.2.1.9000 2022-04-12 [3] Github (bisaloo/fundiversity@87652ba) -#> VP future 1.26.1 2022-09-02 [3] CRAN (R 4.2.1) (on disk 1.28.0) -#> VP future.apply 1.9.0 2022-11-05 [3] CRAN (R 4.2.1) (on disk 1.10.0) -#> generics 0.1.2 2022-01-31 [1] CRAN (R 4.2.0) -#> P geometry 0.4.6 2022-04-18 [3] CRAN (R 4.2.0) -#> ggplot2 * 3.3.6 2022-05-03 [1] CRAN (R 4.2.0) -#> VP globals 0.15.0 2022-08-28 [3] CRAN (R 4.2.1) (on disk 0.16.1) -#> glue 1.6.2 2022-02-24 [1] CRAN (R 4.2.0) -#> gtable 0.3.0 2019-03-25 [1] CRAN (R 4.2.0) -#> htmltools 0.5.3 2022-07-18 [1] CRAN (R 4.2.1) -#> knitr 1.40 2022-08-24 [1] CRAN (R 4.2.1) -#> lattice 0.20-45 2021-09-22 [3] CRAN (R 4.1.3) -#> lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.2.1) -#> P listenv 0.8.0 2019-12-05 [3] CRAN (R 4.2.1) -#> P magic 1.6-0 2022-02-09 [3] CRAN (R 4.2.0) -#> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.2.0) -#> MASS 7.3-58.1 2022-08-03 [3] CRAN (R 4.2.1) -#> Matrix 1.4-1 2022-03-23 [3] CRAN (R 4.1.3) -#> memoise 2.0.1 2021-11-26 [3] CRAN (R 4.1.3) -#> microbenchmark 1.4.9 2021-11-09 [3] CRAN (R 4.1.3) -#> multcomp 1.4-19 2022-04-26 [1] CRAN (R 4.2.0) -#> munsell 0.5.0 2018-06-12 [1] CRAN (R 4.2.0) -#> mvtnorm 1.1-3 2021-10-08 [1] CRAN (R 4.2.0) -#> VP parallelly 1.31.1 2022-07-21 [3] CRAN (R 4.2.1) (on disk 1.32.1) -#> pillar 1.7.0 2022-02-01 [1] CRAN (R 4.2.0) -#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.2.0) -#> R6 2.5.1 2021-08-19 [1] CRAN (R 4.2.0) -#> P Rcpp 1.0.8.3 2022-03-17 [3] CRAN (R 4.2.0) -#> rlang 1.0.6 2022-09-24 [1] CRAN (R 4.2.1) -#> rmarkdown 2.13 2022-03-10 [3] CRAN (R 4.1.3) -#> rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.2.1) -#> sandwich 3.0-2 2022-06-15 [1] CRAN (R 4.2.0) -#> scales 1.2.0 2022-04-13 [1] CRAN (R 4.2.0) -#> sessioninfo 1.2.2 2021-12-06 [3] CRAN (R 4.1.3) -#> stringi 1.7.6 2021-11-29 [1] CRAN (R 4.2.0) -#> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.2.0) -#> survival 3.3-1 2022-03-03 [3] CRAN (R 4.1.3) -#> TH.data 1.1-1 2022-04-26 [1] CRAN (R 4.2.0) -#> tibble 3.1.7 2022-05-03 [1] CRAN (R 4.2.0) -#> tictoc 1.0.1 2021-04-19 [3] CRAN (R 4.1.3) -#> tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.2.1) -#> utf8 1.2.2 2021-07-24 [1] CRAN (R 4.2.0) -#> vctrs 0.5.0 2022-10-22 [1] CRAN (R 4.2.1) -#> withr 2.5.0 2022-03-03 [1] CRAN (R 4.2.0) -#> xfun 0.34 2022-10-18 [1] CRAN (R 4.2.1) -#> yaml 2.3.6 2022-10-18 [1] CRAN (R 4.2.1) -#> zoo 1.8-10 2022-04-15 [1] CRAN (R 4.2.0) +#> ─ Packages ──────────────────────────────────────────────────────────────────────── +#> ! package * version date (UTC) lib source +#> abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) +#> brio 1.1.4 2023-12-10 [1] CRAN (R 4.3.2) +#> cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.1) +#> cli 3.6.2 2023-12-11 [1] CRAN (R 4.3.2) +#> cluster 2.1.6 2023-12-01 [1] CRAN (R 4.3.2) +#> codetools 0.2-19 2023-02-01 [2] CRAN (R 4.3.1) +#> commonmark 1.9.1 2024-01-30 [1] CRAN (R 4.3.2) +#> crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.1) +#> desc 1.4.3 2023-12-10 [1] CRAN (R 4.3.2) +#> devtools 2.4.5 2022-10-11 [1] CRAN (R 4.3.2) +#> diffobj 0.3.5 2021-10-05 [1] CRAN (R 4.3.2) +#> digest 0.6.35 2024-03-11 [1] CRAN (R 4.3.3) +#> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.1) +#> evaluate 0.23 2023-11-01 [1] CRAN (R 4.3.2) +#> fansi 1.0.6 2023-12-08 [1] CRAN (R 4.3.2) +#> fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.1) +#> fs 1.6.3 2023-07-20 [1] CRAN (R 4.3.1) +#> P fundiversity * 1.1.1 2024-01-03 [?] Github (funecology/fundiversity@d11d749) +#> future 1.33.1 2023-12-22 [1] CRAN (R 4.3.2) +#> future.apply 1.11.1 2023-12-21 [1] CRAN (R 4.3.2) +#> geometry 0.4.7 2023-02-03 [1] CRAN (R 4.3.1) +#> globals 0.16.3 2024-03-08 [1] CRAN (R 4.3.3) +#> glue 1.7.0 2024-01-09 [1] CRAN (R 4.3.2) +#> htmltools 0.5.7 2023-11-03 [1] CRAN (R 4.3.2) +#> htmlwidgets 1.6.4 2023-12-06 [1] CRAN (R 4.3.2) +#> httpuv 1.6.14 2024-01-26 [1] CRAN (R 4.3.2) +#> knitr 1.45 2023-10-30 [1] CRAN (R 4.3.2) +#> later 1.3.2 2023-12-06 [1] CRAN (R 4.3.2) +#> lattice 0.22-5 2023-10-24 [1] CRAN (R 4.3.2) +#> lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.2) +#> listenv 0.9.1 2024-01-29 [1] CRAN (R 4.3.2) +#> lpSolve 5.6.20 2023-12-10 [1] CRAN (R 4.3.2) +#> magic 1.6-1 2022-11-16 [1] CRAN (R 4.3.0) +#> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.1) +#> MASS 7.3-60.0.1 2024-01-13 [1] CRAN (R 4.3.2) +#> Matrix 1.6-5 2024-01-11 [1] CRAN (R 4.3.1) +#> memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.1) +#> mgcv 1.9-1 2023-12-21 [1] CRAN (R 4.3.2) +#> microbenchmark 1.4.10 2023-04-28 [1] CRAN (R 4.3.3) +#> mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) +#> miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.3.2) +#> multcomp 1.4-25 2023-06-20 [1] CRAN (R 4.3.1) +#> mvtnorm 1.2-4 2023-11-27 [1] CRAN (R 4.3.2) +#> nlme 3.1-164 2023-11-27 [1] CRAN (R 4.3.2) +#> pak 0.7.2 2024-03-17 [1] CRAN (R 4.3.3) +#> parallelly 1.37.1 2024-02-29 [1] CRAN (R 4.3.3) +#> permute 0.9-7 2022-01-27 [1] CRAN (R 4.3.1) +#> pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.1) +#> pkgbuild 1.4.4 2024-03-17 [1] CRAN (R 4.3.3) +#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.1) +#> pkgload 1.3.4 2024-01-16 [1] CRAN (R 4.3.2) +#> profvis 0.3.8 2023-05-02 [1] CRAN (R 4.3.2) +#> promises 1.2.1 2023-08-10 [1] CRAN (R 4.3.1) +#> purrr 1.0.2 2023-08-10 [1] CRAN (R 4.3.1) +#> R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.1) +#> Rcpp 1.0.12 2024-01-09 [1] CRAN (R 4.3.2) +#> rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.3.1) +#> remotes 2.5.0 2024-03-17 [1] CRAN (R 4.3.3) +#> rlang 1.1.3 2024-01-10 [1] CRAN (R 4.3.2) +#> rmarkdown 2.26 2024-03-05 [1] CRAN (R 4.3.3) +#> roxygen2 7.3.1 2024-01-22 [1] CRAN (R 4.3.2) +#> rprojroot 2.0.4 2023-11-05 [1] CRAN (R 4.3.2) +#> rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.1) +#> sandwich 3.1-0 2023-12-11 [1] CRAN (R 4.3.2) +#> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.1) +#> shiny 1.8.0 2023-11-17 [1] CRAN (R 4.3.2) +#> stringi 1.8.3 2023-12-11 [1] CRAN (R 4.3.2) +#> stringr 1.5.1 2023-11-14 [1] CRAN (R 4.3.2) +#> survival 3.5-8 2024-02-14 [1] CRAN (R 4.3.3) +#> testthat * 3.2.1 2023-12-02 [1] CRAN (R 4.3.2) +#> TH.data 1.1-2 2023-04-17 [1] CRAN (R 4.3.1) +#> tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.1) +#> tictoc 1.2.1 2024-03-18 [1] CRAN (R 4.3.3) +#> urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.3.2) +#> usethis 2.2.3 2024-02-19 [1] CRAN (R 4.3.3) +#> utf8 1.2.4 2023-10-22 [1] CRAN (R 4.3.2) +#> vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.2) +#> vegan 2.6-4 2022-10-11 [1] CRAN (R 4.3.1) +#> waldo 0.5.2 2023-11-02 [1] CRAN (R 4.3.2) +#> withr 3.0.0 2024-01-16 [1] CRAN (R 4.3.2) +#> xfun 0.42 2024-02-08 [1] CRAN (R 4.3.3) +#> xml2 1.3.6 2023-12-04 [1] CRAN (R 4.3.2) +#> xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.1) +#> yaml 2.3.8 2023-12-11 [1] CRAN (R 4.3.2) +#> zoo 1.8-12 2023-04-13 [1] CRAN (R 4.3.1) #> -#> [1] /home/ke76dimu/R-library/4.2 -#> [2] /usr/local/lib/R/site-library -#> [3] /data/library/4.1 -#> [4] /usr/lib/R/site-library -#> [5] /usr/lib/R/library +#> [1] C:/Users/greniem/AppData/Local/R/win-library/4.3 +#> [2] C:/Program Files/R/R-4.3.1/library #> -#> V ── Loaded and on-disk version mismatch. #> P ── Loaded and on-disk path mismatch. #> -#> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +#> ─────────────────────────────────────────────────────────────────────────────────── ```
From d56a9702410ec292aa280f63071f1bb167b95c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Wed, 20 Mar 2024 08:46:06 +0100 Subject: [PATCH 13/27] Made internal function name more explicit than 'f' --- R/fd_fdiv.R | 4 ++-- R/fd_fric.R | 6 +++--- R/fd_fric_intersect.R | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/R/fd_fdiv.R b/R/fd_fdiv.R index 0edb00c..94abeb6 100644 --- a/R/fd_fdiv.R +++ b/R/fd_fdiv.R @@ -66,7 +66,7 @@ fd_fdiv <- function(traits, sp_com) { site_abundances[site_abundances == 0] <- 1 # Account for site with no species sp_com <- sp_com / site_abundances - f <- if (use_memoise()) { + convex_hull <- if (use_memoise()) { fd_chull_memoised } else { fd_chull @@ -85,7 +85,7 @@ fd_fdiv <- function(traits, sp_com) { # Select traits for species actually in site sub_traits <- traits[names(sub_site),, drop = FALSE] - ch <- f(sub_traits) + ch <- convex_hull(sub_traits) verts <- ch$p[unique(c(ch$hull)),, drop = FALSE] diff --git a/R/fd_fric.R b/R/fd_fric.R index ac2d55a..ee5408f 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -101,18 +101,18 @@ fd_fric <- function(traits, sp_com, stand = FALSE) { max_range <- 1 - f <- if (use_memoise()) { + convex_hull <- if (use_memoise()) { fd_chull_memoised } else { fd_chull } if (stand) { - max_range <- f(traits)$vol + max_range <- convex_hull(traits)$vol } fric_site <- future_apply(sp_com, 1, function(site_row) { - res <- f(traits[site_row > 0, , drop = FALSE]) + res <- convex_hull(traits[site_row > 0, , drop = FALSE]) return(res$vol) }, future.globals = FALSE) diff --git a/R/fd_fric_intersect.R b/R/fd_fric_intersect.R index 1aab246..4146426 100644 --- a/R/fd_fric_intersect.R +++ b/R/fd_fric_intersect.R @@ -75,20 +75,20 @@ fd_fric_intersect <- function(traits, sp_com, stand = FALSE) { max_range <- 1 - f <- if (use_memoise()) { + convex_hull <- if (use_memoise()) { fd_chull_memoised } else { fd_chull } - f_inter <- if (use_memoise()) { + convex_hull_intersect <- if (use_memoise()) { fd_chull_intersect_memoised } else { fd_chull_intersect } if (stand) { - max_range <- f(traits)$vol + max_range <- convex_hull(traits)$vol } # All pairs of sites (not within themselves) @@ -116,11 +116,11 @@ fd_fric_intersect <- function(traits, sp_com, stand = FALSE) { second_row <- sp_com[site_comb[[2]],, drop = TRUE] second_traits <- traits[second_row > 0,, drop = FALSE] - f_inter(first_traits, second_traits)$vol + convex_hull_intersect(first_traits, second_traits)$vol } else { # Self-intersection (equivalent to regular convex hulls) - # way more efficient that compute with fd_chull_inters - f(first_traits)$vol + # way more efficient that compute with convex_hull_intersect() + convex_hull(first_traits)$vol } }, future.globals = FALSE) From 1475a3e887080a015d814a219a6b2d1b4b68109e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Wed, 20 Mar 2024 08:50:28 +0100 Subject: [PATCH 14/27] Warn memoise with caution (fixes #71 #77) --- vignettes/fundiversity.Rmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vignettes/fundiversity.Rmd b/vignettes/fundiversity.Rmd index 4f8d051..4983511 100644 --- a/vignettes/fundiversity.Rmd +++ b/vignettes/fundiversity.Rmd @@ -132,7 +132,7 @@ Each row gives the standardized FRic values of each site. **Parallelization**. The computation of this function can be parallelized thanks to the `future` package. Refer to the [parallelization vignette](./fundiversity_1-parallel.html) to get more information about how to do so. -**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed (their results are cached to avoid recomputing the same functional volume twice). To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. If you use it interactively it will only affect your current session. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. **Note**: memoisation is only available when the `memoise` package has been installed **and without parallelization**, otherwise `fundiversity` will use unmemoised versions of the functions. +**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed (their results are cached to avoid recomputing the same functional volume twice). It means repeated call to `fd_fric()` with the same arguments won't be recomputed but recovered from cache. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. By changing the option, the behavior will automatically change the next time you run the function. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. **Important note**: memoisation is only available when the `memoise` package has been installed **and without parallelization**, otherwise `fundiversity` will use unmemoised versions of the functions. # Functional volume intersect (FRic_intersect) - `fd_fric_intersect()` @@ -164,7 +164,7 @@ Note that when standardizing the volumes, the behavior is similar to that of `fd **Parallelization**. The computation of this function can be parallelized thanks to the `future` package. Refer to the [parallelization vignette](./fundiversity_1-parallel.html) to get more information about how to do so. -**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed. It means that repeated calls to `fd_fric_intersect()` with similar arguments won't be recomputed each time but recovered from memory. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. If you use it interactively it will only affect your current session. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. +**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed. It means that repeated calls to `fd_fric_intersect()` with similar arguments won't be recomputed each time but recovered from memory. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. By changing the option, the behavior will automatically change the next time you run the function. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. **Important note**: memoisation is only available when the `memoise` package has been installed **and without parallelization**, otherwise `fundiversity` will use unmemoised versions of the functions. # Functional Divergence (FDiv) - `fd_fdiv()` @@ -215,7 +215,7 @@ Similarly to FRic, if the included species differ between the site-species matri The computation of this function can be parallelized thanks to the `future` package. Refer to the [parallelization vignette](./fundiversity_1-parallel.html) to get more information about how to do so. -**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed. It means that repeated calls to `fd_fdiv()` with similar arguments won't be entirely recomputed each time but recovered from memory. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. If you use it interactively it will only affect your current session. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. +**Memoization**. By default, when loading `fundiversity`, the functions to compute convex hulls are [memoised](https://en.wikipedia.org/wiki/Memoization) through the `memoise` package if it is installed (their results are cached to avoid recomputing the same functional volume twice). It means repeated call to `fd_fdiv()` with the same arguments won't be recomputed but recovered from cache. To deactivate this behavior you can set the option `fundiversity.memoise` to `FALSE` by running the following line: `options(fundiversity.memoise = FALSE)`. By changing the option, the behavior will automatically change the next time you run the function. Add it to your script(s) or `.Rprofile` file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. **Important note**: memoisation is only available when the `memoise` package has been installed **and without parallelization**, otherwise `fundiversity` will use unmemoised versions of the functions. # Functional Dispersion (FDis) - `fd_fdis()` From 21a1f3958307629e84ae02bc652f5bb13363cfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Wed, 20 Mar 2024 09:05:21 +0100 Subject: [PATCH 15/27] Skip line --- vignettes/fundiversity.Rmd | 1 + 1 file changed, 1 insertion(+) diff --git a/vignettes/fundiversity.Rmd b/vignettes/fundiversity.Rmd index 4983511..55d9a93 100644 --- a/vignettes/fundiversity.Rmd +++ b/vignettes/fundiversity.Rmd @@ -87,6 +87,7 @@ fd_fric(traits_birds, site_sp_birds[, 1:60]) fd_fric(traits_birds[1:5,], site_sp_birds[, 6:10]) ``` + # Functional Richness (FRic) - `fd_fric()` Functional Richness (FRic) represents the total amount of functional space filed by a community in a dataset [@Villeger_New_2008]. You can compute FRic in `fundiversity` using the `fd_fric()` function. From 33509b8b09318b0cf5a1512cd76d9b6879397b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Wed, 20 Mar 2024 09:05:42 +0100 Subject: [PATCH 16/27] Add tests for unmemoised versions --- tests/testthat/test-fdiv.R | 15 ++++++++++++++- tests/testthat/test-fric.R | 13 +++++++++++++ tests/testthat/test-fric_intersect.R | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-fdiv.R b/tests/testthat/test-fdiv.R index 5d059ea..bfd9bba 100644 --- a/tests/testthat/test-fdiv.R +++ b/tests/testthat/test-fdiv.R @@ -16,7 +16,7 @@ test_that("Functional Divergence output format", { expect_equal(fdiv$FDiv, 0.7282172, tolerance = 1e-7) }) -test_that("Function Divergence works on subset of site/species", { +test_that("Functional Divergence works on subset of site/species", { site_sp <- matrix(1, ncol = nrow(traits_birds)) colnames(site_sp) <- rownames(traits_birds) rownames(site_sp) <- "s1" @@ -106,6 +106,19 @@ test_that("Functional Divergence works on data.frame as well as matrix", { ) }) +test_that("Functional Divergence works with unmemoised version", { + + withr::local_options(fundiversity.memoise = FALSE) + + fdiv <- expect_silent(fd_fdiv(traits_birds)) + + expect_s3_class(fdiv, "data.frame") + expect_identical(dim(fdiv), c(1L, 2L)) + expect_named(fdiv, c("site", "FDiv")) + + expect_equal(fdiv$FDiv, 0.7282172, tolerance = 1e-7) +}) + # Tests for invalid inputs ----------------------------------------------------- test_that("Functional Divergence fails gracefully", { diff --git a/tests/testthat/test-fric.R b/tests/testthat/test-fric.R index e75fadc..9da6883 100644 --- a/tests/testthat/test-fric.R +++ b/tests/testthat/test-fric.R @@ -160,6 +160,19 @@ test_that("Functional Richness works on data.frame as well as matrix", { ) }) +test_that("Functional Richness works with unmemoised version", { + + withr::local_options(fundiversity.memoise = FALSE) + + fric <- expect_silent(fd_fric(traits_birds)) + + expect_s3_class(fric, "data.frame") + expect_identical(dim(fric), c(1L, 2L)) + expect_named(fric, c("site", "FRic")) + + expect_equal(fd_fric(traits_birds)$FRic, 230967.7, tolerance = 1e-6) +}) + # Tests for invalid inputs ----------------------------------------------------- diff --git a/tests/testthat/test-fric_intersect.R b/tests/testthat/test-fric_intersect.R index 8a3ada0..cf11081 100644 --- a/tests/testthat/test-fric_intersect.R +++ b/tests/testthat/test-fric_intersect.R @@ -187,6 +187,20 @@ test_that("Functional Richness Inters. works on data.frame as well as matrix", { ) }) +test_that("Functional Richness Intersect works with unmemoised version", { + + withr::local_options(fundiversity.memoise = FALSE) + + fric_int <- expect_silent(fd_fric_intersect(traits_birds)) + + expect_s3_class(fric_int, "data.frame") + expect_identical(dim(fric_int), c(1L, 3L)) + expect_named(fric_int, c("first_site", "second_site", "FRic_intersect")) + + expect_equal(fd_fric_intersect(traits_birds, stand = TRUE)$FRic_intersect, + 1, tolerance = 1e-6) +}) + # Tests for invalid inputs ----------------------------------------------------- test_that("Functional Richness Intersection fails gracefully", { From 15ab2bc38b041b2759face95216177db2b30a925 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Sat, 9 Dec 2023 15:00:29 +0100 Subject: [PATCH 17/27] Document fundiversity.memoise option via roxygen2 --- R/use_memoise.R | 14 +++++++++++--- man/fundiversity-options.Rd | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 man/fundiversity-options.Rd diff --git a/R/use_memoise.R b/R/use_memoise.R index ddcb764..f85b237 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -1,6 +1,14 @@ -# We respect users' explicit choice and error if we cannot honour it. However, -# by default, without any explicit option set by the user, we use memoise only -# if it was installed when fundiversity was loaded, without any messages. +#' Options for \pkg{fundiversity} +#' +#' The memoisation is the convex hull computation in \pkg{fundiversity} is +#' controlled via the `fundiversity.memoise` option: +#' - if unset, the default is to use memoisation if \pkg{memoise} was installed +#' when \pkg{fundiversity} was loaded, and not to use memoisation otherwise. +#' - if `options(fundiversity.memoise = TRUE)`, memoisation is used and an error +#' is thrown if \pkg{memoise} is not installed. +#' - if `options(fundiversity.memoise = FALSE)`, memoisation is not used. +#' +#' @rdname fundiversity-options use_memoise <- function() { # Cannot use memoise in parallel settings diff --git a/man/fundiversity-options.Rd b/man/fundiversity-options.Rd new file mode 100644 index 0000000..bb19bde --- /dev/null +++ b/man/fundiversity-options.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/use_memoise.R +\name{use_memoise} +\alias{use_memoise} +\title{Options for \pkg{fundiversity}} +\usage{ +use_memoise() +} +\description{ +The memoisation is the convex hull computation in \pkg{fundiversity} is +controlled via the \code{fundiversity.memoise} option: +\itemize{ +\item if unset, the default is to use memoisation if \pkg{memoise} was installed +when \pkg{fundiversity} was loaded, and not to use memoisation otherwise. +\item if \code{options(fundiversity.memoise = TRUE)}, memoisation is used and an error +is thrown if \pkg{memoise} is not installed. +\item if \code{options(fundiversity.memoise = FALSE)}, memoisation is not used. +} +} From 899ab3e6939599740a1729c673b31c4120df7d7e Mon Sep 17 00:00:00 2001 From: Hugo Gruson <10783929+Bisaloo@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:30:41 +0100 Subject: [PATCH 18/27] Add test to ensure use_memoise() really triggers memoise --- tests/testthat/test-use_memoise.R | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/testthat/test-use_memoise.R b/tests/testthat/test-use_memoise.R index a06b84d..47f9eee 100644 --- a/tests/testthat/test-use_memoise.R +++ b/tests/testthat/test-use_memoise.R @@ -61,3 +61,14 @@ test_that("use_memoise() sends back FALSE when plan is parallel", { future::plan("sequential") }) + +test_that("use_memoise() really triggers memoization when TRUE", { + + skip_if_not_installed("memoise") + + devnull <- fd_fric(c(1, 2, 5, 9)) + expect_true( + memoise::has_cache(fd_chull_memoised)(matrix(c(1, 2, 5, 9), nrow = 4)) + ) + +}) From 7c9ea1365c2ecfa3cd9f24d345fcec61389e8779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Fri, 22 Mar 2024 16:35:57 +0100 Subject: [PATCH 19/27] Update R/fd_fric_intersect.R Co-authored-by: Hugo Gruson <10783929+Bisaloo@users.noreply.github.com> --- R/fd_fric_intersect.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/fd_fric_intersect.R b/R/fd_fric_intersect.R index 49e8064..9f46709 100644 --- a/R/fd_fric_intersect.R +++ b/R/fd_fric_intersect.R @@ -128,7 +128,7 @@ fd_fric_intersect <- function(traits, sp_com, stand = FALSE) { convex_hull_intersect(first_traits, second_traits)$vol } else { # Self-intersection (equivalent to regular convex hulls) - # way more efficient that compute with convex_hull_intersect() + # way more efficient than computing with convex_hull_intersect() convex_hull(first_traits)$vol } }, future.globals = FALSE) From 4b896571602852379fc40448ac3bb7b32fe9a603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Fri, 22 Mar 2024 16:38:31 +0100 Subject: [PATCH 20/27] Update R/use_memoise.R Co-authored-by: Hugo Gruson <10783929+Bisaloo@users.noreply.github.com> --- R/use_memoise.R | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/R/use_memoise.R b/R/use_memoise.R index f85b237..3892da5 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -33,11 +33,9 @@ use_memoise <- function() { return(FALSE) } # unspecified / default - if (is.null(getOption("fundiversity.memoise"))) { - # TRUE or FALSE depending on whether memoise was installed when fundiversity - # was loaded - return(exists("fd_chull_memoised")) - } + # TRUE or FALSE depending on whether memoise was installed when fundiversity + # was loaded + return(exists("fd_chull_memoised")) } exists <- NULL From e1976ee1ce0d049d4270c939879a936db1618d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Fri, 22 Mar 2024 16:40:05 +0100 Subject: [PATCH 21/27] Add comment on exists() --- R/use_memoise.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/use_memoise.R b/R/use_memoise.R index f85b237..021db4c 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -40,4 +40,6 @@ use_memoise <- function() { } } +# Added this to make 'testthat::local_mocked_bindings()' work +# in 'test-use_memoise.R' exists <- NULL From 2e4a8a1c52c56bdd826d1a7a80bd4e8119f521aa Mon Sep 17 00:00:00 2001 From: Hugo Gruson <10783929+Bisaloo@users.noreply.github.com> Date: Mon, 25 Mar 2024 10:57:58 +0100 Subject: [PATCH 22/27] Fix pkgdown --- R/use_memoise.R | 5 ++++- man/fundiversity-options.Rd | 7 ++----- pkgdown/_pkgdown.yml | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/R/use_memoise.R b/R/use_memoise.R index 57c71ce..75d212b 100644 --- a/R/use_memoise.R +++ b/R/use_memoise.R @@ -8,7 +8,10 @@ #' is thrown if \pkg{memoise} is not installed. #' - if `options(fundiversity.memoise = FALSE)`, memoisation is not used. #' -#' @rdname fundiversity-options +#' @name fundiversity-options +NULL + +#' @keywords internal use_memoise <- function() { # Cannot use memoise in parallel settings diff --git a/man/fundiversity-options.Rd b/man/fundiversity-options.Rd index bb19bde..d9d429c 100644 --- a/man/fundiversity-options.Rd +++ b/man/fundiversity-options.Rd @@ -1,11 +1,8 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/use_memoise.R -\name{use_memoise} -\alias{use_memoise} +\name{fundiversity-options} +\alias{fundiversity-options} \title{Options for \pkg{fundiversity}} -\usage{ -use_memoise() -} \description{ The memoisation is the convex hull computation in \pkg{fundiversity} is controlled via the \code{fundiversity.memoise} option: diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index 1ed6fb2..8602f30 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -13,6 +13,9 @@ reference: - title: Functional Diversity Computation contents: - starts_with("fd_") + - title: Package options + contents: + - ends_with("-options") - title: Data desc: Datasets used in examples and tests contents: From 82b297a942bd584f37d31f6fb847bf54ada36f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Mon, 25 Mar 2024 14:55:15 +0100 Subject: [PATCH 23/27] Add warning in README --- README.Rmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.Rmd b/README.Rmd index 6012dcb..2b7bcc9 100644 --- a/README.Rmd +++ b/README.Rmd @@ -101,7 +101,8 @@ future::plan(future::multisession) fd_fdiv(traits_birds) ``` -For more details please refer to the [parallelization vignette](https://funecology.github.io/fundiversity/articles/fundiversity_1-parallel.html) or use `vignette("fundiversity_1-parallel", package = "fundiversity")` within R. +For more details please refer to the [parallelization vignette](https://funecology.github.io/fundiversity/articles/fundiversity_1-parallel.html) or use `vignette("fundiversity_1-parallel", package = "fundiversity")` within R. **Note**: parallelization and memoization are **mutually exclusive**, when doing computation in parallel, fundiversity falls back on **unmemoised** versions of function. + ## Available functional diversity indices From b42284ed05259e843f5b4ff57df2597bd7a3e376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 26 Mar 2024 13:53:31 +0100 Subject: [PATCH 24/27] Update Rmd workflow --- .github/workflows/render-readme.yaml | 33 ------------------------ .github/workflows/render-rmarkdown.yaml | 34 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 33 deletions(-) delete mode 100644 .github/workflows/render-readme.yaml create mode 100644 .github/workflows/render-rmarkdown.yaml diff --git a/.github/workflows/render-readme.yaml b/.github/workflows/render-readme.yaml deleted file mode 100644 index 5cea7dc..0000000 --- a/.github/workflows/render-readme.yaml +++ /dev/null @@ -1,33 +0,0 @@ -on: - push: - paths: - - README.Rmd - -name: Render README - -jobs: - render: - name: Render README - runs-on: ubuntu-latest - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v2 - - - uses: r-lib/actions/setup-pandoc@v1 - - - uses: r-lib/actions/setup-r@v1 - with: - use-public-rspm: true - - - uses: r-lib/actions/setup-r-dependencies@v1 - - - name: Render README - run: Rscript -e 'rmarkdown::render("README.Rmd")' - - - name: Commit results - run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" - git commit README.md -m 'Re-build README.Rmd' || echo "No changes to commit" - git push origin || echo "No changes to commit" diff --git a/.github/workflows/render-rmarkdown.yaml b/.github/workflows/render-rmarkdown.yaml new file mode 100644 index 0000000..6759a8c --- /dev/null +++ b/.github/workflows/render-rmarkdown.yaml @@ -0,0 +1,34 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + paths: + - README.Rmd + +name: Render README + +jobs: + render-rmarkdown: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + + - uses: r-lib/actions/setup-renv@v2 + + - name: Render Rmarkdown files and Commit Results + run: | + RMD_PATH=($(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '[.]Rmd$')) + Rscript -e 'for (f in commandArgs(TRUE)) if (file.exists(f)) rmarkdown::render(f)' ${RMD_PATH[*]} + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" + git commit ${RMD_PATH[*]/.Rmd/.md} -m 'Re-build Rmarkdown files' || echo "No changes to commit" + git push origin || echo "No changes to commit" From 114e95e18e558980a6384ac8756c4a081b74a870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 26 Mar 2024 14:02:46 +0100 Subject: [PATCH 25/27] Render README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c8bf177..bd35d16 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,9 @@ fd_fdiv(traits_birds) For more details please refer to the [parallelization vignette](https://funecology.github.io/fundiversity/articles/fundiversity_1-parallel.html) or use `vignette("fundiversity_1-parallel", package = "fundiversity")` -within R. +within R. **Note**: parallelization and memoization are **mutually +exclusive**, when doing computation in parallel, fundiversity falls back +on **unmemoised** versions of function. ## Available functional diversity indices @@ -140,14 +142,14 @@ mention the numerous wrappers around these packages): | Package Name | Indices included | Has vignettes | Has tests | On GitHub | On CRAN (last updated) | |--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|---------------|-----------|-----------|------------------------------------------------------------| -| [`adiv`](https://github.com/cran/adiv) | Functional Entropy, Functional Redundancy | ✅ | ❌ | ❌ | ![](https://www.r-pkg.org/badges/last-release/adiv) | +| [`adiv`](https://github.com/cran/adiv) | Functional Entropy, Functional Redundancy | ❌ | ❌ | ❌ | ![](https://www.r-pkg.org/badges/last-release/adiv) | | [`BAT`](https://github.com/cardosopmb/BAT) | β-diversity indices, Richness, divergence, and evenness with hypervolumes | ❌ | ❌ | ✅ | ![](https://www.r-pkg.org/badges/last-release/BAT) | | [`betapart`](https://github.com/cran/betapart) | Functional β-diversity | ❌ | ❌ | ❌ | ![](https://www.r-pkg.org/badges/last-release/betapart) | | [`entropart`](https://github.com/EricMarcon/entropart) | Functional Entropy | ✅ | ✅ | ✅ | ![](https://www.r-pkg.org/badges/last-release/entropart) | | [`FD`](https://github.com/cran/FD) | FRic, FDiv, FDis, FEve, Rao’s QE, Functional Group Richness | ❌ | ❌ | ❌ | ![](https://www.r-pkg.org/badges/last-release/FD) | | [`hilldiv`](https://github.com/anttonalberdi/hilldiv) | Dendrogram-based Hill numbers for functional diversity | ❌ | ❌ | ✅ | ![](https://www.r-pkg.org/badges/last-release/hilldiv) | | [`hillR`](https://github.com/daijiang/hillR) | Functional Diversity Hill Numbers | ❌ | ✅ | ✅ | ![](https://www.r-pkg.org/badges/last-release/hillR) | -| [`hypervolume`](https://github.com/cran/hypervolume) | Hypervolume measure of functional diversity (\~FRic) | ✅ | ❌ | ✅ | ![](https://www.r-pkg.org/badges/last-release/hypervolume) | +| [`hypervolume`](https://github.com/cran/hypervolume) | Hypervolume measure of functional diversity (~FRic) | ✅ | ❌ | ✅ | ![](https://www.r-pkg.org/badges/last-release/hypervolume) | | [`mFD`](https://github.com/CmlMagneville/mFD) | Functional α- and β-diversity indices, including FRic, FDiv, FDis, FEve, FIde, FMPD, FNND, FOri, FSpe, Hill Numbers | ✅ | ❌ | ✅ | ![](https://www.r-pkg.org/badges/last-release/mFD) | | [`TPD`](https://github.com/cran/TPD) | FRic, FDiv, FEve but for probability distributions | ✅ | ❌ | ❌ | ![](https://www.r-pkg.org/badges/last-release/TPD) | | [`vegan`](https://github.com/vegandevs/vegan) | Only dendrogram-based FD (`treedive()`) | ✅ | ✅ | ✅ | ![](https://www.r-pkg.org/badges/last-release/vegan) | From 246c196aadd50a7390adf59bf1f33fe696d46af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 26 Mar 2024 14:02:59 +0100 Subject: [PATCH 26/27] Update doc on memoization vs. parallelization --- R/fd_fric.R | 5 +++-- man/fd_fdis.Rd | 2 +- man/fd_fdiv.Rd | 5 +++-- man/fd_feve.Rd | 2 +- man/fd_fric.Rd | 5 +++-- man/fd_fric_intersect.Rd | 5 +++-- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/R/fd_fric.R b/R/fd_fric.R index 0bca0c8..b0ec6ff 100644 --- a/R/fd_fric.R +++ b/R/fd_fric.R @@ -25,7 +25,7 @@ #' The computation of this function can be parallelized thanks to #' [future::plan()]. To get more information on how to parallelize your #' computation please refer to the parallelization vignette with: -#' `vignette("fundiversity_1-parallel", package = "fundiversity")` +#' `vignette("fundiversity_1-parallel", package = "fundiversity")`. #' #' @examples #' data(traits_birds) @@ -43,7 +43,8 @@ #' will automatically change the next time you run the function. **Note**: #' memoisation is only available when the `memoise` package has been installed #' **and without parallelization**, otherwise `fundiversity` will use unmemoised -#' versions of the functions. +#' versions of the functions. In other words, **memoization and parallelization +#' are mutually exclusive**. #' #' @return a data.frame with two columns: #' * `site` the names of the sites as the row names of the input `sp_com`, diff --git a/man/fd_fdis.Rd b/man/fd_fdis.Rd index e7b9874..8583f06 100644 --- a/man/fd_fdis.Rd +++ b/man/fd_fdis.Rd @@ -38,7 +38,7 @@ Legendre (2010). NB: when a site contains no species FDis is equal to 0. The computation of this function can be parallelized thanks to \code{\link[future:plan]{future::plan()}}. To get more information on how to parallelize your computation please refer to the parallelization vignette with: -\code{vignette("fundiversity_1-parallel", package = "fundiversity")} +\code{vignette("fundiversity_1-parallel", package = "fundiversity")}. } \examples{ diff --git a/man/fd_fdiv.Rd b/man/fd_fdiv.Rd index f146df3..4232dbf 100644 --- a/man/fd_fdiv.Rd +++ b/man/fd_fdiv.Rd @@ -48,14 +48,15 @@ file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. \strong{Note}: memoisation is only available when the \code{memoise} package has been installed \strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised -versions of the functions. +versions of the functions. In other words, \strong{memoization and parallelization +are mutually exclusive}. } \section{Parallelization}{ The computation of this function can be parallelized thanks to \code{\link[future:plan]{future::plan()}}. To get more information on how to parallelize your computation please refer to the parallelization vignette with: -\code{vignette("fundiversity_1-parallel", package = "fundiversity")} +\code{vignette("fundiversity_1-parallel", package = "fundiversity")}. } \examples{ diff --git a/man/fd_feve.Rd b/man/fd_feve.Rd index 1255d03..3fb9c29 100644 --- a/man/fd_feve.Rd +++ b/man/fd_feve.Rd @@ -46,7 +46,7 @@ per site is strictly lower than 3. The computation of this function can be parallelized thanks to \code{\link[future:plan]{future::plan()}}. To get more information on how to parallelize your computation please refer to the parallelization vignette with: -\code{vignette("fundiversity_1-parallel", package = "fundiversity")} +\code{vignette("fundiversity_1-parallel", package = "fundiversity")}. } \examples{ diff --git a/man/fd_fric.Rd b/man/fd_fric.Rd index a9fdde0..a4104cf 100644 --- a/man/fd_fric.Rd +++ b/man/fd_fric.Rd @@ -59,14 +59,15 @@ file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. \strong{Note}: memoisation is only available when the \code{memoise} package has been installed \strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised -versions of the functions. +versions of the functions. In other words, \strong{memoization and parallelization +are mutually exclusive}. } \section{Parallelization}{ The computation of this function can be parallelized thanks to \code{\link[future:plan]{future::plan()}}. To get more information on how to parallelize your computation please refer to the parallelization vignette with: -\code{vignette("fundiversity_1-parallel", package = "fundiversity")} +\code{vignette("fundiversity_1-parallel", package = "fundiversity")}. } \examples{ diff --git a/man/fd_fric_intersect.Rd b/man/fd_fric_intersect.Rd index b14fca0..01d28b2 100644 --- a/man/fd_fric_intersect.Rd +++ b/man/fd_fric_intersect.Rd @@ -65,14 +65,15 @@ file to avoid toggling it each time. By changing the option, the behavior will automatically change the next time you run the function. \strong{Note}: memoisation is only available when the \code{memoise} package has been installed \strong{and without parallelization}, otherwise \code{fundiversity} will use unmemoised -versions of the functions. +versions of the functions. In other words, \strong{memoization and parallelization +are mutually exclusive}. } \section{Parallelization}{ The computation of this function can be parallelized thanks to \code{\link[future:plan]{future::plan()}}. To get more information on how to parallelize your computation please refer to the parallelization vignette with: -\code{vignette("fundiversity_1-parallel", package = "fundiversity")} +\code{vignette("fundiversity_1-parallel", package = "fundiversity")}. } \examples{ From fffbaab56bbe4e0fd930fbfe0f0b1404ac58b93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Greni=C3=A9?= Date: Tue, 26 Mar 2024 16:26:28 +0100 Subject: [PATCH 27/27] Correct typo --- vignettes/_fundiversity_1-parallel.Rmd | 2 +- vignettes/fundiversity_1-parallel.Rmd | 39 +++++++++++++------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/vignettes/_fundiversity_1-parallel.Rmd b/vignettes/_fundiversity_1-parallel.Rmd index 93ebe5a..6ab5115 100644 --- a/vignettes/_fundiversity_1-parallel.Rmd +++ b/vignettes/_fundiversity_1-parallel.Rmd @@ -30,7 +30,7 @@ Within `fundiversity` the computation of most indices can be parallelized using ```{r child="../man/rmdchunks/_fundiversity_functions.Rmd"} ``` -Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computation are parallelized, `fundiversity` will use unmemoised version of functions. +Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computations are parallelized, `fundiversity` will use unmemoised versions of functions. The `future` package provides a simple and general framework to allow asynchronous computation depending on the resources available for the user. The [first vignette of `future`](https://cran.r-project.org/package=future) gives a general overview of all its features. The main idea being that the user should write the code once and that it would run seamlessly sequentially, or in parallel on a single computer, or on a cluster, or distributed over several computers. `fundiversity` can thus run on all these different backends following the user's choice. diff --git a/vignettes/fundiversity_1-parallel.Rmd b/vignettes/fundiversity_1-parallel.Rmd index 01cd41b..7dd8bd2 100644 --- a/vignettes/fundiversity_1-parallel.Rmd +++ b/vignettes/fundiversity_1-parallel.Rmd @@ -31,7 +31,7 @@ Within `fundiversity` the computation of most indices can be parallelized using [^1]: parallelization through the `future` backend please refer to the [parallelization vignette](https://funecology.github.io/fundiversity/articles/fundiversity_1-parallel.html) for details. [^2]: memoization means that the results of the functions calls are cached and not recomputed when recalled, to toggle it off see the `fundiversity::fd_fric()` [Details section](https://funecology.github.io/fundiversity/reference/fd_fric.html#details). -Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computation are parallelized, `fundiversity` will use unmemoised version of functions. +Note that **memoization and parallelization cannot be used at the same time**. If the option `fundiversity.memoise` has been set to `TRUE` but the computations are parallelized, `fundiversity` will use unmemoised versions of functions. The `future` package provides a simple and general framework to allow asynchronous computation depending on the resources available for the user. The [first vignette of `future`](https://cran.r-project.org/package=future) gives a general overview of all its features. The main idea being that the user should write the code once and that it would run seamlessly sequentially, or in parallel on a single computer, or on a cluster, or distributed over several computers. `fundiversity` can thus run on all these different backends following the user's choice. @@ -98,9 +98,9 @@ parallel_bench <- microbenchmark::microbenchmark( rbind(non_parallel_bench, parallel_bench) #> Unit: milliseconds -#> expr min lq mean median uq max neval cld -#> non_parallel 12.3267 13.3452 15.03753 14.7037 15.84075 20.0802 20 a -#> parallel 178.1048 188.8670 259.66154 211.7129 219.97645 1312.2693 20 b +#> expr min lq mean median uq max neval cld +#> non_parallel 8.9509 9.2691 14.93812 13.32405 18.4841 33.153 20 a +#> parallel 224.7037 248.9997 345.59427 274.59615 304.6889 1660.164 20 b ``` The non parallelized code runs faster than the parallelized one! Indeed, the parallelization in `fundiversity` parallelize the computation across different sites. So parallelization should be used when you have many sites on which you want to compute similar indices. @@ -137,10 +137,10 @@ microbenchmark::microbenchmark( }, times = 20 ) #> Unit: seconds -#> expr min lq mean median uq max neval cld -#> seq 114.82322 117.47735 149.55998 163.00871 167.59926 184.8759 20 a -#> multisession 54.77985 64.59042 70.99131 67.62465 74.16261 119.5938 20 b -#> multicore 116.11616 160.90286 159.18414 163.86793 166.77678 173.3062 20 a +#> expr min lq mean median uq max neval cld +#> seq 78.13766 195.17853 184.92560 196.89360 197.90500 200.56116 20 a +#> multisession 34.23402 54.44036 53.39172 54.88206 55.19359 61.83829 20 b +#> multicore 75.43857 192.45136 183.07222 196.48277 201.16889 209.39847 20 a ```
@@ -148,8 +148,8 @@ microbenchmark::microbenchmark( ``` -#> seconds needed to generate this document: 7610.61 sec elapsed -#> ─ Session info ──────────────────────────────────────────────────────────────────── +#> seconds needed to generate this document: 8443.78 sec elapsed +#> ─ Session info ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── #> setting value #> version R version 4.3.1 (2023-06-16 ucrt) #> os Windows 11 x64 (build 22631) @@ -159,23 +159,22 @@ microbenchmark::microbenchmark( #> collate French_France.utf8 #> ctype fr_FR.UTF-8 #> tz Europe/Paris -#> date 2024-03-20 +#> date 2024-03-26 #> rstudio 2023.12.1+402 Ocean Storm (desktop) #> pandoc 3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown) #> -#> ─ Packages ──────────────────────────────────────────────────────────────────────── +#> ─ Packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── #> ! package * version date (UTC) lib source #> abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) -#> brio 1.1.4 2023-12-10 [1] CRAN (R 4.3.2) #> cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.1) #> cli 3.6.2 2023-12-11 [1] CRAN (R 4.3.2) #> cluster 2.1.6 2023-12-01 [1] CRAN (R 4.3.2) #> codetools 0.2-19 2023-02-01 [2] CRAN (R 4.3.1) #> commonmark 1.9.1 2024-01-30 [1] CRAN (R 4.3.2) #> crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.1) +#> curl 5.2.1 2024-03-01 [1] CRAN (R 4.3.3) #> desc 1.4.3 2023-12-10 [1] CRAN (R 4.3.2) #> devtools 2.4.5 2022-10-11 [1] CRAN (R 4.3.2) -#> diffobj 0.3.5 2021-10-05 [1] CRAN (R 4.3.2) #> digest 0.6.35 2024-03-11 [1] CRAN (R 4.3.3) #> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.1) #> evaluate 0.23 2023-11-01 [1] CRAN (R 4.3.2) @@ -186,17 +185,20 @@ microbenchmark::microbenchmark( #> future 1.33.1 2023-12-22 [1] CRAN (R 4.3.2) #> future.apply 1.11.1 2023-12-21 [1] CRAN (R 4.3.2) #> geometry 0.4.7 2023-02-03 [1] CRAN (R 4.3.1) +#> gh 1.4.0 2023-02-22 [1] CRAN (R 4.3.1) +#> gitcreds 0.1.2 2022-09-08 [1] CRAN (R 4.3.1) #> globals 0.16.3 2024-03-08 [1] CRAN (R 4.3.3) #> glue 1.7.0 2024-01-09 [1] CRAN (R 4.3.2) #> htmltools 0.5.7 2023-11-03 [1] CRAN (R 4.3.2) #> htmlwidgets 1.6.4 2023-12-06 [1] CRAN (R 4.3.2) #> httpuv 1.6.14 2024-01-26 [1] CRAN (R 4.3.2) +#> httr2 1.0.0 2023-11-14 [1] CRAN (R 4.3.2) +#> jsonlite 1.8.8 2023-12-04 [1] CRAN (R 4.3.2) #> knitr 1.45 2023-10-30 [1] CRAN (R 4.3.2) #> later 1.3.2 2023-12-06 [1] CRAN (R 4.3.2) #> lattice 0.22-5 2023-10-24 [1] CRAN (R 4.3.2) #> lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.2) #> listenv 0.9.1 2024-01-29 [1] CRAN (R 4.3.2) -#> lpSolve 5.6.20 2023-12-10 [1] CRAN (R 4.3.2) #> magic 1.6-1 2022-11-16 [1] CRAN (R 4.3.0) #> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.1) #> MASS 7.3-60.0.1 2024-01-13 [1] CRAN (R 4.3.2) @@ -209,7 +211,6 @@ microbenchmark::microbenchmark( #> multcomp 1.4-25 2023-06-20 [1] CRAN (R 4.3.1) #> mvtnorm 1.2-4 2023-11-27 [1] CRAN (R 4.3.2) #> nlme 3.1-164 2023-11-27 [1] CRAN (R 4.3.2) -#> pak 0.7.2 2024-03-17 [1] CRAN (R 4.3.3) #> parallelly 1.37.1 2024-02-29 [1] CRAN (R 4.3.3) #> permute 0.9-7 2022-01-27 [1] CRAN (R 4.3.1) #> pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.1) @@ -220,8 +221,8 @@ microbenchmark::microbenchmark( #> promises 1.2.1 2023-08-10 [1] CRAN (R 4.3.1) #> purrr 1.0.2 2023-08-10 [1] CRAN (R 4.3.1) #> R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.1) +#> rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.1) #> Rcpp 1.0.12 2024-01-09 [1] CRAN (R 4.3.2) -#> rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.3.1) #> remotes 2.5.0 2024-03-17 [1] CRAN (R 4.3.3) #> rlang 1.1.3 2024-01-10 [1] CRAN (R 4.3.2) #> rmarkdown 2.26 2024-03-05 [1] CRAN (R 4.3.3) @@ -234,7 +235,6 @@ microbenchmark::microbenchmark( #> stringi 1.8.3 2023-12-11 [1] CRAN (R 4.3.2) #> stringr 1.5.1 2023-11-14 [1] CRAN (R 4.3.2) #> survival 3.5-8 2024-02-14 [1] CRAN (R 4.3.3) -#> testthat * 3.2.1 2023-12-02 [1] CRAN (R 4.3.2) #> TH.data 1.1-2 2023-04-17 [1] CRAN (R 4.3.1) #> tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.1) #> tictoc 1.2.1 2024-03-18 [1] CRAN (R 4.3.3) @@ -243,7 +243,6 @@ microbenchmark::microbenchmark( #> utf8 1.2.4 2023-10-22 [1] CRAN (R 4.3.2) #> vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.2) #> vegan 2.6-4 2022-10-11 [1] CRAN (R 4.3.1) -#> waldo 0.5.2 2023-11-02 [1] CRAN (R 4.3.2) #> withr 3.0.0 2024-01-16 [1] CRAN (R 4.3.2) #> xfun 0.42 2024-02-08 [1] CRAN (R 4.3.3) #> xml2 1.3.6 2023-12-04 [1] CRAN (R 4.3.2) @@ -256,7 +255,7 @@ microbenchmark::microbenchmark( #> #> P ── Loaded and on-disk path mismatch. #> -#> ─────────────────────────────────────────────────────────────────────────────────── +#> ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ```