From 6a0a55c9b4cefda1cdbfe0a336b87869d83e7e1e Mon Sep 17 00:00:00 2001 From: Thomas Rose Date: Sat, 4 Jul 2026 15:13:45 -0400 Subject: [PATCH 1/6] emphasize in documentation that read_ASTR() call data to ASTR objects --- R/ASTR_basic.R | 4 ++-- man/ASTR.Rd | 4 ++-- vignettes/ASTR.showcase.Rmd | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/ASTR_basic.R b/R/ASTR_basic.R index b894e40..3e973ae 100644 --- a/R/ASTR_basic.R +++ b/R/ASTR_basic.R @@ -12,8 +12,8 @@ #' \itemize{ #' \item **as_ASTR**: Transforms an R `data.frame` to an object of class #' `ASTR`. -#' \item **read_ASTR**: Reads data from a file (.csv, .xls, .xlsx) into -#' an object of class `ASTR`. +#' \item **read_ASTR**: Reads data from a file (.csv, .xls, .xlsx) and +#' converts it into an object of class `ASTR`. #' \item **validate**: Performs additional validation on `ASTR` and returns #' a `data.frame` as a workable list of potential issues. #' \item **get_..._columns**: Subsets `ASTR` tables to columns of a certain diff --git a/man/ASTR.Rd b/man/ASTR.Rd index 91da787..5f20b2d 100644 --- a/man/ASTR.Rd +++ b/man/ASTR.Rd @@ -139,8 +139,8 @@ interact with them. \itemize{ \item \strong{as_ASTR}: Transforms an R \code{data.frame} to an object of class \code{ASTR}. -\item \strong{read_ASTR}: Reads data from a file (.csv, .xls, .xlsx) into -an object of class \code{ASTR}. +\item \strong{read_ASTR}: Reads data from a file (.csv, .xls, .xlsx) and +converts it into an object of class \code{ASTR}. \item \strong{validate}: Performs additional validation on \code{ASTR} and returns a \code{data.frame} as a workable list of potential issues. \item \strong{get_..._columns}: Subsets \code{ASTR} tables to columns of a certain diff --git a/vignettes/ASTR.showcase.Rmd b/vignettes/ASTR.showcase.Rmd index c0429f9..9b6deb9 100644 --- a/vignettes/ASTR.showcase.Rmd +++ b/vignettes/ASTR.showcase.Rmd @@ -57,7 +57,7 @@ data Note how the column headers are organised according to the ASTR conventions. This allows the package to _understand_ some of the semantics of the dataset in the `read_ASTR()` process, and correctly represent them in the resulting `ASTR` object. A closer look at the mock-up data also reveals (common) problems with the copper isotope data: it seems that some Excel formulas did not work as intended and left `#REF!` entries. `read_ASTR()` will read these as `NA` values. Finally, every `ASTR` object requires one column that acts as a unique row identifier. In this dataset there is no such column, though, only a `Group` identifier. `read_ASTR()` can automatically turn such a column to a unique identifier. -We can now perform the reading process. As we are working with mock-up data in an R vignette, we do not read from the file system. We only need to call an essential internal function of `read_ASTR()`: `as_ASTR()`. It turns R data.frames to `ASTR` objects. If we would start from an Excel file we would call `read_ASTR()` instead. +We can now perform the reading process. As we are working with mock-up data in an R vignette, we do not read from the file system. We only need to call an essential internal function of `read_ASTR()`: `as_ASTR()`. It turns R data.frames to `ASTR` objects. If we would start from an Excel file we would call `read_ASTR()` instead, which internally calls `as_ASTR()` to convert the data into an ASTR object after reading the file. To do this in practice, we not only have to submit our `data` to `as_ASTR()`, but also set two other arguments: 1. We have to define one of the columns as the ID column with `id_column`, and 2. we explicitly have to mark any column providing contextual information with `context` (i.e. no analytical values, cf. [ASTR schema: Implementation](VG.ASTR.Schema.Implementation.html)). From 5ffe7b1e1ca1e1929ec2ffe69cd47a3081c3d3e2 Mon Sep 17 00:00:00 2001 From: Thomas Rose Date: Sat, 4 Jul 2026 16:29:36 -0400 Subject: [PATCH 2/6] first function draft --- NAMESPACE | 1 + R/ASTR_bdl_strategies.R | 20 ++++++++++++++++++++ man/bdl_strategy_negative.Rd | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 R/ASTR_bdl_strategies.R create mode 100644 man/bdl_strategy_negative.Rd diff --git a/NAMESPACE b/NAMESPACE index 7ceaf9c..23a6693 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,6 +20,7 @@ export(abs_to_rel) export(albarede_juteau_1984) export(as_ASTR) export(at_to_wt) +export(bdl_strategy_negative) export(copper_alloy_bb) export(copper_alloy_pollard) export(copper_group_bray) diff --git a/R/ASTR_bdl_strategies.R b/R/ASTR_bdl_strategies.R new file mode 100644 index 0000000..c784d79 --- /dev/null +++ b/R/ASTR_bdl_strategies.R @@ -0,0 +1,20 @@ +#' Replace negative values with a uniform value +#' +#' This function generates a function for the argument `bdl_strategy` in [ASTR] +#' that replaces negative values in specified columns with a uniform value, +#' usually `NA` or `0`. +#' +#' @param cols The names of the columns to be checked according to the ASTR +#' conventions. +#' @param value The replacement value. Default is to `NA_real_`. +#' +#' @returns A function +#' @export +#' +bdl_strategy_negative <- function(cols, value = NA_real_) { + + function(x = x, colname = cols) { + x[, cols][x[, cols] < 0] <- value + } + +} diff --git a/man/bdl_strategy_negative.Rd b/man/bdl_strategy_negative.Rd new file mode 100644 index 0000000..59d9f22 --- /dev/null +++ b/man/bdl_strategy_negative.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ASTR_bdl_strategies.R +\name{bdl_strategy_negative} +\alias{bdl_strategy_negative} +\title{Replace negative values with a uniform value} +\usage{ +bdl_strategy_negative(cols, value = NA_real_) +} +\arguments{ +\item{cols}{The names of the columns to be checked according to the ASTR +conventions.} + +\item{value}{The replacement value. Default is to \code{NA_real_}.} +} +\value{ +A function +} +\description{ +This function generates a function for the argument \code{bdl_strategy} in \link{ASTR} +that replaces negative values in specified columns with a uniform value, +usually \code{NA} or \code{0}. +} From a91aa86b8907481148806e079388c683689b0690 Mon Sep 17 00:00:00 2001 From: Clemens Schmid Date: Fri, 10 Jul 2026 16:22:41 +0200 Subject: [PATCH 3/6] first draft of reworked bdl handling --- NAMESPACE | 2 ++ R/ASTR_basic.R | 30 ++++++----------------- R/ASTR_bdl_strategies.R | 46 ++++++++++++++++++++++++++---------- R/ASTR_colname_parser.R | 12 ++-------- man/ASTR.Rd | 23 ++++-------------- man/bdl_strategies.Rd | 29 +++++++++++++++++++++++ man/bdl_strategy_negative.Rd | 22 ----------------- 7 files changed, 78 insertions(+), 86 deletions(-) create mode 100644 man/bdl_strategies.Rd delete mode 100644 man/bdl_strategy_negative.Rd diff --git a/NAMESPACE b/NAMESPACE index 23a6693..8fc7e8f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,7 +20,9 @@ export(abs_to_rel) export(albarede_juteau_1984) export(as_ASTR) export(at_to_wt) +export(bdl_strategy_default) export(bdl_strategy_negative) +export(bdl_strategy_none) export(copper_alloy_bb) export(copper_alloy_pollard) export(copper_group_bray) diff --git a/R/ASTR_basic.R b/R/ASTR_basic.R index 3e973ae..90dc28d 100644 --- a/R/ASTR_basic.R +++ b/R/ASTR_basic.R @@ -33,10 +33,9 @@ #' @param id_column name of the ID column. Defaults to "ID" #' @param context columns that provide contextual (non-measurement) information; #' may be column names, integer positions, or a logical inclusion vector -#' @param bdl strings representing “below detection limit” values. By default, -#' the following are recognized: "b.d.", "bd", "b.d.l.", "bdl", "% purrr::discard(is.null) df3 <- as.data.frame(col_list, check.names = FALSE) @@ -222,8 +207,7 @@ read_ASTR <- function( "", "n/a", "NA", "N.A.", "N/A", "na", "-", "n.d.", "n.a.", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A", "#NULL!" ), - bdl = c("b.d.", "bd", "b.d.l.", "bdl", " Date: Sat, 11 Jul 2026 17:50:25 -0400 Subject: [PATCH 4/6] update negative bdl strategy with regulat expression --- R/ASTR_bdl_strategies.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/ASTR_bdl_strategies.R b/R/ASTR_bdl_strategies.R index 1d86d3d..c8132d4 100644 --- a/R/ASTR_bdl_strategies.R +++ b/R/ASTR_bdl_strategies.R @@ -33,8 +33,7 @@ bdl_strategy_none <- function(x, colname, ...) { #' @rdname bdl_strategies #' @export bdl_strategy_negative <- function(x, colname, ...) { - y <- suppressWarnings(as.numeric(x)) - bdl_indices <- which(y < 0) + bdl_indices <- which(grepl("^-\\d*\\.?\\d*\\*?\\d*\\^?\\-?\\d*$", x)) x[bdl_indices] <- NA_character_ return(x) } From 5517f9fbe6d322faac4671c7119153022088655a Mon Sep 17 00:00:00 2001 From: Thomas Rose Date: Sat, 11 Jul 2026 18:24:04 -0400 Subject: [PATCH 5/6] include markers and replacement values in function parameters, update documentation --- R/ASTR_basic.R | 11 +++++++++-- R/ASTR_bdl_strategies.R | 11 ++++++----- man/ASTR.Rd | 10 ++++++++-- man/bdl_strategies.Rd | 13 +++++++++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/R/ASTR_basic.R b/R/ASTR_basic.R index 90dc28d..9aad994 100644 --- a/R/ASTR_basic.R +++ b/R/ASTR_basic.R @@ -34,8 +34,9 @@ #' @param context columns that provide contextual (non-measurement) information; #' may be column names, integer positions, or a logical inclusion vector #' @param bdl_strategy function used to replace "below detection limit" strings. -#' See [bdl_strategies] for the different available strategies and on how to implement -#' a custom one. +#' See [bdl_strategies] for the different available strategies and on how to +#' implement a custom one. Use [purrr::compose()] to combine different +#' [bdl_strategies] (see examples). #' @param guess_context_type should appropriate data types for contextual #' columns be guessed automatically? Defaults to `TRUE` #' @param na character vector of strings to be interpret as missing values. By @@ -68,6 +69,7 @@ #' Missing values are allowed anywhere in the data file body, and will be #' replaced by `NA` automatically. #' +#' #' @examples #' library(magrittr) #' @@ -82,6 +84,11 @@ #' # validating an ASTR table #' validate(arch) #' +#' # combining bdl strategies +#' arch2 <- as_ASTR(test_df, id_column = "Sample", context = 1:7, +#' bdl_strategy = purrr::compose(bdl_strategy_default, bdl_strategy_negative) +#' ) +#' #' # extracting subsets of columns #' conc <- get_concentration_columns(arch) # see also other get_..._columns functions #' diff --git a/R/ASTR_bdl_strategies.R b/R/ASTR_bdl_strategies.R index c8132d4..bb4de3c 100644 --- a/R/ASTR_bdl_strategies.R +++ b/R/ASTR_bdl_strategies.R @@ -6,6 +6,8 @@ #' #' @param x a vector, derived from a data.frame column #' @param colname name of the respective data.frame column +#' @param marker values indicating "below detection limit" +#' @param value value to replace values identified as "below detection limit" #' @param ... further arguments passed to or from other methods #' #' @rdname bdl_strategies @@ -17,9 +19,8 @@ NULL #' @rdname bdl_strategies #' @export -bdl_strategy_default <- function(x, colname, ...) { - bdl_strings <- c("b.d.", "bd", "b.d.l.", "bdl", " Date: Sat, 11 Jul 2026 18:27:24 -0400 Subject: [PATCH 6/6] replace default value [skip ci] --- R/ASTR_bdl_strategies.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ASTR_bdl_strategies.R b/R/ASTR_bdl_strategies.R index bb4de3c..3173c40 100644 --- a/R/ASTR_bdl_strategies.R +++ b/R/ASTR_bdl_strategies.R @@ -33,7 +33,7 @@ bdl_strategy_none <- function(x, colname, ...) { #' @rdname bdl_strategies #' @export -bdl_strategy_negative <- function(x, colname, value = "99999", ...) { +bdl_strategy_negative <- function(x, colname, value = NA_character_, ...) { bdl_indices <- which(grepl("^-\\d*\\.?\\d*\\*?\\d*\\^?\\-?\\d*$", x)) x[bdl_indices] <- value return(x)