aboutsummaryrefslogtreecommitdiff
path: root/R/set_nd.R
blob: 10c5cbafeba10a5f0c7eb3a825c91003b9120542 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#' 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 time_zero Is the first value in the series a time zero value?
#' @param time_zero_nd_value Which value should we use for non-detects at time zero?
#' @param stop_after_first_nondetect Should we really stop after the first non-detection?
#' @references FOCUS (2014) Generic Guidance for Estimating Persistence and Degradation
#'   Kinetics from Environmental Fate Studies on Pesticides in EU Registration, Version 1.1, 
#'   18 December 2014, p. 251
#' @describeIn set_nd Set non-detects in residues series
#' @export
#' @examples
#' # FOCUS (2014) p. 75/76 and 131/132
#' 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(r, lod, loq = NA, time_zero = TRUE) {
  result <- set_nd(r, lod, loq = loq, time_zero = time_zero,
    time_zero_nd_value = 0, stop_after_first_nondetect = TRUE)
  return(result)
}

Contact - Imprint