Skip to content

Commit 0410ac6

Browse files
authored
Merge pull request #348 from USEPA/343-mc5-ow-and-loec
343/345 add err for multiple ow methods, update mc5 and loec.coff method to ow_loec.coff and include_loec.coff methods
2 parents 060dd50 + 9ce9154 commit 0410ac6

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

Diff for: R/mc5.R

+19-21
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ mc5 <- function(ae, wr = FALSE) {
7878

7979
## Load cutoff methods
8080
ms <- tcplMthdLoad(lvl = 5L, id = ae, type = "mc")
81-
if ('loec.coff' %in% ms$mthd) {
82-
# using the loec method
81+
if (any(c("ow_loec.coff", "include_loec.coff") %in% ms$mthd)) {
82+
# using a loec method
8383
loec.mthd = TRUE
84-
ms <- ms[!mthd=='loec.coff']
84+
ms <- ms[!mthd=='include_loec.coff']
8585
}
8686

8787
#special case where osd needs to be overwritten
@@ -93,6 +93,9 @@ mc5 <- function(ae, wr = FALSE) {
9393

9494
## Extract methods that need to overwrite hitc and hit_val
9595
ms_overwrite <- ms[grepl("ow_",mthd),]
96+
if (nrow(ms_overwrite) > 1) {
97+
stop(paste0("Only one level 5 hit-call override method may be assigned concurrently. Currently assigned: ", paste0(ms_overwrite$mthd, collapse = ", ")))
98+
}
9699
## Extract methods that don't overwrite
97100
ms <- ms[!grepl("ow_",mthd),]
98101

@@ -124,7 +127,6 @@ mc5 <- function(ae, wr = FALSE) {
124127

125128
## Complete the loec calculations
126129
if (loec.mthd) {
127-
128130
all_resp_gt_conc <-function(resp) {
129131
# all resp > coff
130132
return(as.integer(all(abs(resp) > cutoff))) # All responses must be greater than coff
@@ -137,13 +139,18 @@ mc5 <- function(ae, wr = FALSE) {
137139
mc3[is.infinite(loec), loec := NA] #convert Inf to NA
138140
mc3[, loec_hitc := max(loec_coff), by = spid] # is there a loec? used for hitc
139141
mc3 <- mc3[dat, mult='first', on='spid', nomatch=0L]
140-
141-
dat <- dat[mc3[,c("spid","loec", "loec_hitc")],on = "spid"]
142-
143-
} else {
144-
# if we're using v3 schema and not loec method we want to tcplfit2
145-
dat <- tcplHit2(dat, coff = cutoff)
142+
mc3 <- mc3[,c("m4id","aeid","coff","loec")] |> melt(measure.vars = c("loec"), variable.name = "hit_param", value.name = "hit_val")
143+
}
144+
145+
# if we're using v3 schema we want to tcplfit2
146+
dat <- tcplHit2(dat, coff = cutoff)
147+
148+
if (loec.mthd) {
149+
exprs <- lapply(mthd_funcs["include_loec.coff"], do.call, args = list())
150+
fenv <- environment()
151+
invisible(rapply(exprs, eval, envir = fenv))
146152
}
153+
147154
} else {
148155
# Legacy fitting
149156

@@ -381,30 +388,21 @@ mc5 <- function(ae, wr = FALSE) {
381388
dat <- dat[ , .SD, .SDcols = outcols]
382389
}
383390

384-
385-
# apply overwrite methods
391+
# apply overwrite method
386392
if (nrow(ms_overwrite) > 0) {
387393
exprs <- lapply(mthd_funcs[ms_overwrite$mthd], do.call, args = list())
388394
fenv <- environment()
389395
invisible(rapply(exprs, eval, envir = fenv))
390396
}
391397

392-
# apply loec.coff
393-
if (loec.mthd) {
394-
exprs <- lapply(mthd_funcs[c("loec.coff")], do.call, args = list())
395-
fenv <- environment()
396-
invisible(rapply(exprs, eval, envir = fenv))
397-
}
398-
399398

400399
ttime <- round(difftime(Sys.time(), stime, units = "sec"), 2)
401400
ttime <- paste(unclass(ttime), units(ttime))
402401
cat("Processed L5 AEID", ae, " (", nrow(dat),
403402
" rows; ", ttime, ")\n", sep = "")
404403

405404
res <- TRUE
406-
407-
405+
408406

409407
## Load into mc5 table -- else return results
410408
if (wr) {

Diff for: R/mc5_mthds.R

+24-9
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,20 @@
106106
#' \item{maxmed20pct}{Add a cutoff value of 20 percent of the maximum of all endpoint maximal
107107
#' average response values (max_med).}
108108
#' \item{coff_2.32}{Add a cutoff value of 2.32.}
109-
#' \item{loec.coff}{Identify the lowest observed effective concentration (loec) where the values
110-
#' of all responses are outside the cutoff band (i.e. abs(resp) > cutoff). If loec exists, assume
111-
#' hit call = 1, fitc = 100, model_type = 1. Winning model is not selected based on curve fits
112-
#' and therefore additional potency estimates are not derived.}
113109
#' \item{ow_bidirectional_loss}{Multiply winning model hitcall (hitc) by -1 for models fit in the
114110
#' positive analysis direction. Typically used for endpoints where only negative responses are
115111
#' biologically relevant.}
116112
#' \item{ow_bidirectional_gain}{Multiply winning model hitcall (hitc) by -1 for models fit in the
117113
#' negative analysis direction. Typically used for endpoints where only positive responses are
118114
#' biologically relevant.}
119115
#' \item{osd_coff_bmr}{Overwrite the osd value so that bmr equals cutoff.}
116+
#' \item{ow_loec.coff}{Identify the lowest observed effective concentration (loec) where the values
117+
#' of all responses are outside the cutoff band (i.e. abs(resp) > cutoff). loec is stored alongside
118+
#' winning model and potency estimates. If loec exists, assume hit call = 1, fitc = 100,
119+
#' model_type = 1, and if not, assume hit call = 0.}
120+
#' \item{include_loec.coff}{Identify the lowest observed effective concentration (loec) where the
121+
#' values of all responses are outside the cutoff band (i.e. abs(resp) > cutoff). loec is
122+
#' stored alongside winning model and potency estimates.}
120123
#' }
121124
#' }
122125
#'
@@ -354,12 +357,24 @@ mc5_mthds <- function(ae) {
354357

355358
},
356359

357-
loec.coff = function() {
360+
ow_loec.coff = function() {
358361

359-
e1 <- bquote(dat[, c("modl", "fitc", "model_type", "hitc") := list("loec", 100L, 1, loec_hitc)])
360-
e2 <- bquote(dat <- dat |> melt(measure.vars = c("loec"), variable.name = "hit_param", value.name = "hit_val"))
361-
e3 <- bquote(dat <- dat[,c("m4id", "aeid", "modl", "hitc", "fitc", "coff", "model_type", "hit_param", "hit_val")])
362-
list(e1, e2, e3)
362+
# get all endpoint sample m4ids where the loec param is not na
363+
e1 <- bquote(loec.m4ids <- dat[(hit_param == "loec") & !is.na(hit_val), unique(m4id)])
364+
# set hitcall and hitc param to 1 if found in m4id list and 0 if not
365+
e2 <- bquote(dat[hit_param == "hitcall", hit_val:=ifelse(m4id %in% loec.m4ids, 1, 0)])
366+
e3 <- bquote(dat[, hitc:=ifelse(m4id %in% loec.m4ids, 1, 0)])
367+
# update modl to loec, fitc to 100, model_type to 1
368+
e4 <- bquote(dat[, c("modl", "fitc", "model_type") := list("loec", 100L, 1)])
369+
list(e1, e2, e3, e4)
370+
371+
},
372+
373+
include_loec.coff = function() {
374+
375+
e1 <- bquote(dat <- rbind(dat, mc3, fill = TRUE) |> arrange(m4id))
376+
e2 <- bquote(dat <- dat |> group_by(m4id) |> tidyr::fill(modl,hitc,fitc,model_type) |> as.data.table())
377+
list(e1, e2)
363378

364379
}
365380

Diff for: man/MC5_Methods.Rd

+7-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)