#' Evaluate parent kinetics using the NAFTA guidance #' #' The function fits the SFO, IORE and DFOP models using \code{\link{mmkin}} #' and returns an object of class \code{nafta} that has methods for printing #' and plotting. #' #' @param ds A dataframe that must contain one variable called "time" with the #' time values specified by the \code{time} argument, one column called #' "name" with the grouping of the observed values, and finally one column of #' observed values called "value". #' @param title Optional title of the dataset #' @param quiet Should the evaluation text be shown? #' @param \dots Further arguments passed to \code{\link{mmkin}} (not for the #' printing method). #' @importFrom stats qf #' @return An list of class \code{nafta}. The list element named "mmkin" is the #' \code{\link{mmkin}} object containing the fits of the three models. The #' list element named "title" contains the title of the dataset used. The #' list element "data" contains the dataset used in the fits. #' @author Johannes Ranke #' @source NAFTA (2011) Guidance for evaluating and calculating degradation #' kinetics in environmental media. NAFTA Technical Working Group on #' Pesticides #' \url{https://www.epa.gov/pesticide-science-and-assessing-pesticide-risks/guidance-evaluating-and-calculating-degradation} #' accessed 2019-02-22 #' #' US EPA (2015) Standard Operating Procedure for Using the NAFTA Guidance to #' Calculate Representative Half-life Values and Characterizing Pesticide #' Degradation #' \url{https://www.epa.gov/pesticide-science-and-assessing-pesticide-risks/standard-operating-procedure-using-nafta-guidance} #' @examples #' #' nafta_evaluation <- nafta(NAFTA_SOP_Appendix_D, cores = 1) #' print(nafta_evaluation) #' plot(nafta_evaluation) #' #' @export nafta <- function(ds, title = NA, quiet = FALSE, ...) { if (length(levels(ds$name)) > 1) { stop("The NAFTA procedure is only defined for decline data for a single compound") } n <- nrow(subset(ds, !is.na(value))) models <- c("SFO", "IORE", "DFOP") result <- list(title = title, data = ds) result$mmkin <- mmkin(models, list(ds), quiet = TRUE, ...) distimes <- lapply(result$mmkin, function(x) as.numeric(endpoints(x)$distimes["parent", ])) result$distimes <- matrix(NA, nrow = 3, ncol = 3, dimnames = list(models, c("DT50", "DT90", "DT50_rep"))) result$distimes["SFO", ] <- distimes[[1]][c(1, 2, 1)] result$distimes["IORE", ] <- distimes[[2]][c(1, 2, 3)] result$distimes["DFOP", ] <- distimes[[3]][c(1, 2, 5)] # Get parameters with statistics result$parameters <- lapply(result$mmkin, function(x) { summary(x)$bpar[, c(1, 4:6)] }) names(result$parameters) <- models # Compare the sum of squared residuals (SSR) to the upper bound of the # confidence region of the SSR for the IORE model result$S <- sapply(result$mmkin, function(x) sum(x$data$residual^2)) names(result$S) <- c("SFO", "IORE", "DFOP") # Equation (3) on p. 3 p <- 3 result$S["IORE"] result$S_c <- result$S[["IORE"]] * (1 + p/(n - p) * qf(0.5, p, n - p)) result$t_rep <- .evaluate_nafta_results(result$S, result$S_c, result$distimes, quiet = quiet) class(result) <- "nafta" return(result) } #' Plot the results of the three models used in the NAFTA scheme. #' #' The plots are ordered with increasing complexity of the model in this #' function (SFO, then IORE, then DFOP). #' #' Calls \code{\link{plot.mmkin}}. #' #' @param x An object of class \code{\link{nafta}}. #' @param legend Should a legend be added? #' @param main Possibility to override the main title of the plot. #' @param \dots Further arguments passed to \code{\link{plot.mmkin}}. #' @return The function is called for its side effect. #' @author Johannes Ranke #' @export plot.nafta <- function(x, legend = FALSE, main = "auto", ...) { if (main == "auto") { if (is.na(x$title)) main = "" else main = x$title } plot(x$mmkin, ..., legend = legend, main = main) } #' Print nafta objects #' #' Print nafta objects. The results for the three models are printed in the #' order of increasing model complexity, i.e. SFO, then IORE, and finally DFOP. #' #' @param x An \code{\link{nafta}} object. #' @param digits Number of digits to be used for printing parameters and #' dissipation times. #' @rdname nafta #' @export print.nafta <- function(x, quiet = TRUE, digits = 3, ...) { cat("Sums of squares:\n") print(x$S) cat("\nCritical sum of squares for checking the SFO model:\n") print(x$S_c) cat("\nParameters:\n") print(x$parameters, digits = digits) t_rep <- .evaluate_nafta_results(x$S, x$S_c, x$distimes, quiet = quiet) cat("\nDTx values:\n") print(signif(x$distimes, digits = digits)) cat("\nRepresentative half-life:\n") print(round(t_rep, 2)) } .evaluate_nafta_results <- function(S, S_c, distimes, quiet = FALSE) { t_SFO <- distimes["IORE", "DT50"] t_IORE <- distimes["IORE", "DT50_rep"] t_DFOP2 <- distimes["DFOP", "DT50_rep"] if (S["SFO"] < S_c) { if (!quiet) { message("S_SFO is lower than the critical value S_c, use the SFO model") } t_rep <- t_SFO } else { if (!quiet) { message("The SFO model is rejected as S_SFO is equal or higher than the critical value S_c") } if (t_IORE < t_DFOP2) { if (!quiet) { message("The half-life obtained from the IORE model may be used") } t_rep <- t_IORE } else { if (!quiet) { message("The representative half-life of the IORE model is longer than the one corresponding") message("to the terminal degradation rate found with the DFOP model.") message("The representative half-life obtained from the DFOP model may be used") } t_rep <- t_DFOP2 } } return(t_rep) }