diff --git a/DESCRIPTION b/DESCRIPTION index a696d37..97bf00d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -53,6 +53,7 @@ Imports: tibble, tidyselect, units, + vctrs, robCompositions, ggplot2, ks, diff --git a/R/archchem_basic.R b/R/archchem_basic.R index 9641eb1..22d4582 100644 --- a/R/archchem_basic.R +++ b/R/archchem_basic.R @@ -93,11 +93,11 @@ #' conc <- get_concentration_columns(arch) # see also other get_..._columns functions #' #' # unit-aware arithmetics on archchem columns thanks to the units package -#' conc$Sb_ppm + conc$Ag_ppb # works -#' \dontrun{conc$Sb_ppm + conc$`Sn_µg/ml`} # fails with: cannot convert µg/ml into ppm +#' conc$Sb + conc$Ag # works +#' \dontrun{conc$Sb + conc$Sn} # fails with: cannot convert µg/ml into ppm #' #' # converting units -#' conc$Sb_ppb <- units::set_units(arch$Sb_ppm, "ppb") %>% +#' conc$Sb <- units::set_units(arch$Sb, "ppb") %>% #' magrittr::set_attr("archchem_class", "archchem_concentration") #' #' # removing all units from archchem tables @@ -106,14 +106,13 @@ #' # applying tidyverse data manipulation on archchem tables #' arch %>% #' dplyr::group_by(Site) %>% -#' dplyr::summarise(mean_Na2O = mean(`Na2O_wt%`)) +#' dplyr::summarise(mean_Na2O = mean(Na2O)) #' conc_subset <- conc %>% -#' dplyr::select(-`Sn_µg/ml`, -`Sb_ppm`) %>% -#' dplyr::filter(`Na2O_wt%` > units::set_units(1, "%")) +#' dplyr::select(-Sn, -Sb) %>% +#' dplyr::filter(Na2O > units::set_units(4, "wtP")) #' #' # unify all concentration units -#' unify_concentration_unit(conc_subset, "ppm") -#' # note that the column names are inaccurate now +#' unify_concentration_unit(conc_subset, "ppb") #' #' @export as_archchem <- function( @@ -142,36 +141,39 @@ as_archchem <- function( } context <- append(context, id_column) # add ID column to context for the following operation - df <- df %>% + df1 <- df %>% dplyr::mutate(ID = .data[[id_column]]) %>% dplyr::relocate("ID", .before = 1) # handle ID duplicates - if (length(unique(df$ID)) != nrow(df)) { + if (length(unique(df1$ID)) != nrow(df1)) { warning( "Detected multiple data rows with the same ID. They will be renamed ", "consecutively using the following convention: _1, _2, ... _n" ) } - df <- df %>% + df2 <- df1 %>% dplyr::group_by(.data[["ID"]]) %>% dplyr::mutate( - ID = dplyr::case_when( - dplyr::n() > 1 ~ paste0(.data[["ID"]], "_", as.character(dplyr::row_number())), - .default = .data[["ID"]] - ) + ID = if (dplyr::n() > 1) { + paste0(.data[["ID"]], "_", as.character(dplyr::row_number())) + } else { + .data[["ID"]] + } ) %>% dplyr::ungroup() # determine and apply column types - constructors <- colnames_to_constructors( - df, context, bdl, bdl_strategy, guess_context_type, na, drop_columns - ) - df <- purrr::map2(df, constructors, function(col, f) f(col)) %>% + column_table <- parse_colnames(df2, context, drop_columns) + constructors <- build_constructors(column_table, bdl, 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) + # remove unit names from columns if they got a unit + df4 <- remove_unit_substrings(df3) # turn into tibble-derived object - df <- tibble::new_tibble(df, nrow = nrow(df), class = "archchem") + df5 <- tibble::new_tibble(df4, nrow = nrow(df4), class = "archchem") # post-reading validation if (validate) { - validation_output <- validate(df, quiet = FALSE) + validation_output <- validate(df5, quiet = FALSE) if (nrow(validation_output) > 0) { warning( "See the full list of validation output with: ", @@ -179,7 +181,22 @@ as_archchem <- function( ) } } - return(df) + return(df5) +} + +# helper function to rename column names +remove_unit_substrings <- function(x, ...) { + dplyr::rename_with( + x, + remove_suffix, + tidyselect::where(function(y) { + class(y) == "units" && !is_archchem_class(y, "archchem_error") + }) + ) +} + +remove_suffix <- function(colname) { + sub("_.*$", "", colname, perl = TRUE) } #' @param path path to the file that should be read @@ -359,20 +376,20 @@ print.archchem <- function(x, ...) { # carry over archchem_class column attribute preserve_archchem_attrs <- function(modified, original) { - purrr::map2(modified, original, function(new_col, old_col) { - arch_attr <- attr(old_col, "archchem_class") - if (!is.null(arch_attr)) attr(new_col, "archchem_class") <- arch_attr - new_col - }) %>% - magrittr::set_names(names(modified)) %>% - tibble::new_tibble(nrow = nrow(modified), class = class(original)) + for (nm in intersect(names(modified), names(original))) { + arch_attr <- attr(original[[nm]], "archchem_class") + if (!is.null(arch_attr)) { + attr(modified[[nm]], "archchem_class") <- arch_attr + } + } + tibble::new_tibble(modified, class = class(original)) } # row-slice method #' @exportS3Method dplyr::dplyr_row_slice dplyr_row_slice.archchem <- function(data, i, ...) { - sliced <- purrr::map(data, function(x) x[i]) - sliced_tbl <- tibble::new_tibble(sliced, nrow = length(i), class = class(data)) + sliced <- purrr::map(data, vctrs::vec_slice, i = i) + sliced_tbl <- tibble::new_tibble(sliced, class = class(data)) preserve_archchem_attrs(sliced_tbl, data) } @@ -380,12 +397,13 @@ dplyr_row_slice.archchem <- function(data, i, ...) { #' @exportS3Method dplyr::dplyr_col_modify dplyr_col_modify.archchem <- function(data, cols) { modified_list <- utils::modifyList(as.list(data), cols) - modified_tbl <- tibble::new_tibble(modified_list, nrow = nrow(data), class = class(data)) + modified_tbl <- tibble::new_tibble(modified_list, class = class(data)) preserve_archchem_attrs(modified_tbl, data) } + # final reconstruction #' @exportS3Method dplyr::dplyr_reconstruct dplyr_reconstruct.archchem <- function(data, template) { - tibble::new_tibble(data, nrow = nrow(data), class = class(template)) + preserve_archchem_attrs(data, template) } diff --git a/R/archchem_colname_parser.R b/R/archchem_colname_parser.R index b5e3ff4..9c3f723 100644 --- a/R/archchem_colname_parser.R +++ b/R/archchem_colname_parser.R @@ -5,14 +5,10 @@ # SI-unit column types are defined with the units package # https://cran.r-project.org/web/packages/units/index.html # (so the udunits library) -colnames_to_constructors <- function( - x, - context, - bdl, bdl_strategy, - guess_context_type, na, - drop_columns -) { - purrr::imap( + +# 1. evaluate column names +parse_colnames <- function(x, context, drop_columns) { + column_table <- purrr::imap_dfr( colnames(x), function(colname, idx) { # use while for hacky switch statement @@ -20,91 +16,147 @@ colnames_to_constructors <- function( # ID column if (colname == "ID") { return( - function(x) { - x <- add_archchem_class(x, "archchem_id") - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = FALSE, + type = "as input", + unit = "none", + class = list("archchem_id"), + ) ) break } # contextual columns if (idx %in% context || colname %in% context) { return( - function(x) { - if (guess_context_type && is.character(x)) { - x <- readr::parse_guess(x, na = na) - } - x <- add_archchem_class(x, "archchem_context") - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = FALSE, + type = "guess", + unit = "none", + class = list("archchem_context") + ) ) break } # error columns - if (is_err(colname)) { + if (is_err_percent(colname)) { # check for percent err must be first + return( + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = TRUE, + type = "numeric", + unit = "%", + class = list("archchem_error"), + ) + ) + break + } + if (is_err_abs(colname)) { return( - function(x) { - x <- apply_bdl_strategy(x, colname, bdl, bdl_strategy) - x <- as_numeric_info(x, colname) - x <- add_archchem_class(x, c("archchem_error")) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = TRUE, + type = "numeric", + unit = "from main field", + class = list("archchem_error") + ) ) + break } # ratios if (is_isotope_ratio(colname)) { return( - function(x) { - x <- as_numeric_info(x, colname) - x <- add_archchem_class(x, c("archchem_isotope", "archchem_ratio")) - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = FALSE, + type = "numeric", + unit = "none", + class = list(c("archchem_isotope", "archchem_ratio")), + ) ) break } if (is_isotope_delta_epsilon(colname)) { - # delta_epsilon <- extract_delta_epsilon_string(colname) return( - function(x) { - # if (delta_epsilon == "d") { - # x / 10 # per mille -> percent - # } else if (delta_epsilon == "e") { - # x / 100 # parts per 10000 -> percent - # } - x <- as_numeric_info(x, colname) - x <- add_archchem_class(x, c("archchem_isotope", "archchem_ratio")) - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = FALSE, + type = "numeric", + unit = "none", + class = list(c("archchem_isotope", "archchem_ratio")) + ) ) break } if (is_elemental_ratio(colname)) { return( - function(x) { - x <- as_numeric_info(x, colname) - x <- add_archchem_class(x, c("archchem_element", "archchem_ratio")) - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = FALSE, + type = "numeric", + unit = "none", + class = list(c("archchem_element", "archchem_ratio")) + ) ) break } # concentrations if (is_concentration(colname)) { - unit_from_col <- extract_unit_string(colname) - # handle special cases - unit_from_col <- dplyr::case_match( - unit_from_col, - c("at%", "wt%") ~ "%", + unit_from_name <- extract_unit_string(colname) + # handle relative units and special cases + unit_from_name <- dplyr::recode_values( + unit_from_name, + c("at%", "atP") ~ "atP", + c("wt%", "wtP", + "w/w%", "m/m%", "%w/w", "%m/m", + "(w/w)%", "(m/m)%", "%(w/w)", "%(m/m)", + "pph", "pph(m/m)", "pph(w/w)" + ) ~ "wtP", + c("%w/v", "%m/v", "%(w/v)", "%(m/v)", + "w/v%", "m/v%", "(w/v)%", "(m/v)%", + "pph(m/v)" + ) ~ "0.01 g/L", + c("%v/v", "v/v%", "%(v/v)", "(v/v)%", "pph(v/v)") ~ "0.01 L/L", + c("ppm(w/w)", "ppm(m/m)", "ppm") ~ "mg/kg", + c("ppm(m/v)") ~ "mg/L", + c("ppm(v/v)") ~ "ml/L", + c("ppb(m/m)", "ppb(w/w)", "ppb") ~ "ug/kg", + c("ppb(m/v)", "ppb(w/v)") ~ "ug/L", + c("ppb(v/v)") ~ "ul/L", + c("ppt(m/m)", "ppt(w/w)", "ppt") ~ "ng/kg", + c("ppt(m/v)", "ppt(w/v)") ~ "ng/L", + c("ppt(v/v)") ~ "nl/L", + c("ppq(m/m)", "ppq(w/w)", "ppq") ~ "pg/kg", + c("ppq(m/v)", "ppq(w/v)") ~ "pg/L", + c("ppq(v/v)") ~ "pl/L", c("cps") ~ "count/s", - .default = unit_from_col + default = unit_from_name ) return( - function(x) { - x <- apply_bdl_strategy(x, colname, bdl, bdl_strategy) - x <- as_numeric_info(x, colname) - x <- units::set_units(x, value = unit_from_col, mode = "standard") - x <- add_archchem_class(x, c("archchem_concentration")) - return(x) - } + tibble::tibble( + drop = FALSE, + idx, + colname, + consider_bdl = TRUE, + type = "numeric", + unit = unit_from_name, + class = list("archchem_concentration"), + ) ) break } @@ -116,17 +168,81 @@ colnames_to_constructors <- function( "Either analytical columns do not conform to ASTR conventions or ", "contextual columns are not specified as such." ) + warning(m) if (drop_columns) { - warning(m) - return(function(x) { - NULL - }) + return( + tibble::tibble( + drop = TRUE, + idx, + colname, + unit = "none" + ) + ) } else { stop(m) } } } ) + # get units for columns that depend on a main column, + # so overwrite unit "from main field" with the unit of + # said main field + is_dependent <- column_table$unit == "from main field" + dependent_cols <- column_table[is_dependent, ] + dependent_bases <- remove_suffix(dependent_cols$colname) + independent_cols <- column_table[!is_dependent, ] + independent_bases <- remove_suffix(independent_cols$colname) + for (i in seq_along(dependent_bases)) { + j <- which(dependent_bases[i] == independent_bases) + if (length(j) != 1) { + stop("Column ", dependent_cols$colname[i], " cannot be uniquely matched to a non-error column.") + } else { + column_table[is_dependent, ]$unit[i] <- independent_cols$unit[j] + } + } + return(column_table) +} + +# 2. build constructor functions +build_constructors <- function( + column_table, + bdl, bdl_strategy, + guess_context_type, na +) { + purrr::pmap( + column_table, function(drop, idx, colname, consider_bdl, type, unit, class) { + # delete fields that should be dropped (NULL-constructor) + if (drop) { + return( + function(x) { + NULL + } + ) + } + # assemble normal constructor function based on column properties + return( + function(x) { + # bdl + if (consider_bdl) { + x <- apply_bdl_strategy(x, colname, bdl, bdl_strategy) + } + # type + if (type == "numeric") { + x <- as_numeric_info(x, colname) + } else if (type == "guess" && guess_context_type && is.character(x)) { + x <- readr::parse_guess(x, na = na) + } + # unit + if (unit != "none" && unit != "from main field") { + x <- units::set_units(x, value = unit, mode = "standard") + } + # class + x <- add_archchem_class(x, class) + return(x) + } + ) + } + ) } add_archchem_class <- function(x, class) { @@ -162,8 +278,11 @@ apply_bdl_strategy <- function(x, colname, bdl, bdl_strategy) { #### regex validators #### -is_err <- function(colname) { - grepl(err(), colname, perl = TRUE) +is_err_percent <- function(colname) { + grepl(err_percent(), colname, perl = TRUE) +} +is_err_abs <- function(colname) { + grepl(err_abs(), colname, perl = TRUE) } is_isotope_ratio <- function(colname) { grepl(isotope_ratio(), colname, perl = TRUE) @@ -215,7 +334,7 @@ isotope_ratio <- function() { paste0("(", isotopes_list(), ")/(", isotopes_list(), ")") } -# define regex pattern for delta and espilon notation: +# define regex pattern for delta and epsilon notation: # letter d OR e followed by any isotope isotope_delta_epsilon <- function() { paste0( @@ -225,17 +344,22 @@ isotope_delta_epsilon <- function() { } # error states -err <- function() { +err_percent <- function() { + paste0(c( + err_2sd_percent(), err_sd_percent() + ), collapse = "|") +} +err_2sd_percent <- function() "\\_err2SD%" +err_sd_percent <- function() "\\_errSD%" + +err_abs <- function() { paste0(c( err_2sd(), err_sd(), - err_2sd_percent(), err_sd_percent(), err_2se(), err_se() ), collapse = "|") } err_2sd <- function() "\\_err2SD" err_sd <- function() "\\_errSD" -err_2sd_percent <- function() "\\_err2SD%" -err_sd_percent <- function() "\\_errSD%" err_2se <- function() "\\_err2SE" err_se <- function() "\\_errSE" diff --git a/R/archchem_column_define.R b/R/archchem_column_define.R new file mode 100644 index 0000000..41ed462 --- /dev/null +++ b/R/archchem_column_define.R @@ -0,0 +1,11 @@ +# functions to define classes for columns in archchem (e.g. for columns newly defined in functions) + +#' @rdname archchem +#' @export +as_contextual_column <- function(x, ...) { + UseMethod("as_contextual_column") +} +#' @export +as_contextual_column.archchem <- function(x, ...) { + sapply(x, structure, class = "archchem_context") +} diff --git a/R/archchem_unit_manipulation.R b/R/archchem_unit_manipulation.R index ffecdd6..e90be16 100644 --- a/R/archchem_unit_manipulation.R +++ b/R/archchem_unit_manipulation.R @@ -4,7 +4,36 @@ remove_units <- function(x, ...) { UseMethod("remove_units") } #' @export -remove_units.archchem <- function(x, ...) { +remove_units.archchem <- function(x, recover_unit_names = FALSE, ...) { + # rename columns: recover units in column names + if (recover_unit_names) { + x <- dplyr::rename_with( + x, + function(column_names) { + unit_names <- purrr::map_chr( + column_names, + function(column_name) { + # render individual units + unit <- units(x[[column_name]]) + rendered_unit <- as.character(unit, neg_power = FALSE, prod_sep = "*") + # handle special cases + dplyr::case_match( + rendered_unit, + "atP" ~ "at%", + "wtP" ~ "wt%", + "count/s" ~ "cps", + .default = rendered_unit + ) + } + ) + paste0(column_names, "_", unit_names) + }, + tidyselect::where(function(y) { + class(y) == "units" && !is_archchem_class(y, "archchem_error") + }) + ) + } + # drop units dplyr::mutate( x, dplyr::across( @@ -25,14 +54,42 @@ unify_concentration_unit <- function(x, unit, ...) { } #' @export unify_concentration_unit <- function(x, unit, ...) { - dplyr::mutate( - x, - dplyr::across( - tidyselect::where(function(y) { - class(y) == "units" && - is_archchem_class(y, "archchem_concentration") - }), - function(z) units::set_units(z, unit, mode = "standard") - ) + switch(unit, + # Conversion to atP + atP = { + # identify all oxides and present, convert to wt% + + # convert all other concentrations to wt% + + # convert to at% + + }, + # Conversion to oxP + oxP = { + # identify all elements that are not oxides and convert to wt% + + # convert all elements to ox% + + }, + # conversion to all other units + { + # something here to convert from atP and oxP to wt% first + + dplyr::mutate( + x, + dplyr::across( + tidyselect::where(function(y) { + class(y) == "units" && + units::ud_are_convertible(units::deparse_unit(y), "mg/kg") + }), + function(z) units::set_units(z, unit, mode = "standard") + ) + ) + } ) } + +# units_to_convert <- unlist( +# sapply(df[elements], function(x) class(x) == "units" & units(x)[1] != unit) +# ) +# df_convert <- cbind(df$ID, subset(df[elements], select = units_to_convert)) diff --git a/R/data.R b/R/data.R index ba7d33a..fe773c3 100644 --- a/R/data.R +++ b/R/data.R @@ -57,16 +57,6 @@ #' @name conversion_oxides "conversion_oxides" -#' Example input data for ASTR -#' -#' @docType data -#' @keywords datasets -#' @name archchem_example_input -#' @usage data(archchem_example_input) -#' @format A data frame with 15 observations and 53 variables. -#' -"archchem_example_input" - #' ArgentinaDatabase #' #' Lead isotope data from ore deposits in Argentina prepared for TerraLID database. diff --git a/R/zzz.R b/R/zzz.R index 209e50d..d575db4 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,10 +1,49 @@ # defining global variables -# ugly solution to avoid magrittr NOTE -# see http://stackoverflow.com/questions/9439256/ -# how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when -globalVariables(".") +utils::globalVariables( + c( + # ugly solution to avoid magrittr NOTE + # see http://stackoverflow.com/questions/9439256/ + # how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when + ".", + # register data objects to make lintr aware of them + "isotopes_data", + "elements_data", + "oxides_data", + "special_oxide_states", + "conversion_oxides" + ) +) #' @importFrom magrittr "%>%" #' @importFrom rlang .data := #' NULL + +# registers the dimensionless units at% (atom percent) and wt% (weight percent) +# when the package is loaded +.onLoad <- function(libname, pkgname) { + safe_install <- function(...) { + # tryCatch to prevent an error when these units are already defined in + # the current session + tryCatch( + units::install_unit(...), + error = function(e) NULL + ) + } + # define dummy base units (purely semantic) + # see ?units::install_unit for details on this mechanism + safe_install("atomic_basis") + safe_install("mass_basis", "unitless") + # create percent-like units + # the %-sign can not be used in custom unit names, so we use P + safe_install( + symbol = "atP", + def = "0.01 atomic_basis", + name = "atom percent" + ) + safe_install( + symbol = "wtP", + def = "0.01 mass_basis", + name = "weight percent" + ) +} diff --git a/data-raw/.DS_Store b/data-raw/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/data-raw/.DS_Store and /dev/null differ diff --git a/data-raw/data_prep.R b/data-raw/data_prep.R index 3d1e287..6b36035 100644 --- a/data-raw/data_prep.R +++ b/data-raw/data_prep.R @@ -72,11 +72,3 @@ usethis::use_data( # ) # # usethis::use_data(isotopes, overwrite = T) - -#### archem data input table #### - -archchem_example_input <- readr::read_csv("data-raw/test_data_input_good.csv") - -usethis::use_data(archchem_example_input, - overwrite = TRUE -) diff --git a/data-raw/test_data_input_good.csv b/data-raw/test_data_input_good.csv deleted file mode 100644 index 5322c4e..0000000 --- a/data-raw/test_data_input_good.csv +++ /dev/null @@ -1,15 +0,0 @@ -Sample,Lab no.,Site,latitude,longitude,Type,method_comp,143Nd/144Nd,d65Cu,d65Cu_err2SD,Na2O_wt%,BaO_wt%,Pb_wt%,MgO_wt%,Al2O3_wt%,SiO2_wt%,SiO2_errSD%,P2O5_wt%,S_at%,CaO_wt%,TiO2_wt%,MnO_wt%,FeOtot_wt%,FeOtot_err2SD,ZnO_%,K2O_wt%,Cu_wt%,As_wt%,LOI_wt%,Ag_ppb,Sn_µg/ml,Sb_ppm,Te_ppm,Bi_ppm,U_ppm,V_ppm,Cr_ppm,Co_ppm,Ni_ppm,Sr_ppm,Se_ppm,FeOtot/SiO2,(Na2O+K2O)/SiO2,206Pb/204Pb,206Pb/204Pb_err2SD,207Pb/204Pb,207Pb/204Pb_err2SD,208Pb/204Pb,208Pb/204Pb_err2SD,207Pb/206Pb,207Pb/206Pb_err2SD,208Pb/206Pb,208Pb/206Pb_err2SD -TR-001,3421/19,Bochum,51.48165,7.21648,1,ICP-MS,0.513014,1.24,0.124,3.1,0.07,6.34,0.77,3.92,31.63,4.3,0.15,2.57,2.11,0.52,0.2,43.83,4.12,5.64,1.34,0.11,0.02,1.89,500,85,370,2,18,3,60,160,60,60,130,<5,1.386,0.14037,18.61147,0.01082,15.65405,0.00915,38.7563,0.0227,0.8411,0.00006,2.08239,0.00017 -TR-002_1,3423/19,Oviedo,43.36029,-5.84476,2,ICP-MS,0.512994,0.88,0.06,2.2,0.07,3.52,0.55,3.46,29.06,2.88,-,NA,2.34,0.49,0.54,51.02,3.89,4.07,1.26,0.22,0.01,-,200,85,210,2,20,2,60,140,70,100,120,<5,1.756,0.11906,18.61617,0.01629,15.65682,0.01341,38.76404,0.0345,0.84103,0.00013,2.08229,0.00033 -TR-002_2,3435/19,Oviedo,43.36029,-5.84476,2,ICP-MS,0.512996,0.85,0.05,5,0.054,3.6,0.33,5.87,30.5,5.71,0.11,3.68,2,0.55,0.1,30.59,2.94,6.87,1.54,0.74,bdl,-,210,98,256,<1.5,47,-,63,99,55,87,121,15,1.003,0.21443,18.61615,0.01698,15.6574,0.01441,38.76411,0.03452,0.84107,0.00014,2.08228,0.00033 -TR-003,3422/19,佛山,23.02677,113.13148,3,ICP-MS,0.513008,2.76,0.276,6.9,0.04,5.07,0.76,4.33,25.73,2.22,0.23,2.76,3.91,0.27,0.7,46.09,3.5,5.87,1.66,0.13,0.01,NA,350,45,400,2,bdl,2,45,30,30,20,250,<5,1.791,0.33269,18.61272,0.00926,15.65677,0.00747,38.76097,0.0182,0.84119,0.0001,2.08251,0.00025 -TR-004,3429/19,Băiuț,43.234895,23.124983,4,ICP-MS,,-8.21,-0.821,3,0.03,9.15,0.52,4.17,43.5,4.65,0.4,0.57,1.79,0.24,1,31.91,2.87,2.26,2.15,0.14,0.03,3.57,400,14,410,2,6,3,55,75,n.a.,10,160,<5,0.734,0.11839,18.63562,0.01189,15.64765,0.00989,38.73583,0.02561,0.83966,0.00009,2.07858,0.00023 -TR-005,3430/19,Şuior,41.445566,24.935661,5,ICP-MS,,0.06,0.004,4.1,0.07,12.61,0.58,3.58,33.83,3.67,0.29,0.61,2.06,0.18,0.49,36.57,5.486,1.66,1.21,0.09,0.11,5.66,250,181,453,6,9,3,54,41,8,47,258,-,1.081,0.15696,18.63952,0.01802,15.65502,0.01513,38.75729,0.04157,0.83989,0.00012,2.07923,0.00032 -TR-006.1,3431/19,Blagodat,41.453133,25.505011,5,ICP-MS,,1.48,0.222,3.4,0.05,12.68,0.64,5.6,33.81,3,0.43,0.77,,NA,1.52,35.52,2.66,2.46,2.26,0.21,0.23,0.12,120,566,701,8,9,bdl,75,106,22,19,122,3,1.051,0.16741,18.64465,0.01468,15.65836,0.0121,38.76615,0.02716,0.83984,0.00009,2.07928,0.00023 -TR-006.2,3432/19,Pezinok,45.92125,15.919219,1,ICP-MS,,-0.42,-0.042,1.8,0.04,5.31,0.59,4.47,26.39,2.87,0.62,3.04,4.28,NA,0.4,41.2,3.89,11.65,1.86,0.43,0.02,0.89,430,203,231,15,3,b.d.l.,84,91,47,34,280,3,1.561,0.13869,18.83274,0.01608,15.82161,0.0135,39.20161,0.03356,0.84852,0.00007,2.10238,0.00017 -TR-006.3,3433/19,Free State Geduld Mines,50.35621322,7.651313679,4,ICP-MS,,0.3,0.02,5.1,0.09,2.36,0.53,3.73,21.18,3.44,0.24,3.93,4.08,0.15,0.46,48.26,2.268,6.8,2.01,0.59,0.08,4.75,300,5594,107,6,5,5,32,63,17,37,310,<5,2.279,0.33569,18.83312,0.01875,15.82042,0.01619,39.20067,0.04173,0.84846,0.00007,2.10235,0.00018 -smn348,3424/19,Aggenys,50.99159628,8.02757263,3,ICP-MS,0.512977,0.24,0.024,4.1,0.34,47.49,0.7,6.27,31.73,6.12,0.28,0.21,7.14,NA,0.24,5.26,0.305,0.03,1.34,0.07,0.06,n.a.,2420,32,3310,9,150,NA,61,45,-,4,287,5,0.166,0.17145,18.80371,0.03129,15.81646,0.026,39.15557,0.06458,0.84955,0.00007,2.10313,0.00026 -smn349,3425/19,Chiprovtsi,50.6890264,6.406379006,3,ICP-MS,0.513004,0.54,0.01,3.4,0.04,2.53,0.46,2.91,16.91,3.73,0.22,3.57,2.5,0.14,0.21,56.36,6.763,4.89,1.34,0.15,0.01,4.22,140,23,95,5,1,3,37,36,69,39,155,<5,3.333,0.28031,18.8076,0.0155,15.82128,0.01309,39.17608,0.03091,0.84963,0.00012,2.10388,0.00022 -smn350,3426/19,Krusov Dol; Krushev Dol,40.695753,24.591976,5,ICP-MS,0.512991,2.04,0.8,4.5,0.07,1.56,0.58,3.6,28.49,4.89,0.19,1.95,1.39,0.17,0.13,47.64,4.235,6.56,0.98,0.16,0.02,6.01,1610,45,78,5,4,3,40,33,43,39,165,<5,1.672,0.19235,18.81356,0.01557,15.82045,0.01305,39.17244,0.03263,0.84931,0.00007,2.10297,0.00022 -smn351,3427/19,Masua,37.726179,24.012951,1,ICP-MS,,-0.24,-0.0504,3.2,0.04,3.64,0.88,5.24,38.04,10.12,0.3,1.35,2.1,0.34,1.32,43.21,2.161,1.52,1.48,0.27,0.05,3.22,100,15,610,2,1,2,80,190,20,50,100,<5,1.136,0.12303,18.81501,0.01535,15.80824,0.0135,39.13346,0.03109,0.84859,0.00007,2.10076,0.00018 -8896,3428/19,Σπαρτη,37.07446,22.43009,1,ICP-MS,,-0.42,-0.042,3.7,0.06,7.51,0.84,3.97,31.67,4.3,0.18,0.83,3.51,0.24,0.34,45.9,2.387,0.85,1.32,0.09,0.14,n.a.,100,146,390,<1.5,<0.3,1,40,100,10,65,120,<5,1.449,0.15851,18.82037,0.01483,15.81119,0.01252,39.13715,0.03182,0.84851,0.00007,2.1003,0.00024 diff --git a/data/archchem_example_input.rda b/data/archchem_example_input.rda deleted file mode 100644 index 5a16b8e..0000000 Binary files a/data/archchem_example_input.rda and /dev/null differ diff --git a/inst/extdata/input_format.xlsx b/inst/extdata/input_format.xlsx index 68df68b..5986850 100644 Binary files a/inst/extdata/input_format.xlsx and b/inst/extdata/input_format.xlsx differ diff --git a/man/archchem.Rd b/man/archchem.Rd index 255382a..88304ae 100644 --- a/man/archchem.Rd +++ b/man/archchem.Rd @@ -189,11 +189,11 @@ validate(arch) conc <- get_concentration_columns(arch) # see also other get_..._columns functions # unit-aware arithmetics on archchem columns thanks to the units package -conc$Sb_ppm + conc$Ag_ppb # works -\dontrun{conc$Sb_ppm + conc$`Sn_µg/ml`} # fails with: cannot convert µg/ml into ppm +conc$Sb + conc$Ag # works +\dontrun{conc$Sb + conc$Sn} # fails with: cannot convert µg/ml into ppm # converting units -conc$Sb_ppb <- units::set_units(arch$Sb_ppm, "ppb") \%>\% +conc$Sb <- units::set_units(arch$Sb, "ppb") \%>\% magrittr::set_attr("archchem_class", "archchem_concentration") # removing all units from archchem tables @@ -202,13 +202,12 @@ remove_units(arch) # applying tidyverse data manipulation on archchem tables arch \%>\% dplyr::group_by(Site) \%>\% - dplyr::summarise(mean_Na2O = mean(`Na2O_wt\%`)) + dplyr::summarise(mean_Na2O = mean(Na2O)) conc_subset <- conc \%>\% - dplyr::select(-`Sn_µg/ml`, -`Sb_ppm`) \%>\% - dplyr::filter(`Na2O_wt\%` > units::set_units(1, "\%")) + dplyr::select(-Sn, -Sb) \%>\% + dplyr::filter(Na2O > units::set_units(4, "wtP")) # unify all concentration units -unify_concentration_unit(conc_subset, "ppm") -# note that the column names are inaccurate now +unify_concentration_unit(conc_subset, "ppb") } diff --git a/man/archchem_example_input.Rd b/man/archchem_example_input.Rd deleted file mode 100644 index b86abb1..0000000 --- a/man/archchem_example_input.Rd +++ /dev/null @@ -1,16 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data.R -\docType{data} -\name{archchem_example_input} -\alias{archchem_example_input} -\title{Example input data for ASTR} -\format{ -A data frame with 15 observations and 53 variables. -} -\usage{ -data(archchem_example_input) -} -\description{ -Example input data for ASTR -} -\keyword{datasets} diff --git a/tests/testthat.R b/tests/testthat.R index a26f0d9..6be89e9 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -8,8 +8,5 @@ library(testthat) library(ASTR) -library(tibble) -library(ggplot2) -library(vdiffr) test_check("ASTR") diff --git a/tests/testthat/_snaps/archchem_basic.md b/tests/testthat/_snaps/archchem_basic.md index 3b8c409..de8d737 100644 --- a/tests/testthat/_snaps/archchem_basic.md +++ b/tests/testthat/_snaps/archchem_basic.md @@ -3,10 +3,181 @@ Code as.data.frame(test_input) Output - ID 206Pb/204Pb Al2O3_cps SiO2+Al2O3_ppt 204Pb_ppm other other2 K2O_wt% - 1 troet 0.5 3 [count/s] 20 [ppt] 7 [ppm] troet 27 23 [%] - d18O SiO2/FeO Mn_at% Zn_ppm SiO2/(FeO+MnO) Sb/As Sn_µg/g - 1 -5.32 0.5 2.45 [%] 240 [ppm] 0.32 5.69 56 [µg/g] - K2O+MgO+Na2O_wt% - 1 54 [%] + ID 206Pb/204Pb Al2O3 SiO2+Al2O3 204Pb other other2 K2O + 1 troet 0.5 3 [count/s] 20 [ng/kg] 7 [mg/kg] troet 27 23 [wtP] + d18O SiO2/FeO Mn Zn SiO2/(FeO+MnO) Sb/As Sn + 1 -5.32 0.5 2.45 [atP] 240 [mg/kg] 0.32 5.69 56 [µg/g] + K2O+MgO+Na2O + 1 54 [wtP] + +--- + + Code + as.data.frame(test_input2) + Output + ID Sample Lab no. Site latitude longitude Type + 1 TR-001 TR-001 3421/19 Bochum 51.48165 7.216480 1 + 2 TR-002_1 TR-002_1 3423/19 Oviedo 43.36029 -5.844760 2 + 3 TR-002_2 TR-002_2 3435/19 Oviedo 43.36029 -5.844760 2 + 4 TR-003 TR-003 3422/19 佛山 23.02677 113.131480 3 + 5 TR-004 TR-004 3429/19 Băiuț 43.23490 23.124983 4 + 6 TR-005 TR-005 3430/19 Şuior 41.44557 24.935661 5 + 7 TR-006.1 TR-006.1 3431/19 Blagodat 41.45313 25.505011 5 + 8 TR-006.2 TR-006.2 3432/19 Pezinok 45.92125 15.919219 1 + 9 TR-006.3 TR-006.3 3433/19 Free State Geduld Mines 50.35621 7.651314 4 + 10 smn348 smn348 3424/19 Aggenys 50.99160 8.027573 3 + 11 smn349 smn349 3425/19 Chiprovtsi 50.68903 6.406379 3 + 12 smn350 smn350 3426/19 Krusov Dol; Krushev Dol 40.69575 24.591976 5 + 13 smn351 smn351 3427/19 Masua 37.72618 24.012951 1 + 14 8896 8896 3428/19 Σπαρτη 37.07446 22.430090 1 + method_comp 143Nd/144Nd d65Cu d65Cu_err2SD Na2O BaO Pb + 1 ICP-MS 0.513014 1.24 0.1240 3.1 [wtP] 0.070 [wtP] 6.34 [wtP] + 2 ICP-MS 0.512994 0.88 0.0600 2.2 [wtP] 0.070 [wtP] 3.52 [wtP] + 3 ICP-MS 0.512996 0.85 0.0500 5.0 [wtP] 0.054 [wtP] 3.60 [wtP] + 4 ICP-MS 0.513008 2.76 0.2760 6.9 [wtP] 0.040 [wtP] 5.07 [wtP] + 5 ICP-MS NA -8.21 -0.8210 3.0 [wtP] 0.030 [wtP] 9.15 [wtP] + 6 ICP-MS NA 0.06 0.0040 4.1 [wtP] 0.070 [wtP] 12.61 [wtP] + 7 ICP-MS NA 1.48 0.2220 3.4 [wtP] 0.050 [wtP] 12.68 [wtP] + 8 ICP-MS NA -0.42 -0.0420 1.8 [wtP] 0.040 [wtP] 5.31 [wtP] + 9 ICP-MS NA 0.30 0.0200 5.1 [wtP] 0.090 [wtP] 2.36 [wtP] + 10 ICP-MS 0.512977 0.24 0.0240 4.1 [wtP] 0.340 [wtP] 47.49 [wtP] + 11 ICP-MS 0.513004 0.54 0.0100 3.4 [wtP] 0.040 [wtP] 2.53 [wtP] + 12 ICP-MS 0.512991 2.04 0.8000 4.5 [wtP] 0.070 [wtP] 1.56 [wtP] + 13 ICP-MS NA -0.24 -0.0504 3.2 [wtP] 0.040 [wtP] 3.64 [wtP] + 14 ICP-MS NA -0.42 -0.0420 3.7 [wtP] 0.060 [wtP] 7.51 [wtP] + MgO Al2O3 SiO2 SiO2_errSD% P2O5 S + 1 0.77 [wtP] 3.92 [wtP] 31.63 [wtP] 4.30 [%] 0.15 [wtP] 2.57 [atP] + 2 0.55 [wtP] 3.46 [wtP] 29.06 [wtP] 2.88 [%] NA [wtP] NA [atP] + 3 0.33 [wtP] 5.87 [wtP] 30.50 [wtP] 5.71 [%] 0.11 [wtP] 3.68 [atP] + 4 0.76 [wtP] 4.33 [wtP] 25.73 [wtP] 2.22 [%] 0.23 [wtP] 2.76 [atP] + 5 0.52 [wtP] 4.17 [wtP] 43.50 [wtP] 4.65 [%] 0.40 [wtP] 0.57 [atP] + 6 0.58 [wtP] 3.58 [wtP] 33.83 [wtP] 3.67 [%] 0.29 [wtP] 0.61 [atP] + 7 0.64 [wtP] 5.60 [wtP] 33.81 [wtP] 3.00 [%] 0.43 [wtP] 0.77 [atP] + 8 0.59 [wtP] 4.47 [wtP] 26.39 [wtP] 2.87 [%] 0.62 [wtP] 3.04 [atP] + 9 0.53 [wtP] 3.73 [wtP] 21.18 [wtP] 3.44 [%] 0.24 [wtP] 3.93 [atP] + 10 0.70 [wtP] 6.27 [wtP] 31.73 [wtP] 6.12 [%] 0.28 [wtP] 0.21 [atP] + 11 0.46 [wtP] 2.91 [wtP] 16.91 [wtP] 3.73 [%] 0.22 [wtP] 3.57 [atP] + 12 0.58 [wtP] 3.60 [wtP] 28.49 [wtP] 4.89 [%] 0.19 [wtP] 1.95 [atP] + 13 0.88 [wtP] 5.24 [wtP] 38.04 [wtP] 10.12 [%] 0.30 [wtP] 1.35 [atP] + 14 0.84 [wtP] 3.97 [wtP] 31.67 [wtP] 4.30 [%] 0.18 [wtP] 0.83 [atP] + CaO TiO2 MnO FeOtot FeOtot_err2SD ZnO + 1 2.11 [wtP] 0.52 [wtP] 0.20 [wtP] 43.83 [wtP] 4.120 [wtP] 5.64 [%] + 2 2.34 [wtP] 0.49 [wtP] 0.54 [wtP] 51.02 [wtP] 3.890 [wtP] 4.07 [%] + 3 2.00 [wtP] 0.55 [wtP] 0.10 [wtP] 30.59 [wtP] 2.940 [wtP] 6.87 [%] + 4 3.91 [wtP] 0.27 [wtP] 0.70 [wtP] 46.09 [wtP] 3.500 [wtP] 5.87 [%] + 5 1.79 [wtP] 0.24 [wtP] 1.00 [wtP] 31.91 [wtP] 2.870 [wtP] 2.26 [%] + 6 2.06 [wtP] 0.18 [wtP] 0.49 [wtP] 36.57 [wtP] 5.486 [wtP] 1.66 [%] + 7 NA [wtP] NA [wtP] 1.52 [wtP] 35.52 [wtP] 2.660 [wtP] 2.46 [%] + 8 4.28 [wtP] NA [wtP] 0.40 [wtP] 41.20 [wtP] 3.890 [wtP] 11.65 [%] + 9 4.08 [wtP] 0.15 [wtP] 0.46 [wtP] 48.26 [wtP] 2.268 [wtP] 6.80 [%] + 10 7.14 [wtP] NA [wtP] 0.24 [wtP] 5.26 [wtP] 0.305 [wtP] 0.03 [%] + 11 2.50 [wtP] 0.14 [wtP] 0.21 [wtP] 56.36 [wtP] 6.763 [wtP] 4.89 [%] + 12 1.39 [wtP] 0.17 [wtP] 0.13 [wtP] 47.64 [wtP] 4.235 [wtP] 6.56 [%] + 13 2.10 [wtP] 0.34 [wtP] 1.32 [wtP] 43.21 [wtP] 2.161 [wtP] 1.52 [%] + 14 3.51 [wtP] 0.24 [wtP] 0.34 [wtP] 45.90 [wtP] 2.387 [wtP] 0.85 [%] + K2O Cu As LOI Ag Sn + 1 1.34 [wtP] 0.11 [wtP] 0.02 [wtP] 1.89 [wtP] 500 [ug/kg] 85 [µg/ml] + 2 1.26 [wtP] 0.22 [wtP] 0.01 [wtP] NA [wtP] 200 [ug/kg] 85 [µg/ml] + 3 1.54 [wtP] 0.74 [wtP] NA [wtP] NA [wtP] 210 [ug/kg] 98 [µg/ml] + 4 1.66 [wtP] 0.13 [wtP] 0.01 [wtP] NA [wtP] 350 [ug/kg] 45 [µg/ml] + 5 2.15 [wtP] 0.14 [wtP] 0.03 [wtP] 3.57 [wtP] 400 [ug/kg] 14 [µg/ml] + 6 1.21 [wtP] 0.09 [wtP] 0.11 [wtP] 5.66 [wtP] 250 [ug/kg] 181 [µg/ml] + 7 2.26 [wtP] 0.21 [wtP] 0.23 [wtP] 0.12 [wtP] 120 [ug/kg] 566 [µg/ml] + 8 1.86 [wtP] 0.43 [wtP] 0.02 [wtP] 0.89 [wtP] 430 [ug/kg] 203 [µg/ml] + 9 2.01 [wtP] 0.59 [wtP] 0.08 [wtP] 4.75 [wtP] 300 [ug/kg] 5594 [µg/ml] + 10 1.34 [wtP] 0.07 [wtP] 0.06 [wtP] NA [wtP] 2420 [ug/kg] 32 [µg/ml] + 11 1.34 [wtP] 0.15 [wtP] 0.01 [wtP] 4.22 [wtP] 140 [ug/kg] 23 [µg/ml] + 12 0.98 [wtP] 0.16 [wtP] 0.02 [wtP] 6.01 [wtP] 1610 [ug/kg] 45 [µg/ml] + 13 1.48 [wtP] 0.27 [wtP] 0.05 [wtP] 3.22 [wtP] 100 [ug/kg] 15 [µg/ml] + 14 1.32 [wtP] 0.09 [wtP] 0.14 [wtP] NA [wtP] 100 [ug/kg] 146 [µg/ml] + Sb Te Bi U V Cr + 1 370 [mg/kg] 2 [mg/kg] 18 [mg/kg] 3 [mg/kg] 60 [mg/kg] 160 [mg/kg] + 2 210 [mg/kg] 2 [mg/kg] 20 [mg/kg] 2 [mg/kg] 60 [mg/kg] 140 [mg/kg] + 3 256 [mg/kg] NA [mg/kg] 47 [mg/kg] NA [mg/kg] 63 [mg/kg] 99 [mg/kg] + 4 400 [mg/kg] 2 [mg/kg] NA [mg/kg] 2 [mg/kg] 45 [mg/kg] 30 [mg/kg] + 5 410 [mg/kg] 2 [mg/kg] 6 [mg/kg] 3 [mg/kg] 55 [mg/kg] 75 [mg/kg] + 6 453 [mg/kg] 6 [mg/kg] 9 [mg/kg] 3 [mg/kg] 54 [mg/kg] 41 [mg/kg] + 7 701 [mg/kg] 8 [mg/kg] 9 [mg/kg] NA [mg/kg] 75 [mg/kg] 106 [mg/kg] + 8 231 [mg/kg] 15 [mg/kg] 3 [mg/kg] NA [mg/kg] 84 [mg/kg] 91 [mg/kg] + 9 107 [mg/kg] 6 [mg/kg] 5 [mg/kg] 5 [mg/kg] 32 [mg/kg] 63 [mg/kg] + 10 3310 [mg/kg] 9 [mg/kg] 150 [mg/kg] NA [mg/kg] 61 [mg/kg] 45 [mg/kg] + 11 95 [mg/kg] 5 [mg/kg] 1 [mg/kg] 3 [mg/kg] 37 [mg/kg] 36 [mg/kg] + 12 78 [mg/kg] 5 [mg/kg] 4 [mg/kg] 3 [mg/kg] 40 [mg/kg] 33 [mg/kg] + 13 610 [mg/kg] 2 [mg/kg] 1 [mg/kg] 2 [mg/kg] 80 [mg/kg] 190 [mg/kg] + 14 390 [mg/kg] NA [mg/kg] NA [mg/kg] 1 [mg/kg] 40 [mg/kg] 100 [mg/kg] + Co Ni Sr Se FeOtot/SiO2 (Na2O+K2O)/SiO2 + 1 60 [mg/kg] 60 [mg/kg] 130 [mg/kg] NA [mg/kg] 1.386 0.14037 + 2 70 [mg/kg] 100 [mg/kg] 120 [mg/kg] NA [mg/kg] 1.756 0.11906 + 3 55 [mg/kg] 87 [mg/kg] 121 [mg/kg] 15 [mg/kg] 1.003 0.21443 + 4 30 [mg/kg] 20 [mg/kg] 250 [mg/kg] NA [mg/kg] 1.791 0.33269 + 5 NA [mg/kg] 10 [mg/kg] 160 [mg/kg] NA [mg/kg] 0.734 0.11839 + 6 8 [mg/kg] 47 [mg/kg] 258 [mg/kg] NA [mg/kg] 1.081 0.15696 + 7 22 [mg/kg] 19 [mg/kg] 122 [mg/kg] 3 [mg/kg] 1.051 0.16741 + 8 47 [mg/kg] 34 [mg/kg] 280 [mg/kg] 3 [mg/kg] 1.561 0.13869 + 9 17 [mg/kg] 37 [mg/kg] 310 [mg/kg] NA [mg/kg] 2.279 0.33569 + 10 NA [mg/kg] 4 [mg/kg] 287 [mg/kg] 5 [mg/kg] 0.166 0.17145 + 11 69 [mg/kg] 39 [mg/kg] 155 [mg/kg] NA [mg/kg] 3.333 0.28031 + 12 43 [mg/kg] 39 [mg/kg] 165 [mg/kg] NA [mg/kg] 1.672 0.19235 + 13 20 [mg/kg] 50 [mg/kg] 100 [mg/kg] NA [mg/kg] 1.136 0.12303 + 14 10 [mg/kg] 65 [mg/kg] 120 [mg/kg] NA [mg/kg] 1.449 0.15851 + 206Pb/204Pb 206Pb/204Pb_err2SD 207Pb/204Pb 207Pb/204Pb_err2SD 208Pb/204Pb + 1 18.61147 0.01082 15.65405 0.00915 38.75630 + 2 18.61617 0.01629 15.65682 0.01341 38.76404 + 3 18.61615 0.01698 15.65740 0.01441 38.76411 + 4 18.61272 0.00926 15.65677 0.00747 38.76097 + 5 18.63562 0.01189 15.64765 0.00989 38.73583 + 6 18.63952 0.01802 15.65502 0.01513 38.75729 + 7 18.64465 0.01468 15.65836 0.01210 38.76615 + 8 18.83274 0.01608 15.82161 0.01350 39.20161 + 9 18.83312 0.01875 15.82042 0.01619 39.20067 + 10 18.80371 0.03129 15.81646 0.02600 39.15557 + 11 18.80760 0.01550 15.82128 0.01309 39.17608 + 12 18.81356 0.01557 15.82045 0.01305 39.17244 + 13 18.81501 0.01535 15.80824 0.01350 39.13346 + 14 18.82037 0.01483 15.81119 0.01252 39.13715 + 208Pb/204Pb_err2SD 207Pb/206Pb 207Pb/206Pb_err2SD 208Pb/206Pb + 1 0.02270 0.84110 0.00006 2.08239 + 2 0.03450 0.84103 0.00013 2.08229 + 3 0.03452 0.84107 0.00014 2.08228 + 4 0.01820 0.84119 0.00010 2.08251 + 5 0.02561 0.83966 0.00009 2.07858 + 6 0.04157 0.83989 0.00012 2.07923 + 7 0.02716 0.83984 0.00009 2.07928 + 8 0.03356 0.84852 0.00007 2.10238 + 9 0.04173 0.84846 0.00007 2.10235 + 10 0.06458 0.84955 0.00007 2.10313 + 11 0.03091 0.84963 0.00012 2.10388 + 12 0.03263 0.84931 0.00007 2.10297 + 13 0.03109 0.84859 0.00007 2.10076 + 14 0.03182 0.84851 0.00007 2.10030 + 208Pb/206Pb_err2SD + 1 0.00017 + 2 0.00033 + 3 0.00033 + 4 0.00025 + 5 0.00023 + 6 0.00032 + 7 0.00023 + 8 0.00017 + 9 0.00018 + 10 0.00026 + 11 0.00022 + 12 0.00022 + 13 0.00018 + 14 0.00024 + +--- + + Code + print(test_input) + Output + archchem table + Analytical columns: 206Pb/204Pb, Al2O3, SiO2+Al2O3, 204Pb, K2O, d18O, SiO2/FeO, Mn, Zn, SiO2/(FeO+MnO), Sb/As, Sn, K2O+MgO+Na2O + Contextual columns: other, other2 + # A data frame: 1 x 16 + ID `206Pb/204Pb` Al2O3 `SiO2+Al2O3` `204Pb` other other2 K2O d18O + [count/s] [ng/kg] [mg/kg] [wtP] + 1 troet 0.5 3 20 7 troet 27 23 -5.32 + # i 7 more variables: `SiO2/FeO` , Mn [atP], Zn [mg/kg], + # `SiO2/(FeO+MnO)` , `Sb/As` , Sn [µg/g], `K2O+MgO+Na2O` [wtP] diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R index 6e5e215..ea93e54 100644 --- a/tests/testthat/setup.R +++ b/tests/testthat/setup.R @@ -2,7 +2,12 @@ # Additional packages to load for testing or setting up the test environment +library(testthat) +library(ASTR) +library(tibble) +library(ggplot2) library(vdiffr) +library(readxl) # reference data sets diff --git a/tests/testthat/test_archchem_basic.R b/tests/testthat/test_archchem_basic.R index d4a8491..8f20c35 100644 --- a/tests/testthat/test_archchem_basic.R +++ b/tests/testthat/test_archchem_basic.R @@ -6,9 +6,59 @@ test_input <- read_archchem( context = c("other", "other2") ) +test_input_xlsx <- read_archchem( + system.file("extdata", "input_format.xlsx", package = "ASTR"), + id_column = "other", + context = c("other", "other2") +) + +test_input2 <- suppressWarnings( + read_archchem( + system.file("extdata", "test_data_input_good.csv", package = "ASTR"), + id_column = "Sample", + context = c("Lab no.", "Site", "latitude", "longitude", "Type", "method_comp") + ) +) + +test_input3 <- readr::read_csv(system.file("extdata", "input_format.csv", package = "ASTR")) +test_input3[2, ] <- test_input3[1, ] +test_input3 <- suppressWarnings( + as_archchem(test_input3, id_column = "other2", context = "other") +) + test_that("reading of a basic example table works as expected", { expect_snapshot({ # turn to data.frame to render the entire table as.data.frame(test_input) }) + expect_equal(test_input_xlsx, test_input) + expect_snapshot({ + # turn to data.frame to render the entire table + as.data.frame(test_input2) + }) + expect_snapshot({ + print(test_input) + }) + # checks that automatic renaming of ID values works + expect_all_equal(test_input3$ID[2], "27_2") +}) + +# parsing throws expected errors + +test_input3 <- readr::read_csv(system.file("extdata", "input_format.csv", package = "ASTR")) +test_input3[2, ] <- test_input3[1, ] + +test_that("archem functions result in expected errors and warnings", { + expect_error( + suppressWarnings(as_archchem(test_input3, id_column = "other")), + "Column name .* could not be parsed" + ) + expect_warning( + as_archchem(test_input3, id_column = "other", context = "other2"), + "Detected multiple data rows with the same ID" + ) + expect_error( + validate(2), + "x is not an object of class archchem" + ) }) diff --git a/tests/testthat/test_archchem_column_selectionc.R b/tests/testthat/test_archchem_column_selectionc.R new file mode 100644 index 0000000..6349d8f --- /dev/null +++ b/tests/testthat/test_archchem_column_selectionc.R @@ -0,0 +1,38 @@ +# test columns selection function not checked elsewhere + +test_input <- suppressWarnings( + read_archchem( + system.file("extdata", "test_data_input_good.csv", package = "ASTR"), + id_column = "Sample", + context = c("Lab no.", "Site", "latitude", "longitude", "Type", "method_comp") + ) +) + +test_that("column selection based on archchem column types", { + expect_all_true( + colnames(get_isotope_columns(test_input)) == + c( + "ID", "143Nd/144Nd", "d65Cu", "206Pb/204Pb", "207Pb/204Pb", "208Pb/204Pb", + "207Pb/206Pb", "208Pb/206Pb" + ) + ) + expect_all_true( + colnames(get_element_columns(test_input)) == + c("ID", "FeOtot/SiO2", "(Na2O+K2O)/SiO2") + ) + expect_all_true( + colnames(get_ratio_columns(test_input)) == + c( + "ID", "143Nd/144Nd", "d65Cu", "FeOtot/SiO2", "(Na2O+K2O)/SiO2", "206Pb/204Pb", "207Pb/204Pb", + "208Pb/204Pb", "207Pb/206Pb", "208Pb/206Pb" + ) + ) + expect_all_true( + colnames(get_concentration_columns(test_input)) == + c( + "ID", "Na2O", "BaO", "Pb", "MgO", "Al2O3", "SiO2", "P2O5", "S", "CaO", "TiO2", + "MnO", "FeOtot", "ZnO", "K2O", "Cu", "As", "LOI", "Ag", "Sn", "Sb", "Te", "Bi", + "U", "V", "Cr", "Co", "Ni", "Sr", "Se" + ) + ) +}) diff --git a/vignettes/VG.ASTRschema.0.0.2.Rmd b/vignettes/VG.ASTRschema.0.0.2.Rmd index bc4f461..597c556 100644 --- a/vignettes/VG.ASTRschema.0.0.2.Rmd +++ b/vignettes/VG.ASTRschema.0.0.2.Rmd @@ -26,7 +26,7 @@ All columns that contain element and oxide compositions and analytical errors, i - The names of oxides and trace elements are self-explanatory (e.g. `SiO2` or `Si`). Total iron, if given, should be expressed as: `FeOtot` or `Fe2O3tot`. Loss on ignition, where known, should be expressed as `LOI`. -- Units for values should follow element or oxide, as `_`. Units supported include *all SI units*, as well as *ppm*, *ppb*, *ppt*, *%*, *wt%*, *at%*, *w/w%*, *‰*, *counts*, and *cps*, noted as such. +- Units for values should follow element or oxide, as `_`. Units supported include *all SI units*, as well as *ppm*, *ppb*, *ppt*, *ppq*, *%*, *wt%*, *at%*, *‰*, *counts*, and *cps*, noted as such. For relative units, the type of concentration can be specified, e.g. *w/w%* or *ppm(m/v)* - Where known, specify *wt%* and *at%* instead of using *%*. For *‘per mille’*, use the symbol *‰*.