From 34f5e93d20d1f66fcee645441ecafa458df78669 Mon Sep 17 00:00:00 2001 From: Thomas Rose Date: Mon, 25 May 2026 15:36:45 -0400 Subject: [PATCH] proper handling of NA values --- R/ASTR_copper_alloy_classification_bb.R | 64 ++++++++++++-------- R/ASTR_copper_alloy_classification_pollard.R | 47 ++++++++------ R/ASTR_copper_classification_Bray.R | 41 ++++++++++--- man/copper_alloy_bb.Rd | 4 +- man/copper_alloy_pollard.Rd | 4 +- man/copper_group_bray.Rd | 12 ++-- tests/testthat/test_copper_alloy_bb.R | 41 +++++++------ tests/testthat/test_copper_alloy_pollard.R | 41 +++++++------ tests/testthat/test_copper_group_Bray.R | 54 ++++++++++++----- 9 files changed, 193 insertions(+), 115 deletions(-) diff --git a/R/ASTR_copper_alloy_classification_bb.R b/R/ASTR_copper_alloy_classification_bb.R index 8d12cc4..b3fe844 100644 --- a/R/ASTR_copper_alloy_classification_bb.R +++ b/R/ASTR_copper_alloy_classification_bb.R @@ -25,7 +25,7 @@ #' @examples #' sample_df <- data.frame( #' ID = 1:5, -#' Sn = c(5, 1, 4, 0.5, 2), +#' Sn = c(5, 1, 4, NA, 2), #' Zn = c(12, 20, 6, 2, 10), #' Pb = c(1, 0.5, 5, 9, 12) #' ) @@ -35,7 +35,7 @@ #' sample_df <- as_ASTR( #' data.frame( #' ID = 1:8, -#' SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), +#' SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, NA), #' ZnO_wtP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), #' PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) #' ) @@ -61,56 +61,68 @@ copper_alloy_bb <- function( # Create subset with just ID and classification column copper_alloy <- data.frame( ID_sample = df[[id_column]], - Sn = df[[elements["Sn"]]], - Zn = df[[elements["Zn"]]], - Pb = df[[elements["Pb"]]], - result = rep("Unclassified", nrow(df)), + Sn = df[[elements["Sn"]]], + Zn = df[[elements["Zn"]]], + Pb = df[[elements["Pb"]]], + result = rep("Unclassified", nrow(df)), stringsAsFactors = FALSE ) - # Base alloy classes + # Identify rows where no element is NA — only these will be classified + na_mask <- !is.na(copper_alloy$Sn) & !is.na(copper_alloy$Zn) & !is.na(copper_alloy$Pb) + # Base alloy classes # Copper: Zn < 3 and Sn < 3 - copper_alloy$result[copper_alloy$Zn < 3 & copper_alloy$Sn < 3] <- "Copper" + copper_alloy$result[na_mask & + copper_alloy$Zn < 3 & + copper_alloy$Sn < 3] <- "Copper" - # Copper/brass: 3 ≤ Zn < 8 and Sn < 3 - copper_alloy$result[copper_alloy$Zn >= 3 & + # Copper/brass: 3 <= Zn < 8 and Sn < 3 + copper_alloy$result[na_mask & + copper_alloy$Zn >= 3 & copper_alloy$Zn < 8 & copper_alloy$Sn < 3] <- "Copper/brass" - # Bronze: Sn ≥ 3 and Zn < 3 * Sn - copper_alloy$result[copper_alloy$Sn >= 3 & + # Bronze: Sn >= 3 and Zn < 3 * Sn + copper_alloy$result[na_mask & + copper_alloy$Sn >= 3 & copper_alloy$Zn < 3 * copper_alloy$Sn] <- "Bronze" - # Bronze/gunmetal: Sn ≥ 3 and Zn between 0.33*Sn and 0.67*Sn - copper_alloy$result[copper_alloy$Sn >= 3 & + # Bronze/gunmetal: Sn >= 3 and Zn between 0.33*Sn and 0.67*Sn + copper_alloy$result[na_mask & + copper_alloy$Sn >= 3 & copper_alloy$Zn > 0.33 * copper_alloy$Sn & copper_alloy$Zn < 0.67 * copper_alloy$Sn] <- "Bronze/gunmetal" - # Gunmetal: Zn > 0.67*Sn and Zn < 2.5*Sn and Sn ≥ 3 - copper_alloy$result[copper_alloy$Sn >= 3 & + # Gunmetal: Zn > 0.67*Sn and Zn < 2.5*Sn and Sn >= 3 + copper_alloy$result[na_mask & + copper_alloy$Sn >= 3 & copper_alloy$Zn > 0.67 * copper_alloy$Sn & copper_alloy$Zn < 2.5 * copper_alloy$Sn] <- "Gunmetal" - # Brass/gunmetal: Zn > 2.5*Sn and Zn <= 4*Sn AND (Zn ≥ 8 OR Sn ≥ 3) - copper_alloy$result[(copper_alloy$Zn >= 8 | copper_alloy$Sn >= 3) & + # Brass/gunmetal: Zn > 2.5*Sn and Zn <= 4*Sn AND (Zn >= 8 OR Sn >= 3) + copper_alloy$result[na_mask & + (copper_alloy$Zn >= 8 | copper_alloy$Sn >= 3) & copper_alloy$Zn > 2.5 * copper_alloy$Sn & copper_alloy$Zn <= 4 * copper_alloy$Sn] <- "Brass/gunmetal" - # Brass: Zn ≥ 8 and Zn > 4*Sn - copper_alloy$result[copper_alloy$Zn >= 8 & + # Brass: Zn >= 8 and Zn > 4*Sn + copper_alloy$result[na_mask & + copper_alloy$Zn >= 8 & copper_alloy$Zn > 4 * copper_alloy$Sn] <- "Brass" - # Apply lead modifiers + # Apply lead modifiers only to non-NA rows ## (Leaded): Pb between 4 and 8 - copper_alloy$result[copper_alloy$Pb >= 4 & - copper_alloy$Pb <= 8] <- paste( - "(Leaded)", - copper_alloy$result[copper_alloy$Pb >= 4 & copper_alloy$Pb <= 8] + prefix_leaded <- na_mask & copper_alloy$Pb >= 4 & copper_alloy$Pb <= 8 + copper_alloy$result[prefix_leaded] <- paste( + "(Leaded)", copper_alloy$result[prefix_leaded] ) ## Leaded: Pb > 8 - copper_alloy$result[copper_alloy$Pb > 8] <- paste("Leaded", copper_alloy$result[copper_alloy$Pb > 8]) + prefix_high_lead <- na_mask & copper_alloy$Pb > 8 + copper_alloy$result[prefix_high_lead] <- paste( + "Leaded", copper_alloy$result[prefix_high_lead] + ) # Merge results back to original dataframe by ID copper_alloy_bb <- copper_alloy$result[match(df[[id_column]], copper_alloy$ID_sample)] diff --git a/R/ASTR_copper_alloy_classification_pollard.R b/R/ASTR_copper_alloy_classification_pollard.R index 1b1a0d5..5086da9 100644 --- a/R/ASTR_copper_alloy_classification_pollard.R +++ b/R/ASTR_copper_alloy_classification_pollard.R @@ -27,7 +27,7 @@ #' @examples #' sample_df <- data.frame( #' ID = 1:8, -#' Sn = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), +#' Sn = c(0.5, NA, 5, 5, 0.5, 5, 5, 5), #' Zn = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), #' Pb = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) #' ) @@ -39,7 +39,7 @@ #' ID = 1:8, #' SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), #' ZnO_wtP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), -#' PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) +#' PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, NA, 5, 5) #' ) #' ) #' copper_alloy_pollard(sample_df, elements = c(Sn = "SnO", Zn = "ZnO", Pb = "PbO")) @@ -54,11 +54,9 @@ copper_alloy_pollard <- function( group_as_symbol = FALSE, ...) { - # convert units to wt% - if (inherits(df, "ASTR")) { df <- convert_concentration_units(df, elements, "wtP", ...) - elements <- c(Sn = "Sn", Zn = "Zn", Pb = "Pb") # rename in case input was in oxides + elements <- c(Sn = "Sn", Zn = "Zn", Pb = "Pb") threshold <- units::set_units(1, "wtP") } else { threshold <- 1 # wt%, set in Pollard et al. (2015) @@ -72,6 +70,13 @@ copper_alloy_pollard <- function( Pb_flag = df[[elements["Pb"]]] >= threshold ) + # Identify rows where any element is NA — these stay Unclassified + flags$has_na <- apply( + flags[, c("Sn_flag", "Zn_flag", "Pb_flag")], + 1, + function(row) any(is.na(row)) + ) + # Convert flags into a pattern string flags$pattern <- apply( flags[, c("Sn_flag", "Zn_flag", "Pb_flag")], @@ -107,26 +112,34 @@ copper_alloy_pollard <- function( ) # Join with lookup table, preserving row order - out <- merge(flags[, c("ID_sample", "pattern")], - lookup, - by = "pattern", - all.x = TRUE) - - # Ensure "Unclassified" for any missing matches - out$alloy_name[is.na(out$alloy_name)] <- "Unclassified" - out$alloy_symbol[is.na(out$alloy_symbol)] <- "Unclassified" + out <- merge( + flags[, c("ID_sample", "pattern", "has_na")], + lookup, + by = "pattern", + all.x = TRUE + ) - # Add correct output column + # Add correct output column — NA in any element = Unclassified if (!group_as_symbol) { - copper_alloy_pollard <- out$alloy_name[match(df[[id_column]], out$ID_sample)] + copper_alloy_pollard <- ifelse( + out$has_na[match(df[[id_column]], out$ID_sample)], + "Unclassified", + out$alloy_name[match(df[[id_column]], out$ID_sample)] + ) } else { - copper_alloy_pollard <- out$alloy_symbol[match(df[[id_column]], out$ID_sample)] + copper_alloy_pollard <- ifelse( + out$has_na[match(df[[id_column]], out$ID_sample)], + "Unclassified", + out$alloy_symbol[match(df[[id_column]], out$ID_sample)] + ) } if (inherits(df, "ASTR")) { df_out <- df[c(colnames(get_contextual_columns(df)), elements)] df_out[["copper_alloy_pollard"]] <- copper_alloy_pollard - df_out[["copper_alloy_pollard"]] <- add_ASTR_class(df_out[["copper_alloy_pollard"]], "ASTR_context") + df_out[["copper_alloy_pollard"]] <- add_ASTR_class( + df_out[["copper_alloy_pollard"]], "ASTR_context" + ) } else { df_out <- df df_out[["copper_alloy_pollard"]] <- copper_alloy_pollard diff --git a/R/ASTR_copper_classification_Bray.R b/R/ASTR_copper_classification_Bray.R index 2850f10..be071bd 100644 --- a/R/ASTR_copper_classification_Bray.R +++ b/R/ASTR_copper_classification_Bray.R @@ -30,7 +30,7 @@ #' sample_df <- data.frame( #' ID = 1:3, #' As = c(0.2, 0.01, 0.15), -#' Sb = c(0.00, 0.2, 0.11), +#' Sb = c(0.00, NA, 0.11), #' Ag = c(0.00, 0.00, 0.12), #' Ni = c(0.00, 0.05, 0.20) #' ) @@ -43,11 +43,11 @@ #' # For ASTR objects, units and oxides are automatically converted #' sample_df2 <- as_ASTR( #' data.frame( -#' ID = 1:3, -#' As2O3_wtP = c(0.2, 0.01, 0.15), -#' Sb2O3_wtP = c(0.00, 0.2, 0.11), -#' Ag2O_wtP = c(0.00, 0.00, 0.12), -#' NiO_wtP = c(0.00, 50, 0.20) +#' ID = 1:4, +#' As2O3_wtP = c(0.2, 0.01, 0.15, 2), +#' Sb2O3_wtP = c(0.00, 0.2, 0.11, 0.5), +#' Ag2O_wtP = c(0.00, 0.00, 0.12, NA), +#' NiO_wtP = c(0.00, 5, 0.20, 0.5) #' ) #' ) #' copper_group_bray(sample_df2, elements = c(As = "As2O3", Sb = "Sb2O3", Ag = "Ag2O", Ni = "NiO")) @@ -80,6 +80,12 @@ copper_group_bray <- function( ) # Convert flags into a pattern string + flags$has_na <- apply( + flags[, c("As_flag", "Sb_flag", "Ag_flag", "Ni_flag")], + 1, + function(row) any(is.na(row)) + ) + flags$pattern <- apply( flags[, c("As_flag", "Sb_flag", "Ag_flag", "Ni_flag")], 1, @@ -130,15 +136,30 @@ copper_group_bray <- function( ) # Join with lookup table, preserving row order - out <- merge(flags[, c("ID_sample", "pattern")], lookup, by = "pattern", all.x = TRUE, sort = TRUE) + out <- merge( + flags[, c("ID_sample", "pattern", "has_na")], + lookup, + by = "pattern", + all.x = TRUE, + sort = TRUE + ) - # Add correct output column + # Add correct output column — NA in any element = Unclassified if (!group_as_number) { - copper_group_bray <- out$group_name[match(df[[id_column]], out$ID_sample)] + copper_group_bray <- ifelse( + out$has_na[match(df[[id_column]], out$ID_sample)], + "Unclassified", + out$group_name[match(df[[id_column]], out$ID_sample)] + ) } else { - copper_group_bray <- out$group_number[match(df[[id_column]], out$ID_sample)] + copper_group_bray <- ifelse( + out$has_na[match(df[[id_column]], out$ID_sample)], + NA_integer_, + out$group_number[match(df[[id_column]], out$ID_sample)] + ) } + # Return ASTR object or plain data frame if (inherits(df, "ASTR")) { df_out <- df[c(colnames(get_contextual_columns(df)), elements)] df_out[["copper_group_bray"]] <- copper_group_bray diff --git a/man/copper_alloy_bb.Rd b/man/copper_alloy_bb.Rd index b36b7ec..1cfa8d4 100644 --- a/man/copper_alloy_bb.Rd +++ b/man/copper_alloy_bb.Rd @@ -37,7 +37,7 @@ Classification uses specific thresholds and ratios to define alloy types. \examples{ sample_df <- data.frame( ID = 1:5, - Sn = c(5, 1, 4, 0.5, 2), + Sn = c(5, 1, 4, NA, 2), Zn = c(12, 20, 6, 2, 10), Pb = c(1, 0.5, 5, 9, 12) ) @@ -47,7 +47,7 @@ copper_alloy_bb(sample_df) sample_df <- as_ASTR( data.frame( ID = 1:8, - SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), + SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, NA), ZnO_wtP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) ) diff --git a/man/copper_alloy_pollard.Rd b/man/copper_alloy_pollard.Rd index 08ff352..c3907cd 100644 --- a/man/copper_alloy_pollard.Rd +++ b/man/copper_alloy_pollard.Rd @@ -41,7 +41,7 @@ wt\%. \examples{ sample_df <- data.frame( ID = 1:8, - Sn = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), + Sn = c(0.5, NA, 5, 5, 0.5, 5, 5, 5), Zn = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), Pb = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) ) @@ -53,7 +53,7 @@ sample_df <- as_ASTR( ID = 1:8, SnO_wtP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), ZnO_wtP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), - PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) + PbO_wtP = c(0.5, 5, 0.5, 5, 0.5, NA, 5, 5) ) ) copper_alloy_pollard(sample_df, elements = c(Sn = "SnO", Zn = "ZnO", Pb = "PbO")) diff --git a/man/copper_group_bray.Rd b/man/copper_group_bray.Rd index 30361fa..9e8b3a1 100644 --- a/man/copper_group_bray.Rd +++ b/man/copper_group_bray.Rd @@ -44,7 +44,7 @@ Ag, or Ni being below or above 0.1 wt\%. sample_df <- data.frame( ID = 1:3, As = c(0.2, 0.01, 0.15), - Sb = c(0.00, 0.2, 0.11), + Sb = c(0.00, NA, 0.11), Ag = c(0.00, 0.00, 0.12), Ni = c(0.00, 0.05, 0.20) ) @@ -57,11 +57,11 @@ copper_group_bray(sample_df, group_as_number = TRUE) # For ASTR objects, units and oxides are automatically converted sample_df2 <- as_ASTR( data.frame( - ID = 1:3, - As2O3_wtP = c(0.2, 0.01, 0.15), - Sb2O3_wtP = c(0.00, 0.2, 0.11), - Ag2O_wtP = c(0.00, 0.00, 0.12), - NiO_wtP = c(0.00, 50, 0.20) + ID = 1:4, + As2O3_wtP = c(0.2, 0.01, 0.15, 2), + Sb2O3_wtP = c(0.00, 0.2, 0.11, 0.5), + Ag2O_wtP = c(0.00, 0.00, 0.12, NA), + NiO_wtP = c(0.00, 5, 0.20, 0.5) ) ) copper_group_bray(sample_df2, elements = c(As = "As2O3", Sb = "Sb2O3", Ag = "Ag2O", Ni = "NiO")) diff --git a/tests/testthat/test_copper_alloy_bb.R b/tests/testthat/test_copper_alloy_bb.R index 26376fa..98334d0 100644 --- a/tests/testthat/test_copper_alloy_bb.R +++ b/tests/testthat/test_copper_alloy_bb.R @@ -1,33 +1,38 @@ test_that("copper_alloy_bb", { test_data <- data.frame( - ID = 1:8, - Tin = c(1, 1, 5, 5, 5, 5, 0.5, 5), - Zn = c(2, 5, 2, 4, 8, 15, 2, 8), - Lead = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 9, 6) + ID = 1:11, + Tin = c(1, 1, 5, 5, 5, 5, 0.5, 5, NA, 5, 5), + Zn = c(2, 5, 2, 4, 8, 15, 2, 8, 2, NA, 8), + Lead = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 9, 6, 0.5, 0.5, NA) ) expect_equal( copper_alloy_bb(test_data, elements = c("Sn" = "Tin", "Zn" = "Zn", "Pb" = "Lead"))$copper_alloy_bb, c( - "Copper", # ID 1: Copper (Zn<3, Sn<3) - "Copper/brass", # ID 2: Copper/brass (3≤Zn<8, Sn<3) - "Bronze/gunmetal", # ID 3: Bronze (Sn≥3, Zn<3*Sn) - "Gunmetal", # ID 4: Bronze/gunmetal (Sn≥3, 0.332.5*Sn, Zn≤4*Sn) - "Leaded Copper", # ID 7: Leaded Copper (Copper + Pb>8) - "(Leaded) Gunmetal" # ID 8: (Leaded) Gunmetal (Gunmetal + 4≤Pb≤8) + "Copper", # ID 1: Copper (Zn<3, Sn<3) + "Copper/brass", # ID 2: Copper/brass (3≤Zn<8, Sn<3) + "Bronze/gunmetal", # ID 3: Bronze (Sn≥3, Zn<3*Sn) + "Gunmetal", # ID 4: Bronze/gunmetal (Sn≥3, 0.332.5*Sn, Zn≤4*Sn) + "Leaded Copper", # ID 7: Leaded Copper (Copper + Pb>8) + "(Leaded) Gunmetal", # ID 8: (Leaded) Gunmetal (Gunmetal + 4≤Pb≤8) + "Unclassified", # ID 9: NA Sn + "Unclassified", # ID 10: NA Zn + "Unclassified" # ID 11: NA Pb ) ) }) test_that("copper_alloy_bb: Handling ASTR object", { - test_data_ASTR <- as_ASTR( - data.frame( - ID = 1:8, - Sn_atP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), - Zn_atP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), - Pb_atP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) + suppressWarnings( + test_data_ASTR <- as_ASTR( + data.frame( + ID = 1:8, + Sn_atP = c(0.5, 0.5, 5, 5, 0.5, 5, NA, 5), + Zn_atP = c(0.5, NA, 0.5, 0.5, 5, 5, 0.5, 5), + Pb_atP = c(0.5, 5, 0.5, 5, NA, 0.5, 5, 5) + ) ) ) test_result_ASTR <- copper_alloy_bb(test_data_ASTR) diff --git a/tests/testthat/test_copper_alloy_pollard.R b/tests/testthat/test_copper_alloy_pollard.R index e69437c..2d6d326 100644 --- a/tests/testthat/test_copper_alloy_pollard.R +++ b/tests/testthat/test_copper_alloy_pollard.R @@ -1,9 +1,9 @@ test_that("copper_alloy_pollard: basic classification", { test_data <- data.frame( - ID = 1:8, - Sn = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), - Zn = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), - Pb = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) + ID = 1:11, + Sn = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5, NA, 0.5, 5), + Zn = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5, 0.5, NA, 0.5), + Pb = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5, 0.5, 0.5, NA) ) result <- copper_alloy_pollard(test_data) @@ -11,14 +11,17 @@ test_that("copper_alloy_pollard: basic classification", { expect_equal( result$copper_alloy_pollard, c( - "Copper", # All < 1% - "Leaded copper", # Pb ≥ 1% - "Bronze", # Sn ≥ 1% - "Leaded bronze", # Sn, Pb ≥ 1% - "Brass", # Zn ≥ 1% - "Gunmetal", # Zn, Sn ≥ 1% - "Leaded bronze", # Sn, Pb ≥ 1% (same as ID 4) - "Leaded gunmetal" # All ≥ 1% + "Copper", # All < 1% + "Leaded copper", # Pb ≥ 1% + "Bronze", # Sn ≥ 1% + "Leaded bronze", # Sn, Pb ≥ 1% + "Brass", # Zn ≥ 1% + "Gunmetal", # Zn, Sn ≥ 1% + "Leaded bronze", # Sn, Pb ≥ 1% (same as ID 4) + "Leaded gunmetal", # All ≥ 1% + "Unclassified", # NA Sn + "Unclassified", # NA Zn + "Unclassified" # NA Pb ) ) }) @@ -50,12 +53,14 @@ test_that("copper_alloy_pollard: function arguments", { }) test_that("copper_alloy_pollard: Handling ASTR object", { - test_data_ASTR <- as_ASTR( - data.frame( - ID = 1:8, - Sn_atP = c(0.5, 0.5, 5, 5, 0.5, 5, 5, 5), - Zn_atP = c(0.5, 0.5, 0.5, 0.5, 5, 5, 0.5, 5), - Pb_atP = c(0.5, 5, 0.5, 5, 0.5, 0.5, 5, 5) + suppressWarnings( + test_data_ASTR <- as_ASTR( + data.frame( + ID = 1:8, + Sn_atP = c(0.5, 0.5, 5, 5, 0.5, 5, NA, 5), + Zn_atP = c(0.5, NA, 0.5, 0.5, 5, 5, 0.5, 5), + Pb_atP = c(0.5, 5, 0.5, 5, NA, 0.5, 5, 5) + ) ) ) test_result_ASTR <- copper_alloy_pollard(test_data_ASTR) diff --git a/tests/testthat/test_copper_group_Bray.R b/tests/testthat/test_copper_group_Bray.R index 9818354..ca1980f 100644 --- a/tests/testthat/test_copper_group_Bray.R +++ b/tests/testthat/test_copper_group_Bray.R @@ -1,10 +1,10 @@ test_that("copper_group_bray: basic classification", { df <- data.frame( - ID = 1:4, - As = c(0.2, 0.01, 0.15, 0.00), - Sb = c(0.00, 0.2, 0.00, 0.00), - Ag = c(0.00, 0.00, 0.12, 0.00), - Ni = c(0.00, 0.00, 0.00, 0.20) + ID = 1:7, + As = c(0.2, 0.01, 0.15, 0.00, NA, 0.2, 0.15), + Sb = c(0.00, 0.2, 0.00, 0.00, 0.15, NA, 0.11), + Ag = c(0.00, 0.00, 0.12, 0.00, 0.00, 0.00, NA), + Ni = c(0.00, 0.00, 0.00, 0.20, 0.00, 0.00, 0.20) ) result <- copper_group_bray(df) @@ -13,9 +13,18 @@ test_that("copper_group_bray: basic classification", { expect_true("copper_group_bray" %in% names(result)) # Expected group names - expected <- c("As", "Sb", "As+Ag", "Ni") - - expect_equal(result$copper_group_bray, expected) + expect_equal( + result$copper_group_bray, + c( + "As", # ID 1: As only + "Sb", # ID 2: Sb only + "As+Ag", # ID 3: As and Ag + "Ni", # ID 4: Ni only + "Unclassified", # ID 5: NA As + "Unclassified", # ID 6: NA Sb + "Unclassified" # ID 7: NA Ag + ) + ) }) test_that("copper_group_bray: function arguments", { @@ -27,7 +36,7 @@ test_that("copper_group_bray: function arguments", { Nickel = 0.0 ) - # "As+Sb" is group 6 in the lookup table + # Custom column names — As+Sb is group 6 expect_equal( copper_group_bray( df, @@ -43,16 +52,29 @@ test_that("copper_group_bray: function arguments", { )$copper_group_bray, 6 ) + + # NA with group_as_number = TRUE returns NA + df_na <- data.frame(ID = 1, Arsenic = NA, Antimony = 0.2, Silver = 0.0, Nickel = 0.0) + expect_equal( + copper_group_bray( + df_na, + elements = c(As = "Arsenic", Sb = "Antimony", Ag = "Silver", Ni = "Nickel"), + group_as_number = TRUE + )$copper_group_bray, + NA_integer_ + ) }) test_that("copper_alloy_pollard: Handling ASTR object", { - test_data_ASTR <- as_ASTR( - data.frame( - ID = 1, - As_atP = 0.3, - Sb_atP = 0.2, - Ag_atP = 0.0, - Ni_atP = 0.0 + suppressWarnings( + test_data_ASTR <- as_ASTR( + data.frame( + ID = 1, + As_atP = c(0.3, 0.1), + Sb_atP = c(0.2, 0.5), + Ag_atP = c(0.0, 0.2), + Ni_atP = c(0.0, NA) + ) ) ) test_result_ASTR <- copper_group_bray(test_data_ASTR)