Skip to content
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
a62e3ff
store raw cube data
shawndove Dec 18, 2025
b6df31f
calculate bootstrap CIs using dubicube and add them to calculated ind…
shawndove Dec 18, 2025
895ef5a
add dubicube as dependency
shawndove Dec 18, 2025
c073d18
add documentation and indicator level CIs
shawndove Dec 19, 2025
42f4e7f
export add_ci
shawndove Dec 19, 2025
81b8146
remove ci calculations (offloaded to add_ci)
shawndove Dec 19, 2025
3384d31
documentation update
shawndove Dec 19, 2025
981154d
first commit
shawndove Dec 19, 2025
cdbfec6
version update
shawndove Dec 19, 2025
9dfffdf
version update
shawndove Dec 19, 2025
be41572
add dubicube to remotes
shawndove Dec 19, 2025
97dd488
fix dubicube github url
shawndove Dec 19, 2025
9caef30
update CI calculation in vignette
shawndove Dec 19, 2025
a996cc8
remove leftover confidence interval code and adjust documentation
shawndove Dec 19, 2025
03528ce
remove CI code artifacts
shawndove Dec 19, 2025
d3dcdd2
fix spelling mistake
shawndove Dec 19, 2025
dcbc575
documentation fix
shawndove Jan 9, 2026
209696a
add missing null assignment
shawndove Jan 9, 2026
1f6584c
fix documentation, add missing null assignments, and fix incorrectly …
shawndove Jan 9, 2026
84395c3
fix roxygen2 code style issue
shawndove Jan 9, 2026
2bbb77e
fix documentation typo
shawndove Jan 9, 2026
283eb35
add separate grouping logic for species occurrences and species range
shawndove Jan 9, 2026
a168427
prevent warning during testing of single point geometry
shawndove Jan 9, 2026
ca4efd3
add missing parameter
shawndove Jan 9, 2026
303505d
fix broken tests
shawndove Jan 9, 2026
78faaad
remove invalid paramter from documentation
shawndove Jan 9, 2026
d1fde1e
increase hill diversity bootstrap defaults to 1000
shawndove Jan 9, 2026
b0fafc1
documentation update
shawndove Jan 9, 2026
b45e4d2
fix broken tests
shawndove Jan 9, 2026
308f58e
feat(uncertainty): Implement add_ci with dubicube integration and add…
shawndove Jan 16, 2026
4ed87e6
conductor(plan): Mark Phase 2 as COMPLETED and Phase 3 as IN PROGRESS
shawndove Jan 16, 2026
846b9ec
fix(uncertainty): Fix full_join error in add_ci and include bootstrap…
shawndove Jan 16, 2026
423c9c7
docs(vignette): Add dubicube exploration details and links
shawndove Jan 16, 2026
556aca0
chore(metadata): Update documentation and project metadata for versio…
shawndove Jan 16, 2026
3d289d2
fix(docs): Standardize roxygen2 tags and ignore files to fix building…
shawndove Jan 16, 2026
9ea866a
conductor(plan): Update commit hashes for integration and documentation
shawndove Jan 16, 2026
8e14023
fix(ci): Resolve R-CMD-check failures by fixing ignore file encoding …
shawndove Jan 16, 2026
aab7c33
test(utils): Fix expected type in breaks_pretty_int for NA input
shawndove Jan 16, 2026
8566502
fix type mismatch
shawndove Jan 16, 2026
68f1bd9
refactor(ci): Correctly categorize indicators for whole-cube vs group…
shawndove Jan 16, 2026
488d144
add space
wlangera Jan 28, 2026
88f7e3b
identify bootstrap method
wlangera Jan 28, 2026
80d0704
prepare indicator bootstrapping with dubicube
wlangera Jan 28, 2026
5bc0a3d
add transformation functions
wlangera Jan 28, 2026
6dd8053
add function to namespace
wlangera Jan 28, 2026
20ad4b4
add unit tests
wlangera Jan 28, 2026
508bb68
fix bug
wlangera Jan 28, 2026
1b92517
parse no_bias argument according to dubicube v0.11.0
wlangera Feb 4, 2026
8a05b54
update documentation
wlangera Feb 4, 2026
112f445
Merge pull request #103 from b-cubed-eu/update-dubicube-ward
shawndove Feb 9, 2026
e5974cc
reorder ci_type options, and update documentation
shawndove Feb 9, 2026
49ddb1e
update news items to reflect merged changes
shawndove Feb 9, 2026
b0355f9
update after merged changes
shawndove Feb 9, 2026
d06f60f
update to reflect merged changes
shawndove Feb 9, 2026
989bfb1
Merge branch 'main' into outsource_uncertainty
shawndove Feb 9, 2026
faba649
fix malformed function call
shawndove Feb 9, 2026
6f8da1e
fix missing package issue for r-cmd-check
shawndove Feb 9, 2026
712d6b8
fix missing colon
shawndove Feb 9, 2026
c203d1d
add another missing package that fell off CRAN to remotes
shawndove Feb 9, 2026
1055299
fix missing comma
shawndove Feb 9, 2026
b234969
another attempt to fix missing dependency
shawndove Feb 9, 2026
1885b01
another attempt to fix missing dependency
shawndove Feb 9, 2026
a9f63cd
another attempt to fix missing dependency
shawndove Feb 9, 2026
5986ae4
another attempt to solve missing dependency
shawndove Feb 9, 2026
71ed724
fix malformed function call
shawndove Feb 9, 2026
35bcd4b
attempt r-cmd-check fix through workflow update
shawndove Feb 9, 2026
c11fc19
call dubicube as an extra package
shawndove Feb 9, 2026
0ef0692
try again
shawndove Feb 9, 2026
4011d19
fix accidental rename of bootstrap_results
shawndove Feb 9, 2026
2c1c4e6
add ellipsis back to parameters, as it is used to transfer paramters …
shawndove Feb 9, 2026
0eb019b
documentation update
shawndove Feb 9, 2026
51bb93f
fix year to handle more type mismatches
shawndove Feb 9, 2026
256a846
use all_of with select to fix warning
shawndove Feb 9, 2026
fec5999
add missing seed parameter
shawndove Feb 9, 2026
2373f98
fix broken tests
shawndove Feb 9, 2026
5a81648
only add seed to bootstrap_params if not NULL
shawndove Feb 9, 2026
4591343
fix select line
shawndove Feb 9, 2026
89ff894
documentation update
shawndove Feb 9, 2026
001511b
fix parameter naming mismatch with dubicube
shawndove Feb 10, 2026
b2c893f
suppress 'extreme order statistics' warning due to low replicates
shawndove Feb 10, 2026
2571e6f
fix missing seed parameter
shawndove Feb 10, 2026
632d67c
set default seed and adjust logit function to avoid failure when even…
shawndove Feb 10, 2026
ba95cc7
reduce bootstraps to make faster
shawndove Feb 10, 2026
1bb3537
fix: create composite key for multiple grouping variables
shawndove Feb 10, 2026
2f930d2
fix: add validation for missing grouping columns
shawndove Feb 11, 2026
d1e6a50
fix: preserve raw data without indicator classes for bootstrapping
shawndove Feb 11, 2026
53d7f1b
fix: update test mock data to include required grouping columns
shawndove Feb 11, 2026
d43ed2f
fix: update test expectations for new composite key behavior
shawndove Feb 11, 2026
cdca6e2
fix: apply indicator class to data for S3 method dispatch during boot…
shawndove Feb 11, 2026
7417331
fix: ensure indicator class is first for S3 dispatch and add debug ou…
shawndove Feb 11, 2026
0be520b
test: add S3 dispatch verification test and diagnostic script
shawndove Feb 11, 2026
99929d6
chore: remove temporary diagnostic script
shawndove Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ message: 'To cite package "b3gbi" in publications use:'
type: software
license: MIT
title: 'b3gbi: General Biodiversity Indicators for Biodiversity Data Cubes'
version: 0.8.12
version: 0.9.0
abstract: Calculate general biodiversity indicators from GBIF data cubes. Includes
many common indicators such as species richness and evenness, which can be calculated
over time (trends) or space (maps).
Expand Down Expand Up @@ -78,6 +78,23 @@ references:
orcid: https://orcid.org/0000-0003-4777-038X
year: '2025'
doi: 10.32614/CRAN.package.dplyr
- type: software
title: dubicube
abstract: 'dubicube: Calculation and Interpretation of Data Cube Indicator Uncertainty'
notes: Imports
url: https://b-cubed-eu.github.io/dubicube/
authors:
- family-names: Langeraert
given-names: Ward
email: ward.langeraert@inbo.be
orcid: https://orcid.org/0000-0002-5900-8109
affiliation: Research Institute for Nature and Forest (INBO)
- family-names: Van Daele
given-names: Toon
email: toon.vandaele@inbo.be
orcid: https://orcid.org/0000-0002-1362-853X
affiliation: Research Institute for Nature and Forest (INBO)
year: '2025'
- type: software
title: ggplot2
abstract: 'ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics'
Expand Down
6 changes: 4 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: b3gbi
Title: General Biodiversity Indicators for Biodiversity Data Cubes
Version: 0.8.12
Version: 0.9.0
Authors@R: c(
person("Shawn", "Dove", email = "Shawn.Dove@allzool.bio.uni-giessen.de",
role = c("aut", "cre"), comment = c(ORCID = "0000-0001-9465-5638")),
Expand All @@ -19,6 +19,7 @@ Depends:
Imports:
boot,
dplyr,
dubicube,
ggplot2,
iNEXT,
labeling,
Expand Down Expand Up @@ -60,7 +61,8 @@ Remotes:
github::hrbrmstr/mgrs,
github::ropensci/bold,
github::ropensci/taxize,
github::ropensci/rnaturalearthhires
github::ropensci/rnaturalearthhires,
github::b-cubed-eu/dubicube
BugReports: https://github.com/b-cubed-eu/b3gbi/issues
Funding: This project receives funding from the European Union’s Horizon Europe
Research and Innovation Programme (ID No 101059592).
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ S3method(print,sim_cube)
export("%>%")
export(ab_rarity_map)
export(ab_rarity_ts)
export(add_ci)
export(area_rarity_map)
export(area_rarity_ts)
export(calc_ci)
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# b3gbi 0.9.0 - Major update:

* Confidence intervals are no longer calculated in the core indicator workflow, except for Hill diversity (Hill diversity is handled by the iNEXT package, which calculates confidence intervals internally). They are now calculated using a separaed function, add_ci(), which can be applied to any indicator_ts object for which reasonable confidence intervals can be calculated. This gives the user more freedom. After adding CIs, you can recalculate with different parameters by setting 'replace = TRUE' when you call add_ci().
* Bootstrapping for confidence intervals is now done across the entire cube by default. This uses the dubicube package, which is now added as a dependency. The option to calculate at indicator level is still available by setting 'level = "indicator"' when calling add_ci(). Indicator level bootstrapping is a faster but less robust method.
* The default number of bootstrap replicates when calculating confidence intervals is now 1000. This improves robustness at the sake of speed. This can still be changed using the 'num_bootstrap' parameter when calling add_ci().

# b3gbi 0.8.12 - Minor update:

* The cellCode column from the cube is now retained in indicator map outputs. This allows users to trace back grid cells to their original codes in the cube.
Expand Down
207 changes: 207 additions & 0 deletions R/add_ci.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
#' Add Confidence Intervals to an Indicator Object
#'
#' @description
#' This function calculates bootstrap confidence intervals for an existing
#' `indicator_ts` object. It supports both cube-level bootstrapping (resampling
#' occurrence records) and indicator-level bootstrapping (resampling
#' calculated values), allowing for advanced transformations during the
#' CI calculation process.
#'
#' @param indicator An object of class `indicator_ts` to which confidence
#' intervals should be added.
#' @param num_bootstrap (Optional) Number of bootstrap replicates to perform.
#' (Default: 1000)
#' @param bootstrap_level (Optional) Level at which to perform bootstrapping:
#' * `cube` (default): Bootstrapping is done by resampling the
#' occurrence records in the cube. This is mathematically more robust as it
#' captures the underlying sampling uncertainty.
#' * `indicator`: Bootstrapping is done by resampling indicator
#' values. This is faster for large cubes but less robust.
#'
#' @param ci_type (Optional) Type of bootstrap confidence intervals to
#' calculate. (Default: `"norm"`). Supported options are:
#' * `norm`: Normal approximation intervals.
#' * `basic`: Basic bootstrap intervals.
#' * `perc`: Percentile intervals.
#' * `bca`: Bias-corrected and accelerated intervals.
#' * `none`: No confidence intervals calculated.
#'
#' @param trans (Optional) A function for transforming the indicator values
#' before calculating confidence intervals (e.g., `log`).
#' (Default: identity function)
#' @param inv_trans (Optional) The inverse of the transformation function
#' `trans` (e.g., `exp`). Used to back-transform the intervals
#' to the original scale. (Default: identity function)
#' @param confidence_level (Optional) The confidence level for the calculated
#' intervals (e.g., 0.95 for 95% CIs). (Default: 0.95)
#' @param overwrite (Optional) Logical. If the indicator already contains
#' confidence intervals (`ll` and `ul` columns), should they
#' be replaced? (Default: TRUE)
#' @param ... Additional arguments passed to the underlying functions.
#'
#' @details
#' The function acts as a bridge to the `dubicube` package for statistical
#' heavy lifting. For certain indicators (e.g., Hill numbers), confidence
#' intervals cannot be added post-hoc as they are calculated internally by
#' the `iNext` package during the initial calculation. In such cases,
#' a warning is issued and the original object is returned.
#'
#' @return An updated object of class `indicator_ts` containing the
#' original data with the following additional columns:
#' * `ll`: Lower limit of the confidence interval.
#' * `ul`: Upper limit of the confidence interval.
#' * `est_boot`: The bootstrap estimate of the indicator value.
#' * `se_boot`: The bootstrap standard error.
#' \item `bias_boot`: The bootstrap estimate of bias.
#' \item `int_type`: The type of interval calculated (e.g., 'perc').
#' \item `conf`: The confidence level used.
#'
#' @seealso [dubicube::bootstrap_cube()], [dubicube::calculate_bootstrap_ci()]
#'
#' @export
add_ci <- function(indicator,
num_bootstrap = 1000,
bootstrap_level = c("cube",
"indicator"),
ci_type = c("norm",
"basic",
"perc",
"bca",
"none"),
trans = function(t) t,
inv_trans = function(t) t,
confidence_level = 0.95,
overwrite = TRUE,
...) {

# Check for correct object class
if (!inherits(indicator, "indicator_ts")) {
stop("indicator must be an indicator_ts object.")
}

ll <- ul <- year <- est_original <- NULL

# List of indicators for which bootstrapped confidence intervals should not
# be calculated
noci_list <- c("obs_richness",
"cum_richness",
"occ_turnover",
"tax_distinct",
"hill0",
"hill1",
"hill2")

# Match ci_type argument
ci_type <- match.arg(ci_type)
bootstrap_level <- match.arg(bootstrap_level)

# If indicator is in noci_list, return indicator without calculating CIs
if (indicator$div_type %in% noci_list) {
if (indicator$div_type %in% c("hill0", "hill1", "hill2")) {
warning(
paste0(
"Confidence intervals cannot calculated for ",
indicator$div_type,
" as they are handled by the iNext package when calculating
your indicator. Returning indicator without adding CIs."
)
)
} else
warning(
paste0(
"Cannot calculate sensible confidence intervals for ",
indicator$div_type, ". Returning indicator without CIs."
)
)
return(indicator)
}

# Extract data from indicator object
x <- indicator$data
raw_data <- indicator$raw_data

if(any(c("ll", "ul") %in% names(x)) & !overwrite) {
warning(
paste0(
"Indicator already contains confidence intervals. Returning indicator
without adding CIs. Use 'replace = TRUE' argument to recalculate CIs."
)
)
return(indicator)
}

# Remove existing confidence intervals if overwrite = TRUE
if (overwrite &
all(c("ll", "ul") %in% names(x))) {
x <- x %>%
dplyr::select(-ll, -ul)
}

# Calculate confidence intervals
if (bootstrap_level == "indicator") {

# Send data to calc_ci for indicator level bootstrapping
indicator <- calc_ci(raw_data,
indicator = indicator,
num_bootstrap = num_bootstrap,
ci_type = ci_type,
...)

} else if (bootstrap_level == "cube") {

# Identify indicators that require species-level grouping
species_level_indicators <- c("spec_occ", "spec_range")

if (indicator$div_type %in% species_level_indicators) {
group_cols <- c("year", "taxonKey")
} else {
group_cols <- "year"
}

# Bootstrap cube data
bootstrap_results <- dubicube::bootstrap_cube(
data_cube = raw_data,
fun = calc_ts,
grouping_var = group_cols,
samples = num_bootstrap,
seed = 123,
progress = TRUE,
processed_cube = FALSE,
#method = "whole_cube",
)

# Calculate confidence intervals from bootstrap results
ci_df <- dubicube::calculate_bootstrap_ci(
bootstrap_samples_df = bootstrap_results,
grouping_var = group_cols,
type = ci_type,
h = trans,
hinv = inv_trans,
conf = confidence_level,
data_cube = raw_data,
fun = calc_ts
) %>%
dplyr::select(-est_original)

# Join confidence intervals to indicator object
if (nrow(ci_df) > 0) {
# Convert negative values to zero as rarity cannot be less than zero
ci_df$ll <- ifelse(ci_df$ll > 0, ci_df$ll, 0)
# Join confidence intervals to indicator values by year
x <- x %>%
dplyr::full_join(ci_df,
by = group_cols)
indicator$data <- x
return(indicator)
} else {
warning(
paste0(
"Unable to calculate confidence intervals. There may be ",
"insufficient data."
)
)
}
} else {
stop("Invalid bootstrap_level. Choose 'cube' or 'indicator'.")
}
}
2 changes: 1 addition & 1 deletion R/calc_map_evenness_core.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ calc_map_evenness_core <- function(x,
internal function, not meant to be called directly.",
inherits(x, c("data.frame", "sf")))

num_occ <- obs <- cellid <- taxonKey <- cellCode <- . <- NULL
num_occ <- obs <- cellid <- taxonKey <- diversity_val <- cellCode <- . <- NULL

type <- match.arg(type, names(available_indicators))

Expand Down
Loading