Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +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)
Expand Down
34 changes: 9 additions & 25 deletions R/ASTR_basic.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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", "<LOD", "<"
#' @param bdl_strategy function used to replace BDL strings. Defaults to a
#' static function returning `NA`
#' @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.
#' @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
Expand Down Expand Up @@ -66,15 +65,6 @@
#' unless `drop_columns = TRUE` (then it will result in warnings for the
#' respective columns).
#'
#' Below detection limit notation (i.e. ‘b.d.’, ‘bd’, ‘b.d.l.’, ‘bdl’, ‘<LOD’,
#' or ‘<..’) for element and oxide concentrations is specified using the `bdl`
#' argument. One or more notations can be used as is appropriate for the
#' dataset, and can be notations not included in the list above. The argument
#' `bdl_strategy` is used to specify the value for handling detection limits.
#' This is to facilitate the different handling needs of the detection limit
#' for future statistical applications, as opposed to automatically assigning
#' such values as ‘NA’.
#'
#' Missing values are allowed anywhere in the data file body, and will be
#' replaced by `NA` automatically.
#'
Expand Down Expand Up @@ -120,12 +110,7 @@
#' @export
as_ASTR <- function(
df, id_column = "ID", context = c(),
bdl = c("b.d.", "bd", "b.d.l.", "bdl", "<LOD", "<"),
bdl_strategy = function() NA_character_,
# this only allows static functions, essentially: bdl_replace = "NA"
# in case more sophisticated handling is desired:
# bdl_strategy = function(x, colname) { bdl_lookup_table[colname] / sqrt(2) }
# bdl_lookup_table = c("Fe_%" = 3)
bdl_strategy = bdl_strategy_default,
guess_context_type = TRUE,
na = c(
"", "n/a", "NA", "N.A.", "N/A", "na", "-", "n.d.", "n.a.",
Expand Down Expand Up @@ -166,7 +151,7 @@ as_ASTR <- function(
dplyr::ungroup()
# determine and apply column types
column_table <- parse_colnames(df2, context, drop_columns)
constructors <- build_constructors(column_table, bdl, bdl_strategy, guess_context_type, na)
constructors <- build_constructors(column_table, bdl_strategy, guess_context_type, na)
col_list <- purrr::map2(df2, constructors, function(col, f) f(col)) %>%
purrr::discard(is.null)
df3 <- as.data.frame(col_list, check.names = FALSE)
Expand Down Expand Up @@ -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", "<LOD", "<"),
bdl_strategy = function() NA_character_,
bdl_strategy = bdl_strategy_default,
drop_columns = FALSE,
validate = TRUE,
...
Expand Down Expand Up @@ -284,7 +268,7 @@ read_ASTR <- function(
as_ASTR(
input_file,
id_column = id_column, context = context,
bdl = bdl, bdl_strategy = bdl_strategy,
bdl_strategy = bdl_strategy,
guess_context_type = guess_context_type, na = na,
drop_columns = drop_columns,
validate = validate
Expand Down
39 changes: 39 additions & 0 deletions R/ASTR_bdl_strategies.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#' @name bdl_strategies
#'
#' @title Strategies to replace "below detection limit" values
#'
#' @description ...
#'
#' @param x a vector, derived from a data.frame column
#' @param colname name of the respective data.frame column
#' @param ... further arguments passed to or from other methods
#'
#' @rdname bdl_strategies
#'
#' @examples
#' plot(1,1)
#'
NULL

#' @rdname bdl_strategies
#' @export
bdl_strategy_default <- function(x, colname, ...) {
bdl_strings <- c("b.d.", "bd", "b.d.l.", "bdl", "<LOD", "<")
bdl_indices <- which(grepl(paste(bdl_strings, collapse = "|"), x, perl = FALSE))
x[bdl_indices] <- NA_character_
return(x)
}

#' @rdname bdl_strategies
#' @export
bdl_strategy_none <- function(x, colname, ...) {
return(x)
}

#' @rdname bdl_strategies
#' @export
bdl_strategy_negative <- function(x, colname, ...) {
bdl_indices <- which(grepl("^-\\d*\\.?\\d*\\*?\\d*\\^?\\-?\\d*$", x))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized that the bdl strategy functions are called by as_ASTR, which accepts any data.frame. The assumption that the column would certainly be of type character is wrong, if I'm not missing anything. This should work in both cases:

y <- suppressWarnings(as.numeric(x))
bdl_indices <- which(y < 0)

Sorry for missing this initially. I was too focused on the read_ASTR case.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will revert the code to your generalised version then. Thanks!

x[bdl_indices] <- NA_character_
return(x)
}
12 changes: 2 additions & 10 deletions R/ASTR_colname_parser.R
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ parse_colnames <- function(x, context, drop_columns) {
# 2. build constructor functions
build_constructors <- function(
column_table,
bdl, bdl_strategy,
bdl_strategy,
guess_context_type, na
) {
purrr::pmap(
Expand All @@ -224,7 +224,7 @@ build_constructors <- function(
function(x) {
# bdl
if (consider_bdl) {
x <- apply_bdl_strategy(x, colname, bdl, bdl_strategy)
x <- bdl_strategy(x = x, colname = colname)
}
# type
if (type == "numeric") {
Expand Down Expand Up @@ -268,14 +268,6 @@ as_numeric_info <- function(x, colname) {
return(y)
}

# colname only an argument in case we want to implement more specific handling
# eventually
apply_bdl_strategy <- function(x, colname, bdl, bdl_strategy) {
bdl_values <- which(grepl(paste(bdl, collapse = "|"), x, perl = FALSE))
x[bdl_values] <- bdl_strategy()
return(x)
}

#### regex validators ####

is_err_percent <- function(colname) {
Expand Down
27 changes: 7 additions & 20 deletions man/ASTR.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions man/bdl_strategies.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vignettes/ASTR.showcase.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -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)).

Expand Down