From 63df3871a442de4bf47e4d9de1449e7f6ed65b2f Mon Sep 17 00:00:00 2001 From: Johannes Ranke Date: Wed, 9 Oct 2019 19:17:07 +0200 Subject: Function to set non-detects in residue series --- ChangeLog | 6 +++ DESCRIPTION | 2 +- NAMESPACE | 2 + R/process_residues.R | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ build.log | 9 +++-- man/set_nd.Rd | 65 +++++++++++++++++++++++++++++++ 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 R/process_residues.R create mode 100644 man/set_nd.Rd diff --git a/ChangeLog b/ChangeLog index 1f47ac8..17ffa8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +commit 9f848a9518aabf162723271bafba244221ee83ed +Author: Johannes Ranke +Date: 2019-09-27 12:55:03 +0200 + + Built windows binary for drat + commit 435e07a6f7fd2599d783fd306ee6d9e08acc0c6b Author: Johannes Ranke Date: 2019-09-27 10:00:15 +0200 diff --git a/DESCRIPTION b/DESCRIPTION index 1589b14..73c561d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: pfm Type: Package Title: Utilities for Pesticide Fate Modelling Version: 0.5.7 -Date: 2019-09-27 +Date: 2019-10-09 Authors@R: person("Johannes Ranke", email = "jranke@uni-bremen.de", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0003-4371-6538")) diff --git a/NAMESPACE b/NAMESPACE index 59e8040..8eb6863 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -36,6 +36,8 @@ export(perc_runoff_reduction_exposit) export(pfm_degradation) export(read.TOXSWA_cwa) export(sawtooth) +export(set_nd) +export(set_nd_focus) export(soil_DT50) export(soil_Kfoc) export(soil_N) diff --git a/R/process_residues.R b/R/process_residues.R new file mode 100644 index 0000000..35d3a4e --- /dev/null +++ b/R/process_residues.R @@ -0,0 +1,107 @@ +#' Set non-detects in residue series without replicates + +#' Sets non-detects directly before or directly after detects to NA. Values between +#' lod and loq are set to their mean value if an loq is specified. +#' If 'time_zero' is set to TRUE, the residue series is assumed to start with time +#' zero, and non-detects at time zero are set to 'time_zero_nd_value'. For the +#' set_nd_focus variant, this is zero, otherwise this argument has NA as default +#' value. +#' If stopping after the first non-detection is requested, as in in the FOCUS +#' variant of the function, an loq has to be specified in order to decide +#' if any later detections are above the loq. + +#' @param r A character vector of sequential residues without replicates, with +#' non-detects specified as 'nd' and unquantified values above the limit of +#' detection specified as 'nq', otherwise coercible to numeric +#' @param lod Limit of detection (numeric) +#' @param loq Limit of quantification(numeric). Must be specified if the FOCUS rule to +#' stop after the first non-detection is to be applied +#' @param stop_after_first_nondetect Should we really stop after the first non-detection? +#' @references FOCUS (2014) p. 75, 76, 131, 132 +#' @export +#' @examples +#' parent_1 <- c(.12, .09, .05, .03, "nd", "nd", "nd", "nd", "nd", "nd") +#' set_nd(parent_1, 0.02) +#' parent_2 <- c(.12, .09, .05, .03, "nd", "nd", .03, "nd", "nd", "nd") +#' set_nd(parent_2, 0.02) +#' set_nd_focus(parent_2, 0.02, loq = 0.05) +#' parent_3 <- c(.12, .09, .05, .03, "nd", "nd", .06, "nd", "nd", "nd") +#' set_nd(parent_3, 0.02) +#' set_nd_focus(parent_3, 0.02, loq = 0.05) +#' metabolite <- c("nd", "nd", "nd", 0.03, 0.06, 0.10, 0.11, 0.10, 0.09, 0.05, 0.03, "nd", "nd") +#' set_nd(metabolite, 0.02) +set_nd <- function(r, lod, loq = NA, + time_zero = TRUE, time_zero_nd_value = NA, stop_after_first_nondetect = FALSE) +{ + + if (stop_after_first_nondetect & is.na(loq)) { + stop("You need to specify an loq to decide if the curve should be cut off after the first non-detect") + } + + result <- r + + # Handle nq values + if (!missing(loq)) { + nq = 0.5 * (lod + loq) + result[r == "nq"] <- nq + } else { + if (any(r == "nq")) stop("You need to specify lod and loq") + } + + # Handle nd values + if (time_zero) { + if (r[1] == "nd") { + residues_present = FALSE + result[1] <- time_zero_nd_value + } else { + residues_present = TRUE + } + start_i <- 2 + } else { + residues_present <- if (r[1] == "nd") FALSE else TRUE + start_i <- 1 + } + + for (i in start_i:length(r)) { + + # residues_in_next + if (i < length(r)) { + next_value <- r[i + 1] + if (next_value == "nd") residues_in_next = FALSE + else residues_in_next = TRUE + } else { + residues_in_next = FALSE + } + + if (r[i] == "nd") { + if (residues_present | residues_in_next) { + result[i] <- 0.5 * lod + } else { + result[i] <- NA + } + + if (stop_after_first_nondetect) { + if (residues_present & !residues_in_next) { + remaining <- (i + 1):length(r) + if (!any(suppressWarnings(as.numeric(r[remaining])) > loq, na.rm = TRUE)) { + result[remaining] <- NA + return(as.numeric(result)) + } + } + + } + if (!residues_in_next) residues_present <- FALSE + else residues_present <- TRUE + } + + } + return(as.numeric(result)) +} + +#' @describeIn set_nd Set non-detects in residues series according to FOCUS rules +#' @export +set_nd_focus <- function(res, lod, loq = NA, time_zero = TRUE) { + result <- set_nd(res, lod, loq = loq, time_zero = time_zero, + time_zero_nd_value = 0, stop_after_first_nondetect = TRUE) + return(result) +} diff --git a/build.log b/build.log index 6048d87..e001d03 100644 --- a/build.log +++ b/build.log @@ -1,9 +1,12 @@ -* checking for file './DESCRIPTION' ... OK -* preparing 'pfm': +* checking for file ‘./DESCRIPTION’ ... OK +* preparing ‘pfm’: * checking DESCRIPTION meta-information ... OK * checking for LF line-endings in source and make files and shell scripts * checking for empty or unneeded directories -* looking to see if a 'data/datalist' file should be added +Removed empty directory ‘pfm/inst/testdata/SwashProjects/Project_1/MACRO’ +Removed empty directory ‘pfm/inst/testdata/SwashProjects/Project_1’ +Removed empty directory ‘pfm/inst/testdata/SwashProjects’ +* looking to see if a ‘data/datalist’ file should be added NB: this package now depends on R (>= 3.5.0) WARNING: Added dependency on R >= 3.5.0 because serialized objects in serialize/load version 3 cannot be read in older versions of R. File(s) containing such objects: 'pfm/data/EFSA_GW_interception_2014.RData' WARNING: Added dependency on R >= 3.5.0 because serialized objects in serialize/load version 3 cannot be read in older versions of R. File(s) containing such objects: 'pfm/data/EFSA_washoff_2017.RData' * building 'pfm_0.5.7.tar.gz' diff --git a/man/set_nd.Rd b/man/set_nd.Rd new file mode 100644 index 0000000..8c766ac --- /dev/null +++ b/man/set_nd.Rd @@ -0,0 +1,65 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_residues.R +\name{set_nd} +\alias{set_nd} +\alias{set_nd_focus} +\title{Set non-detects in residue series without replicates +Sets non-detects directly before or directly after detects to NA. Values between +lod and loq are set to their mean value if an loq is specified. +If 'time_zero' is set to TRUE, the residue series is assumed to start with time +zero, and non-detects at time zero are set to 'time_zero_nd_value'. For the +set_nd_focus variant, this is zero, otherwise this argument has NA as default +value. +If stopping after the first non-detection is requested, as in in the FOCUS +variant of the function, an loq has to be specified in order to decide +if any later detections are above the loq.} +\usage{ +set_nd(r, lod, loq = NA, time_zero = TRUE, time_zero_nd_value = NA, + stop_after_first_nondetect = FALSE) + +set_nd_focus(res, lod, loq = NA, time_zero = TRUE) +} +\arguments{ +\item{r}{A character vector of sequential residues without replicates, with +non-detects specified as 'nd' and unquantified values above the limit of +detection specified as 'nq', otherwise coercible to numeric} + +\item{lod}{Limit of detection (numeric)} + +\item{loq}{Limit of quantification(numeric). Must be specified if the FOCUS rule to +stop after the first non-detection is to be applied} + +\item{stop_after_first_nondetect}{Should we really stop after the first non-detection?} +} +\description{ +Set non-detects in residue series without replicates +Sets non-detects directly before or directly after detects to NA. Values between +lod and loq are set to their mean value if an loq is specified. +If 'time_zero' is set to TRUE, the residue series is assumed to start with time +zero, and non-detects at time zero are set to 'time_zero_nd_value'. For the +set_nd_focus variant, this is zero, otherwise this argument has NA as default +value. +If stopping after the first non-detection is requested, as in in the FOCUS +variant of the function, an loq has to be specified in order to decide +if any later detections are above the loq. +} +\section{Functions}{ +\itemize{ +\item \code{set_nd_focus}: Set non-detects in residues series according to FOCUS rules +}} + +\examples{ +parent_1 <- c(.12, .09, .05, .03, "nd", "nd", "nd", "nd", "nd", "nd") +set_nd(parent_1, 0.02) +parent_2 <- c(.12, .09, .05, .03, "nd", "nd", .03, "nd", "nd", "nd") +set_nd(parent_2, 0.02) +set_nd_focus(parent_2, 0.02, loq = 0.05) +parent_3 <- c(.12, .09, .05, .03, "nd", "nd", .06, "nd", "nd", "nd") +set_nd(parent_3, 0.02) +set_nd_focus(parent_3, 0.02, loq = 0.05) +metabolite <- c("nd", "nd", "nd", 0.03, 0.06, 0.10, 0.11, 0.10, 0.09, 0.05, 0.03, "nd", "nd") +set_nd(metabolite, 0.02) +} +\references{ +FOCUS (2014) p. 75, 76, 131, 132 +} -- cgit v1.2.1