-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add method, function, and plots for EFSA criteria: PPC (function and …
…plot), and NRMSE. Results of EFSA criteria in validation plots are now rounded at 2 significant digits after the decimal
- Loading branch information
Showing
8 changed files
with
229 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#' Computes PPC and NRMSE as defined in EFSA 2018 | ||
#' | ||
#' @param x an object of class \code{beeSurvFit} or \code{beeSurvPred} | ||
#' | ||
#' @return The function returns a list with three items: | ||
#' \item{PPC}{The criterion, in percent, compares the predicted median number of survivors associated | ||
#' to their uncertainty limits with the observed numbers of survivors. | ||
#' Based on experience, PPC resulting in more than \eqn{50\%} of the | ||
#' observations within the uncertainty limits indicate good model performance (EFSA 2018). A fit of | ||
#' \eqn{100\%} may hide too large uncertainties of prediction (so covering all data).} | ||
#' \item{PPC_global}{percentage of PPC for the whole data set by gathering data types.} | ||
#' \item{NRMSE}{The criterion, in percent, is based on the classical root-mean-square error (RMSE), | ||
#' used to aggregate the magnitudes of the errors in predictions for various time-points | ||
#' into a single measure of predictive power. In order to provide a criterion expressed | ||
#' as a percentage, NRMSE is the normalised RMSE by the mean of the observations. | ||
#' EFSA (2018) recognised that a NRMSE of less than 50% indicates good model performance} | ||
#' | ||
#' | ||
#' @references | ||
#' EFSA PPR Scientific Opinion (2018) | ||
#' \emph{Scientific Opinion on the state of the art of Toxicokinetic/Toxicodynamic (TKTD) effect models for regulatory risk assessment of pesticides for aquatic organisms} | ||
#' \url{https://www.efsa.europa.eu/en/efsajournal/pub/5377} | ||
#' | ||
#' @export | ||
#' | ||
criteriaCheck<- function(x){ | ||
|
||
# --- PPC | ||
dfGlobal<- ppc(x) %>% | ||
dplyr::mutate(ppcMatching_valid = ifelse(value<q_0.025|value>q_0.975, 0, 1), | ||
SE_id = (value - median)^2) | ||
|
||
dfPPC <- dfGlobal %>% | ||
dplyr::select(data, ppcMatching_valid) %>% | ||
dplyr::group_by(data) %>% | ||
dplyr::summarise(PPC = mean(ppcMatching_valid)*100) | ||
|
||
# --- NRMSE | ||
dfNRMSE <- dfGlobal %>% | ||
dplyr::select(value, data, SE_id) %>% | ||
dplyr::group_by(data) %>% | ||
dplyr::summarise(NRMSE = sqrt(mean(SE_id, na.rm = TRUE)) / mean(value , na.rm = TRUE) * 100) | ||
|
||
|
||
return(list(percentPPC = as.data.frame(dfPPC), | ||
percentNRMSE = as.data.frame(dfNRMSE)) | ||
|
||
) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#' Generates an object to be used in posterior predictive check for \code{beeSurvFit}, \code{beeSurvPred} | ||
#' | ||
#' @param x an object used to select a method \code{ppc} | ||
#' | ||
#' @export | ||
#' | ||
ppc <- function(x){ | ||
UseMethod("ppc") | ||
} | ||
|
||
|
||
|
||
#' Posterior predictive check method for \code{beeSurvFit} objects | ||
#' | ||
#' @param x an object of class \code{beeSurvFit} | ||
#' | ||
#' | ||
#' @return a \code{data.frame} of class \code{ppc} | ||
#' | ||
#' @examples | ||
#' @export | ||
#' | ||
ppc.beeSurvFit <- function(x){ | ||
NsurvPred_all<- as.data.frame(x$stanFit, pars = "Nsurv_ppc") | ||
NsurvPred_quantiles<- NsurvPred_all%>% | ||
tidyr::pivot_longer(cols = tidyr::starts_with('Nsurv'), | ||
names_to = "ppc", | ||
values_to = "value")%>% | ||
dplyr::group_by(ppc)%>% | ||
dplyr::summarise(median = stats::quantile(value, 0.5, na.rm = TRUE), | ||
q_0.025=stats::quantile(value, 0.025, na.rm = TRUE), | ||
q_0.975=stats::quantile(value, 0.975, na.rm = TRUE)) | ||
|
||
NsurvData_all<- data.frame(value=x$dataFit$Nsurv, id=seq(1,x$dataFit$nData_Nsurv, 1))%>% | ||
dplyr::mutate(ppc=paste0("Nsurv_ppc[",id, "]")) | ||
|
||
Nsurv_ppc<- dplyr::full_join( NsurvPred_quantiles, NsurvData_all, by="ppc")%>% | ||
dplyr::mutate(col=ifelse(value<q_0.025|value>q_0.975, "red", "green")) %>% | ||
dplyr::arrange(id) | ||
|
||
Nsurv_ppc$data<-"Survival" | ||
|
||
class(Nsurv_ppc) <- c("ppc", class(Nsurv_ppc)) | ||
return(Nsurv_ppc) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.