-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor of main MAP fit function #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
mccarthy-m-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvements! Left some small suggestions below.
R/get_map_estimates.R
Outdated
| ## Checks for estimation type | ||
| if(tolower(type) %in% c("map", "pls")) { | ||
| if(is.null(model) || is.null(data) || is.null(parameters) || is.null(omega) || is.null(regimen)) { | ||
| stop("The 'model', 'data', 'omega', 'regimen', and 'parameters' arguments are required.") | ||
| } | ||
| } | ||
| if(tolower(type) == "pls") { | ||
| weight_prior <- 0.001 | ||
| ## RK: Empirically determined to be a good penalty. | ||
| ## In principle, PLS is just MAP with very flat priors | ||
| } | ||
| if(tolower(type) %in% c("ls")) { | ||
| if(is.null(model) || is.null(data) || is.null(regimen)) { | ||
| stop("The 'model', 'data', and 'parameters' arguments are required.") | ||
| } | ||
| calc_ofv <- calc_ofv_ls | ||
| error <- list(prop = 0, add = 1) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could refactor this into a function like:
check_estimation_type <- function(
type,
model,
data,
parameters,
omega,
regimen
) {
if(tolower(type) %in% c("map", "pls")) {
if(is.null(model) || is.null(data) || is.null(parameters) || is.null(omega) || is.null(regimen)) {
stop("The 'model', 'data', 'omega', 'regimen', and 'parameters' arguments are required.")
}
}
if(tolower(type) %in% c("ls")) {
if(is.null(model) || is.null(data) || is.null(regimen)) {
stop("The 'model', 'data', and 'parameters' arguments are required.")
}
}
type
}Then call this in the main function instead:
type <- check_estimation_type(type, model, data, parameters, omega, regimen)
if(tolower(type) %in% c("ls")) {
calc_ofv <- calc_ofv_ls
error <- list(prop = 0, add = 1)
}There are some other if statements in the main function that are similar (mainly just running a check and throwing an error if it's not met). It might be nice to refactor all of these into check_ functions too?
R/get_map_estimates.R
Outdated
| if(!is.null(censoring) && !inherits(censoring, "character")) { | ||
| stop("Censoring argument requires label specifying column in dataset with censoring info.") | ||
| } | ||
| if(!("function" %in% class(model))) { | ||
| stop("The 'model' argument requires a function, e.g. a model defined using the new_ode_model() function from the PKPDsim package.") | ||
| } | ||
| if(!all(unlist(cols) %in% names(data))) { | ||
| stop("Expected column names were not found in data. Please use 'cols' argument to specify column names for independent and dependent variable.") | ||
| } | ||
| if("PKPDsim" %in% class(data)) { | ||
| if("comp" %in% names(data)) { | ||
| data <- data[data$comp == "obs",] | ||
| # data <- data[!duplicated(data$t),] | ||
| data$evid <- 0 | ||
| } | ||
| } | ||
| colnames(data) <- tolower(colnames(data)) | ||
| sig <- round(-log10(int_step_size)) | ||
| if("evid" %in% colnames(data)) { | ||
| data <- data[data$evid == 0,] | ||
| if(is.null(attr(model, "cpp")) || !attr(model, "cpp")) { | ||
| warning("Provided model is not PKPDsim model, using generic likelihood function.") | ||
| ll_func <- ll_func_generic | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, these could all be check_ functions.
| individual population eta relative | ||
| CL 6.699894 7.67 -0.671110 --o--|----- | ||
| V 87.000059 97.70 -3.668013 o-----|----- | ||
| Q 3.421152 3.00 1.313651 -----|--o-- | ||
| V2 50.000000 50.00 NA <NA> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed we don't have a NEWS file for this package. It might be nice to add one so we can communicate/keep track of changes like this that affect output (i.e., "The print method for map_estimates() now uses sqrt(diag(PKPDsim::triangle_to_full(x$prior$omega$full))) instead of sqrt(diag(PKPDsim::triangle_to_full(x$prior$omega))) for etas").
The function has become way too big and unwieldy. Splitting up in separate functions that can be unit-tested.
Also made code more readable in places, and added comments.
The new version is already much more readable, although there are still some places that could warrant refactor. But putting up for review now to get some signal on the current state.