From 4ece817450b1412f907edf03edaad8f3189bf618 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Mon, 14 Jul 2025 11:35:09 +1000 Subject: [PATCH 01/57] adds dummy data set with a placebo group --- .Rbuildignore | 1 + other/d_sim_emax_placebo.csv | 101 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 other/d_sim_emax_placebo.csv diff --git a/.Rbuildignore b/.Rbuildignore index 37f66b0..57647b1 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -23,6 +23,7 @@ ^cran-comments\.md$ ^data-raw$ +^other$ ^LICENSE\.md$ ^_pkgdown\.yml$ diff --git a/other/d_sim_emax_placebo.csv b/other/d_sim_emax_placebo.csv new file mode 100644 index 0000000..5aeea91 --- /dev/null +++ b/other/d_sim_emax_placebo.csv @@ -0,0 +1,101 @@ +dose,exposure,cnt_a,cnt_b,cnt_c,bin_d,bin_e,response_1,response_2 +0,0,3.952880036530093,4.782598842039988,5.9161563565104895,0,1,6.427069951617644,0 +0,0,5.841294924224819,2.683406240502799,3.4339613348994593,1,0,8.062437149462342,0 +0,0,5.716078953551537,7.6657841388450985,6.125564938607381,1,1,8.016604493523499,1 +0,0,2.5544083534270423,1.4150310195749958,6.274423104959172,0,1,6.54846126696043,0 +0,0,2.804051666808075,4.481257320557605,8.261145039986175,1,0,5.870606168009292,0 +0,0,4.6585985259507225,9.189853490818997,7.374844068066782,0,1,8.396990182182455,0 +0,0,2.6168096263271634,4.617709396351545,6.023757516837388,1,1,5.897382450234828,0 +0,0,6.885234415871807,4.959602339675849,9.201732549185433,0,1,8.069365105711126,0 +0,0,6.489321020320995,3.8374525487035327,2.2582086889956687,1,1,8.381115058977572,1 +0,0,2.2165008526438785,4.158214804044999,0.9367460595450317,1,1,6.39263634498957,0 +0,0,3.0406937867683093,5.6248823562441155,7.205285116382316,1,0,6.4644594445428725,0 +0,0,5.264571070397124,7.429320220932172,1.9102220578308038,0,1,6.6692154617218975,0 +0,0,3.017990744932089,4.253212843775993,2.5652557678505112,1,0,6.5948927531274375,0 +0,0,2.0754282087105547,3.7873475881916456,4.21827534437606,0,1,7.006166424217858,0 +0,0,6.96908666843108,7.114583932625646,3.084300286733747,1,1,8.343376856106447,1 +0,0,2.222649030800067,8.16967328080111,8.339444319160462,1,0,6.140748078461426,0 +0,0,3.332013998309595,8.169131981181605,4.350940609181816,0,1,5.921393685208718,0 +0,0,1.6900621518949324,7.521621681563115,5.678676035550162,1,0,5.466529591714193,0 +0,0,2.3505577998204767,3.3928035157063894,9.490669956378566,1,1,5.811199724286352,0 +0,0,1.8714937888696836,9.47793624292725,3.8581626488326832,0,1,6.055023433683756,0 +0,0,1.5145245506405283,6.923729938929179,2.5972312811184466,0,0,5.767182319683468,0 +0,0,1.6728123607000291,9.024875991153499,7.302277267768003,1,0,5.73199609469093,0 +0,0,4.664361546788167,4.902576138550616,3.9779361964143427,0,1,7.103249919457015,0 +0,0,4.787519626947647,8.038554633581656,8.950434572398123,0,0,7.868779020395443,0 +0,0,1.7792710033908123,8.465625885299996,6.869060228775687,1,1,6.345109023852281,0 +0,0,6.23866006436972,3.84145917766257,6.211480220335174,1,1,7.2224908230602125,1 +0,0,7.439909048970701,6.213475122045633,5.270001519421568,1,1,8.9680836097436,1 +0,0,3.503746390886932,6.907780366033196,3.1477878135288155,0,0,6.684251099905927,0 +0,0,4.724766351824213,3.903849378090934,8.111520250710253,1,1,7.382972245531514,0 +0,0,1.8827523722765263,3.7236904549493923,5.343992771570206,1,1,4.709303824583265,0 +0,0,3.8141085650324005,7.331551599545567,4.081220636410214,1,0,6.528057026206427,0 +0,0,4.163463504725296,6.509073581341786,1.9507156153062846,0,0,7.355463132885835,0 +0,0,2.07343521329668,2.5840439234292227,3.1958548543780636,0,1,6.442271390093384,0 +0,0,4.740666583257507,5.698438528130301,7.674878569289248,1,1,6.874508597079776,0 +0,0,5.70925563346642,2.423523384903256,1.128088747120814,1,0,8.084661084156714,0 +0,0,2.86391676081075,6.204720279827448,1.5318439831775355,1,1,7.090375217899183,0 +0,0,5.447415024482427,8.422182800345889,7.20934447572385,1,1,7.752702756026671,0 +0,0,3.5797197514719477,2.475137752094184,7.279682445211339,1,1,7.128443776510267,0 +0,0,3.4948306479576536,3.9776304797039908,2.165226571978162,1,0,7.585531362460668,0 +0,0,3.08091640125228,4.204968606817771,2.291494467827065,0,1,6.267871489108469,0 +0,0,5.707198610595537,5.128913531755067,3.9650791227878375,1,0,8.271388786108973,0 +0,0,3.7295560280577207,7.166710650141313,5.446573899572731,1,0,7.034752565554011,1 +0,0,7.388732429927314,2.9827358918988307,8.406188505945728,0,1,8.689080220015907,0 +0,0,8.006962561062874,3.067034598979179,1.2043046065958316,1,1,9.72546220119042,0 +0,0,3.6083679617950013,6.010258123573811,2.862944375907376,0,0,6.332708495256055,0 +0,0,7.004465049091021,1.2953616104893797,4.62699982268007,1,1,8.517032171427548,1 +0,0,3.8078212636795246,8.114346663327577,2.3011509111783988,1,0,6.777673442396677,0 +0,0,4.944348679198809,8.446425837854061,5.805057036232123,0,1,6.833634858475877,0 +0,0,8.13909914371656,6.689867299409372,7.112437671422457,0,1,8.237427178629378,0 +0,0,4.979490747753561,6.58783816515665,6.580398981917332,0,1,7.619361700011146,1 +0,0,8.528318306455906,3.069361980179994,3.860168533589858,1,1,9.367158418787225,0 +0,0,6.321067305432038,4.077523672909338,7.894202518255389,0,1,7.493808714217577,0 +0,0,4.169644422111446,8.235096289425588,1.462469608589925,1,1,7.290305216463268,0 +0,0,4.457375355900767,4.753217719349556,6.985009668699588,1,0,6.6798262291135995,1 +0,0,3.854655033515523,2.630485142544531,5.015227496004052,0,1,7.679973073327202,0 +0,0,4.387856382840367,5.623590655695557,7.8166580999621305,1,1,7.0843992693815805,1 +0,0,7.894482582399872,8.817860945154958,5.656839637471562,0,1,8.98127985041745,0 +0,0,5.398200042823513,6.472447302612663,4.160996034564034,1,0,7.095290880088593,0 +0,0,3.9299925334963346,7.378320014915384,2.213498217615762,1,1,6.83001448371422,0 +0,0,7.1157406668825685,2.153902124538826,2.2163831560507594,0,0,9.070286401291465,0 +0,0,3.541728758715812,6.945290241927995,2.8494699694099257,1,0,7.351327754423014,0 +0,0,8.418664937124742,8.016969640796258,6.17291835748897,1,0,9.362030994203879,1 +0,0,9.068819652632316,9.27746976230922,3.6759386722270824,1,0,9.186825657439906,1 +0,0,5.1412634212459984,7.773332130803549,7.6650257624730855,0,1,7.9465506969721496,0 +0,0,3.656017277628845,6.916802339694198,6.279135472025278,0,0,7.184372750668907,0 +0,0,8.71710742794296,4.484235152691303,2.1916260816185176,0,0,9.036777836157274,1 +0,0,5.7303172603894,4.882907453734691,1.4767974179004404,0,1,8.103886402199914,0 +0,0,5.0151396848695935,5.3117212777015945,6.272634304974829,0,1,7.665395219045523,0 +0,0,2.7304627176064686,8.738310177291392,6.512381571637316,0,0,6.2497899178532625,0 +0,0,6.000194409394423,7.363843582156503,4.935262056704689,1,1,8.046618219905893,1 +0,0,8.405084151250225,3.137105831031765,3.0788237538489494,1,0,8.906441726845626,0 +0,0,3.700804991975529,9.147958113862314,0.9166280092956501,1,0,7.040228371293574,1 +0,0,2.431243706310597,7.160664048700809,6.165028065631967,0,1,6.067872324054391,1 +0,0,2.126843572213349,5.665499438920464,0.8531348951664335,0,1,5.599305641295684,0 +0,0,0.7771429394479674,7.898742269700062,2.532435693066752,1,1,6.299468911168454,1 +0,0,1.1497572031833938,3.857249852736702,5.510867624092505,0,1,5.862989554164378,0 +0,0,7.4201124082983,7.679871756620718,7.2808454907032605,1,1,9.620156954522347,1 +0,0,9.266737274613789,8.266380999260761,7.919243689009598,1,0,9.833311454037931,1 +0,0,3.4928609464004583,3.569586166158329,3.436844236833925,1,1,6.925655367305305,1 +0,0,4.631952487209714,7.3161123388488205,8.197672987487186,1,1,7.853565283392347,0 +0,0,8.72248955452373,4.808992344921092,5.4159382626790356,1,1,9.551203993870491,1 +0,0,7.315116008668844,8.164499303365762,8.723462938252691,1,0,8.64695493358732,0 +0,0,2.7823532765282044,6.255782760404478,6.944966608083979,1,1,7.075217147928312,1 +0,0,8.106043372364617,9.116882550043288,5.769742396879479,0,0,8.859931393099464,0 +0,0,5.475486650290691,4.523352915865783,3.0323229300082994,1,0,8.642065126212108,1 +0,0,7.056861559538987,3.4777860837326995,6.473046145979152,0,0,9.005468957483945,0 +0,0,1.9698742154204385,7.180200396471539,7.0167369843634875,1,1,6.025283813652302,0 +0,0,4.8752053664187835,4.796856800171225,2.3417600800213227,1,0,6.991991900452571,1 +0,0,1.8471893877062802,3.382076049868186,4.70794371889021,0,1,6.075060647632719,0 +0,0,3.3430373989396394,5.1316104042088115,3.848444226417702,0,1,6.5670685144723935,1 +0,0,5.778401885095007,0.5150695288446585,4.240356078346891,1,1,8.06782064006898,1 +0,0,6.3865258237066875,0.8335771477490507,4.853136320397461,0,1,7.729846023734352,0 +0,0,7.732358689296773,3.6995817524031596,2.5239304263620603,1,1,8.286989850761891,1 +0,0,2.8808738042606645,5.153171463375221,4.785843092091883,1,1,5.628369659905883,1 +0,0,6.906474387763609,7.4977684099348245,5.2029912354712025,0,1,7.463357284387273,0 +0,0,3.026563544855879,1.9488007394084204,7.24857328161834,0,1,5.940700207389531,0 +0,0,5.320876061103953,6.594579931615943,7.443881064633588,0,0,7.466690828318081,0 +0,0,5.3248696098137245,3.3026806664699366,4.131087060456872,1,1,7.739900114008058,0 +0,0,6.218037717764129,9.007170939369193,2.7311330782536,0,1,8.296236330732269,0 +0,0,4.465925037184349,2.1835768805044005,1.7833756449526825,1,0,7.660812632870584,0 From 195ded1653bef12f99509fe99cce91fee3a7b374 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Mon, 14 Jul 2025 11:39:39 +1000 Subject: [PATCH 02/57] adds placebo related args for ermod_bin --- R/dev_ermod_lin.R | 18 +++++++++++++++++- R/ermod-class.R | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 89784f4..842ec69 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -11,6 +11,8 @@ #' @param var_resp Response variable name in character #' @param var_exposure Exposure variable names in character #' @param var_cov Covariate variable names in character vector +#' @param var_placebo Placebo group indicator variable in character +#' @param exclude_placebo Should placebo group be ignored when fitting the model? #' @param prior,prior_intercept,prior_aux See [rstanarm::stan_glm()] #' @param verbosity_level Verbosity level. 0: No output, 1: Display steps, #' 2: Display progress in each step, 3: Display MCMC sampling. @@ -38,6 +40,8 @@ dev_ermod_bin <- function( var_resp, var_exposure, var_cov = NULL, + var_placebo = NULL, + exclude_placebo = FALSE, prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), verbosity_level = 1, @@ -66,13 +70,23 @@ dev_ermod_bin <- function( paste(var_resp, "~", paste(var_full, collapse = " + ")) ) + # if user specifies a placebo group to be ignored in the model, + # drop the corresponding rows when passing data to stan (but + # retain all rows in the ermod object for future plotting) + if (!is.null(var_placebo) & exclude_placebo) { + keep <- !data[[var_placebo]] + stan_data <- data[keep, ] + } else { + stan_data <- data + } + # Need to construct call and then evaluate. Directly calling # rstanarm::stan_glm with formula_final does not work for the cross-validation call_stan_glm <- rlang::call2( rstanarm::stan_glm, formula = formula_final, family = stats::binomial(), - data = quote(data), + data = quote(stan_data), prior = prior, prior_intercept = prior_intercept, QR = dplyr::if_else(length(var_full) > 1, TRUE, FALSE), @@ -86,6 +100,8 @@ dev_ermod_bin <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, + var_placebo = var_placebo, + exclude_placebo = exclude_placebo, input_args = input_args ) } diff --git a/R/ermod-class.R b/R/ermod-class.R index 216121d..7f6c703 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -115,15 +115,20 @@ new_ermod_lin_cov_sel <- function( #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable #' @param var_cov Name of the covariate variable +#' @param var_placebo Name of the placebo indicator variable +#' @param exclude_placebo Logical: are placebo data are passed to the model new_ermod_bin <- function( mod, data, var_resp = character(), var_exposure = character(), var_cov = NULL, + var_placebo = character(), + exclude_placebo = FALSE, input_args = list()) { coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) + # TODO: var_placebo and exclude_placebo would need to be checked check_input_new_ermod( mod = mod, data = data, var_resp = var_resp, input_args = input_args, coef_exp_draws = coef_exp_draws, @@ -137,6 +142,7 @@ new_ermod_bin <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, + var_placebo = var_placebo, input_args = input_args, coef_exp_draws = coef_exp_draws, endpoint_type = "binary" From 7960af6a4f0ebc922be6f5504d372532ce7b46e0 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Mon, 14 Jul 2025 11:40:01 +1000 Subject: [PATCH 03/57] adds illustrative placebo script --- other/placebo-example.R | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 other/placebo-example.R diff --git a/other/placebo-example.R b/other/placebo-example.R new file mode 100644 index 0000000..40eb332 --- /dev/null +++ b/other/placebo-example.R @@ -0,0 +1,39 @@ +library(BayesERtools) + +# a data set that includes a placebo group +dat <- dplyr::bind_rows( + readr::read_csv("data-raw/d_sim_emax.csv"), # current emax data set in pacakge + readr::read_csv("other/d_sim_emax_placebo.csv") # placebo data from same model +) |> + dplyr::mutate(placebo = dose == 0) # represent the placebo group explicitly + +# scenario 1: nothing should change if the user doesn't specify placebo group +mod1 <- dat |> + dev_ermod_bin( + var_resp = "response_2", + var_exposure = "exposure" + ) + +mod1 |> + sim_er_curve(output_type = "median_qi") |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + + +# scenario 2: model should not pass placebo data to stan if user requests +mod2 <- dat |> + dev_ermod_bin( + var_resp = "response_2", + var_exposure = "exposure", + var_placebo = "placebo", + exclude_placebo = TRUE + ) + +mod2 |> + sim_er_curve(output_type = "median_qi") |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) From 3531749b0e4ddd9a334b4371020d82ba7779c546 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Sun, 27 Jul 2025 13:50:08 +1000 Subject: [PATCH 04/57] switches to options_placebo_handling arg --- R/dev_ermod_lin.R | 47 +++++++++++++++++++++++++++-------------- R/ermod-class.R | 38 ++++++++++++++++++++++++--------- other/placebo-example.R | 12 +++++++---- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 842ec69..fb06d32 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -11,8 +11,7 @@ #' @param var_resp Response variable name in character #' @param var_exposure Exposure variable names in character #' @param var_cov Covariate variable names in character vector -#' @param var_placebo Placebo group indicator variable in character -#' @param exclude_placebo Should placebo group be ignored when fitting the model? +#' @param options_placebo_handling List containing options for placebo handling #' @param prior,prior_intercept,prior_aux See [rstanarm::stan_glm()] #' @param verbosity_level Verbosity level. 0: No output, 1: Display steps, #' 2: Display progress in each step, 3: Display MCMC sampling. @@ -40,13 +39,13 @@ dev_ermod_bin <- function( var_resp, var_exposure, var_cov = NULL, - var_placebo = NULL, - exclude_placebo = FALSE, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), verbosity_level = 1, chains = 4, iter = 2000) { + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -54,6 +53,8 @@ dev_ermod_bin <- function( c("chains", "iter"), environment() ) + + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) check_data_columns( data = data, @@ -69,17 +70,9 @@ dev_ermod_bin <- function( stats::formula( paste(var_resp, "~", paste(var_full, collapse = " + ")) ) + + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) - # if user specifies a placebo group to be ignored in the model, - # drop the corresponding rows when passing data to stan (but - # retain all rows in the ermod object for future plotting) - if (!is.null(var_placebo) & exclude_placebo) { - keep <- !data[[var_placebo]] - stan_data <- data[keep, ] - } else { - stan_data <- data - } - # Need to construct call and then evaluate. Directly calling # rstanarm::stan_glm with formula_final does not work for the cross-validation call_stan_glm <- rlang::call2( @@ -100,8 +93,7 @@ dev_ermod_bin <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, - var_placebo = var_placebo, - exclude_placebo = exclude_placebo, + options_placebo_handling = options_placebo_handling, input_args = input_args ) } @@ -839,3 +831,26 @@ capture_selected_args <- function(arg_names, env) { .if_run_ex_covsel <- function() { requireNamespace("projpred", quietly = TRUE) } + +.apply_placebo_handling <- function(data, options, var_exposure = NULL) { + + # do nothing if user wants to retain placebo + if (options$include_placebo) return(data) + + # "none" method: no filtering, also do nothing + if (options$method == "none") return(data) + + # "var_placebo" method: filter rows using named column + if (options$method == "var_placebo") { + keep <- !data[[options$var_placebo]] + return(data[keep, ]) + } + + # "zero_exposure_as_placebo" method: drop zero-exposure rows + if (options$method == "zero_exposure_as_placebo") { + keep <- data[[var_exposure]] != 0 + return(data[keep, ]) + } + + stop("unknown placebo handling method", call. = FALSE) +} diff --git a/R/ermod-class.R b/R/ermod-class.R index 7f6c703..c619986 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -115,23 +115,27 @@ new_ermod_lin_cov_sel <- function( #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable #' @param var_cov Name of the covariate variable -#' @param var_placebo Name of the placebo indicator variable -#' @param exclude_placebo Logical: are placebo data are passed to the model +#' @param options_placebo_handling List specifying how placebo groups are handled new_ermod_bin <- function( mod, data, var_resp = character(), var_exposure = character(), var_cov = NULL, - var_placebo = character(), - exclude_placebo = FALSE, - input_args = list()) { + input_args = list(), + options_placebo_handling = list() + ) { + coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) - - # TODO: var_placebo and exclude_placebo would need to be checked + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, - input_args = input_args, coef_exp_draws = coef_exp_draws, + mod = mod, + data = data, + var_resp = var_resp, + input_args = input_args, + options_placebo_handling = options_placebo_handling, + coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -142,8 +146,8 @@ new_ermod_bin <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, - var_placebo = var_placebo, input_args = input_args, + options_placebo_handling = options_placebo_handling, coef_exp_draws = coef_exp_draws, endpoint_type = "binary" ), @@ -234,6 +238,7 @@ new_ermod_emax <- function( var_exposure = character(), l_var_cov = NULL, input_args = list()) { + check_input_new_ermod( mod = mod, data = data, var_resp = var_resp, var_exposure = var_exposure, l_var_cov = l_var_cov, basemodclass = "stanemax" @@ -323,6 +328,7 @@ new_ermod_bin_emax_exp_sel <- function(l_ermod_exp_sel) { # utils ----------------------------------------------------------------------- +# TODO: add checks for options_placebo_handling() check_input_new_ermod <- function( mod, data, @@ -337,6 +343,7 @@ check_input_new_ermod <- function( cvvs = NULL, rk = NULL, input_args = list(), + options_placebo_handling = list(), coef_exp_draws = NULL, basemodclass = "stanreg") { stopifnot(inherits(mod, basemodclass)) @@ -369,3 +376,14 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { .get_coef_exp_draws <- function(mod, var_exposure) { posterior::as_draws_df(mod)[[var_exposure]] } + +.apply_placebo_handling_defaults <- function(options) { + utils::modifyList( + list( + include_placebo = FALSE, + method = "zero_exposure_as_placebo", # alternatives: "var_placebo", "none" + var_placebo = NULL # if specified must be a string referring to a logical vector + ), + options + ) +} diff --git a/other/placebo-example.R b/other/placebo-example.R index 40eb332..b0999a0 100644 --- a/other/placebo-example.R +++ b/other/placebo-example.R @@ -7,7 +7,8 @@ dat <- dplyr::bind_rows( ) |> dplyr::mutate(placebo = dose == 0) # represent the placebo group explicitly -# scenario 1: nothing should change if the user doesn't specify placebo group +# scenario 1: default is to implicitly drop placebo, assuming that the placebo +# group maps onto the zero exposure rows mod1 <- dat |> dev_ermod_bin( var_resp = "response_2", @@ -22,13 +23,16 @@ mod1 |> ) -# scenario 2: model should not pass placebo data to stan if user requests +# scenario 2: model should n mod2 <- dat |> dev_ermod_bin( var_resp = "response_2", var_exposure = "exposure", - var_placebo = "placebo", - exclude_placebo = TRUE + options_placebo_handling = list( + include_placebo = TRUE, + method = "var_placebo", + var_placebo = "placebo" + ) ) mod2 |> From 3b0e0e90aedd28975bd3b7d75b59864465d66dfe Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Sun, 27 Jul 2025 14:06:41 +1000 Subject: [PATCH 05/57] expands documentation for options_placebo_handling --- R/dev_ermod_lin.R | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index fb06d32..9122c9a 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -11,7 +11,22 @@ #' @param var_resp Response variable name in character #' @param var_exposure Exposure variable names in character #' @param var_cov Covariate variable names in character vector -#' @param options_placebo_handling List containing options for placebo handling +#' @param options_placebo_handling List of for placebo handling. +#' Possible options include: +#' - `include_placebo`: Logical, whether the placebo group should be +#' used when estimating the model. Default is observed data. Default +#' is `FALSE`. +#' - `method`: Character, specifying the method used to detect placebo +#' group samples. Possible values include `"zero_exposure_as_placebo"` +#' (the default), in which rows with zero values for the exposure +#' variable are automatically assigned to a placebo group, +#' `"var_placebo"`, indicating that the user will supply the name of +#' a data column specifying the placebo group, and `"none"`, in which +#' case no placebo handling takes place. +#' - `var_placebo`: Character, specifying the name of a column in the +#' data set that indicates which rows belong to the placebo group. This +#' column is interpreted as a logical vector. This value is ignored +#' unless `method = "var_placebo"`. #' @param prior,prior_intercept,prior_aux See [rstanarm::stan_glm()] #' @param verbosity_level Verbosity level. 0: No output, 1: Display steps, #' 2: Display progress in each step, 3: Display MCMC sampling. From 33a95de8280eef6cdc5e58ce0b24cce363a1dbf8 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Tue, 26 Aug 2025 18:38:11 +1000 Subject: [PATCH 06/57] adds placebo handling arguments to ermod classes and dev functions for linear models --- R/dev_ermod_lin.R | 41 ++++++++++++++++++-- R/ermod-class.R | 95 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 112 insertions(+), 24 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 9122c9a..d48d4a6 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -145,18 +145,23 @@ dev_ermod_bin_exp_sel <- function( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), verbosity_level = 1, chains = 4, iter = 2000) { + + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + fun_dev_ermod <- purrr::partial( dev_ermod_bin, + options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept ) - + l_out <- .dev_ermod_exp_sel( data = data, @@ -218,6 +223,7 @@ dev_ermod_bin_cov_sel <- function( var_resp, var_exposure, var_cov_candidates, + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), k = 5, validate_search = FALSE, @@ -228,9 +234,13 @@ dev_ermod_bin_cov_sel <- function( verbosity_level = 1, chains = 4, iter = 2000) { + + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + fun_dev_ermod <- purrr::partial( dev_ermod_bin, + options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept ) @@ -292,12 +302,14 @@ dev_ermod_lin <- function( var_resp, var_exposure, var_cov = NULL, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE), verbosity_level = 1, chains = 4, iter = 2000) { + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -306,6 +318,8 @@ dev_ermod_lin <- function( environment() ) + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + check_data_columns( data = data, var_exposure = var_exposure, @@ -320,10 +334,12 @@ dev_ermod_lin <- function( paste(var_resp, "~", paste(var_full, collapse = " + ")) ) + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) + mod <- rstanarm::stan_glm( formula_final, family = stats::gaussian(), - data = data, + data = stan_data, prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux, @@ -339,6 +355,7 @@ dev_ermod_lin <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, + options_placebo_handling = options_placebo_handling, input_args = input_args ) } @@ -363,15 +380,20 @@ dev_ermod_lin_exp_sel <- function( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE), verbosity_level = 1, chains = 4, iter = 2000) { + + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + fun_dev_ermod <- purrr::partial( dev_ermod_lin, + options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux @@ -413,6 +435,7 @@ dev_ermod_lin_cov_sel <- function( var_resp, var_exposure, var_cov_candidates, + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), k = 5, validate_search = FALSE, @@ -424,9 +447,13 @@ dev_ermod_lin_cov_sel <- function( verbosity_level = 1, chains = 4, iter = 2000) { + + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + fun_dev_ermod <- purrr::partial( dev_ermod_lin, + options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux @@ -470,9 +497,14 @@ dev_ermod_lin_cov_sel <- function( # Internal functions ---------------------------------------------------------- .dev_ermod_exp_sel <- function( - data, var_resp, var_exp_candidates, - verbosity_level = 1, chains = 4, iter = 2000, + data, + var_resp, + var_exp_candidates, + verbosity_level = 1, + chains = 4, + iter = 2000, fun_dev_ermod) { + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) verbose <- dplyr::if_else(verbosity_level == 2, TRUE, FALSE) @@ -552,6 +584,7 @@ dev_ermod_lin_cov_sel <- function( prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE)) { + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) rlang::check_installed("projpred") diff --git a/R/ermod-class.R b/R/ermod-class.R index c619986..ddada32 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -9,19 +9,29 @@ #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable #' @param var_cov Name of the covariate variable +#' @param input_args Captured inputs +#' @param options_placebo_handling List specifying how placebo groups are handled new_ermod_lin <- function( mod, data, var_resp = character(), var_exposure = character(), var_cov = NULL, - input_args = list()) { + input_args = list(), + options_placebo_handling = list()) { + coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, - var_exposure = var_exposure, var_cov = var_cov, - input_args = input_args, coef_exp_draws = coef_exp_draws, + mod = mod, + data = data, + var_resp = var_resp, + var_exposure = var_exposure, + var_cov = var_cov, + input_args = input_args, + options_placebo_handling = options_placebo_handling, + coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -33,6 +43,7 @@ new_ermod_lin <- function( var_exposure = var_exposure, var_cov = var_cov, input_args = input_args, + options_placebo_handling = options_placebo_handling, coef_exp_draws = coef_exp_draws, endpoint_type = "continuous" ), @@ -69,18 +80,28 @@ new_ermod_lin_cov_sel <- function( var_cov_candidates = character(), var_cov = NULL, var_selected = character(), + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), cvvs = NULL, rk = NULL, input_args = list()) { + cv_method <- match.arg(cv_method) coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, var_exposure = var_exposure, - var_cov_candidates = var_cov_candidates, var_cov = var_cov, - var_selected = var_selected, cvvs = cvvs, rk = rk, - input_args = input_args, coef_exp_draws = coef_exp_draws, + mod = mod, + data = data, + var_resp = var_resp, + var_exposure = var_exposure, + var_cov_candidates = var_cov_candidates, + var_cov = var_cov, + var_selected = var_selected, + options_placebo_handling = options_placebo_handling, + cvvs = cvvs, + rk = rk, + input_args = input_args, + coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -93,6 +114,7 @@ new_ermod_lin_cov_sel <- function( var_cov_candidates = var_cov_candidates, var_cov = var_cov, var_selected = var_selected, + options_placebo_handling = options_placebo_handling, cv_method = cv_method, cvvs = cvvs, rk = rk, @@ -115,6 +137,7 @@ new_ermod_lin_cov_sel <- function( #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable #' @param var_cov Name of the covariate variable +#' @param input_args Captured inputs #' @param options_placebo_handling List specifying how placebo groups are handled new_ermod_bin <- function( mod, @@ -184,19 +207,28 @@ new_ermod_bin_cov_sel <- function( var_cov_candidates = character(), var_cov = NULL, var_selected = character(), + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), cvvs = NULL, rk = NULL, input_args = list()) { + cv_method <- match.arg(cv_method) - coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, var_exposure = var_exposure, - var_cov_candidates = var_cov_candidates, var_cov = var_cov, - var_selected = var_selected, cvvs = cvvs, rk = rk, - input_args = input_args, coef_exp_draws = coef_exp_draws, + mod = mod, + data = data, + var_resp = var_resp, + var_exposure = var_exposure, + var_cov_candidates = var_cov_candidates, + var_cov = var_cov, + var_selected = var_selected, + options_placebo_handling = list(), + cvvs = cvvs, + rk = rk, + input_args = input_args, + coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -209,6 +241,7 @@ new_ermod_bin_cov_sel <- function( var_cov_candidates = var_cov_candidates, var_cov = var_cov, var_selected = var_selected, + options_placebo_handling = options_placebo_handling, cv_method = cv_method, cvvs = cvvs, rk = rk, @@ -230,18 +263,25 @@ new_ermod_bin_cov_sel <- function( #' @param data Data frame used to fit the model #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable +#' @param options_placebo_handling List specifying how placebo groups are handled #' @param l_var_cov List of the covariate variables new_ermod_emax <- function( mod, data, var_resp = character(), var_exposure = character(), + options_placebo_handling = list(), l_var_cov = NULL, input_args = list()) { check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, var_exposure = var_exposure, - l_var_cov = l_var_cov, basemodclass = "stanemax" + mod = mod, + data = data, + var_resp = var_resp, + var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, + l_var_cov = l_var_cov, + basemodclass = "stanemax" ) structure( @@ -250,6 +290,7 @@ new_ermod_emax <- function( data = data, var_resp = var_resp, var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, l_var_cov = l_var_cov, input_args = input_args, endpoint_type = "continuous" @@ -282,17 +323,25 @@ new_ermod_emax_exp_sel <- function(l_ermod_exp_sel) { #' @param data Data frame used to fit the model #' @param var_resp Name of the response variable #' @param var_exposure Name of the exposure variable +#' @param options_placebo_handling List specifying how placebo groups are handled #' @param l_var_cov List of the covariate variables new_ermod_bin_emax <- function( mod, data, var_resp = character(), var_exposure = character(), + options_placebo_handling = list(), l_var_cov = NULL, input_args = list()) { + check_input_new_ermod( - mod = mod, data = data, var_resp = var_resp, var_exposure = var_exposure, - l_var_cov = l_var_cov, basemodclass = "stanemaxbin" + mod = mod, + data = data, + var_resp = var_resp, + var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, + l_var_cov = l_var_cov, + basemodclass = "stanemaxbin" ) structure( @@ -301,6 +350,7 @@ new_ermod_bin_emax <- function( data = data, var_resp = var_resp, var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, l_var_cov = l_var_cov, input_args = input_args, endpoint_type = "binary" @@ -346,6 +396,7 @@ check_input_new_ermod <- function( options_placebo_handling = list(), coef_exp_draws = NULL, basemodclass = "stanreg") { + stopifnot(inherits(mod, basemodclass)) stopifnot(is.data.frame(data)) stopifnot(is.character(var_resp)) @@ -367,9 +418,13 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { ll <- l_ermod_exp_sel check_input_new_ermod( - mod = ll$mod, data = ll$data, var_resp = ll$var_resp, - var_exp_candidates = ll$var_exp_candidates, var_exposure = ll$var_exposure, - l_mod_exposures = ll$l_mod_exposures, basemodclass = basemodclass + mod = ll$mod, + data = ll$data, + var_resp = ll$var_resp, + var_exp_candidates = ll$var_exp_candidates, + var_exposure = ll$var_exposure, + l_mod_exposures = ll$l_mod_exposures, + basemodclass = basemodclass ) } From 69a4d803425b5b05a5189b68e0a7ca72ca9d90d7 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Tue, 26 Aug 2025 18:38:37 +1000 Subject: [PATCH 07/57] roxygenise --- man/dev_ermod_bin.Rd | 21 +++++++++++++++++++++ man/dev_ermod_bin_cov_sel.Rd | 21 +++++++++++++++++++++ man/dev_ermod_bin_exp_sel.Rd | 21 +++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/man/dev_ermod_bin.Rd b/man/dev_ermod_bin.Rd index c77f209..8dc7c5b 100644 --- a/man/dev_ermod_bin.Rd +++ b/man/dev_ermod_bin.Rd @@ -10,6 +10,7 @@ dev_ermod_bin( var_resp, var_exposure, var_cov = NULL, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), verbosity_level = 1, @@ -22,6 +23,7 @@ dev_ermod_lin( var_resp, var_exposure, var_cov = NULL, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE), @@ -39,6 +41,25 @@ dev_ermod_lin( \item{var_cov}{Covariate variable names in character vector} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{prior, prior_intercept, prior_aux}{See \code{\link[rstanarm:stan_glm]{rstanarm::stan_glm()}}} \item{verbosity_level}{Verbosity level. 0: No output, 1: Display steps, diff --git a/man/dev_ermod_bin_cov_sel.Rd b/man/dev_ermod_bin_cov_sel.Rd index 634f0f6..2088d8e 100644 --- a/man/dev_ermod_bin_cov_sel.Rd +++ b/man/dev_ermod_bin_cov_sel.Rd @@ -10,6 +10,7 @@ dev_ermod_bin_cov_sel( var_resp, var_exposure, var_cov_candidates, + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), k = 5, validate_search = FALSE, @@ -27,6 +28,7 @@ dev_ermod_lin_cov_sel( var_resp, var_exposure, var_cov_candidates, + options_placebo_handling = list(), cv_method = c("LOO", "kfold"), k = 5, validate_search = FALSE, @@ -49,6 +51,25 @@ dev_ermod_lin_cov_sel( \item{var_cov_candidates}{Candidate covariate names in character vector} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{cv_method}{Cross-validation method. Default is "LOO" (recommended). Use "kfold" if you see warnings on Pareto k estimates.} diff --git a/man/dev_ermod_bin_exp_sel.Rd b/man/dev_ermod_bin_exp_sel.Rd index 9c9f6b5..2aac225 100644 --- a/man/dev_ermod_bin_exp_sel.Rd +++ b/man/dev_ermod_bin_exp_sel.Rd @@ -9,6 +9,7 @@ dev_ermod_bin_exp_sel( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), verbosity_level = 1, @@ -20,6 +21,7 @@ dev_ermod_lin_exp_sel( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE), @@ -36,6 +38,25 @@ dev_ermod_lin_exp_sel( \item{var_exp_candidates}{Candidate exposure variable names in character vector} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{prior, prior_intercept, prior_aux}{See \code{\link[rstanarm:stan_glm]{rstanarm::stan_glm()}}} \item{verbosity_level}{Verbosity level. 0: No output, 1: Display steps, From 56da0eec2a08ce89b6d1fac9398a2ff0a2c483d8 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Tue, 26 Aug 2025 19:23:53 +1000 Subject: [PATCH 08/57] emax mod class and dev function take placebo handling argument --- R/dev_ermod_emax.R | 28 +++++++++++++++++++++++++--- man/dev_ermod_emax.Rd | 21 +++++++++++++++++++++ man/dev_ermod_emax_exp_sel.Rd | 21 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index cfc5def..5d84800 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -54,6 +54,7 @@ dev_ermod_emax <- function( data, var_resp, var_exposure, + options_placebo_handling = list(), l_var_cov = NULL, gamma_fix = 1, e0_fix = NULL, @@ -63,6 +64,7 @@ dev_ermod_emax <- function( chains = 4, iter = 2000, seed = sample.int(.Machine$integer.max, 1)) { + input_args <- capture_selected_args( c( "gamma_fix", "e0_fix", "emax_fix", @@ -71,6 +73,8 @@ dev_ermod_emax <- function( environment() ) + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -78,15 +82,18 @@ dev_ermod_emax <- function( data = data, var_exposure = var_exposure, var_resp = var_resp, - var_cov = unlist(l_var_cov) + var_cov = unlist(l_var_cov), + options_placebo_handling = options_placebo_handling ) formula <- stats::formula(paste(var_resp, "~", var_exposure)) + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) + mod <- rstanemax::stan_emax( formula, - data = data, + data = stan_data, gamma.fix = gamma_fix, e0.fix = e0_fix, emax.fix = emax_fix, @@ -103,6 +110,7 @@ dev_ermod_emax <- function( data = data, var_resp = var_resp, var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, l_var_cov = l_var_cov, input_args = input_args ) @@ -142,6 +150,7 @@ dev_ermod_emax_exp_sel <- function( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), verbosity_level = 1, chains = 4, iter = 2000, @@ -150,9 +159,11 @@ dev_ermod_emax_exp_sel <- function( emax_fix = NULL, priors = NULL, seed = sample.int(.Machine$integer.max, 1)) { + fun_dev_ermod <- purrr::partial( dev_ermod_emax, + options_placebo_handling = options_placebo_handling, gamma_fix = gamma_fix, e0_fix = e0_fix, emax_fix = emax_fix, @@ -204,6 +215,7 @@ dev_ermod_bin_emax <- function( data, var_resp, var_exposure, + options_placebo_handling = list(), l_var_cov = NULL, gamma_fix = 1, e0_fix = NULL, @@ -213,6 +225,7 @@ dev_ermod_bin_emax <- function( chains = 4, iter = 2000, seed = sample.int(.Machine$integer.max, 1)) { + # Warn when e0_fix is set if (!is.null(e0_fix) && e0_fix == 0) { warning( @@ -249,6 +262,8 @@ dev_ermod_bin_emax <- function( environment() ) + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -257,15 +272,18 @@ dev_ermod_bin_emax <- function( var_exposure = var_exposure, var_resp = var_resp, var_cov = unlist(l_var_cov), + options_placebo_handling = options_placebo_handling, is_binary = TRUE ) formula <- stats::formula(paste(var_resp, "~", var_exposure)) + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) + mod <- rstanemax::stan_emax_binary( formula, - data = data, + data = stan_data, gamma.fix = gamma_fix, e0.fix = e0_fix, emax.fix = emax_fix, @@ -282,6 +300,7 @@ dev_ermod_bin_emax <- function( data = data, var_resp = var_resp, var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, l_var_cov = l_var_cov, input_args = input_args ) @@ -311,6 +330,7 @@ dev_ermod_bin_emax_exp_sel <- function( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), verbosity_level = 1, chains = 4, iter = 2000, @@ -319,9 +339,11 @@ dev_ermod_bin_emax_exp_sel <- function( emax_fix = NULL, priors = NULL, seed = sample.int(.Machine$integer.max, 1)) { + fun_dev_ermod <- purrr::partial( dev_ermod_bin_emax, + options_placebo_handling = options_placebo_handling, gamma_fix = gamma_fix, e0_fix = e0_fix, emax_fix = emax_fix, diff --git a/man/dev_ermod_emax.Rd b/man/dev_ermod_emax.Rd index 431b992..29eaf59 100644 --- a/man/dev_ermod_emax.Rd +++ b/man/dev_ermod_emax.Rd @@ -9,6 +9,7 @@ dev_ermod_emax( data, var_resp, var_exposure, + options_placebo_handling = list(), l_var_cov = NULL, gamma_fix = 1, e0_fix = NULL, @@ -24,6 +25,7 @@ dev_ermod_bin_emax( data, var_resp, var_exposure, + options_placebo_handling = list(), l_var_cov = NULL, gamma_fix = 1, e0_fix = NULL, @@ -42,6 +44,25 @@ dev_ermod_bin_emax( \item{var_exposure}{Exposure variable names in character} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{l_var_cov}{a names list of categorical covariate variables in character vector. See details in the \code{param.cov} argument of \code{\link[rstanemax:stan_emax]{rstanemax::stan_emax()}} or \code{\link[rstanemax:stan_emax_binary]{rstanemax::stan_emax_binary()}}} diff --git a/man/dev_ermod_emax_exp_sel.Rd b/man/dev_ermod_emax_exp_sel.Rd index 1a39599..bf718fd 100644 --- a/man/dev_ermod_emax_exp_sel.Rd +++ b/man/dev_ermod_emax_exp_sel.Rd @@ -9,6 +9,7 @@ dev_ermod_emax_exp_sel( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), verbosity_level = 1, chains = 4, iter = 2000, @@ -23,6 +24,7 @@ dev_ermod_bin_emax_exp_sel( data, var_resp, var_exp_candidates, + options_placebo_handling = list(), verbosity_level = 1, chains = 4, iter = 2000, @@ -41,6 +43,25 @@ dev_ermod_bin_emax_exp_sel( \item{var_exp_candidates}{Candidate exposure variable names in character vector} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{verbosity_level}{Verbosity level. 0: No output, 1: Display steps, 2: Display progress in each step, 3: Display MCMC sampling.} From 043dc5601985c1c28c702a972a5f02056e2ac201 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 29 Aug 2025 13:17:19 +1000 Subject: [PATCH 09/57] update print_coveff test --- tests/testthat/test-coveff.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-coveff.R b/tests/testthat/test-coveff.R index fccf02b..5f8c78e 100644 --- a/tests/testthat/test-coveff.R +++ b/tests/testthat/test-coveff.R @@ -121,7 +121,7 @@ if (.if_run_ex_coveff()) { expect_equal( table_coveff_lin$`Response difference`, c( - "−20.5", "0", "20.5", "0", "−4.04", "−8.50", "0", "8.34" + "−20.6", "0", "20.6", "0", "−3.95", "−8.46", "0", "8.30" ) ) }) From c6e5d6a8afad9554c9f59ab67b84a7560d25cf81 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 29 Aug 2025 13:35:39 +1000 Subject: [PATCH 10/57] removes incorrect check on placebo option --- R/dev_ermod_emax.R | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index 5d84800..ab7b447 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -82,8 +82,7 @@ dev_ermod_emax <- function( data = data, var_exposure = var_exposure, var_resp = var_resp, - var_cov = unlist(l_var_cov), - options_placebo_handling = options_placebo_handling + var_cov = unlist(l_var_cov) ) formula <- @@ -272,7 +271,6 @@ dev_ermod_bin_emax <- function( var_exposure = var_exposure, var_resp = var_resp, var_cov = unlist(l_var_cov), - options_placebo_handling = options_placebo_handling, is_binary = TRUE ) From d40891d148bf50e97bb8ed7e8532f68603f52547 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 29 Aug 2025 13:35:50 +1000 Subject: [PATCH 11/57] temporary test skip --- tests/testthat/test-loo_kfold.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testthat/test-loo_kfold.R b/tests/testthat/test-loo_kfold.R index 4f57450..2316a49 100644 --- a/tests/testthat/test-loo_kfold.R +++ b/tests/testthat/test-loo_kfold.R @@ -80,6 +80,9 @@ if (.if_run_ex_eval_mod()) { # Test ---------------------------------------------------------------------- test_that("loo", { + + skip("temporarily disable loo test") + loo_ermod_bin <- loo(ermod_bin) loo_ermod_emax_w_cov <- suppressWarnings(loo(ermod_emax_w_cov)) loo_ermod_bin_emax <- loo(ermod_bin_emax) @@ -103,6 +106,9 @@ if (.if_run_ex_eval_mod()) { }) test_that("kfold", { + + skip("temporarily disable kfold test") + expect_gt(comp[[2, 1]], -0.5) expect_equal( kfold_ermod_bin$estimates[, 1], From 37c3d91ae25968e3aad0a11208cc2ec5a7333b30 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 11:08:03 +1000 Subject: [PATCH 12/57] adds placebo group to the emax data --- data-raw/d_sim_emax.R | 5 +- data-raw/d_sim_emax.csv | 700 +++++++++++++++++++++++----------------- data/d_sim_emax.rda | Bin 12512 -> 15640 bytes 3 files changed, 403 insertions(+), 302 deletions(-) diff --git a/data-raw/d_sim_emax.R b/data-raw/d_sim_emax.R index ff2767f..dc1f533 100644 --- a/data-raw/d_sim_emax.R +++ b/data-raw/d_sim_emax.R @@ -59,7 +59,7 @@ simulate_data <- function(seed = 123) { make_dose_data <- function(dose, n, par) { tibble::tibble( dose = dose, - exposure = generate_exposure(max(dose, .01), n = n), + exposure = generate_exposure(dose, n = n), # add continuous and binary covariates cnt_a = continuous_covariate(n = n), @@ -102,8 +102,9 @@ simulate_data <- function(seed = 123) { dplyr::select(-bin_pred, -bin_prob) # remove intermediate variables } - # create data set assuming three dosing groups + # create data set assuming three dosing groups and placebo dat <- dplyr::bind_rows( + make_dose_data(dose = 0, n = 100, par = par), make_dose_data(dose = 100, n = 100, par = par), make_dose_data(dose = 200, n = 100, par = par), make_dose_data(dose = 300, n = 100, par = par) diff --git a/data-raw/d_sim_emax.csv b/data-raw/d_sim_emax.csv index 133d389..0abd7f9 100644 --- a/data-raw/d_sim_emax.csv +++ b/data-raw/d_sim_emax.csv @@ -1,301 +1,401 @@ dose,exposure,response_1,response_2,cnt_a,cnt_b,cnt_c,bin_d,bin_e -100,4151.151667179985,12.801048208794716,1,5.7118182538981035,2.331889533141997,7.831692190211973,0,1 -100,8067.255814055288,14.580964704457022,1,4.919475027306991,4.663321699049897,6.736228833251078,1,1 -100,4877.670561270752,12.759616379819523,1,4.879078118623973,4.212790522479133,4.679678561997343,1,1 -100,9712.927413188414,16.553626457579277,1,8.422660289429919,6.55754402063303,1.2863606477552603,0,1 -100,11490.740355578493,14.40500956600399,0,4.3650796126345455,3.9582148934550783,3.554226571334798,0,1 -100,2451.5495569450463,12.596613052845976,1,8.68613506754053,7.595489431737389,3.638255369559842,0,0 -100,5651.736724774641,14.768108564906203,1,6.61487033671654,3.952325847405934,5.133002254197158,0,0 -100,9939.23292683402,15.175382479024572,1,5.349061674450915,7.768908985600291,8.291267427930208,0,1 -100,5816.850066202131,14.591223483790275,0,5.6074382527727495,2.239051110003308,9.603130421338324,0,1 -100,5175.964861258692,13.704149483174687,1,6.061574235451451,1.7883542502918455,8.737906764586185,0,1 -100,12291.089758428909,14.909524340080445,1,3.604705760426211,9.947833220078346,4.624791492313548,0,1 -100,5155.022947598127,13.651708772292174,1,4.066370907314752,3.836474930158519,0.9479016704071886,1,0 -100,6841.002793415447,12.323823702221034,0,2.3085206629451775,5.836746443519315,3.913335344787947,1,1 -100,5972.140571711047,11.421524964571125,0,2.1883508498157287,6.751428137824397,5.251527659398115,0,0 -100,2963.727098503042,12.062000647540268,0,5.851453827174215,3.6546906417684255,7.279915212248259,0,1 -100,10130.698882143437,15.186736433550566,1,6.248946755764191,6.4343604653319755,7.561752057655783,0,0 -100,3904.002699225606,12.589861580968245,0,5.149496690816861,6.032229989181176,6.87533701803964,1,1 -100,2412.9210868284126,13.352069558459243,1,7.466648489695158,4.394131091899446,1.527715426423224,1,1 -100,4390.03692383188,14.76767222227337,1,9.396607279468206,5.184140720120146,7.2912576705315155,0,0 -100,12162.724824490264,14.529234545818587,1,3.6351248964732434,4.903904831455794,3.755544692732871,0,1 -100,9868.041433029815,12.194552846512277,0,0.3854486118994365,9.470488873582738,5.492196282433816,1,1 -100,6985.588811804739,15.200115619342231,1,7.662048360358453,2.9787789954421093,5.210234205415462,1,1 -100,6511.496692682876,12.88201743710806,0,3.0606916825784127,5.106589921030279,6.194388338744096,0,0 -100,16030.158841848192,15.22468257090902,1,3.1151277592739044,5.870728665027908,5.069604305128964,1,0 -100,6643.097829476301,15.156078623643086,1,7.707447406309846,6.2171579903474505,7.008933463280042,1,1 -100,7141.3778725146185,13.866511393422238,0,4.200620885889098,3.7234796082647232,6.079110269281988,0,1 -100,5764.077040497287,12.2271197897739,1,1.86867827817389,2.207265210424865,4.2538171865405925,1,1 -100,6135.521360518691,14.266084834329064,1,5.510428946836155,8.217739224212957,5.33299767577077,0,1 -100,4160.5251098171,12.115483682920935,0,4.608652628296863,4.02097165691434,5.377704450488606,0,0 -100,3280.7173485078747,12.827606683231902,0,5.016260425078036,2.6700084694627915,5.621638371030827,1,1 -100,12662.734795782948,15.447486547058256,1,6.077062479430111,4.335723324364887,8.885370219399134,0,1 -100,10197.565497520736,14.111276641686631,1,3.963106314316518,4.44508762676838,4.383867474338036,0,1 -100,6965.320395773617,15.440059361708888,0,6.771796908000768,7.895878207562873,5.4732923005963965,1,1 -100,8165.0210049183725,14.548851786590877,1,4.379851633068588,5.238935506370299,8.021877066128875,1,0 -100,2193.974805292514,10.961959872409814,0,5.929689048492463,7.053421125180893,7.772214756108311,1,0 -100,5312.8548078354415,14.201906452298376,1,7.867160640853731,3.6128653184311132,7.972511578275215,1,0 -100,7689.495504280548,14.005836593688668,1,6.213503542148596,5.60325293462034,3.404042379611012,0,1 -100,3724.0838116944124,11.955560592737227,1,4.086489418052165,4.089935603971496,9.34814287428454,1,1 -100,4332.321386728388,14.271897081919453,1,7.980119199989259,5.266670623347122,5.18810898018986,1,0 -100,3816.7947983761287,13.881790968287081,0,7.633841063997927,2.597763370896309,9.19455593970929,0,1 -100,3251.375555091962,13.019236025415342,1,6.518703900799501,1.6879816675797454,1.6107718165359886,1,1 -100,4911.963094056122,13.046266178993584,1,5.67112306006591,9.342607679520592,5.059192055690255,1,0 -100,4906.893178143231,11.647858360782273,0,3.2712228183727996,6.657355351681319,8.19096862138861,0,1 -100,4634.05232586616,15.0844204025963,1,8.407693364068619,1.8062845834502341,3.0452330849131855,1,1 -100,3316.609148667041,11.580431417066173,0,3.3438282609126286,3.3151279514916165,2.9500285270149664,0,1 -100,3223.952636121491,13.064859220623632,1,8.713154707308803,9.530794498671527,2.494727353474394,1,1 -100,3825.321883738831,12.009485804115885,1,4.337340696294668,8.3151598291108,2.231536982108955,0,1 -100,5236.008792885709,11.366459565519905,1,2.290617044552199,4.255227863865191,3.781110248838436,1,1 -100,4022.8699293991335,10.507679494353885,0,3.057604138550052,6.5048262145977995,5.928022604062216,1,1 -100,9180.420723057681,14.901133736314945,1,5.721756322894736,3.843353277081516,5.596357122618091,1,1 -100,2454.52681132072,10.916524391683165,1,4.306662489636756,3.6750485047242183,8.164048170942932,0,1 -100,5084.425486922404,12.561568050657346,0,4.026785976794121,2.859747442471744,9.384136933581672,0,1 -100,8213.329837275429,13.064897792127422,0,2.463863258060802,3.358705389477543,8.293185904182378,0,1 -100,3104.784164860843,12.247720779203908,0,4.872994734282217,8.900582353371462,7.060294015893987,0,1 -100,5885.878587255624,12.491121566547484,0,2.8689966820760624,4.847616458270171,0.9891378149704455,0,0 -100,3663.2674024320077,10.009062324139935,0,1.0739717499346388,5.336094862461806,3.340542646361642,0,1 -100,3145.0818384745266,11.002750684561988,1,3.9368133844428,5.684954810605893,4.01436413941897,1,0 -100,7628.554381736593,15.223717034825354,1,7.458853827432172,8.155465805731481,6.924758203920312,1,1 -100,10005.70497757912,14.003860476679321,1,3.4096620672871,3.567781482168498,4.702108291584847,1,1 -100,4667.834827105005,13.203624565920846,1,6.676454688442828,2.368463526508572,1.7913882312063083,1,1 -100,6726.956837673853,11.75385093230378,1,1.1498574658087628,8.937483791078602,8.950295974620941,0,0 -100,2900.6583716205446,12.108731203953297,0,4.843291877321143,3.770213591451922,7.44069103341229,0,1 -100,4725.220975477769,13.582042814591425,1,6.44118794564693,3.02525423623661,5.667489562991372,1,1 -100,4072.8896044022904,12.618366795477316,1,5.844864897522034,1.836772334277975,8.125941885183199,0,0 -100,8442.900213452154,14.296295487364832,1,5.297905392095343,1.7392847852757576,1.6339101370821265,1,1 -100,5124.385911019433,12.792355008604545,0,3.2377748040270617,3.4133025300781754,6.814565947210721,0,1 -100,8374.282410163598,13.396807442799672,0,2.708592276596476,6.70278061728451,3.5494149774296235,0,0 -100,8408.960005469966,13.542781196369111,1,2.295841048528449,7.895720292986464,6.873882591265058,1,0 -100,8149.460238444679,14.443019922607967,1,5.331596650065819,6.935178060436716,4.828462897504693,1,1 -100,5069.499812053769,12.0315628225529,0,2.4736236516343975,3.9823751404750323,6.741998475444482,1,1 -100,7642.263137513102,13.10321465597247,0,3.636402445415764,5.1685150222288945,8.359845276233736,1,1 -100,6416.6374318918615,13.602899437601632,0,4.280449760548192,3.072490942913965,5.02056493147758,0,1 -100,7158.155600487524,15.745104847484075,1,9.166186936740194,3.0401829165007643,7.689154457290752,0,1 -100,1725.353467064743,8.907490349544462,0,3.2084826277456076,7.376402078240974,1.9358130482650757,0,0 -100,5296.673281963084,13.592273661072019,1,5.661783084376143,2.3153442251303264,3.028982987246704,1,1 -100,3746.795142067277,13.419421310242827,0,5.219842511230999,9.297344462554067,8.690758328514333,1,1 -100,4700.1172917671865,12.022728450006278,1,2.439820890273393,4.745339037970463,6.055388758518544,0,0 -100,6282.364635390301,14.091923705879804,1,4.798905539326781,5.603514564621188,0.6012804192296205,1,0 -100,4532.01710261365,14.771980089895836,1,8.561550734038173,2.985906427671349,1.5859239845676845,1,1 -100,3025.8593143424923,12.131415844143508,1,6.25789639838503,3.412201885253288,4.434990961782319,1,1 -100,3889.1709863264864,12.386790311185404,0,5.116303936114074,1.6758840872248122,7.330640203272737,1,1 -100,6753.559309894723,13.054216401521177,1,3.821078200980879,4.4850233372526755,4.712773364508995,1,0 -100,4931.11310482688,10.587060152660985,0,0.6002701880216281,6.169328031881751,6.719039769004755,1,0 -100,8065.787162255762,16.008166925341868,1,7.942484085552649,5.909008628253317,7.553493698877518,1,1 -100,2963.265961519032,9.361881246683847,0,1.4099877514239743,2.877429329556436,8.930636220129895,1,0 -100,5038.47294010054,14.516505552435339,1,7.017697637314545,2.8596996096972966,5.157990287469736,1,1 -100,14579.440242398832,17.901613530148428,1,9.244909354681717,3.605041399149745,4.853385781119949,1,1 -100,9955.093141276631,12.254161743245163,0,1.4396198728914003,8.651472668956238,0.9523967453693967,0,1 -100,9793.997733256598,15.880081474124204,1,6.920294927893139,2.0446240867431293,5.280030511415713,1,0 -100,3464.8902456604083,12.988414416145531,1,4.263437574345913,4.495886018469261,3.41893293537652,1,0 -100,3167.4469055083696,9.751668350052128,0,1.222127713009047,9.23702888417423,2.4114157094508424,0,0 -100,6620.222528703428,12.314505087994307,0,1.316904779782032,4.7153309924433255,4.493489246332375,0,1 -100,4482.672183131137,10.48108620675104,0,1.1753646679091903,3.1751900838248073,7.683168998292205,1,1 -100,6652.382647207845,13.564331477350446,0,3.528008455169637,6.349843427422446,3.80803161169825,0,1 -100,4345.305693646351,13.774116352152133,1,6.8846356118338825,3.9495167676639937,5.328756578852783,1,0 -100,3545.4879711609515,15.247077014530934,1,9.444601308449784,3.4454145535575735,2.602953705894361,0,1 -100,7987.487984207757,11.801051236369055,1,1.734698243101259,4.036790159940795,5.935551388632815,0,1 -100,2890.7549594211423,12.73851828934971,0,7.13809282528176,5.2551596887784155,6.148692973657265,1,0 -100,5241.281031516189,13.953737279161908,1,7.091208214482693,8.819872123768606,4.90681285503473,1,1 -100,5537.528850392705,13.67283494533648,1,5.930851719676042,4.750281176544861,0.28728200406004556,1,1 -200,7219.541462897405,14.276357258045111,1,5.340242305044612,7.574227199144689,5.40464737349589,0,1 -200,23511.92239376686,16.98334382885113,1,7.325452548498071,8.244540117504954,2.1268703367809025,1,1 -200,8991.013530706801,16.400531548632024,1,8.444936023489612,4.367342649049377,7.4218273576543,1,1 -200,11219.558093914648,16.85932575440134,1,9.309383965221754,4.09766545377707,8.630350006188655,0,1 -200,6059.955098911258,13.43101063151967,1,4.919902947967591,8.637352007271096,7.162708383432515,1,0 -200,19564.503717028005,15.481740708199993,1,5.088927853447451,1.0739922916629092,9.165442715639248,1,1 -200,24298.706657606534,17.328225846336974,1,5.578392427859483,3.7820075038941523,8.183891482723245,0,0 -200,4787.741607744652,12.895725486168505,1,4.5624196251692055,6.274069923828192,4.6283796337001295,1,1 -200,10834.34156162985,15.704679694466426,1,6.57161761812892,1.1500261793162043,6.327088508921066,1,1 -200,7566.0698055826315,14.532373600045004,1,7.673393046575546,5.785075382849431,2.4161161615802493,0,0 -200,18398.60351229757,15.325387132391025,1,3.562633604832432,9.207901606732886,4.4786401900569395,0,0 -200,11342.939527491468,13.968488003927058,1,4.174724299282259,4.988545113554121,8.131828605495993,1,1 -200,3667.2240153666103,12.39298101581843,0,6.111507685588209,4.218189001356344,6.499728080331969,0,1 -200,8183.500893983943,13.91425559740625,0,3.4764271855154365,6.321340653696426,6.2737856928139415,1,0 -200,8747.850101709668,14.264530992860374,1,5.257330619121986,4.216469855103002,2.2640136191468,1,1 -200,12187.27354613704,12.002530865666891,0,0.6955880913297218,7.2019777600989565,3.332625794762305,1,0 -200,7851.1652103799,13.55092730054934,1,2.0823415776428815,7.424031830897312,2.9199573959918617,1,1 -200,4849.501921172143,10.118814340364818,1,1.6550924039632455,5.007593061880345,6.104530679559303,1,1 -200,6044.900736603831,12.653788662555009,1,2.6990057711098525,1.9605340473349886,2.373090006200211,1,1 -200,14186.636942230856,14.85995441449179,1,3.101493748861424,1.67354471214608,6.555024120128498,1,1 -200,22859.243337514992,16.229718277565624,1,6.068894880168244,3.362980217320941,2.089931299414432,0,0 -200,8581.615173766977,15.846622983701659,1,7.607443013232494,7.162159780199832,9.146885082679887,0,0 -200,5532.211878158424,12.530391637974056,0,3.0142485434857025,0.7819509967146185,6.282557734599852,1,1 -200,8706.853450101253,13.551631347820047,0,2.358454656526437,3.2037234233395684,3.0817090184599594,0,0 -200,12761.935358152306,13.983670081050848,1,2.255959335021762,6.102061242924149,5.677582909313927,1,1 -200,10144.164893059782,13.970873538329034,1,3.8426735139674935,2.5541097911022876,4.013242714293911,0,1 -200,16495.200631435175,15.670343037375913,1,4.3280468767634925,7.381471085856077,6.0382355501224625,0,1 -200,8203.959548514635,15.295120875275742,1,6.344868916295087,5.934078409839395,5.684523092726447,0,0 -200,11915.700197913633,14.068092274157745,0,4.099236803747891,4.5194838282396095,2.318729591469035,1,1 -200,4827.381850741882,10.056139744357566,0,0.5757767219110138,7.215419864118568,2.8529745339112034,1,1 -200,7129.1679437459125,13.857079334309782,1,4.742199285416932,6.0855269596998705,5.840537417966934,0,0 -200,14669.507712344417,16.751272116483676,1,8.061568711822733,3.7572360618668323,8.88264316453284,1,1 -200,17262.60228163662,16.661406998863583,1,8.070827662573762,5.649852263471692,7.840159354507797,0,1 -200,11064.3889463118,13.816120043115367,1,2.858846746471948,6.7799695915185225,3.279964702170296,1,1 -200,11871.423280942028,12.450634877731483,0,1.2617720125267762,5.997314661459724,7.2329528676534816,1,0 -200,3482.175862777836,12.005848986284773,1,4.542548560784726,3.1927298833273166,4.863010774121801,1,1 -200,6516.106207236989,13.246473191050045,0,4.725253244475737,7.304851362065715,5.845309578720973,0,1 -200,18684.49300844548,16.80210000734607,1,6.173673958520038,7.988962456324628,5.731447565440183,1,1 -200,5601.170012882008,12.62399680829661,0,1.1558222963496592,5.775748977845448,9.768457908702274,1,1 -200,7789.778230728716,12.655300977900536,0,3.0121202006786687,5.406000291318604,1.9424191506274955,1,0 -200,28371.87307779879,14.930121011941733,1,1.273859011362721,4.786739470025871,5.284514001506384,0,1 -200,12018.35895476995,14.466457062646334,1,3.102033799645479,9.499436205343333,6.628672321798162,1,1 -200,7839.673824658189,14.25392202654819,1,5.334981178428791,5.77586295625652,7.866652862190444,1,1 -200,12599.847834945658,15.678046151150593,1,6.629059961435624,4.554138753252859,8.563527714400418,1,1 -200,4579.808711144873,14.031585404030256,1,5.8120803062153445,0.26473396020633844,0.736573077175806,0,1 -200,6552.083494046815,11.494798924384218,1,2.576496815109108,1.2332121574620427,6.152354798176315,1,1 -200,14173.044801437916,15.295574801693528,0,5.636468578027366,4.780968009933569,8.811758710128707,1,1 -200,5302.271143719686,13.500710381073462,0,7.038314533730373,5.580443825935508,3.8442389065603915,0,0 -200,12711.112318939744,17.19790854551185,1,7.787737348624024,5.77741211918768,4.403166928497591,1,0 -200,22719.26885358504,15.608208722636926,1,4.401214782148651,7.222044515456588,4.8969387761531795,0,1 -200,5689.489584037458,12.97747786068819,1,4.735995773524593,4.453557312702329,6.021372480755105,1,1 -200,26736.38148564329,17.668380522871182,1,4.755495302717215,8.118671270371696,6.825822214243295,1,1 -200,4427.178913628781,14.50645820993523,1,8.556047500044514,2.5351413278342356,8.325678916293239,1,1 -200,14629.762772215528,16.59547493641402,1,7.928903087243032,1.8940593045849228,4.730783275724553,1,1 -200,10314.791673764437,15.982544951861613,1,7.25384947071388,1.8516825719777905,5.5523974161679615,1,1 -200,11848.626187624057,13.788652227753678,0,4.193485206851784,7.023658305970124,9.724763998276183,0,0 -200,18967.56453166382,16.525560816339475,1,6.043991961599474,4.766184543104558,6.2023811544956775,1,1 -200,11678.868874455231,15.463927327027491,1,6.126426749589054,7.143288872834308,5.531313073765541,0,0 -200,14900.049813825193,14.245863279168223,1,2.255994512440458,4.248095754058324,1.6272733438698141,1,1 -200,12732.7581337199,12.611759121700414,0,0.9869297191500099,3.3658978093705234,5.008056759021672,1,1 -200,8579.950611459688,14.691423979620517,1,6.765157244775387,3.969453519960786,4.37750420065168,1,0 -200,9550.235838224226,12.347485419796213,1,1.292341784893301,0.8229287026925227,4.968840492437989,1,0 -200,7271.420266065919,13.569581470215734,0,5.004749631861717,1.9755109460550722,3.4094747845010254,0,0 -200,18168.626206803438,16.696801167884463,1,5.703255914975262,1.442930970077672,3.1182017495858054,1,1 -200,12469.921833333194,16.64084139208247,1,6.559876608029552,7.772532367419991,3.0311032088011673,0,1 -200,15322.836733336095,15.618064398353512,1,5.533199601538724,3.3515500057118475,4.396581478637527,0,1 -200,11794.727000888453,13.788203258773361,0,3.0003245745194063,7.142394261294255,8.421778370188349,0,1 -200,8163.778474872884,15.355685829427676,1,7.617314217444926,8.68616875893034,7.760745127203258,1,1 -200,14853.726485480911,17.42676029998311,1,9.027477109006654,4.460219006653846,3.9925145266741198,0,0 -200,11602.70760882936,16.168798271268997,1,7.368007516277543,5.796894047311976,1.047543110338311,1,1 -200,8996.427653263805,16.30734971369774,1,8.48020271000731,0.955369096809161,2.721138118915017,1,0 -200,11122.251472170234,14.402501363242044,1,4.841899208696454,2.7849719257353134,3.7251203680133873,1,0 -200,16920.104019664825,15.89248989137257,1,6.455948935486724,5.158548790489286,5.292167149690834,0,0 -200,11277.998005565541,16.33709212595645,1,6.713394743909287,5.839131150759974,3.1807972752530245,1,1 -200,7283.256086292974,13.54431436503738,1,4.727408028541704,2.9330851353483323,9.352528235705389,0,1 -200,17996.01954597567,15.72689163367644,1,4.787759253836047,9.814890908096901,4.2353998375593,1,1 -200,9287.917785421356,15.807665766339964,1,7.6928089127681485,3.7234123497655065,1.8826611682271177,1,0 -200,8488.770655907365,14.79092579819105,1,6.945455582333315,5.181182427714609,4.601989728626647,1,1 -200,15675.560744756134,17.07572303300921,1,7.6263419728954,6.785901896509959,2.338781640987216,0,0 -200,14807.371893222575,17.791539673541944,1,9.663625672397128,4.926605797897124,5.439856309359714,0,1 -200,17669.961815123494,17.265965197227835,1,6.823893275846952,3.2303123798238937,5.656887530444408,1,1 -200,11891.002134043289,15.333325347740665,1,5.583486577256426,7.7522147470929745,5.995397317191248,0,0 -200,4434.660023203783,10.321696379571996,0,0.459612443729511,8.846517271204602,1.1437080458189886,0,1 -200,10735.109011283135,14.253378305204107,1,3.6576716159939497,4.916239363595229,5.620776704153693,0,1 -200,11508.448180988018,16.65718223023593,1,9.65843483454642,6.555624685133521,5.870643736355493,0,1 -200,17592.986476781145,15.753522895179639,1,6.047846531210102,4.725362335324697,1.4805231435665986,1,1 -200,14703.440445537975,15.461861949418036,1,4.690738574105143,7.686630158181885,7.54494806177226,1,1 -200,11686.842527230427,15.493475247048819,1,6.419886725342899,2.0041302020697844,7.129167333401898,0,1 -200,5443.990032351899,13.532466471186671,1,5.601889699389221,3.335210970848082,9.60780472731524,0,1 -200,6416.034316054205,13.340188688547169,0,4.4760653342797205,1.413138549660384,5.441393293591616,0,0 -200,13814.153864200745,14.759674865659772,1,4.660673455120376,4.0174762342690045,5.131815419639071,0,0 -200,5876.4055842870885,13.779768146735139,1,7.678337824312067,5.413317329063969,5.272309627583235,0,1 -200,7292.514885085292,13.848795590051305,1,4.433094890378933,8.859012126378158,5.196748900413432,1,0 -200,9233.706740608844,12.666112153808601,1,0.6157542727464536,7.440256643457809,0.8280683899723338,1,1 -200,17926.801836548857,14.755736271610695,1,4.448691674541115,5.401373736784317,1.0692570171295552,1,1 -200,7697.046141131699,15.569404591469045,1,6.4957400051660175,1.538411884022035,4.78134624304099,0,1 -200,14209.135577636214,16.345260485431954,1,6.698765254943929,2.6687311606468516,3.3945120195844947,0,1 -200,5998.787253502862,15.019864755564274,0,6.6990595310069825,4.540125855663566,5.154380866573085,0,1 -200,15890.998199101503,13.029729341620754,1,1.0385489796846095,7.941872462300682,1.3440169016450578,0,1 -200,7916.070133481703,14.742388250904188,1,6.031618002163338,3.5378375872265795,2.1226217327924153,1,1 -300,13528.712473055677,13.833058456427985,1,4.692632385591738,6.7098040410515445,2.9026089528154775,1,0 -300,18087.150309054847,15.340037825434239,1,5.645048626675996,6.243791550172116,6.991623016358376,1,0 -300,24866.321676306256,16.25139627047055,1,5.137893049749563,6.17725117010814,3.378594604229306,0,1 -300,13390.005523102789,16.899463848631385,1,7.516348512434502,6.2333271569991,5.00215570606778,1,1 -300,9589.605570798689,13.526845495608049,1,4.691845314666129,6.542270780866933,9.543464504186478,0,1 -300,23627.135007230892,15.327200843394323,1,4.801529962094956,6.758703835985029,7.577907827185454,0,1 -300,28745.980763623036,16.487367372125345,1,3.6532366617835073,0.687983516026325,7.088605833425862,1,1 -300,44928.32917181212,16.270634454107043,1,4.610212849874517,4.580760085018319,2.107607528211808,0,1 -300,19905.863383812106,15.98265601561583,1,4.806071247603542,5.317011474043442,2.8656655667037123,0,1 -300,11854.757305592138,12.404757434280551,0,0.3822543267058238,6.9788520188221845,9.596654155217937,1,1 -300,19558.736653984382,13.945038833046265,0,1.58442837933213,1.937802919585324,2.140639278783543,1,0 -300,15413.093576957363,15.380948744269247,1,4.795583296660901,3.6120356110972676,5.603348242057016,0,1 -300,10811.27346064354,14.432256127180265,1,4.25484154379102,7.779089015615104,7.395513024342368,1,0 -300,18689.597841887935,14.095701463665044,1,1.9098079134747614,8.249506257402004,7.691896780377903,1,1 -300,40563.61431192644,14.19920466802518,0,0.663392348032651,7.137937447641996,7.850108947290144,0,0 -300,10852.725205702345,12.786941439096701,1,4.007960700712725,1.865206776616193,4.540563581450756,0,1 -300,15112.903251703789,17.239269728994074,1,6.795537960421843,6.2591133128978544,2.7792412005278297,0,1 -300,13377.038838531036,18.130678110461552,1,9.074708337482411,7.983637635095456,4.13820664123158,0,1 -300,6954.395549848393,13.243719436270448,1,4.891525114687095,5.4729431465457345,2.5815764689447604,1,1 -300,8804.721805325971,16.11537071621274,1,8.646544235718753,3.4341682707490264,6.726585324472071,0,1 -300,14822.77927674212,16.17960466905598,1,5.234103406572213,2.1565152618469985,7.9186494894534,0,1 -300,7412.174149173207,14.65693939424838,0,5.325646529573214,3.1738073613946978,6.024387939558229,0,1 -300,6662.267339620128,14.841978575550662,1,5.910450085493086,6.953759986960283,2.6474902828318903,1,0 -300,10364.891789732914,13.008407176793169,0,2.657694765475529,3.7960867522213397,7.704948008390015,0,1 -300,14069.028451950426,16.501965925688822,1,4.854129250224855,5.640073473400067,7.424807484579822,0,1 -300,18272.092376250494,16.354123777687576,1,7.43364664006159,8.280935274708733,4.330225450892959,1,0 -300,13321.611677110881,14.546465721125706,1,2.957522978922724,6.598253752795379,1.245279248047586,1,1 -300,16270.130473004181,15.14652026288998,1,4.098458431027025,8.415272439798224,7.071736434980718,0,1 -300,22851.226915609004,14.319507391698506,1,2.0221047867429873,4.212009335357813,4.171913183980421,0,1 -300,10278.471782008388,15.004868035363364,1,5.991992370424447,5.183506414126201,6.486261471953715,1,1 -300,26752.809584065184,16.296210186692683,1,6.185205516999218,6.598927319918896,4.225319467208315,1,0 -300,13034.666269658723,16.85424774032129,1,6.782141367286601,1.976377583534322,6.870192700236892,1,1 -300,11491.450290806733,13.397961674181698,0,1.8705489519065366,7.184069738471094,4.669404747979894,1,0 -300,12851.55082758163,15.40708707003085,1,5.302293739689455,5.86216166073668,4.03469627651173,0,1 -300,24266.69606730011,14.930565633408614,0,2.4816841692778917,5.741042860050186,5.314638003431375,1,1 -300,11863.378416325702,14.790341096228413,1,4.9989148898553815,6.411863828837955,4.204422398694544,0,1 -300,32463.00002234384,17.522714073759765,1,8.373454272590994,4.672028106014602,3.368207978784787,1,1 -300,9867.300939644492,14.04311577130472,1,3.6014721247661416,7.474451458736145,4.11415469236427,1,0 -300,11173.53627943975,14.796236866426234,1,6.958450397202258,6.781835223456852,4.97700325782903,0,1 -300,19172.220853537354,14.043345553274,1,2.957667747428917,4.576846423657821,5.583805644983615,0,0 -300,11909.328292917591,13.781993903638245,1,3.6688808992383635,7.7410724158877855,8.712843704663113,0,1 -300,21382.97801055,15.996372541968746,1,6.2231423922055304,5.821008859724009,1.5973222819497293,1,1 -300,22509.632194886126,15.113746780728107,1,3.1380757728641067,6.835128259727633,4.438244909947643,0,0 -300,12003.97136636766,13.811302076287204,0,1.0228758602253354,3.359865326720936,6.738239912603264,1,1 -300,17916.117718752925,16.528057966944157,1,8.22172162081735,8.791175022654155,9.059571856405903,0,1 -300,31762.609006245573,17.102620347105493,1,6.008537932081865,4.988747430994735,6.188518696219091,1,1 -300,21420.778001687344,15.570109682795076,1,3.387706540036621,7.2868496721221865,4.961202750961421,0,0 -300,26791.361946509747,13.536518975781556,0,0.6607014134882027,4.717747950095126,4.1373758038875845,1,1 -300,32174.942361558755,16.659744746293857,1,5.5837644287612695,4.214918874145839,6.156559852137251,0,1 -300,12578.84104602017,16.644920593603242,1,7.291658055918559,7.129836533598022,7.623553249251586,0,1 -300,19796.49761785175,17.260940970496495,1,8.139230305969704,1.2021427091465415,4.482407710132829,0,0 -300,9732.904017781699,13.516772173976236,0,3.079653521330339,6.330681027061026,5.461211754474274,0,1 -300,27295.27297782938,15.884069342579792,1,4.016708496847256,6.0997902730102975,5.6102205558065235,1,1 -300,20205.004021922494,13.811737258594947,1,0.9885894729456886,6.03061460402364,6.990575218321654,0,0 -300,22207.056046778933,14.69129583817355,1,2.9908575670446624,0.49457361043969406,7.899071878403177,1,1 -300,12935.845578196682,15.926029022423139,1,6.714381699380723,6.811928937436892,5.783776626340147,0,1 -300,20251.48401918209,16.38409067927257,1,4.184108764764857,3.735560306200156,4.785202021995395,1,1 -300,15667.880465323613,15.601762052805832,1,4.397400993055825,3.0972955488860117,8.471157609700592,1,1 -300,19786.842438334876,15.202459081608156,1,4.682719083187264,4.980686974961544,5.4633808918825535,1,0 -300,24100.308230654085,13.358735869588642,0,0.8093332221716508,8.431002472066902,8.787043799207138,0,1 -300,30544.044315709594,17.292961821039054,1,7.261789896481088,3.251827980197564,4.825360005765777,0,0 -300,16940.647813478656,14.474393114959167,0,1.4403326915519195,6.544552295465943,6.692115398316059,0,1 -300,10062.978801637266,14.508584792235043,1,4.413185665585546,5.9555922566624275,1.264547503534594,0,1 -300,12133.704450281428,14.058609786867407,1,3.7772884341086006,0.969212047809994,4.683190741542122,0,1 -300,9583.123494519528,14.688858593538948,0,4.385144156407654,0.6622817057699124,4.938520500938148,0,0 -300,11557.97170651226,14.058228276901636,0,3.391885400346448,6.526371725922302,2.935741240483583,0,1 -300,21875.43463024025,14.330552754221884,1,2.873519514527609,4.902001663436763,2.269087219312311,1,1 -300,19197.82563586262,14.914866661818595,1,2.8171399431387654,9.174537643832089,7.527990222841342,0,0 -300,15446.536730140248,14.696545865287911,0,1.9827919717413545,6.58590644642735,7.447306470664485,0,0 -300,19377.290999900008,16.575755163771774,1,6.139166517673372,7.2913869510598195,1.7116141130667442,0,1 -300,16984.283827007508,14.52786994540613,0,2.6761164708960914,8.35766763754037,6.184056983238202,0,1 -300,13209.002006662695,15.273952413086361,0,5.852877728055253,3.6090235321012605,2.234778889631768,0,0 -300,23518.605582906017,16.124373373354874,1,4.587472261750969,6.4161986767147585,6.457283348603054,0,1 -300,19394.48380937849,13.483951177731209,1,1.4580824295865442,7.337970201443137,3.12024220494258,0,0 -300,23655.67371323142,14.154436653929215,1,2.8547379764975527,8.42406695898467,7.633785826250657,1,0 -300,10467.760625414296,15.902314852184412,1,7.377518250463897,7.075117368376639,5.108663265163866,0,1 -300,14402.15739624049,16.519430508891627,1,7.42077088858326,6.175238078047302,6.4860106793942505,1,0 -300,37929.15334238431,19.904224385985927,1,9.351373574003865,2.6634135828854184,3.5475007918879475,1,1 -300,14055.042918527437,14.671328893986686,1,4.989900129513007,6.9912950692814055,2.014708417627811,0,0 -300,8274.153993486665,13.281754984630124,0,2.91036446612353,6.389756475800491,7.448724248338268,1,1 -300,16980.900646706832,16.566355604025055,0,6.140649813264108,6.7453688562033145,5.669279840627434,0,1 -300,35747.870576460016,19.136160596740943,1,9.234414786142786,6.182055063485128,4.327938852150423,1,1 -300,27442.26980324405,16.377516209064545,1,5.3101024764577165,4.43203117658782,5.195252527677445,1,1 -300,17407.428733743887,16.74087270243586,1,7.9620220448860435,4.783242905040938,8.341341798094335,0,1 -300,20176.499742052,16.85700424581053,1,7.088790986340493,6.883211677797529,3.0889943773217334,0,0 -300,16388.46311350079,14.997355732534867,0,1.9787431345490853,5.483299347753819,2.958326011193038,0,1 -300,32590.868813078225,16.407278837743323,1,4.518156477672033,2.7567233666866815,3.292945540193643,1,1 -300,8632.257145541142,14.961861502910907,1,8.301193388941007,4.185655511607695,1.2015456747365851,1,1 -300,16318.266566356231,17.420906547003018,1,7.355697721464739,1.6717884972402892,7.217399042507797,1,0 -300,23959.7042287697,16.98524387967205,0,6.291245694944286,2.4277067971653916,5.541447788916603,0,0 -300,28267.805485550598,16.90723680365054,1,6.327296719482268,4.592576529689572,5.5829011378688955,1,1 -300,30531.66603851653,15.649769115016635,1,3.6341160204153704,0.8922967389190681,4.87773330324598,0,1 -300,25181.67998926081,14.39002460810843,1,1.6712849401279457,1.0437181636347865,3.5836333084783663,0,0 -300,9975.604260390894,16.407089837898855,1,8.281880735528555,7.879754746210574,2.7732309492899643,1,1 -300,22090.604350216356,13.956013976935768,1,1.4821327910273432,3.406291692991092,7.2966732194680874,1,1 -300,23105.93591782941,14.909755224982547,1,2.4938822548620303,4.681864377584831,1.4713518026576184,1,1 -300,20065.307966264118,16.23795246234569,1,6.731548347460567,8.331979922918233,6.227434727573419,1,0 -300,31076.293454498,14.851827966940084,1,1.784251751780173,6.8182869617707285,2.849734475285235,1,1 -300,14281.382531926938,15.101420361113682,1,3.4720399530716333,6.230384850730686,5.792533445254061,0,1 -300,36897.81153766472,15.250383489536217,0,1.9476557514817725,8.054335993164528,2.9804168606539996,1,0 +0,0,7.708330226507263,0,5.7118182538981035,2.331889533141997,7.831692190211973,0,1 +0,0,7.895719990692867,0,4.919475027306991,4.663321699049897,6.736228833251078,1,1 +0,0,7.265302834834181,1,4.879078118623973,4.212790522479133,4.679678561997343,1,1 +0,0,9.470582027659084,1,8.422660289429919,6.55754402063303,1.2863606477552603,0,1 +0,0,6.987197316997783,0,4.3650796126345455,3.9582148934550783,3.554226571334798,0,1 +0,0,8.796673929219512,1,8.68613506754053,7.595489431737389,3.638255369559842,0,0 +0,0,8.912440423578403,1,6.61487033671654,3.952325847405934,5.133002254197158,0,0 +0,0,8.044980842862595,1,5.349061674450915,7.768908985600291,8.291267427930208,0,1 +0,0,8.6658502459646,0,5.6074382527727495,2.239051110003308,9.603130421338324,0,1 +0,0,8.063364084015378,0,6.061574235451451,1.7883542502918455,8.737906764586185,0,1 +0,0,7.364854253127191,0,3.604705760426211,9.947833220078346,4.624791492313548,0,1 +0,0,8.020894980666915,0,4.066370907314752,3.836474930158519,0.9479016704071886,1,0 +0,0,6.013519273953105,0,2.3085206629451775,5.836746443519315,3.913335344787947,1,1 +0,0,5.432699868530257,0,2.1883508498157287,6.751428137824397,5.251527659398115,0,0 +0,0,7.806051130018049,0,5.851453827174215,3.6546906417684255,7.279915212248259,0,1 +0,0,8.017452757889403,0,6.248946755764191,6.4343604653319755,7.561752057655783,0,0 +0,0,7.6505885976630905,0,5.149496690816861,6.032229989181176,6.87533701803964,1,1 +0,0,9.58947673350722,0,7.466648489695158,4.394131091899446,1.527715426423224,1,1 +0,0,9.535231693481428,1,9.396607279468206,5.184140720120146,7.2912576705315155,0,0 +0,0,7.00406477613908,0,3.6351248964732434,4.903904831455794,3.755544692732871,0,1 +0,0,5.078882273501953,0,0.3854486118994365,9.470488873582738,5.492196282433816,1,1 +0,0,8.841249534441744,1,7.662048360358453,2.9787789954421093,5.210234205415462,1,1 +0,0,6.687374673042337,0,3.0606916825784127,5.106589921030279,6.194388338744096,0,0 +0,0,7.221671227655445,0,3.1151277592739044,5.870728665027908,5.069604305128964,1,0 +0,0,8.914382891900312,1,7.707447406309846,6.2171579903474505,7.008933463280042,1,1 +0,0,7.456731602960105,0,4.200620885889098,3.7234796082647232,6.079110269281988,0,1 +0,0,6.323769153978713,0,1.86867827817389,2.207265210424865,4.2538171865405925,1,1 +0,0,8.212601108845895,0,5.510428946836155,8.217739224212957,5.33299767577077,0,1 +0,0,7.01712903805624,0,4.608652628296863,4.02097165691434,5.377704450488606,0,0 +0,0,8.321570819636356,0,5.016260425078036,2.6700084694627915,5.621638371030827,1,1 +0,0,7.848052870068049,0,6.077062479430111,4.335723324364887,8.885370219399134,0,1 +0,0,6.928661073333383,0,3.963106314316518,4.44508762676838,4.383867474338036,0,1 +0,0,9.08792358785747,0,6.771796908000768,7.895878207562873,5.4732923005963965,1,1 +0,0,7.836967769607084,0,4.379851633068588,5.238935506370299,8.021877066128875,1,0 +0,0,7.419848588040613,0,5.929689048492463,7.053421125180893,7.772214756108311,1,0 +0,0,8.497044820218134,0,7.867160640853731,3.6128653184311132,7.972511578275215,1,0 +0,0,7.42771224138899,0,6.213503542148596,5.60325293462034,3.404042379611012,0,1 +0,0,7.134168305335998,0,4.086489418052165,4.089935603971496,9.34814287428454,1,1 +0,0,9.072480033953864,1,7.980119199989259,5.266670623347122,5.18810898018986,1,0 +0,0,8.998977875676495,0,7.633841063997927,2.597763370896309,9.19455593970929,0,1 +0,0,8.53543080750903,0,6.518703900799501,1.6879816675797454,1.6107718165359886,1,1 +0,0,7.534615107040446,1,5.67112306006591,9.342607679520592,5.059192055690255,1,0 +0,0,6.138762113637042,0,3.2712228183727996,6.657355351681319,8.19096862138861,0,1 +0,0,9.717239210071762,1,8.407693364068619,1.8062845834502341,3.0452330849131855,1,1 +0,0,7.047444781759476,0,3.3438282609126286,3.3151279514916165,2.9500285270149664,0,1 +0,0,8.60199408499005,1,8.713154707308803,9.530794498671527,2.494727353474394,1,1 +0,0,7.12109662272269,0,4.337340696294668,8.3151598291108,2.231536982108955,0,1 +0,0,5.69733461089785,1,2.290617044552199,4.255227863865191,3.781110248838436,1,1 +0,0,5.493426534004044,0,3.057604138550052,6.5048262145977995,5.928022604062216,1,1 +0,0,7.93593822704144,1,5.721756322894736,3.843353277081516,5.596357122618091,1,1 +0,0,7.113725390189084,0,4.306662489636756,3.6750485047242183,8.164048170942932,0,1 +0,0,6.96470835464052,0,4.026785976794121,2.859747442471744,9.384136933581672,0,1 +0,0,6.340007899931017,0,2.463863258060802,3.358705389477543,8.293185904182378,0,1 +0,0,7.877729949339401,0,4.872994734282217,8.900582353371462,7.060294015893987,0,1 +0,0,6.537297093279724,0,2.8689966820760624,4.847616458270171,0.9891378149704455,0,0 +0,0,5.228767953530555,0,1.0739717499346388,5.336094862461806,3.340542646361642,0,1 +0,0,6.60100706626076,0,3.9368133844428,5.684954810605893,4.01436413941897,1,0 +0,0,8.663525517195495,1,7.458853827432172,8.155465805731481,6.924758203920312,1,1 +0,0,6.859839526933025,0,3.4096620672871,3.567781482168498,4.702108291584847,1,1 +0,0,7.818387167870393,1,6.676454688442828,2.368463526508572,1.7913882312063083,1,1 +0,0,5.482774298483189,0,1.1498574658087628,8.937483791078602,8.950295974620941,0,0 +0,0,7.905279568744528,0,4.843291877321143,3.770213591451922,7.44069103341229,0,1 +0,0,8.166453927206222,1,6.44118794564693,3.02525423623661,5.667489562991372,1,1 +0,0,7.573222114963821,0,5.844864897522034,1.836772334277975,8.125941885183199,0,0 +0,0,7.510980111834901,0,5.297905392095343,1.7392847852757576,1.6339101370821265,1,1 +0,0,7.176211674694521,0,3.2377748040270617,3.4133025300781754,6.814565947210721,0,1 +0,0,6.6293181189053065,0,2.708592276596476,6.70278061728451,3.5494149774296235,0,0 +0,0,6.766258424305027,0,2.295841048528449,7.895720292986464,6.873882591265058,1,0 +0,0,7.735347253613795,0,5.331596650065819,6.935178060436716,4.828462897504693,1,1 +0,0,6.441949374062411,0,2.4736236516343975,3.9823751404750323,6.741998475444482,1,1 +0,0,6.538972766533816,0,3.636402445415764,5.1685150222288945,8.359845276233736,1,1 +0,0,7.442910214739262,0,4.280449760548192,3.072490942913965,5.02056493147758,0,1 +0,0,9.329926697275479,1,9.166186936740194,3.0401829165007643,7.689154457290752,0,1 +0,0,5.893958561524931,0,3.2084826277456076,7.376402078240974,1.9358130482650757,0,0 +0,0,7.894888025030134,0,5.661783084376143,2.3153442251303264,3.028982987246704,1,1 +0,0,8.582846864481217,0,5.219842511230999,9.297344462554067,8.690758328514333,1,1 +0,0,6.620367614923227,1,2.439820890273393,4.745339037970463,6.055388758518544,0,0 +0,0,7.982079464636521,1,4.798905539326781,5.603514564621188,0.6012804192296205,1,0 +0,0,9.460203228565662,0,8.561550734038173,2.985906427671349,1.5859239845676845,1,1 +0,0,7.824669610034402,1,6.25789639838503,3.412201885253288,4.434990961782319,1,1 +0,0,7.4570315405018945,0,5.116303936114074,1.6758840872248122,7.330640203272737,1,1 +0,0,6.7739150470844764,0,3.821078200980879,4.4850233372526755,4.712773364508995,1,0 +0,0,5.065785204119771,0,0.6002701880216281,6.169328031881751,6.719039769004755,1,0 +0,0,9.323325684741183,0,7.942484085552649,5.909008628253317,7.553493698877518,1,1 +0,0,5.106312124529282,0,1.4099877514239743,2.877429329556436,8.930636220129895,1,0 +0,0,8.942031884713659,0,7.017697637314545,2.8596996096972966,5.157990287469736,1,1 +0,0,10.054530920453805,1,9.244909354681717,3.605041399149745,4.853385781119949,1,1 +0,0,5.120498756911326,0,1.4396198728914003,8.651472668956238,0.9523967453693967,0,1 +0,0,8.779893462896837,1,6.920294927893139,2.0446240867431293,5.280030511415713,1,0 +0,0,8.346832113345211,1,4.263437574345913,4.495886018469261,3.41893293537652,1,0 +0,0,5.33245611553372,0,1.222127713009047,9.23702888417423,2.4114157094508424,0,0 +0,0,6.080904510595052,0,1.316904779782032,4.7153309924433255,4.493489246332375,0,1 +0,0,5.196581411144893,0,1.1753646679091903,3.1751900838248073,7.683168998292205,1,1 +0,0,7.319359936686219,0,3.528008455169637,6.349843427422446,3.80803161169825,0,1 +0,0,8.567230165880222,1,6.8846356118338825,3.9495167676639937,5.328756578852783,1,0 +0,0,10.548258350036473,1,9.444601308449784,3.4454145535575735,2.602953705894361,0,1 +0,0,5.137863757282172,0,1.734698243101259,4.036790159940795,5.935551388632815,0,1 +0,0,8.5433974695782,0,7.13809282528176,5.2551596887784155,6.148692973657265,1,0 +0,0,8.282141519178547,1,7.091208214482693,8.819872123768606,4.90681285503473,1,1 +0,0,7.866793425299871,0,5.930851719676042,4.750281176544861,0.28728200406004556,1,1 +100,3609.7707314487025,12.585165200843901,0,5.340242305044612,7.574227199144689,5.40464737349589,0,1 +100,11755.96119688343,15.898537288476954,1,7.325452548498071,8.244540117504954,2.1268703367809025,1,1 +100,4495.506765353401,14.77121179928003,1,8.444936023489612,4.367342649049377,7.4218273576543,1,1 +100,5609.779046957324,15.325096348739942,1,9.309383965221754,4.09766545377707,8.630350006188655,0,1 +100,3029.977549455629,11.717252921895241,1,4.919902947967591,8.637352007271096,7.162708383432515,1,0 +100,9782.251858514002,14.276925747174406,1,5.088927853447451,1.0739922916629092,9.165442715639248,1,1 +100,12149.353328803267,16.2648386425115,1,5.578392427859483,3.7820075038941523,8.183891482723245,0,0 +100,2393.870803872326,11.1915293974552,1,4.5624196251692055,6.274069923828192,4.6283796337001295,1,1 +100,5417.170780814925,14.153565408627761,1,6.57161761812892,1.1500261793162043,6.327088508921066,1,1 +100,3783.0349027913157,12.851381964801744,1,7.673393046575546,5.785075382849431,2.4161161615802493,0,0 +100,9199.301756148785,14.080749418676563,1,3.562633604832432,9.207901606732886,4.4786401900569395,0,0 +100,5671.469763745734,12.439674322176474,1,4.174724299282259,4.988545113554121,8.131828605495993,1,1 +100,1833.6120076833051,10.75317776736724,0,6.111507685588209,4.218189001356344,6.499728080331969,0,1 +100,4091.7504469919713,12.25407799723455,0,3.4764271855154365,6.321340653696426,6.2737856928139415,1,0 +100,4373.925050854834,12.625582479497938,1,5.257330619121986,4.216469855103002,2.2640136191468,1,1 +100,6093.63677306852,10.510715154586022,0,0.6955880913297218,7.2019777600989565,3.332625794762305,1,0 +100,3925.58260518995,11.879175257375866,0,2.0823415776428815,7.424031830897312,2.9199573959918617,1,1 +100,2424.7509605860714,8.412920482471353,0,1.6550924039632455,5.007593061880345,6.104530679559303,1,1 +100,3022.4503683019157,10.939891177644634,0,2.6990057711098525,1.9605340473349886,2.373090006200211,1,1 +100,7093.318471115428,13.453597437392505,0,3.101493748861424,1.67354471214608,6.555024120128498,1,1 +100,11429.621668757496,15.126547382838543,1,6.068894880168244,3.362980217320941,2.089931299414432,0,0 +100,4290.8075868834885,14.201244561901,1,7.607443013232494,7.162159780199832,9.146885082679887,0,0 +100,2766.105939079212,10.814869526942273,0,3.0142485434857025,0.7819509967146185,6.282557734599852,1,1 +100,4353.426725050626,11.911084858664593,0,2.358454656526437,3.2037234233395684,3.0817090184599594,0,0 +100,6380.967679076153,12.51682403067546,1,2.255959335021762,6.102061242924149,5.677582909313927,1,1 +100,5072.082446529891,12.389763861876554,0,3.8426735139674935,2.5541097911022876,4.013242714293911,0,1 +100,8247.600315717587,14.356073570287657,1,4.3280468767634925,7.381471085856077,6.0382355501224625,0,1 +100,4101.979774257317,13.63568073195854,1,6.344868916295087,5.934078409839395,5.684523092726447,0,0 +100,5957.8500989568165,12.564402559018127,0,4.099236803747891,4.5194838282396095,2.318729591469035,1,1 +100,2413.690925370941,8.350836148025119,0,0.5757767219110138,7.215419864118568,2.8529745339112034,1,1 +100,3564.5839718729562,12.163439354788563,1,4.742199285416932,6.0855269596998705,5.840537417966934,0,0 +100,7334.7538561722085,15.36483372573182,1,8.061568711822733,3.7572360618668323,8.88264316453284,1,1 +100,8631.30114081831,15.375907962248595,1,8.070827662573762,5.649852263471692,7.840159354507797,0,1 +100,5532.1944731559,12.275083222935974,1,2.858846746471948,6.7799695915185225,3.279964702170296,1,1 +100,5935.711640471014,10.945006009791237,0,1.2617720125267762,5.997314661459724,7.2329528676534816,1,0 +100,1741.087931388918,10.384566892769305,1,4.542548560784726,3.1927298833273166,4.863010774121801,1,1 +100,3258.0531036184943,11.539042651724294,0,4.725253244475737,7.304851362065715,5.845309578720973,0,1 +100,9342.24650422274,15.567423240074088,1,6.173673958520038,7.988962456324628,5.731447565440183,1,1 +100,2800.585006441004,10.90830879498139,0,1.1558222963496592,5.775748977845448,9.768457908702274,1,1 +100,3894.889115364358,10.98150153553822,0,3.0121202006786687,5.406000291318604,1.9424191506274955,1,0 +100,14185.936538899396,13.966259799510677,1,1.273859011362721,4.786739470025871,5.284514001506384,0,1 +100,6009.179477384975,12.967260187239786,0,3.102033799645479,9.499436205343333,6.628672321798162,1,1 +100,3919.8369123290945,12.581784425033062,1,5.334981178428791,5.77586295625652,7.866652862190444,1,1 +100,6299.923917472829,14.204182961814794,1,6.629059961435624,4.554138753252859,8.563527714400418,1,1 +100,2289.9043555724365,12.33429682991233,1,5.8120803062153445,0.26473396020633844,0.736573077175806,0,1 +100,3276.0417470234074,9.788024927797965,0,2.576496815109108,1.2332121574620427,6.152354798176315,1,1 +100,7086.522400718958,13.888652481675319,0,5.636468578027366,4.780968009933569,8.811758710128707,1,1 +100,2651.135571859843,11.7867249196575,0,7.038314533730373,5.580443825935508,3.8442389065603915,0,0 +100,6355.556159469872,15.728864674841327,1,7.787737348624024,5.77741211918768,4.403166928497591,1,0 +100,11359.63442679252,14.501027026560495,1,4.401214782148651,7.222044515456588,4.8969387761531795,0,1 +100,2844.744792018729,11.261762884577607,0,4.735995773524593,4.453557312702329,6.021372480755105,1,1 +100,13368.190742821645,16.666709046171796,0,4.755495302717215,8.118671270371696,6.825822214243295,1,1 +100,2213.5894568143904,12.815502239841207,1,8.556047500044514,2.5351413278342356,8.325678916293239,1,1 +100,7314.881386107764,15.20740947098768,1,7.928903087243032,1.8940593045849228,4.730783275724553,1,1 +100,5157.395836882219,14.408803307448895,1,7.25384947071388,1.8516825719777905,5.5523974161679615,1,1 +100,5924.3130938120285,12.28202464274394,0,4.193485206851784,7.023658305970124,9.724763998276183,0,0 +100,9483.78226583191,15.300620610188174,1,6.043991961599474,4.766184543104558,6.2023811544956775,1,1 +100,5839.4344372276155,13.949857468583119,1,6.126426749589054,7.143288872834308,5.531313073765541,0,0 +100,7450.024906912597,12.868817635027582,1,2.255994512440458,4.248095754058324,1.6272733438698141,1,1 +100,6366.37906685995,11.143651592347004,0,0.9869297191500099,3.3658978093705234,5.008056759021672,1,1 +100,4289.975305729844,13.045981857834526,1,6.765157244775387,3.969453519960786,4.37750420065168,1,0 +100,4775.117919112113,10.741120257765255,0,1.292341784893301,0.8229287026925227,4.968840492437989,1,0 +100,3635.7101330329597,11.879836488168124,0,5.004749631861717,1.9755109460550722,3.4094747845010254,0,0 +100,9084.313103401719,15.444057036452099,1,5.703255914975262,1.442930970077672,3.1182017495858054,1,1 +100,6234.960916666597,15.161337880772622,1,6.559876608029552,7.772532367419991,3.0311032088011673,0,1 +100,7661.418366668047,14.258039343979364,1,5.533199601538724,3.3515500057118475,4.396581478637527,0,1 +100,5897.363500444227,12.279213667460315,0,3.0003245745194063,7.142394261294255,8.421778370188349,0,1 +100,4081.889237436442,13.69479988092266,1,7.617314217444926,8.68616875893034,7.760745127203258,1,1 +100,7426.8632427404555,16.04783358331684,1,9.027477109006654,4.460219006653846,3.9925145266741198,0,0 +100,5801.35380441468,14.651386994281882,1,7.368007516277543,5.796894047311976,1.047543110338311,1,1 +100,4498.2138266319025,14.678247103189575,1,8.48020271000731,0.955369096809161,2.721138118915017,1,0 +100,5561.125736085117,12.864002355398547,1,4.841899208696454,2.7849719257353134,3.7251203680133873,1,0 +100,8460.052009832412,14.594266800223828,1,6.455948935486724,5.158548790489286,5.292167149690834,0,0 +100,5638.999002782771,14.805427703126313,1,6.713394743909287,5.839131150759974,3.1807972752530245,1,1 +100,3641.628043146487,11.854903680593665,1,4.727408028541704,2.9330851353483323,9.352528235705389,0,1 +100,8998.009772987834,14.468008265832191,1,4.787759253836047,9.814890908096901,4.2353998375593,1,1 +100,4643.958892710678,14.190409908551954,1,7.6928089127681485,3.7234123497655065,1.8826611682271177,1,0 +100,4244.3853279536825,13.142016283966097,1,6.945455582333315,5.181182427714609,4.601989728626647,1,1 +100,7837.780372378067,15.729690104328466,1,7.6263419728954,6.785901896509959,2.338781640987216,0,0 +100,7403.685946611287,16.410727462918683,1,9.663625672397128,4.926605797897124,5.439856309359714,0,1 +100,8834.980907561747,15.995355300738765,1,6.823893275846952,3.2303123798238937,5.656887530444408,1,1 +100,5945.501067021644,13.828554051378052,0,5.583486577256426,7.7522147470929745,5.995397317191248,0,0 +100,2217.3300116018913,8.630403484713089,0,0.459612443729511,8.846517271204602,1.1437080458189886,0,1 +100,5367.554505641568,12.697925377512712,0,3.6576716159939497,4.916239363595229,5.620776704153693,0,1 +100,5754.224090494009,15.135634115565832,1,9.65843483454642,6.555624685133521,5.870643736355493,0,1 +100,8796.493238390573,14.480119861319071,1,6.047846531210102,4.725362335324697,1.4805231435665986,1,1 +100,7351.720222768988,14.07681089415548,1,4.690738574105143,7.686630158181885,7.54494806177226,1,1 +100,5843.421263615213,13.979755141920831,1,6.419886725342899,2.0041302020697844,7.129167333401898,0,1 +100,2721.9950161759493,11.817350027096346,1,5.601889699389221,3.335210970848082,9.60780472731524,0,1 +100,3208.0171580271026,11.631045455096746,0,4.4760653342797205,1.413138549660384,5.441393293591616,0,0 +100,6907.076932100373,13.337736706469848,1,4.660673455120376,4.0174762342690045,5.131815419639071,0,0 +100,2938.2027921435442,12.06464284919909,0,7.678337824312067,5.413317329063969,5.272309627583235,0,1 +100,3646.257442542646,12.15964747849463,0,4.433094890378933,8.859012126378158,5.196748900413432,1,0 +100,4616.853370304422,11.046631128946867,0,0.6157542727464536,7.440256643457809,0.8280683899723338,1,1 +100,8963.400918274428,13.494377681599042,1,4.448691674541115,5.401373736784317,1.0692570171295552,1,1 +100,3848.5230705658496,13.892571085217451,1,6.4957400051660175,1.538411884022035,4.78134624304099,0,1 +100,7104.567788818107,14.939838753669639,1,6.698765254943929,2.6687311606468516,3.3945120195844947,0,1 +100,2999.393626751431,13.305569157261612,0,6.6990595310069825,4.540125855663566,5.154380866573085,0,1 +100,7945.4990995507515,11.692147710109008,0,1.0385489796846095,7.941872462300682,1.3440169016450578,0,1 +100,3958.0350667408516,13.072833253990595,1,6.031618002163338,3.5378375872265795,2.1226217327924153,1,1 +200,9019.141648703784,13.042629514164247,0,4.692632385591738,6.7098040410515445,2.9026089528154775,1,0 +200,12058.100206036564,14.660090869288274,1,5.645048626675996,6.243791550172116,6.991623016358376,1,0 +200,16577.547784204173,15.693227905847875,1,5.137893049749563,6.17725117010814,3.378594604229306,0,1 +200,8926.670348735193,16.105257966799424,1,7.516348512434502,6.2333271569991,5.00215570606778,1,1 +200,6393.070380532459,12.621553331829352,0,4.691845314666129,6.542270780866933,9.543464504186478,0,1 +200,15751.423338153927,14.749882240382636,1,4.801529962094956,6.758703835985029,7.577907827185454,0,1 +200,19163.98717574869,15.982072897770692,1,3.6532366617835073,0.687983516026325,7.088605833425862,1,1 +200,29952.219447874744,15.910030528810246,1,4.610212849874517,4.580760085018319,2.107607528211808,0,1 +200,13270.57558920807,15.33980769958156,1,4.806071247603542,5.317011474043442,2.8656655667037123,0,1 +200,7903.171537061425,11.567210577312132,0,0.3822543267058238,6.9788520188221845,9.596654155217937,1,1 +200,13039.157769322921,13.295388875902415,0,1.58442837933213,1.937802919585324,2.140639278783543,1,0 +200,10275.395717971576,14.639389850492227,1,4.795583296660901,3.6120356110972676,5.603348242057016,0,1 +200,7207.5156404290265,13.563868083767185,1,4.25484154379102,7.779089015615104,7.395513024342368,1,0 +200,12459.731894591956,13.428450610475869,0,1.9098079134747614,8.249506257402004,7.691896780377903,1,1 +200,27042.40954128429,13.80823816462601,0,0.663392348032651,7.137937447641996,7.850108947290144,0,0 +200,7235.150137134898,11.919794856635686,1,4.007960700712725,1.865206776616193,4.540563581450756,0,1 +200,10075.268834469192,16.490232715529032,1,6.795537960421843,6.2591133128978544,2.7792412005278297,0,1 +200,8918.025892354024,17.336117919738168,1,9.074708337482411,7.983637635095456,4.13820664123158,0,1 +200,4636.263699898929,12.263589143759685,1,4.891525114687095,5.4729431465457345,2.5815764689447604,1,1 +200,5869.8145368839805,15.18645729928725,1,8.646544235718753,3.4341682707490264,6.726585324472071,0,1 +200,9881.852851161413,15.423229623366524,1,5.234103406572213,2.1565152618469985,7.9186494894534,0,1 +200,4941.449432782138,13.688420637229994,0,5.325646529573214,3.1738073613946978,6.024387939558229,0,1 +200,4441.511559746752,13.855037997557988,1,5.910450085493086,6.953759986960283,2.6474902828318903,1,0 +200,6909.927859821943,12.126588543850888,0,2.657694765475529,3.7960867522213397,7.704948008390015,0,1 +200,9379.352301300283,15.72601732696922,1,4.854129250224855,5.640073473400067,7.424807484579822,0,1 +200,12181.394917500329,15.678118568876709,1,7.43364664006159,8.280935274708733,4.330225450892959,1,0 +200,8881.074451407254,13.750388645440198,1,2.957522978922724,6.598253752795379,1.245279248047586,1,1 +200,10846.753648669453,14.425675536193518,0,4.098458431027025,8.415272439798224,7.071736434980718,0,1 +200,15234.15127707267,13.729562972197662,1,2.0221047867429873,4.212009335357813,4.171913183980421,0,1 +200,6852.314521338925,14.120438606650305,1,5.991992370424447,5.183506414126201,6.486261471953715,1,1 +200,17835.20638937679,15.76500044041852,1,6.185205516999218,6.598927319918896,4.225319467208315,1,0 +200,8689.777513105815,16.050257058226,1,6.782141367286601,1.976377583534322,6.870192700236892,1,1 +200,7660.966860537822,12.549783797445448,0,1.8705489519065366,7.184069738471094,4.669404747979894,1,0 +200,8567.700551721087,14.597993824034253,1,5.302293739689455,5.86216166073668,4.03469627651173,0,1 +200,16177.797378200072,14.363281572198234,0,2.4816841692778917,5.741042860050186,5.314638003431375,1,1 +200,7908.918944217135,13.953044941655946,1,4.9989148898553815,6.411863828837955,4.204422398694544,0,1 +200,21642.000014895893,17.059775792571614,1,8.373454272590994,4.672028106014602,3.368207978784787,1,1 +200,6578.2006264296615,13.146237772816455,1,3.6014721247661416,7.474451458736145,4.11415469236427,1,0 +200,7449.024186293167,13.938657941156126,1,6.958450397202258,6.781835223456852,4.97700325782903,0,1 +200,12781.480569024901,13.385970488982469,1,2.957667747428917,4.576846423657821,5.583805644983615,0,0 +200,7939.552195278394,12.946032701849504,1,3.6688808992383635,7.7410724158877855,8.712843704663113,0,1 +200,14255.3186737,15.38108951658294,1,6.2231423922055304,5.821008859724009,1.5973222819497293,1,1 +200,15006.421463257417,14.518080415903128,1,3.1380757728641067,6.835128259727633,4.438244909947643,0,0 +200,8002.647577578439,12.978083646932921,0,1.0228758602253354,3.359865326720936,6.738239912603264,1,1 +200,11944.078479168616,15.844430354410877,1,8.22172162081735,8.791175022654155,9.059571856405903,0,1 +200,21175.072670830385,16.63223370780855,1,6.008537932081865,4.988747430994735,6.188518696219091,1,1 +200,14280.518667791563,14.95550392393603,0,3.387706540036621,7.2868496721221865,4.961202750961421,0,0 +200,17860.90796433983,13.005834438532075,0,0.6607014134882027,4.717747950095126,4.1373758038875845,1,1 +200,21449.961574372504,16.193770906782273,1,5.5837644287612695,4.214918874145839,6.156559852137251,0,1 +200,8385.894030680112,15.8281542414353,1,7.291658055918559,7.129836533598022,7.623553249251586,0,1 +200,13197.665078567834,16.61596346292753,1,8.139230305969704,1.2021427091465415,4.482407710132829,0,0 +200,6488.6026785211325,12.61582120155227,0,3.079653521330339,6.330681027061026,5.461211754474274,0,1 +200,18196.848651886252,15.360160035432283,1,4.016708496847256,6.0997902730102975,5.6102205558065235,1,1 +200,13470.002681281661,13.174649079420814,1,0.9885894729456886,6.03061460402364,6.990575218321654,0,0 +200,14804.704031185955,14.090475002027592,1,2.9908575670446624,0.49457361043969406,7.899071878403177,1,1 +200,8623.897052131122,15.119289692941278,1,6.714381699380723,6.811928937436892,5.783776626340147,0,1 +200,13500.989346121394,15.747889206274316,1,4.184108764764857,3.735560306200156,4.785202021995395,1,1 +200,10445.253643549077,14.866459194806065,1,4.397400993055825,3.0972955488860117,8.471157609700592,1,1 +200,13191.22829222325,14.557292997678305,1,4.682719083187264,4.980686974961544,5.4633808918825535,1,0 +200,16066.87215376939,12.788872730384362,0,0.8093332221716508,8.431002472066902,8.787043799207138,0,1 +200,20362.696210473063,16.809049426627976,1,7.261789896481088,3.251827980197564,4.825360005765777,0,0 +200,11293.765208985771,13.76910881048054,0,1.4403326915519195,6.544552295465943,6.692115398316059,0,1 +200,6708.652534424844,13.617635175903052,0,4.413185665585546,5.9555922566624275,1.264547503534594,0,1 +200,8089.136300187619,13.229135786245685,0,3.7772884341086006,0.969212047809994,4.683190741542122,0,1 +200,6388.748996346352,13.78337013560465,0,4.385144156407654,0.6622817057699124,4.938520500938148,0,0 +200,7705.314471008174,13.212006299184877,0,3.391885400346448,6.526371725922302,2.935741240483583,0,1 +200,14583.623086826832,13.723987700887616,1,2.873519514527609,4.902001663436763,2.269087219312311,1,1 +200,12798.550423908413,14.258008361206736,1,2.8171399431387654,9.174537643832089,7.527990222841342,0,0 +200,10297.691153426831,13.955812890610009,0,1.9827919717413545,6.58590644642735,7.447306470664485,0,0 +200,12918.193999933339,15.922498852378933,1,6.139166517673372,7.2913869510598195,1.7116141130667442,0,1 +200,11322.855884671671,13.823578997268944,0,2.6761164708960914,8.35766763754037,6.184056983238202,0,1 +200,8806.001337775131,14.474781783544552,0,5.852877728055253,3.6090235321012605,2.234778889631768,0,0 +200,15679.070388604012,15.545319057727317,1,4.587472261750969,6.4161986767147585,6.457283348603054,0,1 +200,12929.655872918995,12.831038104749473,1,1.4580824295865442,7.337970201443137,3.12024220494258,0,0 +200,15770.44914215428,13.577572863166337,1,2.8547379764975527,8.42406695898467,7.633785826250657,1,0 +200,6978.50708360953,15.023600098457257,0,7.377518250463897,7.075117368376639,5.108663265163866,0,1 +200,9601.438264160326,15.752223231200327,1,7.42077088858326,6.175238078047302,6.4860106793942505,1,0 +200,25286.102228256204,19.4923789874426,1,9.351373574003865,2.6634135828854184,3.5475007918879475,1,1 +200,9370.028612351625,13.895010188033229,1,4.989900129513007,6.9912950692814055,2.014708417627811,0,0 +200,5516.102662324443,12.337233916275414,0,2.91036446612353,6.389756475800491,7.448724248338268,1,1 +200,11320.60043113789,15.861987722625967,0,6.140649813264108,6.7453688562033145,5.669279840627434,0,1 +200,23831.91371764001,18.705304763500777,1,9.234414786142786,6.182055063485128,4.327938852150423,1,1 +200,18294.84653549603,15.855552403107888,1,5.3101024764577165,4.43203117658782,5.195252527677445,1,1 +200,11604.952489162592,16.04609414788363,1,7.9620220448860435,4.783242905040938,8.341341798094335,0,1 +200,13450.999828034668,16.21937118861699,1,7.088790986340493,6.883211677797529,3.0889943773217334,0,0 +200,10925.642075667194,14.279297853479777,0,1.9787431345490853,5.483299347753819,2.958326011193038,0,1 +200,21727.245875385484,15.945675802167152,1,4.518156477672033,2.7567233666866815,3.292945540193643,1,1 +200,5754.8380970274275,14.027828800129736,1,8.301193388941007,4.185655511607695,1.2015456747365851,1,1 +200,10878.84437757082,16.701197594870294,1,7.355697721464739,1.6717884972402892,7.217399042507797,1,0 +200,15973.136152513134,16.413184179996286,0,6.291245694944286,2.4277067971653916,5.541447788916603,0,0 +200,18845.203657033733,16.395947901096097,1,6.327296719482268,4.592576529689572,5.5829011378688955,1,1 +200,20354.444025677687,15.165715477493398,1,3.6341160204153704,0.8922967389190681,4.87773330324598,0,1 +200,16787.78665950721,13.836540831678608,1,1.6712849401279457,1.0437181636347865,3.5836333084783663,0,0 +200,6650.402840260595,15.513493625409515,1,8.281880735528555,7.879754746210574,2.7732309492899643,1,1 +200,14727.069566810902,13.353187427362057,1,1.4821327910273432,3.406291692991092,7.2966732194680874,1,1 +200,15403.95727855294,14.324011581776091,0,2.4938822548620303,4.681864377584831,1.4713518026576184,1,1 +200,13376.871977509412,15.59818589508953,1,6.731548347460567,8.331979922918233,6.227434727573419,1,0 +200,20717.528969665334,14.373914571185699,1,1.784251751780173,6.8182869617707285,2.849734475285235,1,1 +200,9520.921687951291,14.331060484320565,1,3.4720399530716333,6.230384850730686,5.792533445254061,0,1 +200,24598.54102510981,14.829758183322305,0,1.9476557514817725,8.054335993164528,2.9804168606539996,1,0 +300,31748.927252879563,15.604097762927344,1,1.2452646432208851,5.216130876211581,4.43676640344995,0,1 +300,18831.2735936316,17.90351169991329,1,7.8337837903897976,5.71696508841696,6.084032002386403,1,1 +300,32091.717625587877,15.134095730182986,1,2.9391843388932894,5.779009734285671,7.15352656260047,1,1 +300,19176.359221719642,13.22804104046807,0,1.7307625861136466,6.487900228021807,4.604091565641033,0,1 +300,9412.254880159013,16.20418921283141,1,8.318874751119047,3.7177290788567605,6.269573902003725,1,1 +300,9750.878553470719,16.518557874296988,1,7.974652618371957,3.5797560734899174,2.026822942112406,1,1 +300,20637.28132543302,15.924560826001803,1,4.318126473528333,5.6661147907017115,4.298409400922215,0,1 +300,32483.486818784582,16.82237746235928,1,7.067274566710352,3.499457574174914,3.8270792459470466,0,1 +300,9913.759142466353,12.909895774730463,1,2.682644304820088,8.128250308508274,5.550678791770228,0,1 +300,29266.851915918036,16.15174247585525,1,4.5745365446875494,5.4903255933748305,6.000169835053462,0,0 +300,15404.899011867039,15.619581683816907,1,4.735752279446968,3.304351759535594,4.651602924563358,0,1 +300,7390.711637219311,14.030748733083062,0,4.211831999182768,0.880880285080554,2.915907862324824,0,0 +300,25739.335272921788,17.564596542580492,1,7.002841057210485,3.2300159355272307,2.5156432827750628,1,1 +300,38638.576375290555,17.93838753519442,1,8.720985812234847,3.448375856193967,5.781996178866821,0,1 +300,25004.8713344647,14.82987817899807,0,3.7305187967093505,2.7422196408920025,8.40048136626599,0,1 +300,12607.577625614877,14.039140091658483,1,4.907878153137965,6.794112194703816,2.8634155725666597,1,0 +300,10828.720879238233,16.994573064263673,1,8.879149423694804,6.2301397760542,3.9242596900443747,0,1 +300,10899.399068570196,14.76832706516041,1,4.077886632176067,7.047291571939587,5.926644108504782,1,1 +300,13555.163569475582,16.102711116395504,1,6.426635320865293,4.219521015348999,3.4647164923990923,1,0 +300,11312.971769691643,13.167877101441105,1,2.619207486117717,7.923650655053935,5.342642143333594,1,0 +300,10189.053516398244,14.14205044534573,1,2.3545332891362794,1.9691685149856362,4.865752240243183,0,1 +300,8651.540437073103,15.912730816068132,1,8.518948911964351,4.862141128350764,2.8906799366458773,1,0 +300,19341.90982756813,15.305999955617866,1,2.260273221791628,3.0736606271914866,7.246560465897039,1,1 +300,24061.024366265232,17.71016637008474,1,7.719860157899834,6.866175236277018,7.283089125551737,0,1 +300,7781.42230317207,14.567257732620517,1,4.734556438267059,5.366366806288394,7.704183374014861,1,1 +300,8445.315134366167,14.651012325965015,1,5.399544103253097,7.895413838712959,8.227392282518487,1,1 +300,5474.279415406555,14.812942001948667,1,8.134450169125596,9.404890403759078,3.5938432837800587,0,0 +300,9742.24069830052,14.383540854714159,1,5.601096724592346,5.396306367756646,3.706895886358846,0,0 +300,33135.98717405961,14.995884560342681,1,2.704527915309427,3.518085399485708,5.733833762553269,1,1 +300,10137.73517775082,13.992560295574338,1,3.6908434031745085,2.772988570287307,6.734468087347215,1,1 +300,45156.645560088335,17.767334162456624,1,6.880044606488963,4.261107527490839,4.04863733927543,0,1 +300,21294.03670164458,13.585498197641446,1,0.36701642678092605,4.803714467222958,3.8187641409057793,0,1 +300,13110.02886872942,16.505027332243714,1,7.863647052223733,9.336887503478682,3.296469747910344,1,0 +300,13173.037571385952,13.377604144159497,0,1.2301880933941418,2.062339690176903,8.627622221640676,1,1 +300,23745.112000095975,15.827050894552594,1,5.061864606975953,2.140823216746805,4.528075480811905,1,1 +300,16351.366755027782,14.998654522823122,1,4.4641864217941425,3.8607774190312516,5.107787028373085,1,1 +300,16319.338772110688,16.44219785726523,1,8.277236407531047,6.622657732265851,2.2155937050106393,1,0 +300,12075.79400439998,15.700714098789776,1,5.531582773708,7.221068267942256,6.077461802019259,0,1 +300,33203.00420958361,16.591976203320844,1,5.28738401326219,2.5675818821718446,0.6896993061766031,0,1 +300,20522.31486503528,16.78248374256413,1,6.9109264712206855,5.35801890596137,7.5440156427450304,1,0 +300,21476.832099319454,14.441663338332944,1,2.764353123063128,4.879014630715309,1.0807770397385408,0,1 +300,12350.61093486311,14.654053672055635,1,4.448664744891942,7.850286259847539,2.9225827340522663,0,1 +300,18097.883539130635,16.66715550668771,1,8.041350074081006,4.124283423749765,5.4564926112612335,1,1 +300,36448.35470701619,16.923026567519557,1,6.87318124415495,5.129729408209757,3.209478314271692,0,1 +300,7027.2411455177125,11.291951947689217,1,1.7576167577607285,6.793527255314303,3.452299218247541,0,1 +300,16586.693786768312,16.92537131360972,1,6.755049097987914,4.129852681497894,5.9336224187940605,1,1 +300,27702.83859704431,14.58152368241988,1,1.560516626214006,6.58908145510361,2.2171834467231566,1,1 +300,12274.045587199686,13.658192590016313,1,3.348964425337142,3.548558065150425,4.757931015073547,1,1 +300,13794.250008798945,17.38951523386476,1,8.1110781902655,4.831010675844202,6.3336155523310325,1,1 +300,31844.48502130152,18.343150023438234,1,8.293571925013616,4.9407404043872285,8.993967426578921,0,1 +300,8342.888029751575,13.527744271529471,0,2.7945715306694985,3.0237564787013143,6.262393409089084,1,1 +300,16637.49278532306,17.038081247454873,1,8.178372939127499,2.3639032372093123,4.990856917557221,1,1 +300,14837.73517503716,14.928261021712123,1,4.526189073756284,4.4375499253059365,0.4237968696579822,0,1 +300,10061.794965072482,15.203047477849875,1,6.193321977988092,4.028206176538874,1.8605677508677991,0,0 +300,15392.994553878703,16.740583147173698,1,7.201676610952844,7.253095161238875,4.105776088873533,0,1 +300,10289.354462141722,14.205871979660746,1,3.2104027670324573,8.708611406829652,6.947166342534725,0,0 +300,27392.69483155855,16.593352757773918,1,4.145599939640541,4.966367856891851,4.095946812192366,0,1 +300,20821.89300672218,15.054626282616956,1,3.841284247076098,6.113780763590365,6.506039270330609,0,0 +300,9306.25535880805,16.41612503793867,0,9.860024708986744,4.801421726045876,2.206178944213633,0,1 +300,9253.883201170793,14.710201535485536,1,5.35551128282137,6.659070462754071,4.2302181066561015,0,0 +300,12470.630506796842,17.240301411775103,1,6.315629029654789,5.61458078492284,5.610415468942813,1,0 +300,34442.58137934506,15.767941301415318,1,4.045524152472864,5.665158774876485,3.9941379748886567,1,1 +300,33409.002392092,16.66374854173967,1,4.320338544313545,7.902426090702296,5.318046878823711,0,1 +300,10545.848675229247,16.34935365588756,1,8.441656495077233,2.380239240805175,3.159702149508177,1,0 +300,31506.165384398948,15.659507440518599,1,4.050687938197208,5.977544470985794,6.047026420444653,0,0 +300,7978.222695345035,13.833798889805266,1,5.056802067053337,5.509078841315148,4.7714393663982015,1,1 +300,28772.0056038055,16.70093312804699,1,6.054218729549,3.449759972622635,4.867294036548311,1,0 +300,7761.728637216388,14.317989662028019,1,3.7959161364675276,4.538462083113486,0.709878654109487,1,1 +300,36045.67334801896,14.885690166293902,1,1.4672525492178012,6.0452109327959995,3.152145266452795,1,1 +300,10101.856330573335,17.08581932206896,1,9.357321507759938,0.5900213503726094,1.3595385163875793,1,1 +300,18101.13594352642,15.617314941812506,0,4.015617539092387,3.340502515516117,1.1688051672647148,0,1 +300,21512.235722104047,18.66850387499218,1,8.401016504985986,6.618513553914851,3.6274361867491525,0,0 +300,12324.42647647349,16.710807472190478,1,7.546627687447449,4.173651306608464,4.547106756612444,0,0 +300,6666.491461891411,14.21463781787692,1,7.356510181586874,2.8300013224420018,5.796119451164186,1,1 +300,21487.91637124985,13.796954464560928,1,1.7661625154155056,3.25085768049635,7.854861496049223,1,1 +300,12900.44096846603,13.293769687406336,1,2.9105987860242633,5.662795240720598,6.238591142785923,0,1 +300,27386.40755330786,15.073631807561274,1,5.544684443448315,1.1237871090059044,7.676586479187717,1,1 +300,15821.766646548695,17.612105014876555,0,7.969443300370104,7.343888807850256,3.5403118719719506,0,0 +300,46873.60113616399,15.425100120751697,0,2.9164489265590516,0.49413351217529466,4.136590519113031,1,1 +300,8282.127662117808,14.12555925863415,1,4.369677270358444,3.6019718568700005,7.8413821125192005,1,1 +300,6585.94669808374,12.845294273932335,0,2.0661597002616143,2.8632982850364233,5.003405403324509,0,0 +300,17973.236006641815,16.048919346007413,1,6.250464211822248,1.8116944788770464,1.0558358377240693,1,0 +300,18724.74282083443,14.228877692566861,1,2.1131149093270767,2.1747332215568953,2.716303896599326,1,1 +300,5480.765427524687,12.539639629607121,0,3.167160338918131,5.702780504414793,7.666308334112778,1,1 +300,22553.545917352312,17.170014934813537,1,7.1269309464934505,4.6624173106372035,3.316254578128906,0,1 +300,7394.148077553943,13.952099679579666,1,5.699662609939123,4.155969415987869,5.934283378860381,0,1 +300,15947.058329674104,17.62344363832393,1,8.526688103300925,1.6617264642314922,5.040121019122167,1,1 +300,34230.56970584425,15.896440820628577,1,3.3398123660300234,4.629976371704361,3.6207683939785023,1,1 +300,7785.714575214634,11.965047814027024,0,1.0064235451191441,2.6396033820922264,4.0178387018989605,1,1 +300,36349.78971735264,17.276430874290543,1,7.7579047887942725,2.839364576459753,6.094729752325873,1,0 +300,23521.14830790697,15.524147402003939,0,3.321816660288865,7.7617685810247625,5.589637113640483,1,1 +300,27184.004474139678,17.100639185667443,0,5.339176510505906,5.494400202216409,4.437682784421077,0,1 +300,11200.85839423006,17.55884333581621,1,9.000029861845402,2.25108557848423,2.531111934962899,1,1 +300,48213.31306973088,16.818369373627696,1,4.296280464565218,3.6954807818868995,5.467223480836103,1,1 +300,20977.703428244226,17.527578591875926,1,8.741148761203005,4.200258253252075,6.929401572872285,1,1 +300,12445.55583043555,13.36814711079269,0,2.1321772397552525,3.1350212559480855,3.7090609575495517,1,0 +300,25480.17425570534,17.0864978500973,1,7.474368622464169,2.434675062610122,4.085322095444034,0,1 +300,37322.641264568294,16.672977182083763,1,5.693636902861883,4.853887165436772,7.371187022395759,0,1 +300,30440.04478205255,15.688337371161152,1,2.9903664723112033,7.020862321610841,8.253907683776733,0,0 +300,9420.488882507934,13.021996627497115,0,1.7486312074498631,5.6379414903468845,3.190985625331063,1,1 diff --git a/data/d_sim_emax.rda b/data/d_sim_emax.rda index 1af62ac5882180951e45b121ba19aa826377be3d..4baaae285f5fe4dff35ed5fc8eca768ef665af97 100644 GIT binary patch literal 15640 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 From 8d1630965e8df15e9c0848502db6b9f8e1dbf5b3 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 13:20:29 +1000 Subject: [PATCH 13/57] adds test for internal data storage across placebo settings --- tests/testthat/test-placebo_handling.R | 97 ++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/testthat/test-placebo_handling.R diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R new file mode 100644 index 0000000..90a363a --- /dev/null +++ b/tests/testthat/test-placebo_handling.R @@ -0,0 +1,97 @@ + +# two versions of the data to test +dat <- list( + placebo = d_sim_emax |> dplyr::slice_sample(n = 10, by = dose), + noplacebo = d_sim_emax |> dplyr::filter(dose != 0) |> dplyr::slice_sample(n = 10, by = dose) +) + +# four versions of the modelling function +dev_ermod <- list( + dev_ermod_bin = dev_ermod_bin, + dev_ermod_lin = dev_ermod_lin, + dev_ermod_emax = dev_ermod_emax, + dev_ermod_bin_emax = dev_ermod_bin_emax +) + +# two versions of the placebo handling options +opts <- list( + drop_placebo = list(include_placebo = FALSE), + use_placebo = list(include_placebo = TRUE) +) + +# all 16 test cases +cases <- tidyr::expand_grid( + dat = names(dat), + dev_ermod = names(dev_ermod), + opts = names(opts), +) |> dplyr::mutate( + var_resp = dplyr::case_when( + dev_ermod == "dev_ermod_bin" ~ "response_2", + dev_ermod == "dev_ermod_lin" ~ "response_1", + dev_ermod == "dev_ermod_emax" ~ "response_1", + dev_ermod == "dev_ermod_bin_emax" ~ "response_2" + ) +) + +# fit the model for each case +m <- list() +for(r in 1:nrow(cases)) { + f <- dev_ermod[[cases$dev_ermod[r]]] + d <- dat[[cases$dat[r]]] + o <- opts[[cases$opts[r]]] + set.seed(123L) + suppressWarnings( + m[[r]] <- d |> f( + var_exposure = "exposure", + var_resp = cases$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) + ) +} +cases$mod <- m + +# helper function to inspect internal data objects +internal_stan_data_rows <- function(object) { + if (inherits(object, "stanemax") | inherits(object, "stanemaxbin")) { + return(object$standata$N) + } + return(nrow(object$data)) +} + +cases$inner_n <- numeric(nrow(cases)) +cases$outer_n <- numeric(nrow(cases)) +for(r in 1:nrow(cases)) { + cases$inner_n[r] <- internal_stan_data_rows(cases$mod[[r]]$mod) + cases$outer_n[r] <- nrow(cases$mod[[r]]$data) +} + +# the "stan" data set should only include placebo samples if the data set +# originally contained a placebo group, and the options specify that the +# placebo group is to be used during model fitting +test_that("internal stan data respects placebo options", { + + for(r in 1:nrow(cases)) { + if (cases$dat[r] == "placebo" & cases$opts[r] == "use_placebo") { + expect_equal(cases$inner_n[r], 40L) + } else { + expect_equal(cases$inner_n[r], 30L) + } + } + +}) + +# the "user facing" data set should only include placebo samples if the data set +# originally contained a placebo group, regardless of the placebo handling settings +test_that("outer data preserves all data rows", { + + for(r in 1:nrow(cases)) { + if (cases$dat[r] == "placebo") { + expect_equal(cases$outer_n[r], 40L) + } else { + expect_equal(cases$outer_n[r], 30L) + } + } + +}) From c4d05fbd4d2d36a7b59235ac42ca679738358f69 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 14:01:37 +1000 Subject: [PATCH 14/57] use multiple metrics in emax data set --- R/yyy.R | 3 +- data-raw/d_sim_emax.R | 13 +- data-raw/d_sim_emax.csv | 802 ++++++++++++++++++++-------------------- data/d_sim_emax.rda | Bin 15640 -> 18006 bytes 4 files changed, 411 insertions(+), 407 deletions(-) diff --git a/R/yyy.R b/R/yyy.R index 619d5f1..b83f85b 100644 --- a/R/yyy.R +++ b/R/yyy.R @@ -121,7 +121,8 @@ if (getRversion() >= "2.15.1") { #' @format A data frame with columns: #' \describe{ #' \item{dose}{Nominal dose, units not specified} -#' \item{exposure}{Exposure value, units and metric not specified} +#' \item{exposure_1}{Exposure value, units and metric not specified} +#' \item{exposure_2}{Exposure value, units and metric not specified, but different from exposure_1} #' \item{response_1}{Continuous response value (units not specified)} #' \item{response_2}{Binary response value (group labels not specified)} #' \item{cnt_a}{Continuous valued covariate} diff --git a/data-raw/d_sim_emax.R b/data-raw/d_sim_emax.R index dc1f533..4fd98dd 100644 --- a/data-raw/d_sim_emax.R +++ b/data-raw/d_sim_emax.R @@ -55,11 +55,14 @@ simulate_data <- function(seed = 123) { coef_d2 = 1 ) - # conditional on a dose group, generate data + # conditional on a dose group, generate data; include multiple exposure metrics + # but treat the first one as source of ground truth. exposures are strongly + # correlated but on the same scale make_dose_data <- function(dose, n, par) { tibble::tibble( dose = dose, - exposure = generate_exposure(dose, n = n), + exposure_1 = generate_exposure(dose, n = n), + exposure_2 = 0.7 * exposure_1 + 0.3 * generate_exposure(dose, n = n), # add continuous and binary covariates cnt_a = continuous_covariate(n = n), @@ -70,7 +73,7 @@ simulate_data <- function(seed = 123) { # response 1 is continuous response_1 = emax_fn( - exposure, + exposure_1, emax = par$emax_1, ec50 = par$ec50_1, e0 = par$e0_1, @@ -84,7 +87,7 @@ simulate_data <- function(seed = 123) { # response 2 is binary; start with the predictor bin_pred = emax_fn( - exposure, + exposure_1, emax = par$emax_2, ec50 = par$ec50_2, e0 = par$e0_2, @@ -116,6 +119,6 @@ simulate_data <- function(seed = 123) { # generate data ----------------------------------------------------------- d_sim_emax <- simulate_data() -d_sim_emax <- dplyr::relocate(d_sim_emax, response_1, response_2, .after = exposure) +d_sim_emax <- dplyr::relocate(d_sim_emax, response_1, response_2, .after = exposure_2) readr::write_csv(d_sim_emax, "data-raw/d_sim_emax.csv") usethis::use_data(d_sim_emax, overwrite = TRUE) diff --git a/data-raw/d_sim_emax.csv b/data-raw/d_sim_emax.csv index 0abd7f9..85d08c7 100644 --- a/data-raw/d_sim_emax.csv +++ b/data-raw/d_sim_emax.csv @@ -1,401 +1,401 @@ -dose,exposure,response_1,response_2,cnt_a,cnt_b,cnt_c,bin_d,bin_e -0,0,7.708330226507263,0,5.7118182538981035,2.331889533141997,7.831692190211973,0,1 -0,0,7.895719990692867,0,4.919475027306991,4.663321699049897,6.736228833251078,1,1 -0,0,7.265302834834181,1,4.879078118623973,4.212790522479133,4.679678561997343,1,1 -0,0,9.470582027659084,1,8.422660289429919,6.55754402063303,1.2863606477552603,0,1 -0,0,6.987197316997783,0,4.3650796126345455,3.9582148934550783,3.554226571334798,0,1 -0,0,8.796673929219512,1,8.68613506754053,7.595489431737389,3.638255369559842,0,0 -0,0,8.912440423578403,1,6.61487033671654,3.952325847405934,5.133002254197158,0,0 -0,0,8.044980842862595,1,5.349061674450915,7.768908985600291,8.291267427930208,0,1 -0,0,8.6658502459646,0,5.6074382527727495,2.239051110003308,9.603130421338324,0,1 -0,0,8.063364084015378,0,6.061574235451451,1.7883542502918455,8.737906764586185,0,1 -0,0,7.364854253127191,0,3.604705760426211,9.947833220078346,4.624791492313548,0,1 -0,0,8.020894980666915,0,4.066370907314752,3.836474930158519,0.9479016704071886,1,0 -0,0,6.013519273953105,0,2.3085206629451775,5.836746443519315,3.913335344787947,1,1 -0,0,5.432699868530257,0,2.1883508498157287,6.751428137824397,5.251527659398115,0,0 -0,0,7.806051130018049,0,5.851453827174215,3.6546906417684255,7.279915212248259,0,1 -0,0,8.017452757889403,0,6.248946755764191,6.4343604653319755,7.561752057655783,0,0 -0,0,7.6505885976630905,0,5.149496690816861,6.032229989181176,6.87533701803964,1,1 -0,0,9.58947673350722,0,7.466648489695158,4.394131091899446,1.527715426423224,1,1 -0,0,9.535231693481428,1,9.396607279468206,5.184140720120146,7.2912576705315155,0,0 -0,0,7.00406477613908,0,3.6351248964732434,4.903904831455794,3.755544692732871,0,1 -0,0,5.078882273501953,0,0.3854486118994365,9.470488873582738,5.492196282433816,1,1 -0,0,8.841249534441744,1,7.662048360358453,2.9787789954421093,5.210234205415462,1,1 -0,0,6.687374673042337,0,3.0606916825784127,5.106589921030279,6.194388338744096,0,0 -0,0,7.221671227655445,0,3.1151277592739044,5.870728665027908,5.069604305128964,1,0 -0,0,8.914382891900312,1,7.707447406309846,6.2171579903474505,7.008933463280042,1,1 -0,0,7.456731602960105,0,4.200620885889098,3.7234796082647232,6.079110269281988,0,1 -0,0,6.323769153978713,0,1.86867827817389,2.207265210424865,4.2538171865405925,1,1 -0,0,8.212601108845895,0,5.510428946836155,8.217739224212957,5.33299767577077,0,1 -0,0,7.01712903805624,0,4.608652628296863,4.02097165691434,5.377704450488606,0,0 -0,0,8.321570819636356,0,5.016260425078036,2.6700084694627915,5.621638371030827,1,1 -0,0,7.848052870068049,0,6.077062479430111,4.335723324364887,8.885370219399134,0,1 -0,0,6.928661073333383,0,3.963106314316518,4.44508762676838,4.383867474338036,0,1 -0,0,9.08792358785747,0,6.771796908000768,7.895878207562873,5.4732923005963965,1,1 -0,0,7.836967769607084,0,4.379851633068588,5.238935506370299,8.021877066128875,1,0 -0,0,7.419848588040613,0,5.929689048492463,7.053421125180893,7.772214756108311,1,0 -0,0,8.497044820218134,0,7.867160640853731,3.6128653184311132,7.972511578275215,1,0 -0,0,7.42771224138899,0,6.213503542148596,5.60325293462034,3.404042379611012,0,1 -0,0,7.134168305335998,0,4.086489418052165,4.089935603971496,9.34814287428454,1,1 -0,0,9.072480033953864,1,7.980119199989259,5.266670623347122,5.18810898018986,1,0 -0,0,8.998977875676495,0,7.633841063997927,2.597763370896309,9.19455593970929,0,1 -0,0,8.53543080750903,0,6.518703900799501,1.6879816675797454,1.6107718165359886,1,1 -0,0,7.534615107040446,1,5.67112306006591,9.342607679520592,5.059192055690255,1,0 -0,0,6.138762113637042,0,3.2712228183727996,6.657355351681319,8.19096862138861,0,1 -0,0,9.717239210071762,1,8.407693364068619,1.8062845834502341,3.0452330849131855,1,1 -0,0,7.047444781759476,0,3.3438282609126286,3.3151279514916165,2.9500285270149664,0,1 -0,0,8.60199408499005,1,8.713154707308803,9.530794498671527,2.494727353474394,1,1 -0,0,7.12109662272269,0,4.337340696294668,8.3151598291108,2.231536982108955,0,1 -0,0,5.69733461089785,1,2.290617044552199,4.255227863865191,3.781110248838436,1,1 -0,0,5.493426534004044,0,3.057604138550052,6.5048262145977995,5.928022604062216,1,1 -0,0,7.93593822704144,1,5.721756322894736,3.843353277081516,5.596357122618091,1,1 -0,0,7.113725390189084,0,4.306662489636756,3.6750485047242183,8.164048170942932,0,1 -0,0,6.96470835464052,0,4.026785976794121,2.859747442471744,9.384136933581672,0,1 -0,0,6.340007899931017,0,2.463863258060802,3.358705389477543,8.293185904182378,0,1 -0,0,7.877729949339401,0,4.872994734282217,8.900582353371462,7.060294015893987,0,1 -0,0,6.537297093279724,0,2.8689966820760624,4.847616458270171,0.9891378149704455,0,0 -0,0,5.228767953530555,0,1.0739717499346388,5.336094862461806,3.340542646361642,0,1 -0,0,6.60100706626076,0,3.9368133844428,5.684954810605893,4.01436413941897,1,0 -0,0,8.663525517195495,1,7.458853827432172,8.155465805731481,6.924758203920312,1,1 -0,0,6.859839526933025,0,3.4096620672871,3.567781482168498,4.702108291584847,1,1 -0,0,7.818387167870393,1,6.676454688442828,2.368463526508572,1.7913882312063083,1,1 -0,0,5.482774298483189,0,1.1498574658087628,8.937483791078602,8.950295974620941,0,0 -0,0,7.905279568744528,0,4.843291877321143,3.770213591451922,7.44069103341229,0,1 -0,0,8.166453927206222,1,6.44118794564693,3.02525423623661,5.667489562991372,1,1 -0,0,7.573222114963821,0,5.844864897522034,1.836772334277975,8.125941885183199,0,0 -0,0,7.510980111834901,0,5.297905392095343,1.7392847852757576,1.6339101370821265,1,1 -0,0,7.176211674694521,0,3.2377748040270617,3.4133025300781754,6.814565947210721,0,1 -0,0,6.6293181189053065,0,2.708592276596476,6.70278061728451,3.5494149774296235,0,0 -0,0,6.766258424305027,0,2.295841048528449,7.895720292986464,6.873882591265058,1,0 -0,0,7.735347253613795,0,5.331596650065819,6.935178060436716,4.828462897504693,1,1 -0,0,6.441949374062411,0,2.4736236516343975,3.9823751404750323,6.741998475444482,1,1 -0,0,6.538972766533816,0,3.636402445415764,5.1685150222288945,8.359845276233736,1,1 -0,0,7.442910214739262,0,4.280449760548192,3.072490942913965,5.02056493147758,0,1 -0,0,9.329926697275479,1,9.166186936740194,3.0401829165007643,7.689154457290752,0,1 -0,0,5.893958561524931,0,3.2084826277456076,7.376402078240974,1.9358130482650757,0,0 -0,0,7.894888025030134,0,5.661783084376143,2.3153442251303264,3.028982987246704,1,1 -0,0,8.582846864481217,0,5.219842511230999,9.297344462554067,8.690758328514333,1,1 -0,0,6.620367614923227,1,2.439820890273393,4.745339037970463,6.055388758518544,0,0 -0,0,7.982079464636521,1,4.798905539326781,5.603514564621188,0.6012804192296205,1,0 -0,0,9.460203228565662,0,8.561550734038173,2.985906427671349,1.5859239845676845,1,1 -0,0,7.824669610034402,1,6.25789639838503,3.412201885253288,4.434990961782319,1,1 -0,0,7.4570315405018945,0,5.116303936114074,1.6758840872248122,7.330640203272737,1,1 -0,0,6.7739150470844764,0,3.821078200980879,4.4850233372526755,4.712773364508995,1,0 -0,0,5.065785204119771,0,0.6002701880216281,6.169328031881751,6.719039769004755,1,0 -0,0,9.323325684741183,0,7.942484085552649,5.909008628253317,7.553493698877518,1,1 -0,0,5.106312124529282,0,1.4099877514239743,2.877429329556436,8.930636220129895,1,0 -0,0,8.942031884713659,0,7.017697637314545,2.8596996096972966,5.157990287469736,1,1 -0,0,10.054530920453805,1,9.244909354681717,3.605041399149745,4.853385781119949,1,1 -0,0,5.120498756911326,0,1.4396198728914003,8.651472668956238,0.9523967453693967,0,1 -0,0,8.779893462896837,1,6.920294927893139,2.0446240867431293,5.280030511415713,1,0 -0,0,8.346832113345211,1,4.263437574345913,4.495886018469261,3.41893293537652,1,0 -0,0,5.33245611553372,0,1.222127713009047,9.23702888417423,2.4114157094508424,0,0 -0,0,6.080904510595052,0,1.316904779782032,4.7153309924433255,4.493489246332375,0,1 -0,0,5.196581411144893,0,1.1753646679091903,3.1751900838248073,7.683168998292205,1,1 -0,0,7.319359936686219,0,3.528008455169637,6.349843427422446,3.80803161169825,0,1 -0,0,8.567230165880222,1,6.8846356118338825,3.9495167676639937,5.328756578852783,1,0 -0,0,10.548258350036473,1,9.444601308449784,3.4454145535575735,2.602953705894361,0,1 -0,0,5.137863757282172,0,1.734698243101259,4.036790159940795,5.935551388632815,0,1 -0,0,8.5433974695782,0,7.13809282528176,5.2551596887784155,6.148692973657265,1,0 -0,0,8.282141519178547,1,7.091208214482693,8.819872123768606,4.90681285503473,1,1 -0,0,7.866793425299871,0,5.930851719676042,4.750281176544861,0.28728200406004556,1,1 -100,3609.7707314487025,12.585165200843901,0,5.340242305044612,7.574227199144689,5.40464737349589,0,1 -100,11755.96119688343,15.898537288476954,1,7.325452548498071,8.244540117504954,2.1268703367809025,1,1 -100,4495.506765353401,14.77121179928003,1,8.444936023489612,4.367342649049377,7.4218273576543,1,1 -100,5609.779046957324,15.325096348739942,1,9.309383965221754,4.09766545377707,8.630350006188655,0,1 -100,3029.977549455629,11.717252921895241,1,4.919902947967591,8.637352007271096,7.162708383432515,1,0 -100,9782.251858514002,14.276925747174406,1,5.088927853447451,1.0739922916629092,9.165442715639248,1,1 -100,12149.353328803267,16.2648386425115,1,5.578392427859483,3.7820075038941523,8.183891482723245,0,0 -100,2393.870803872326,11.1915293974552,1,4.5624196251692055,6.274069923828192,4.6283796337001295,1,1 -100,5417.170780814925,14.153565408627761,1,6.57161761812892,1.1500261793162043,6.327088508921066,1,1 -100,3783.0349027913157,12.851381964801744,1,7.673393046575546,5.785075382849431,2.4161161615802493,0,0 -100,9199.301756148785,14.080749418676563,1,3.562633604832432,9.207901606732886,4.4786401900569395,0,0 -100,5671.469763745734,12.439674322176474,1,4.174724299282259,4.988545113554121,8.131828605495993,1,1 -100,1833.6120076833051,10.75317776736724,0,6.111507685588209,4.218189001356344,6.499728080331969,0,1 -100,4091.7504469919713,12.25407799723455,0,3.4764271855154365,6.321340653696426,6.2737856928139415,1,0 -100,4373.925050854834,12.625582479497938,1,5.257330619121986,4.216469855103002,2.2640136191468,1,1 -100,6093.63677306852,10.510715154586022,0,0.6955880913297218,7.2019777600989565,3.332625794762305,1,0 -100,3925.58260518995,11.879175257375866,0,2.0823415776428815,7.424031830897312,2.9199573959918617,1,1 -100,2424.7509605860714,8.412920482471353,0,1.6550924039632455,5.007593061880345,6.104530679559303,1,1 -100,3022.4503683019157,10.939891177644634,0,2.6990057711098525,1.9605340473349886,2.373090006200211,1,1 -100,7093.318471115428,13.453597437392505,0,3.101493748861424,1.67354471214608,6.555024120128498,1,1 -100,11429.621668757496,15.126547382838543,1,6.068894880168244,3.362980217320941,2.089931299414432,0,0 -100,4290.8075868834885,14.201244561901,1,7.607443013232494,7.162159780199832,9.146885082679887,0,0 -100,2766.105939079212,10.814869526942273,0,3.0142485434857025,0.7819509967146185,6.282557734599852,1,1 -100,4353.426725050626,11.911084858664593,0,2.358454656526437,3.2037234233395684,3.0817090184599594,0,0 -100,6380.967679076153,12.51682403067546,1,2.255959335021762,6.102061242924149,5.677582909313927,1,1 -100,5072.082446529891,12.389763861876554,0,3.8426735139674935,2.5541097911022876,4.013242714293911,0,1 -100,8247.600315717587,14.356073570287657,1,4.3280468767634925,7.381471085856077,6.0382355501224625,0,1 -100,4101.979774257317,13.63568073195854,1,6.344868916295087,5.934078409839395,5.684523092726447,0,0 -100,5957.8500989568165,12.564402559018127,0,4.099236803747891,4.5194838282396095,2.318729591469035,1,1 -100,2413.690925370941,8.350836148025119,0,0.5757767219110138,7.215419864118568,2.8529745339112034,1,1 -100,3564.5839718729562,12.163439354788563,1,4.742199285416932,6.0855269596998705,5.840537417966934,0,0 -100,7334.7538561722085,15.36483372573182,1,8.061568711822733,3.7572360618668323,8.88264316453284,1,1 -100,8631.30114081831,15.375907962248595,1,8.070827662573762,5.649852263471692,7.840159354507797,0,1 -100,5532.1944731559,12.275083222935974,1,2.858846746471948,6.7799695915185225,3.279964702170296,1,1 -100,5935.711640471014,10.945006009791237,0,1.2617720125267762,5.997314661459724,7.2329528676534816,1,0 -100,1741.087931388918,10.384566892769305,1,4.542548560784726,3.1927298833273166,4.863010774121801,1,1 -100,3258.0531036184943,11.539042651724294,0,4.725253244475737,7.304851362065715,5.845309578720973,0,1 -100,9342.24650422274,15.567423240074088,1,6.173673958520038,7.988962456324628,5.731447565440183,1,1 -100,2800.585006441004,10.90830879498139,0,1.1558222963496592,5.775748977845448,9.768457908702274,1,1 -100,3894.889115364358,10.98150153553822,0,3.0121202006786687,5.406000291318604,1.9424191506274955,1,0 -100,14185.936538899396,13.966259799510677,1,1.273859011362721,4.786739470025871,5.284514001506384,0,1 -100,6009.179477384975,12.967260187239786,0,3.102033799645479,9.499436205343333,6.628672321798162,1,1 -100,3919.8369123290945,12.581784425033062,1,5.334981178428791,5.77586295625652,7.866652862190444,1,1 -100,6299.923917472829,14.204182961814794,1,6.629059961435624,4.554138753252859,8.563527714400418,1,1 -100,2289.9043555724365,12.33429682991233,1,5.8120803062153445,0.26473396020633844,0.736573077175806,0,1 -100,3276.0417470234074,9.788024927797965,0,2.576496815109108,1.2332121574620427,6.152354798176315,1,1 -100,7086.522400718958,13.888652481675319,0,5.636468578027366,4.780968009933569,8.811758710128707,1,1 -100,2651.135571859843,11.7867249196575,0,7.038314533730373,5.580443825935508,3.8442389065603915,0,0 -100,6355.556159469872,15.728864674841327,1,7.787737348624024,5.77741211918768,4.403166928497591,1,0 -100,11359.63442679252,14.501027026560495,1,4.401214782148651,7.222044515456588,4.8969387761531795,0,1 -100,2844.744792018729,11.261762884577607,0,4.735995773524593,4.453557312702329,6.021372480755105,1,1 -100,13368.190742821645,16.666709046171796,0,4.755495302717215,8.118671270371696,6.825822214243295,1,1 -100,2213.5894568143904,12.815502239841207,1,8.556047500044514,2.5351413278342356,8.325678916293239,1,1 -100,7314.881386107764,15.20740947098768,1,7.928903087243032,1.8940593045849228,4.730783275724553,1,1 -100,5157.395836882219,14.408803307448895,1,7.25384947071388,1.8516825719777905,5.5523974161679615,1,1 -100,5924.3130938120285,12.28202464274394,0,4.193485206851784,7.023658305970124,9.724763998276183,0,0 -100,9483.78226583191,15.300620610188174,1,6.043991961599474,4.766184543104558,6.2023811544956775,1,1 -100,5839.4344372276155,13.949857468583119,1,6.126426749589054,7.143288872834308,5.531313073765541,0,0 -100,7450.024906912597,12.868817635027582,1,2.255994512440458,4.248095754058324,1.6272733438698141,1,1 -100,6366.37906685995,11.143651592347004,0,0.9869297191500099,3.3658978093705234,5.008056759021672,1,1 -100,4289.975305729844,13.045981857834526,1,6.765157244775387,3.969453519960786,4.37750420065168,1,0 -100,4775.117919112113,10.741120257765255,0,1.292341784893301,0.8229287026925227,4.968840492437989,1,0 -100,3635.7101330329597,11.879836488168124,0,5.004749631861717,1.9755109460550722,3.4094747845010254,0,0 -100,9084.313103401719,15.444057036452099,1,5.703255914975262,1.442930970077672,3.1182017495858054,1,1 -100,6234.960916666597,15.161337880772622,1,6.559876608029552,7.772532367419991,3.0311032088011673,0,1 -100,7661.418366668047,14.258039343979364,1,5.533199601538724,3.3515500057118475,4.396581478637527,0,1 -100,5897.363500444227,12.279213667460315,0,3.0003245745194063,7.142394261294255,8.421778370188349,0,1 -100,4081.889237436442,13.69479988092266,1,7.617314217444926,8.68616875893034,7.760745127203258,1,1 -100,7426.8632427404555,16.04783358331684,1,9.027477109006654,4.460219006653846,3.9925145266741198,0,0 -100,5801.35380441468,14.651386994281882,1,7.368007516277543,5.796894047311976,1.047543110338311,1,1 -100,4498.2138266319025,14.678247103189575,1,8.48020271000731,0.955369096809161,2.721138118915017,1,0 -100,5561.125736085117,12.864002355398547,1,4.841899208696454,2.7849719257353134,3.7251203680133873,1,0 -100,8460.052009832412,14.594266800223828,1,6.455948935486724,5.158548790489286,5.292167149690834,0,0 -100,5638.999002782771,14.805427703126313,1,6.713394743909287,5.839131150759974,3.1807972752530245,1,1 -100,3641.628043146487,11.854903680593665,1,4.727408028541704,2.9330851353483323,9.352528235705389,0,1 -100,8998.009772987834,14.468008265832191,1,4.787759253836047,9.814890908096901,4.2353998375593,1,1 -100,4643.958892710678,14.190409908551954,1,7.6928089127681485,3.7234123497655065,1.8826611682271177,1,0 -100,4244.3853279536825,13.142016283966097,1,6.945455582333315,5.181182427714609,4.601989728626647,1,1 -100,7837.780372378067,15.729690104328466,1,7.6263419728954,6.785901896509959,2.338781640987216,0,0 -100,7403.685946611287,16.410727462918683,1,9.663625672397128,4.926605797897124,5.439856309359714,0,1 -100,8834.980907561747,15.995355300738765,1,6.823893275846952,3.2303123798238937,5.656887530444408,1,1 -100,5945.501067021644,13.828554051378052,0,5.583486577256426,7.7522147470929745,5.995397317191248,0,0 -100,2217.3300116018913,8.630403484713089,0,0.459612443729511,8.846517271204602,1.1437080458189886,0,1 -100,5367.554505641568,12.697925377512712,0,3.6576716159939497,4.916239363595229,5.620776704153693,0,1 -100,5754.224090494009,15.135634115565832,1,9.65843483454642,6.555624685133521,5.870643736355493,0,1 -100,8796.493238390573,14.480119861319071,1,6.047846531210102,4.725362335324697,1.4805231435665986,1,1 -100,7351.720222768988,14.07681089415548,1,4.690738574105143,7.686630158181885,7.54494806177226,1,1 -100,5843.421263615213,13.979755141920831,1,6.419886725342899,2.0041302020697844,7.129167333401898,0,1 -100,2721.9950161759493,11.817350027096346,1,5.601889699389221,3.335210970848082,9.60780472731524,0,1 -100,3208.0171580271026,11.631045455096746,0,4.4760653342797205,1.413138549660384,5.441393293591616,0,0 -100,6907.076932100373,13.337736706469848,1,4.660673455120376,4.0174762342690045,5.131815419639071,0,0 -100,2938.2027921435442,12.06464284919909,0,7.678337824312067,5.413317329063969,5.272309627583235,0,1 -100,3646.257442542646,12.15964747849463,0,4.433094890378933,8.859012126378158,5.196748900413432,1,0 -100,4616.853370304422,11.046631128946867,0,0.6157542727464536,7.440256643457809,0.8280683899723338,1,1 -100,8963.400918274428,13.494377681599042,1,4.448691674541115,5.401373736784317,1.0692570171295552,1,1 -100,3848.5230705658496,13.892571085217451,1,6.4957400051660175,1.538411884022035,4.78134624304099,0,1 -100,7104.567788818107,14.939838753669639,1,6.698765254943929,2.6687311606468516,3.3945120195844947,0,1 -100,2999.393626751431,13.305569157261612,0,6.6990595310069825,4.540125855663566,5.154380866573085,0,1 -100,7945.4990995507515,11.692147710109008,0,1.0385489796846095,7.941872462300682,1.3440169016450578,0,1 -100,3958.0350667408516,13.072833253990595,1,6.031618002163338,3.5378375872265795,2.1226217327924153,1,1 -200,9019.141648703784,13.042629514164247,0,4.692632385591738,6.7098040410515445,2.9026089528154775,1,0 -200,12058.100206036564,14.660090869288274,1,5.645048626675996,6.243791550172116,6.991623016358376,1,0 -200,16577.547784204173,15.693227905847875,1,5.137893049749563,6.17725117010814,3.378594604229306,0,1 -200,8926.670348735193,16.105257966799424,1,7.516348512434502,6.2333271569991,5.00215570606778,1,1 -200,6393.070380532459,12.621553331829352,0,4.691845314666129,6.542270780866933,9.543464504186478,0,1 -200,15751.423338153927,14.749882240382636,1,4.801529962094956,6.758703835985029,7.577907827185454,0,1 -200,19163.98717574869,15.982072897770692,1,3.6532366617835073,0.687983516026325,7.088605833425862,1,1 -200,29952.219447874744,15.910030528810246,1,4.610212849874517,4.580760085018319,2.107607528211808,0,1 -200,13270.57558920807,15.33980769958156,1,4.806071247603542,5.317011474043442,2.8656655667037123,0,1 -200,7903.171537061425,11.567210577312132,0,0.3822543267058238,6.9788520188221845,9.596654155217937,1,1 -200,13039.157769322921,13.295388875902415,0,1.58442837933213,1.937802919585324,2.140639278783543,1,0 -200,10275.395717971576,14.639389850492227,1,4.795583296660901,3.6120356110972676,5.603348242057016,0,1 -200,7207.5156404290265,13.563868083767185,1,4.25484154379102,7.779089015615104,7.395513024342368,1,0 -200,12459.731894591956,13.428450610475869,0,1.9098079134747614,8.249506257402004,7.691896780377903,1,1 -200,27042.40954128429,13.80823816462601,0,0.663392348032651,7.137937447641996,7.850108947290144,0,0 -200,7235.150137134898,11.919794856635686,1,4.007960700712725,1.865206776616193,4.540563581450756,0,1 -200,10075.268834469192,16.490232715529032,1,6.795537960421843,6.2591133128978544,2.7792412005278297,0,1 -200,8918.025892354024,17.336117919738168,1,9.074708337482411,7.983637635095456,4.13820664123158,0,1 -200,4636.263699898929,12.263589143759685,1,4.891525114687095,5.4729431465457345,2.5815764689447604,1,1 -200,5869.8145368839805,15.18645729928725,1,8.646544235718753,3.4341682707490264,6.726585324472071,0,1 -200,9881.852851161413,15.423229623366524,1,5.234103406572213,2.1565152618469985,7.9186494894534,0,1 -200,4941.449432782138,13.688420637229994,0,5.325646529573214,3.1738073613946978,6.024387939558229,0,1 -200,4441.511559746752,13.855037997557988,1,5.910450085493086,6.953759986960283,2.6474902828318903,1,0 -200,6909.927859821943,12.126588543850888,0,2.657694765475529,3.7960867522213397,7.704948008390015,0,1 -200,9379.352301300283,15.72601732696922,1,4.854129250224855,5.640073473400067,7.424807484579822,0,1 -200,12181.394917500329,15.678118568876709,1,7.43364664006159,8.280935274708733,4.330225450892959,1,0 -200,8881.074451407254,13.750388645440198,1,2.957522978922724,6.598253752795379,1.245279248047586,1,1 -200,10846.753648669453,14.425675536193518,0,4.098458431027025,8.415272439798224,7.071736434980718,0,1 -200,15234.15127707267,13.729562972197662,1,2.0221047867429873,4.212009335357813,4.171913183980421,0,1 -200,6852.314521338925,14.120438606650305,1,5.991992370424447,5.183506414126201,6.486261471953715,1,1 -200,17835.20638937679,15.76500044041852,1,6.185205516999218,6.598927319918896,4.225319467208315,1,0 -200,8689.777513105815,16.050257058226,1,6.782141367286601,1.976377583534322,6.870192700236892,1,1 -200,7660.966860537822,12.549783797445448,0,1.8705489519065366,7.184069738471094,4.669404747979894,1,0 -200,8567.700551721087,14.597993824034253,1,5.302293739689455,5.86216166073668,4.03469627651173,0,1 -200,16177.797378200072,14.363281572198234,0,2.4816841692778917,5.741042860050186,5.314638003431375,1,1 -200,7908.918944217135,13.953044941655946,1,4.9989148898553815,6.411863828837955,4.204422398694544,0,1 -200,21642.000014895893,17.059775792571614,1,8.373454272590994,4.672028106014602,3.368207978784787,1,1 -200,6578.2006264296615,13.146237772816455,1,3.6014721247661416,7.474451458736145,4.11415469236427,1,0 -200,7449.024186293167,13.938657941156126,1,6.958450397202258,6.781835223456852,4.97700325782903,0,1 -200,12781.480569024901,13.385970488982469,1,2.957667747428917,4.576846423657821,5.583805644983615,0,0 -200,7939.552195278394,12.946032701849504,1,3.6688808992383635,7.7410724158877855,8.712843704663113,0,1 -200,14255.3186737,15.38108951658294,1,6.2231423922055304,5.821008859724009,1.5973222819497293,1,1 -200,15006.421463257417,14.518080415903128,1,3.1380757728641067,6.835128259727633,4.438244909947643,0,0 -200,8002.647577578439,12.978083646932921,0,1.0228758602253354,3.359865326720936,6.738239912603264,1,1 -200,11944.078479168616,15.844430354410877,1,8.22172162081735,8.791175022654155,9.059571856405903,0,1 -200,21175.072670830385,16.63223370780855,1,6.008537932081865,4.988747430994735,6.188518696219091,1,1 -200,14280.518667791563,14.95550392393603,0,3.387706540036621,7.2868496721221865,4.961202750961421,0,0 -200,17860.90796433983,13.005834438532075,0,0.6607014134882027,4.717747950095126,4.1373758038875845,1,1 -200,21449.961574372504,16.193770906782273,1,5.5837644287612695,4.214918874145839,6.156559852137251,0,1 -200,8385.894030680112,15.8281542414353,1,7.291658055918559,7.129836533598022,7.623553249251586,0,1 -200,13197.665078567834,16.61596346292753,1,8.139230305969704,1.2021427091465415,4.482407710132829,0,0 -200,6488.6026785211325,12.61582120155227,0,3.079653521330339,6.330681027061026,5.461211754474274,0,1 -200,18196.848651886252,15.360160035432283,1,4.016708496847256,6.0997902730102975,5.6102205558065235,1,1 -200,13470.002681281661,13.174649079420814,1,0.9885894729456886,6.03061460402364,6.990575218321654,0,0 -200,14804.704031185955,14.090475002027592,1,2.9908575670446624,0.49457361043969406,7.899071878403177,1,1 -200,8623.897052131122,15.119289692941278,1,6.714381699380723,6.811928937436892,5.783776626340147,0,1 -200,13500.989346121394,15.747889206274316,1,4.184108764764857,3.735560306200156,4.785202021995395,1,1 -200,10445.253643549077,14.866459194806065,1,4.397400993055825,3.0972955488860117,8.471157609700592,1,1 -200,13191.22829222325,14.557292997678305,1,4.682719083187264,4.980686974961544,5.4633808918825535,1,0 -200,16066.87215376939,12.788872730384362,0,0.8093332221716508,8.431002472066902,8.787043799207138,0,1 -200,20362.696210473063,16.809049426627976,1,7.261789896481088,3.251827980197564,4.825360005765777,0,0 -200,11293.765208985771,13.76910881048054,0,1.4403326915519195,6.544552295465943,6.692115398316059,0,1 -200,6708.652534424844,13.617635175903052,0,4.413185665585546,5.9555922566624275,1.264547503534594,0,1 -200,8089.136300187619,13.229135786245685,0,3.7772884341086006,0.969212047809994,4.683190741542122,0,1 -200,6388.748996346352,13.78337013560465,0,4.385144156407654,0.6622817057699124,4.938520500938148,0,0 -200,7705.314471008174,13.212006299184877,0,3.391885400346448,6.526371725922302,2.935741240483583,0,1 -200,14583.623086826832,13.723987700887616,1,2.873519514527609,4.902001663436763,2.269087219312311,1,1 -200,12798.550423908413,14.258008361206736,1,2.8171399431387654,9.174537643832089,7.527990222841342,0,0 -200,10297.691153426831,13.955812890610009,0,1.9827919717413545,6.58590644642735,7.447306470664485,0,0 -200,12918.193999933339,15.922498852378933,1,6.139166517673372,7.2913869510598195,1.7116141130667442,0,1 -200,11322.855884671671,13.823578997268944,0,2.6761164708960914,8.35766763754037,6.184056983238202,0,1 -200,8806.001337775131,14.474781783544552,0,5.852877728055253,3.6090235321012605,2.234778889631768,0,0 -200,15679.070388604012,15.545319057727317,1,4.587472261750969,6.4161986767147585,6.457283348603054,0,1 -200,12929.655872918995,12.831038104749473,1,1.4580824295865442,7.337970201443137,3.12024220494258,0,0 -200,15770.44914215428,13.577572863166337,1,2.8547379764975527,8.42406695898467,7.633785826250657,1,0 -200,6978.50708360953,15.023600098457257,0,7.377518250463897,7.075117368376639,5.108663265163866,0,1 -200,9601.438264160326,15.752223231200327,1,7.42077088858326,6.175238078047302,6.4860106793942505,1,0 -200,25286.102228256204,19.4923789874426,1,9.351373574003865,2.6634135828854184,3.5475007918879475,1,1 -200,9370.028612351625,13.895010188033229,1,4.989900129513007,6.9912950692814055,2.014708417627811,0,0 -200,5516.102662324443,12.337233916275414,0,2.91036446612353,6.389756475800491,7.448724248338268,1,1 -200,11320.60043113789,15.861987722625967,0,6.140649813264108,6.7453688562033145,5.669279840627434,0,1 -200,23831.91371764001,18.705304763500777,1,9.234414786142786,6.182055063485128,4.327938852150423,1,1 -200,18294.84653549603,15.855552403107888,1,5.3101024764577165,4.43203117658782,5.195252527677445,1,1 -200,11604.952489162592,16.04609414788363,1,7.9620220448860435,4.783242905040938,8.341341798094335,0,1 -200,13450.999828034668,16.21937118861699,1,7.088790986340493,6.883211677797529,3.0889943773217334,0,0 -200,10925.642075667194,14.279297853479777,0,1.9787431345490853,5.483299347753819,2.958326011193038,0,1 -200,21727.245875385484,15.945675802167152,1,4.518156477672033,2.7567233666866815,3.292945540193643,1,1 -200,5754.8380970274275,14.027828800129736,1,8.301193388941007,4.185655511607695,1.2015456747365851,1,1 -200,10878.84437757082,16.701197594870294,1,7.355697721464739,1.6717884972402892,7.217399042507797,1,0 -200,15973.136152513134,16.413184179996286,0,6.291245694944286,2.4277067971653916,5.541447788916603,0,0 -200,18845.203657033733,16.395947901096097,1,6.327296719482268,4.592576529689572,5.5829011378688955,1,1 -200,20354.444025677687,15.165715477493398,1,3.6341160204153704,0.8922967389190681,4.87773330324598,0,1 -200,16787.78665950721,13.836540831678608,1,1.6712849401279457,1.0437181636347865,3.5836333084783663,0,0 -200,6650.402840260595,15.513493625409515,1,8.281880735528555,7.879754746210574,2.7732309492899643,1,1 -200,14727.069566810902,13.353187427362057,1,1.4821327910273432,3.406291692991092,7.2966732194680874,1,1 -200,15403.95727855294,14.324011581776091,0,2.4938822548620303,4.681864377584831,1.4713518026576184,1,1 -200,13376.871977509412,15.59818589508953,1,6.731548347460567,8.331979922918233,6.227434727573419,1,0 -200,20717.528969665334,14.373914571185699,1,1.784251751780173,6.8182869617707285,2.849734475285235,1,1 -200,9520.921687951291,14.331060484320565,1,3.4720399530716333,6.230384850730686,5.792533445254061,0,1 -200,24598.54102510981,14.829758183322305,0,1.9476557514817725,8.054335993164528,2.9804168606539996,1,0 -300,31748.927252879563,15.604097762927344,1,1.2452646432208851,5.216130876211581,4.43676640344995,0,1 -300,18831.2735936316,17.90351169991329,1,7.8337837903897976,5.71696508841696,6.084032002386403,1,1 -300,32091.717625587877,15.134095730182986,1,2.9391843388932894,5.779009734285671,7.15352656260047,1,1 -300,19176.359221719642,13.22804104046807,0,1.7307625861136466,6.487900228021807,4.604091565641033,0,1 -300,9412.254880159013,16.20418921283141,1,8.318874751119047,3.7177290788567605,6.269573902003725,1,1 -300,9750.878553470719,16.518557874296988,1,7.974652618371957,3.5797560734899174,2.026822942112406,1,1 -300,20637.28132543302,15.924560826001803,1,4.318126473528333,5.6661147907017115,4.298409400922215,0,1 -300,32483.486818784582,16.82237746235928,1,7.067274566710352,3.499457574174914,3.8270792459470466,0,1 -300,9913.759142466353,12.909895774730463,1,2.682644304820088,8.128250308508274,5.550678791770228,0,1 -300,29266.851915918036,16.15174247585525,1,4.5745365446875494,5.4903255933748305,6.000169835053462,0,0 -300,15404.899011867039,15.619581683816907,1,4.735752279446968,3.304351759535594,4.651602924563358,0,1 -300,7390.711637219311,14.030748733083062,0,4.211831999182768,0.880880285080554,2.915907862324824,0,0 -300,25739.335272921788,17.564596542580492,1,7.002841057210485,3.2300159355272307,2.5156432827750628,1,1 -300,38638.576375290555,17.93838753519442,1,8.720985812234847,3.448375856193967,5.781996178866821,0,1 -300,25004.8713344647,14.82987817899807,0,3.7305187967093505,2.7422196408920025,8.40048136626599,0,1 -300,12607.577625614877,14.039140091658483,1,4.907878153137965,6.794112194703816,2.8634155725666597,1,0 -300,10828.720879238233,16.994573064263673,1,8.879149423694804,6.2301397760542,3.9242596900443747,0,1 -300,10899.399068570196,14.76832706516041,1,4.077886632176067,7.047291571939587,5.926644108504782,1,1 -300,13555.163569475582,16.102711116395504,1,6.426635320865293,4.219521015348999,3.4647164923990923,1,0 -300,11312.971769691643,13.167877101441105,1,2.619207486117717,7.923650655053935,5.342642143333594,1,0 -300,10189.053516398244,14.14205044534573,1,2.3545332891362794,1.9691685149856362,4.865752240243183,0,1 -300,8651.540437073103,15.912730816068132,1,8.518948911964351,4.862141128350764,2.8906799366458773,1,0 -300,19341.90982756813,15.305999955617866,1,2.260273221791628,3.0736606271914866,7.246560465897039,1,1 -300,24061.024366265232,17.71016637008474,1,7.719860157899834,6.866175236277018,7.283089125551737,0,1 -300,7781.42230317207,14.567257732620517,1,4.734556438267059,5.366366806288394,7.704183374014861,1,1 -300,8445.315134366167,14.651012325965015,1,5.399544103253097,7.895413838712959,8.227392282518487,1,1 -300,5474.279415406555,14.812942001948667,1,8.134450169125596,9.404890403759078,3.5938432837800587,0,0 -300,9742.24069830052,14.383540854714159,1,5.601096724592346,5.396306367756646,3.706895886358846,0,0 -300,33135.98717405961,14.995884560342681,1,2.704527915309427,3.518085399485708,5.733833762553269,1,1 -300,10137.73517775082,13.992560295574338,1,3.6908434031745085,2.772988570287307,6.734468087347215,1,1 -300,45156.645560088335,17.767334162456624,1,6.880044606488963,4.261107527490839,4.04863733927543,0,1 -300,21294.03670164458,13.585498197641446,1,0.36701642678092605,4.803714467222958,3.8187641409057793,0,1 -300,13110.02886872942,16.505027332243714,1,7.863647052223733,9.336887503478682,3.296469747910344,1,0 -300,13173.037571385952,13.377604144159497,0,1.2301880933941418,2.062339690176903,8.627622221640676,1,1 -300,23745.112000095975,15.827050894552594,1,5.061864606975953,2.140823216746805,4.528075480811905,1,1 -300,16351.366755027782,14.998654522823122,1,4.4641864217941425,3.8607774190312516,5.107787028373085,1,1 -300,16319.338772110688,16.44219785726523,1,8.277236407531047,6.622657732265851,2.2155937050106393,1,0 -300,12075.79400439998,15.700714098789776,1,5.531582773708,7.221068267942256,6.077461802019259,0,1 -300,33203.00420958361,16.591976203320844,1,5.28738401326219,2.5675818821718446,0.6896993061766031,0,1 -300,20522.31486503528,16.78248374256413,1,6.9109264712206855,5.35801890596137,7.5440156427450304,1,0 -300,21476.832099319454,14.441663338332944,1,2.764353123063128,4.879014630715309,1.0807770397385408,0,1 -300,12350.61093486311,14.654053672055635,1,4.448664744891942,7.850286259847539,2.9225827340522663,0,1 -300,18097.883539130635,16.66715550668771,1,8.041350074081006,4.124283423749765,5.4564926112612335,1,1 -300,36448.35470701619,16.923026567519557,1,6.87318124415495,5.129729408209757,3.209478314271692,0,1 -300,7027.2411455177125,11.291951947689217,1,1.7576167577607285,6.793527255314303,3.452299218247541,0,1 -300,16586.693786768312,16.92537131360972,1,6.755049097987914,4.129852681497894,5.9336224187940605,1,1 -300,27702.83859704431,14.58152368241988,1,1.560516626214006,6.58908145510361,2.2171834467231566,1,1 -300,12274.045587199686,13.658192590016313,1,3.348964425337142,3.548558065150425,4.757931015073547,1,1 -300,13794.250008798945,17.38951523386476,1,8.1110781902655,4.831010675844202,6.3336155523310325,1,1 -300,31844.48502130152,18.343150023438234,1,8.293571925013616,4.9407404043872285,8.993967426578921,0,1 -300,8342.888029751575,13.527744271529471,0,2.7945715306694985,3.0237564787013143,6.262393409089084,1,1 -300,16637.49278532306,17.038081247454873,1,8.178372939127499,2.3639032372093123,4.990856917557221,1,1 -300,14837.73517503716,14.928261021712123,1,4.526189073756284,4.4375499253059365,0.4237968696579822,0,1 -300,10061.794965072482,15.203047477849875,1,6.193321977988092,4.028206176538874,1.8605677508677991,0,0 -300,15392.994553878703,16.740583147173698,1,7.201676610952844,7.253095161238875,4.105776088873533,0,1 -300,10289.354462141722,14.205871979660746,1,3.2104027670324573,8.708611406829652,6.947166342534725,0,0 -300,27392.69483155855,16.593352757773918,1,4.145599939640541,4.966367856891851,4.095946812192366,0,1 -300,20821.89300672218,15.054626282616956,1,3.841284247076098,6.113780763590365,6.506039270330609,0,0 -300,9306.25535880805,16.41612503793867,0,9.860024708986744,4.801421726045876,2.206178944213633,0,1 -300,9253.883201170793,14.710201535485536,1,5.35551128282137,6.659070462754071,4.2302181066561015,0,0 -300,12470.630506796842,17.240301411775103,1,6.315629029654789,5.61458078492284,5.610415468942813,1,0 -300,34442.58137934506,15.767941301415318,1,4.045524152472864,5.665158774876485,3.9941379748886567,1,1 -300,33409.002392092,16.66374854173967,1,4.320338544313545,7.902426090702296,5.318046878823711,0,1 -300,10545.848675229247,16.34935365588756,1,8.441656495077233,2.380239240805175,3.159702149508177,1,0 -300,31506.165384398948,15.659507440518599,1,4.050687938197208,5.977544470985794,6.047026420444653,0,0 -300,7978.222695345035,13.833798889805266,1,5.056802067053337,5.509078841315148,4.7714393663982015,1,1 -300,28772.0056038055,16.70093312804699,1,6.054218729549,3.449759972622635,4.867294036548311,1,0 -300,7761.728637216388,14.317989662028019,1,3.7959161364675276,4.538462083113486,0.709878654109487,1,1 -300,36045.67334801896,14.885690166293902,1,1.4672525492178012,6.0452109327959995,3.152145266452795,1,1 -300,10101.856330573335,17.08581932206896,1,9.357321507759938,0.5900213503726094,1.3595385163875793,1,1 -300,18101.13594352642,15.617314941812506,0,4.015617539092387,3.340502515516117,1.1688051672647148,0,1 -300,21512.235722104047,18.66850387499218,1,8.401016504985986,6.618513553914851,3.6274361867491525,0,0 -300,12324.42647647349,16.710807472190478,1,7.546627687447449,4.173651306608464,4.547106756612444,0,0 -300,6666.491461891411,14.21463781787692,1,7.356510181586874,2.8300013224420018,5.796119451164186,1,1 -300,21487.91637124985,13.796954464560928,1,1.7661625154155056,3.25085768049635,7.854861496049223,1,1 -300,12900.44096846603,13.293769687406336,1,2.9105987860242633,5.662795240720598,6.238591142785923,0,1 -300,27386.40755330786,15.073631807561274,1,5.544684443448315,1.1237871090059044,7.676586479187717,1,1 -300,15821.766646548695,17.612105014876555,0,7.969443300370104,7.343888807850256,3.5403118719719506,0,0 -300,46873.60113616399,15.425100120751697,0,2.9164489265590516,0.49413351217529466,4.136590519113031,1,1 -300,8282.127662117808,14.12555925863415,1,4.369677270358444,3.6019718568700005,7.8413821125192005,1,1 -300,6585.94669808374,12.845294273932335,0,2.0661597002616143,2.8632982850364233,5.003405403324509,0,0 -300,17973.236006641815,16.048919346007413,1,6.250464211822248,1.8116944788770464,1.0558358377240693,1,0 -300,18724.74282083443,14.228877692566861,1,2.1131149093270767,2.1747332215568953,2.716303896599326,1,1 -300,5480.765427524687,12.539639629607121,0,3.167160338918131,5.702780504414793,7.666308334112778,1,1 -300,22553.545917352312,17.170014934813537,1,7.1269309464934505,4.6624173106372035,3.316254578128906,0,1 -300,7394.148077553943,13.952099679579666,1,5.699662609939123,4.155969415987869,5.934283378860381,0,1 -300,15947.058329674104,17.62344363832393,1,8.526688103300925,1.6617264642314922,5.040121019122167,1,1 -300,34230.56970584425,15.896440820628577,1,3.3398123660300234,4.629976371704361,3.6207683939785023,1,1 -300,7785.714575214634,11.965047814027024,0,1.0064235451191441,2.6396033820922264,4.0178387018989605,1,1 -300,36349.78971735264,17.276430874290543,1,7.7579047887942725,2.839364576459753,6.094729752325873,1,0 -300,23521.14830790697,15.524147402003939,0,3.321816660288865,7.7617685810247625,5.589637113640483,1,1 -300,27184.004474139678,17.100639185667443,0,5.339176510505906,5.494400202216409,4.437682784421077,0,1 -300,11200.85839423006,17.55884333581621,1,9.000029861845402,2.25108557848423,2.531111934962899,1,1 -300,48213.31306973088,16.818369373627696,1,4.296280464565218,3.6954807818868995,5.467223480836103,1,1 -300,20977.703428244226,17.527578591875926,1,8.741148761203005,4.200258253252075,6.929401572872285,1,1 -300,12445.55583043555,13.36814711079269,0,2.1321772397552525,3.1350212559480855,3.7090609575495517,1,0 -300,25480.17425570534,17.0864978500973,1,7.474368622464169,2.434675062610122,4.085322095444034,0,1 -300,37322.641264568294,16.672977182083763,1,5.693636902861883,4.853887165436772,7.371187022395759,0,1 -300,30440.04478205255,15.688337371161152,1,2.9903664723112033,7.020862321610841,8.253907683776733,0,0 -300,9420.488882507934,13.021996627497115,0,1.7486312074498631,5.6379414903468845,3.190985625331063,1,1 +dose,exposure_1,exposure_2,response_1,response_2,cnt_a,cnt_b,cnt_c,bin_d,bin_e +0,0,0,6.489196214645731,0,3.057604138550052,6.5048262145977995,5.928022604062216,0,1 +0,0,0,7.812193527690828,0,5.721756322894736,3.843353277081516,5.596357122618091,0,1 +0,0,0,7.261407515718995,0,4.306662489636756,3.6750485047242183,8.164048170942932,0,0 +0,0,0,7.454625570595354,0,4.026785976794121,2.859747442471744,9.384136933581672,1,1 +0,0,0,6.334730381272093,0,2.463863258060802,3.358705389477543,8.293185904182378,0,1 +0,0,0,7.128279445704344,0,4.872994734282217,8.900582353371462,7.060294015893987,0,0 +0,0,0,6.067098715077391,0,2.8689966820760624,4.847616458270171,0.9891378149704455,0,1 +0,0,0,5.471084478446729,1,1.0739717499346388,5.336094862461806,3.340542646361642,1,1 +0,0,0,7.123415185510876,0,3.9368133844428,5.684954810605893,4.01436413941897,1,1 +0,0,0,8.209586737365065,1,7.458853827432172,8.155465805731481,6.924758203920312,1,1 +0,0,0,6.6126765992223575,0,3.4096620672871,3.567781482168498,4.702108291584847,1,1 +0,0,0,8.821860974305372,0,6.676454688442828,2.368463526508572,1.7913882312063083,0,0 +0,0,0,5.520788687287139,1,1.1498574658087628,8.937483791078602,8.950295974620941,1,0 +0,0,0,7.072435604863376,0,4.843291877321143,3.770213591451922,7.44069103341229,0,1 +0,0,0,8.082621388610695,1,6.44118794564693,3.02525423623661,5.667489562991372,1,0 +0,0,0,8.479756721442007,0,5.844864897522034,1.836772334277975,8.125941885183199,0,1 +0,0,0,7.92397467665474,0,5.297905392095343,1.7392847852757576,1.6339101370821265,0,0 +0,0,0,7.237225302054334,1,3.2377748040270617,3.4133025300781754,6.814565947210721,0,1 +0,0,0,6.423845066879124,0,2.708592276596476,6.70278061728451,3.5494149774296235,0,1 +0,0,0,6.3530580725094365,0,2.295841048528449,7.895720292986464,6.873882591265058,0,0 +0,0,0,7.386569868858843,0,5.331596650065819,6.935178060436716,4.828462897504693,1,0 +0,0,0,6.539497160282365,0,2.4736236516343975,3.9823751404750323,6.741998475444482,1,1 +0,0,0,6.565034451613263,0,3.636402445415764,5.1685150222288945,8.359845276233736,0,0 +0,0,0,6.429942127926224,0,4.280449760548192,3.072490942913965,5.02056493147758,0,1 +0,0,0,9.64708995121216,0,9.166186936740194,3.0401829165007643,7.689154457290752,0,1 +0,0,0,7.577166922738521,0,3.2084826277456076,7.376402078240974,1.9358130482650757,1,1 +0,0,0,8.231348711974602,0,5.661783084376143,2.3153442251303264,3.028982987246704,0,1 +0,0,0,8.19254795058863,1,5.219842511230999,9.297344462554067,8.690758328514333,1,1 +0,0,0,6.399338306683272,0,2.439820890273393,4.745339037970463,6.055388758518544,0,1 +0,0,0,7.095174180505278,1,4.798905539326781,5.603514564621188,0.6012804192296205,1,1 +0,0,0,9.179654939463944,1,8.561550734038173,2.985906427671349,1.5859239845676845,1,1 +0,0,0,7.992324145786552,0,6.25789639838503,3.412201885253288,4.434990961782319,1,1 +0,0,0,7.323802078165993,0,5.116303936114074,1.6758840872248122,7.330640203272737,1,1 +0,0,0,7.262622742455297,0,3.821078200980879,4.4850233372526755,4.712773364508995,0,1 +0,0,0,4.701453342828108,0,0.6002701880216281,6.169328031881751,6.719039769004755,0,0 +0,0,0,9.404425108832712,1,7.942484085552649,5.909008628253317,7.553493698877518,0,1 +0,0,0,6.137070118824934,0,1.4099877514239743,2.877429329556436,8.930636220129895,0,1 +0,0,0,7.909537639122898,0,7.017697637314545,2.8596996096972966,5.157990287469736,1,0 +0,0,0,9.942200676291126,1,9.244909354681717,3.605041399149745,4.853385781119949,0,1 +0,0,0,6.9349232626179544,0,1.4396198728914003,8.651472668956238,0.9523967453693967,1,1 +0,0,0,8.181539722975765,0,6.920294927893139,2.0446240867431293,5.280030511415713,1,1 +0,0,0,7.554170907876992,0,4.263437574345913,4.495886018469261,3.41893293537652,0,1 +0,0,0,5.219962933694823,0,1.222127713009047,9.23702888417423,2.4114157094508424,1,1 +0,0,0,6.213808098992416,0,1.316904779782032,4.7153309924433255,4.493489246332375,1,1 +0,0,0,5.712594693917876,0,1.1753646679091903,3.1751900838248073,7.683168998292205,0,1 +0,0,0,7.589961923396401,1,3.528008455169637,6.349843427422446,3.80803161169825,1,1 +0,0,0,7.712832441648484,0,6.8846356118338825,3.9495167676639937,5.328756578852783,0,0 +0,0,0,9.696651711162211,1,9.444601308449784,3.4454145535575735,2.602953705894361,1,1 +0,0,0,5.603886533487831,0,1.734698243101259,4.036790159940795,5.935551388632815,1,1 +0,0,0,8.47041397810273,0,7.13809282528176,5.2551596887784155,6.148692973657265,1,1 +0,0,0,8.230814735898344,1,7.091208214482693,8.819872123768606,4.90681285503473,0,0 +0,0,0,7.54850406957052,0,5.930851719676042,4.750281176544861,0.28728200406004556,0,1 +0,0,0,6.455305953879224,1,2.331889533141997,7.831692190211973,9.766596474919776,1,0 +0,0,0,6.787870492486485,0,4.663321699049897,6.736228833251078,4.4223408117605585,1,1 +0,0,0,7.848410727017708,0,4.212790522479133,4.679678561997343,6.789548890261756,0,0 +0,0,0,7.68566871765964,0,6.55754402063303,1.2863606477552603,5.768771262112718,0,1 +0,0,0,7.029647022425179,0,3.9582148934550783,3.554226571334798,7.705400262315004,0,1 +0,0,0,9.064239359281935,0,7.595489431737389,3.638255369559842,7.212527703302422,0,1 +0,0,0,7.2695305932492795,0,3.952325847405934,5.133002254197158,4.409763065110667,1,0 +0,0,0,8.733581160866954,0,7.768908985600291,8.291267427930208,6.057531259738392,0,1 +0,0,0,6.159276552665855,0,2.239051110003308,9.603130421338324,2.4784954790375173,0,1 +0,0,0,6.374809201050762,0,1.7883542502918455,8.737906764586185,3.7162301959388833,0,1 +0,0,0,9.24568365150096,1,9.947833220078346,4.624791492313548,9.684407108191902,1,1 +0,0,0,6.527367609313219,0,3.836474930158519,0.9479016704071886,1.0992047975011434,0,0 +0,0,0,8.078574378917963,0,5.836746443519315,3.913335344787947,3.7082364170268924,0,0 +0,0,0,8.153323079743704,0,6.751428137824397,5.251527659398115,7.231612426462339,1,1 +0,0,0,7.512347317869713,0,3.6546906417684255,7.279915212248259,6.416291712665252,0,0 +0,0,0,8.553807164343407,0,6.4343604653319755,7.561752057655783,3.3722651093262366,0,0 +0,0,0,8.052198370797965,0,6.032229989181176,6.87533701803964,2.358589153510275,1,1 +0,0,0,6.443186887181383,0,4.394131091899446,1.527715426423224,5.407043063117593,1,1 +0,0,0,7.605120472723194,0,5.184140720120146,7.2912576705315155,4.959640027343177,1,1 +0,0,0,7.293744481629401,0,4.903904831455794,3.755544692732871,0.9026147135691049,1,1 +0,0,0,9.68407118003107,0,9.470488873582738,5.492196282433816,5.097459711409097,0,1 +0,0,0,5.8986098841932115,0,2.9787789954421093,5.210234205415462,5.535452988935702,0,1 +0,0,0,7.802623982430102,0,5.106589921030279,6.194388338744096,5.49198226853115,0,1 +0,0,0,7.415886112360438,0,5.870728665027908,5.069604305128964,2.225905631120264,0,1 +0,0,0,7.995468004452522,0,6.2171579903474505,7.008933463280042,6.324644251767971,0,1 +0,0,0,7.052452718858038,0,3.7234796082647232,6.079110269281988,8.441312422438378,0,0 +0,0,0,5.711874710705908,0,2.207265210424865,4.2538171865405925,6.270744046377193,1,1 +0,0,0,9.40036531494651,0,8.217739224212957,5.33299767577077,2.048326010890793,1,1 +0,0,0,6.352230627631324,0,4.02097165691434,5.377704450488606,3.785232901064999,1,0 +0,0,0,4.930116895251125,0,2.6700084694627915,5.621638371030827,5.9692437458742464,0,1 +0,0,0,7.40034565757537,1,4.335723324364887,8.885370219399134,3.2212485831997344,0,1 +0,0,0,7.64281372686469,0,4.44508762676838,4.383867474338036,7.375436228573392,0,1 +0,0,0,8.805016391985745,0,7.895878207562873,5.4732923005963965,2.758278656324931,0,1 +0,0,0,7.871530880480954,0,5.238935506370299,8.021877066128875,3.414397964755505,0,0 +0,0,0,7.948752300048611,0,7.053421125180893,7.772214756108311,8.664852524495881,0,0 +0,0,0,6.742858355802726,0,3.6128653184311132,7.972511578275215,2.8959681377020297,0,1 +0,0,0,6.830867279289861,1,5.60325293462034,3.404042379611012,7.281676646597158,0,0 +0,0,0,7.635558247705009,0,4.089935603971496,9.34814287428454,1.7872923230791404,0,1 +0,0,0,8.56329074244514,0,5.266670623347122,5.18810898018986,4.007483411246163,0,1 +0,0,0,6.83588781558915,1,2.597763370896309,9.19455593970929,4.792570296721133,1,1 +0,0,0,5.830317350583002,0,1.6879816675797454,1.6107718165359886,1.9775553172041402,1,1 +0,0,0,9.654638668622335,1,9.342607679520592,5.059192055690255,3.2533298096985734,1,1 +0,0,0,7.57064386426511,0,6.657355351681319,8.19096862138861,4.918643596211149,0,1 +0,0,0,6.298334963669231,0,1.8062845834502341,3.0452330849131855,6.840163109538288,0,1 +0,0,0,6.552196885399921,0,3.3151279514916165,2.9500285270149664,1.0999609269595663,1,1 +0,0,0,9.437025786655225,1,9.530794498671527,2.494727353474394,4.020685201518525,0,0 +0,0,0,8.451567018226246,0,8.3151598291108,2.231536982108955,7.059364045010511,0,1 +0,0,0,6.977732683609459,0,4.255227863865191,3.781110248838436,3.5068814191751585,0,1 +100,5792.486656313507,6414.352377165037,13.332158939099946,0,4.448691674541115,5.401373736784317,1.0692570171295552,0,1 +100,2316.812393852626,2953.695558091119,12.586382412252071,1,6.4957400051660175,1.538411884022035,4.78134624304099,1,1 +100,8316.178369022535,8563.049963084737,14.623036698435774,1,6.698765254943929,2.6687311606468516,3.3945120195844947,1,1 +100,4448.398311447696,4923.296593068148,13.69829515582635,1,6.6990595310069825,4.540125855663566,5.154380866573085,1,0 +100,10607.527062580408,8901.036002183104,12.73095322701507,0,1.0385489796846095,7.941872462300682,1.3440169016450578,1,0 +100,4563.718644027419,6546.138163921706,13.729194644085908,0,6.031618002163338,3.5378375872265795,2.1226217327924153,1,0 +100,13585.146582038302,11074.097054011396,16.224536867784664,1,7.574227199144689,5.40464737349589,7.616600745981121,1,1 +100,4727.695511048153,4190.204288498101,14.53410991356924,0,8.244540117504954,2.1268703367809025,2.1292044251663524,1,0 +100,5384.3758869409385,5338.872628705425,12.031937890598988,0,4.367342649049377,7.4218273576543,2.8325252023387764,0,1 +100,5398.304178953146,8120.922161543971,12.403935030786384,1,4.09766545377707,8.630350006188655,5.2252328210433685,0,1 +100,1994.6334267428565,4667.80644303015,12.708558081498825,1,8.637352007271096,7.162708383432515,4.095302522621443,1,0 +100,6519.729324271813,6076.304264272965,11.381456196998606,0,1.0739922916629092,9.165442715639248,5.41249879954274,0,0 +100,5544.811059092583,6707.3540490092455,12.678460307548216,0,3.7820075038941523,8.183891482723245,9.611661240986761,0,1 +100,4345.180562227983,4309.6670788071715,13.10988629110322,1,6.274069923828192,4.6283796337001295,2.0721136664247046,1,0 +100,6038.233995493904,6686.748889168508,11.89371350511611,0,1.1500261793162043,6.327088508921066,4.1431631739657675,1,1 +100,6319.24103370329,6894.191022795127,14.600527781245962,1,5.785075382849431,2.4161161615802493,3.565914840643755,1,1 +100,5059.70342538998,4964.7293760526045,14.777544531505729,1,9.207901606732886,4.4786401900569395,8.679258225960595,1,1 +100,3434.63856189365,3817.4955541993113,11.9605330781573,1,4.988545113554121,8.131828605495993,2.907678445951289,0,1 +100,7208.390511707033,7012.181626295823,14.260220101367162,1,4.218189001356344,6.499728080331969,4.768531648642092,1,1 +100,7564.479861185214,8071.835755462335,13.602341506407251,1,6.321340653696426,6.2737856928139415,7.1365794998092005,1,0 +100,8922.62502848016,8241.219872076512,13.852969698266365,1,4.216469855103002,2.2640136191468,2.2178798664589743,0,1 +100,5698.2530256614045,5659.906953574882,15.508886865876645,1,7.2019777600989565,3.332625794762305,8.906994915504088,1,0 +100,4237.935123967621,3954.1514713551915,14.953225248216373,1,7.424031830897312,2.9199573959918617,6.85326880575046,0,1 +100,5175.34755648003,5507.4403990750425,13.22258630980483,1,5.007593061880345,6.104530679559303,2.182968137246969,0,1 +100,4727.477691771624,4032.7977535648015,10.96523685444541,0,1.9605340473349886,2.373090006200211,6.266242436479251,0,1 +100,3921.7587097305022,4379.877532102205,10.870117277990063,0,1.67354471214608,6.555024120128498,4.399931047582023,0,1 +100,6633.601198006653,6884.728457794412,12.593442184920951,1,3.362980217320941,2.089931299414432,5.878343415203785,1,1 +100,12207.262766240096,10835.73353313552,16.839459192983774,1,7.162159780199832,9.146885082679887,4.746309125714758,0,0 +100,4171.916279455729,3708.781141135064,10.092921420091253,0,0.7819509967146185,6.282557734599852,7.808804827137682,0,1 +100,6594.797700087421,6142.219546695741,13.012879682870928,0,3.2037234233395684,3.0817090184599594,1.6103961628580932,1,1 +100,5709.511451713659,5635.95440101879,14.241283912240545,1,6.102061242924149,5.677582909313927,3.5502074368343184,1,1 +100,6161.231689170206,5527.346562571429,11.961769163842144,0,2.5541097911022876,4.013242714293911,4.299692420863066,1,1 +100,2198.0079398096027,3390.135439532008,12.662811410793399,1,7.381471085856077,6.0382355501224625,2.3608565347230863,1,1 +100,1838.5492930592943,3515.967315244419,10.742057298605726,1,5.934078409839395,5.684523092726447,2.259882709876835,1,1 +100,3172.2471156226825,4378.443111025503,11.997809148640858,1,4.5194838282396095,2.318729591469035,4.949279656524511,0,0 +100,2196.8596541132188,2457.4443504163005,12.70115839970234,1,7.215419864118568,2.8529745339112034,4.6275354989119215,1,0 +100,2879.0361002609925,3812.54132104598,11.733773871347346,1,6.0855269596998705,5.840537417966934,0.24394186493636158,1,0 +100,5298.248469112444,6169.429554524686,13.130730079887934,1,3.7572360618668323,8.88264316453284,7.7415170361108165,0,1 +100,3601.8544560622922,3666.696383343603,12.318285737453547,1,5.649852263471692,7.840159354507797,5.701799880070509,1,1 +100,8443.414476847287,8103.665059465606,15.322609722500612,1,6.7799695915185225,3.279964702170296,9.68406836528176,0,1 +100,3891.8149150167706,5370.208593950568,13.031033478034908,0,5.997314661459724,7.2329528676534816,6.87762898868221,0,1 +100,5385.263167709534,4694.466998411651,12.12076585568827,1,3.1927298833273166,4.863010774121801,3.754451716802504,0,0 +100,6583.4486446949395,8332.280985020578,15.006990736603775,0,7.304851362065715,5.845309578720973,9.86486719455298,1,1 +100,3358.346732046069,4620.110948282721,12.943262073779078,1,7.988962456324628,5.731447565440183,1.8728136227342227,1,1 +100,8801.909605536828,8677.299881130804,14.695272195576635,1,5.775748977845448,9.768457908702274,6.305428899261613,0,1 +100,5049.161438068318,4602.276455025105,13.695596479222603,1,5.406000291318604,1.9424191506274955,4.405695164213576,1,1 +100,3828.1139745462183,3343.5819764782136,11.196519774441084,0,4.786739470025871,5.284514001506384,5.526542765912774,0,1 +100,4217.935131991256,5741.935628540729,14.138352266388052,1,9.499436205343333,6.628672321798162,5.639871705454672,0,1 +100,3363.006491696749,5564.1318058660945,11.874399242390284,1,5.77586295625652,7.866652862190444,1.7848430279386882,1,1 +100,6069.635927245591,5213.489569588661,12.510186275320383,1,4.554138753252859,8.563527714400418,5.8016485262482025,0,1 +100,3291.9652858368854,3897.9432776410504,9.856668863961172,0,0.26473396020633844,0.736573077175806,9.042132590019838,0,1 +100,3490.5997316201665,4008.421176808425,9.78011554639762,0,1.2332121574620427,6.152354798176315,4.537865821823549,1,0 +100,4457.1271519769025,5237.322608123255,11.578471949307403,0,4.780968009933569,8.811758710128707,4.541131450210465,0,1 +100,3521.4722460325142,3260.410616885845,12.153329759558666,1,5.580443825935508,3.8442389065603915,7.409531416544217,0,1 +100,4856.583970161082,5619.3736789822615,13.176974415227482,1,5.77741211918768,4.403166928497591,1.1030530458970804,0,0 +100,6288.699266035842,5841.44471711933,15.15165435882498,0,7.222044515456588,4.8969387761531795,5.642705780327924,0,1 +100,6917.160229998115,6404.17117619874,13.010946105411415,1,4.453557312702329,6.021372480755105,8.904551157621274,0,1 +100,8580.691201223957,8201.176680515433,16.460504719127336,1,8.118671270371696,6.825822214243295,8.508898573113331,0,0 +100,4664.94065286352,4844.099710458668,11.850448044302432,0,2.5351413278342356,8.325678916293239,6.171974258449712,1,1 +100,12074.476052801303,13648.904016387885,13.639788698504733,1,1.8940593045849228,4.730783275724553,6.970038023084847,1,0 +100,2107.322449718774,4162.743444852758,8.9500634498934,0,1.8516825719777905,5.5523974161679615,1.9180154205510414,0,1 +100,6279.187235193722,6992.191526681294,15.597304847892234,1,7.023658305970124,9.724763998276183,5.842029860254204,0,0 +100,5220.611746491492,5972.7532292195765,12.962849894735042,1,4.766184543104558,6.2023811544956775,2.4572063590477384,0,1 +100,4549.517439586109,4094.5896149303944,12.980569010409285,0,7.143288872834308,5.531313073765541,3.7244217086420854,1,1 +100,9699.19010698969,9440.294882979259,14.10223899965973,1,4.248095754058324,1.6272733438698141,7.498324231730922,1,0 +100,2742.8955090377162,4449.312130217009,9.783557232938731,1,3.3658978093705234,5.008056759021672,2.045509808130631,0,1 +100,9719.276902507589,11455.284580351816,13.913866143262826,1,3.969453519960786,4.37750420065168,5.7497097784720985,1,1 +100,3548.8420973264283,3228.517662412744,9.901524952443733,0,0.8229287026925227,4.968840492437989,6.194838988771196,0,1 +100,3715.8577129934097,4867.007403836559,11.144541542417256,0,1.9755109460550722,3.4094747845010254,5.154875503057598,0,0 +100,9416.004624196456,8073.631031036719,13.244699996147334,0,1.442930970077672,3.1182017495858054,9.138811194841654,1,1 +100,2606.755095814242,3637.8135208109334,12.468804324810412,1,7.772532367419991,3.0311032088011673,2.299905034838547,1,1 +100,3836.6048173752497,5294.791256223592,11.974578178729077,0,3.3515500057118475,4.396581478637527,6.671629874942297,0,1 +100,15788.765254797207,11657.527167108356,17.26200972889094,1,7.142394261294255,8.421778370188349,4.749251679001337,1,1 +100,6846.8408106782945,5387.042743513291,15.263302683671972,1,8.68616875893034,7.760745127203258,4.2672409087031165,1,1 +100,5042.197937859863,8479.817466534067,12.480204114851102,0,4.460219006653846,3.9925145266741198,6.292045413494025,0,1 +100,4684.992130655429,5612.595266647488,13.61819012078654,1,5.796894047311976,1.047543110338311,2.3043498131594404,1,0 +100,5205.245119112871,4937.118069783274,11.223859823764469,1,0.955369096809161,2.721138118915017,1.6828184464132887,1,1 +100,8254.820675697525,8299.364291916176,13.402851793281098,0,2.7849719257353134,3.7251203680133873,3.6258251230370435,0,1 +100,6707.642714012442,9337.448291769626,14.54596705659988,1,5.158548790489286,5.292167149690834,9.045576217735778,0,1 +100,5236.274779677547,4753.6275874099,13.782356810588034,0,5.839131150759974,3.1807972752530245,5.157279937378575,1,1 +100,2532.2524409269954,3740.2324983859908,10.86893114097975,0,2.9330851353483323,9.352528235705389,5.928728174850139,1,1 +100,3850.486818962948,4211.887055396882,15.12367276513488,1,9.814890908096901,4.2353998375593,4.465622207332454,0,1 +100,3826.566308037372,6095.113021350251,11.967718297467444,0,3.7234123497655065,1.8826611682271177,6.309383600402507,0,1 +100,3810.903603782641,7161.9580475636485,12.66258700489874,0,5.181182427714609,4.601989728626647,2.4637197402434357,1,1 +100,2615.2133652181474,3382.872717179358,12.991944444576255,0,6.785901896509959,2.338781640987216,7.999591071781965,0,1 +100,5440.526370436758,4951.569239257368,12.725121082733946,1,4.926605797897124,5.439856309359714,6.61511231610895,1,1 +100,3892.210831747181,4828.059542450879,10.994276502485038,1,3.2303123798238937,5.656887530444408,2.81526438207593,1,1 +100,7686.225346282486,7136.688013148966,15.74924718362566,1,7.7522147470929745,5.995397317191248,5.153864141075233,1,1 +100,5787.183235283224,5869.960361020014,15.276436065569396,1,8.846517271204602,1.1437080458189886,6.957551635563912,0,1 +100,11835.09341261012,9793.736097284518,14.96908729954546,1,4.916239363595229,5.620776704153693,6.5435617325385635,1,1 +100,2830.606810532896,3476.6306974298313,12.792455932983522,0,6.555624685133521,5.870643736355493,8.627158713909894,0,1 +100,11826.237564338295,10125.339958900408,15.211880216395718,0,4.725362335324697,1.4805231435665986,3.310341051654835,0,1 +100,7284.854050372306,6643.518777780306,15.167405850515747,1,7.686630158181885,7.54494806177226,7.909458486083551,1,1 +100,10793.38243742387,11238.905288452286,13.141881456743105,0,2.0041302020697844,7.129167333401898,7.732398425384018,0,0 +100,6290.961458620722,7083.211332081773,12.817498774310547,1,3.335210970848082,9.60780472731524,4.542376722547146,1,0 +100,3373.2002355311456,3490.130833246618,10.81302544851094,1,1.413138549660384,5.441393293591616,2.4069481755552844,1,1 +100,3515.360408025521,3944.7717405498743,11.899315658872002,0,4.0174762342690045,5.131815419639071,2.1498177740091546,0,1 +100,7368.133190941582,6641.364706981902,14.904554806173449,1,5.413317329063969,5.272309627583235,6.274951313341083,1,0 +100,6099.923792599079,4911.275466481761,15.465261705824036,1,8.859012126378158,5.196748900413432,4.799416648269644,1,0 +100,4298.58154706991,4420.186232216749,14.462861270582733,1,7.440256643457809,0.8280683899723338,9.082554374882273,0,0 +200,8209.271398899262,8322.398272378017,14.42615070944615,1,4.576846423657821,5.583805644983615,0.5603381353237358,1,0 +200,23377.75162675892,18472.978487405628,16.468656524254413,1,7.7410724158877855,8.712843704663113,3.5914433407609185,1,1 +200,4343.543579178599,4774.575596410565,13.804098890749641,1,5.821008859724009,1.5973222819497293,7.90340385899413,0,1 +200,6958.820623997664,6095.367805341273,15.467031555883697,1,6.835128259727633,4.438244909947643,4.536846610366807,0,0 +200,26516.05528688492,24681.65323541862,14.797489126742068,0,3.359865326720936,6.738239912603264,3.9089626548887795,1,0 +200,16449.59520867885,16418.60637381704,17.675708854353314,1,8.791175022654155,9.059571856405903,8.423594349210143,0,0 +200,34723.39440726302,25962.326836944878,15.944586813151124,1,4.988747430994735,6.188518696219091,7.90975559401876,1,1 +200,7983.409395606317,7361.166057224115,15.242876631857007,1,7.2868496721221865,4.961202750961421,2.59137017366799,1,1 +200,12087.820498910349,10535.923227337289,15.336852391769247,1,4.717747950095126,4.1373758038875845,6.193569610313256,0,1 +200,5424.186445692916,7190.363826468417,13.297231059496548,0,4.214918874145839,6.156559852137251,1.8527934061346358,0,1 +200,16521.977924404157,16019.886720471797,16.19120110297062,1,7.129836533598022,7.623553249251586,3.6767572187350606,1,0 +200,19313.328980289385,15366.186150864569,13.691996444374482,1,1.2021427091465415,4.482407710132829,8.848119345800464,0,1 +200,19740.491664130757,15598.949877513955,15.99237365631981,1,6.330681027061026,5.461211754474274,8.571454882737584,1,1 +200,3954.2679085845075,6261.679826169998,13.190920077403154,0,6.0997902730102975,5.6102205558065235,7.893905150079405,1,0 +200,7751.640831053143,7927.29279000329,13.831989722170949,0,6.03061460402364,6.990575218321654,3.4214426776710742,1,0 +200,12476.885818703891,11777.820330192857,11.50498087321346,1,0.49457361043969406,7.899071878403177,0.7878087987714055,1,1 +200,9194.62687369045,8284.08157193938,16.109333576973913,1,6.811928937436892,5.783776626340147,1.9626341482292649,0,1 +200,14296.511937215988,16475.831782318433,15.818307558535741,1,3.735560306200156,4.785202021995395,7.538343708996904,0,0 +200,4826.1441577213245,7814.877847158479,11.789140671375423,0,3.0972955488860117,8.471157609700592,4.1845201118121205,0,1 +200,13312.064160485812,12442.927226808873,15.560367249776236,1,4.980686974961544,5.4633808918825535,0.4995398375468965,0,1 +200,7622.241726496546,9411.031695473263,15.770073019577064,1,8.431002472066902,8.787043799207138,4.492700507159636,1,1 +200,8129.069645317478,8184.2990256654575,14.06520871505845,1,3.251827980197564,4.825360005765777,8.499726616165573,1,1 +200,14801.139774399042,14387.959103924612,16.42181752385276,1,6.544552295465943,6.692115398316059,6.769430144533219,1,1 +200,6970.9146609596,7682.530569204619,14.433623995813866,1,5.9555922566624275,1.264547503534594,2.778569144636375,0,1 +200,9470.59724620107,10697.234815137143,11.615607469958421,1,0.969212047809994,4.683190741542122,1.2648303735022692,1,1 +200,13809.339371886665,12606.976141257437,13.626606128486348,0,0.6622817057699124,4.938520500938148,2.7655062502246244,0,0 +200,9831.883204098003,11184.174083003676,15.195889639699084,1,6.526371725922302,2.935741240483583,5.097393757834039,0,1 +200,11501.071519544857,10518.31684037761,14.16878901649519,1,4.902001663436763,2.269087219312311,7.384668735849478,0,0 +200,10333.722061048044,11710.641269634576,16.695748498211188,0,9.174537643832089,7.527990222841342,0.7197849475381869,0,1 +200,6283.526340573909,7992.006136064673,14.339847846080165,1,6.58590644642735,7.447306470664485,7.7020445345283,1,1 +200,4565.158335131761,4510.991452284402,14.505213950765611,1,7.2913869510598195,1.7116141130667442,5.015395959854497,1,1 +200,6807.895551719606,7523.822073211199,14.894137786087615,1,8.35766763754037,6.184056983238202,6.575572824704613,1,1 +200,16425.416885343704,14543.33713788378,14.567345590338162,0,3.6090235321012605,2.234778889631768,3.1703043148559202,0,1 +200,6497.116898988364,7454.067350482352,15.141589182685388,1,6.4161986767147585,6.457283348603054,3.7509869136782954,1,1 +200,5462.02344698657,7284.881511745612,15.120892400704863,1,7.337970201443137,3.12024220494258,7.749020029958312,1,1 +200,4496.891687676902,8719.524974845956,15.086036904025729,1,8.42406695898467,7.633785826250657,7.713374994713613,0,0 +200,9859.074400984788,11567.443136790072,16.482125024839554,1,7.075117368376639,5.108663265163866,6.213255612865558,1,0 +200,18215.567674035257,14340.808209535735,16.38909534907553,1,6.175238078047302,6.4860106793942505,8.828835549488922,1,1 +200,8810.540467459372,8011.165178048513,12.918336186972658,0,2.6634135828854184,3.5475007918879475,3.569533009727026,0,0 +200,10197.09690037155,9707.548727570622,15.955772141793389,1,6.9912950692814055,2.014708417627811,7.677656726515382,0,1 +200,9810.813545941719,9433.209003169592,15.827958574009308,1,6.389756475800491,7.448724248338268,4.8986229551658225,0,1 +200,9063.471881084204,10779.352761820925,16.517527924987345,1,6.7453688562033145,5.669279840627434,3.1685223304242682,1,1 +200,21993.102319233854,17340.62238871631,15.569666571826328,1,6.182055063485128,4.327938852150423,7.469297536479742,0,1 +200,22154.046901458245,23779.457394964964,15.823233414251554,1,4.43203117658782,5.195252527677445,8.446026839471305,1,1 +200,8215.580075999376,11224.334130362786,14.44451194598585,0,4.783242905040938,8.341341798094335,7.36091811579305,0,1 +200,14717.368092267401,13936.43272355872,16.277253919058197,1,6.883211677797529,3.0889943773217334,3.585667326265747,1,1 +200,7452.788306831202,11291.196407397529,13.470139286611099,1,5.483299347753819,2.958326011193038,3.692525122406318,1,1 +200,22962.758054122452,17236.760389073926,15.265584371591512,1,2.7567233666866815,3.292945540193643,8.439644239418358,1,1 +200,5278.836738672018,8505.554172264987,12.392399681934142,0,4.185655511607695,1.2015456747365851,5.9877862472678425,0,1 +200,30153.145582077905,27318.415124255684,14.91762980303145,0,1.6717884972402892,7.217399042507797,7.241958900850255,1,0 +200,7371.951997797979,6974.279307151979,13.150203218862549,1,2.4277067971653916,5.541447788916603,4.051189748883261,1,1 +200,8668.805248290519,9209.221276512939,14.780905107631913,1,4.592576529689572,5.5829011378688955,8.213416108232037,0,1 +200,6207.701816905771,8432.08243421734,10.748606707523777,0,0.8922967389190681,4.87773330324598,2.809546114424311,1,1 +200,12118.668178218077,11622.698728647252,13.581135400339358,1,1.0437181636347865,3.5836333084783663,6.722088895944066,1,1 +200,13332.82748825203,15052.938896108017,16.253627038735885,1,7.879754746210574,2.7732309492899643,2.7886715962824944,1,1 +200,32871.87854448492,25907.898042493605,14.973798515746246,1,3.406291692991092,7.2966732194680874,1.6259083847871711,1,0 +200,7171.278497283298,8576.708113584458,14.417481760886448,0,4.681864377584831,1.4713518026576184,5.384048970276291,1,1 +200,16942.370674350077,15834.96828294537,17.82911650951283,1,8.331979922918233,6.227434727573419,7.372225732900471,0,1 +200,12672.701596927698,11354.763592853526,15.888720562432239,1,6.8182869617707285,2.849734475285235,0.9550475775284323,0,1 +200,29321.414468464438,26481.42437102584,17.29453354587027,1,6.230384850730686,5.792533445254061,1.8059748070335928,0,1 +200,10163.702685198072,9048.579667671656,15.77288484538769,1,8.054335993164528,2.9804168606539996,9.062993642269163,1,1 +200,14607.565931436136,13740.405333396891,14.226125472069569,0,2.9026089528154775,3.5482645420216907,3.789988662273085,0,1 +200,5486.586483773231,6207.616964870593,14.23247012079122,0,6.991623016358376,9.069501661429328,6.4043775847042985,0,1 +200,12851.923109129337,10630.556376660195,14.175310937963365,1,3.378594604229306,6.833914093520549,3.5386380898740244,0,1 +200,7425.81894263422,9842.017694451728,14.367284069397416,1,5.00215570606778,5.3562576422869,4.1622675430351705,0,0 +200,21396.782289275034,18716.529132965537,18.965393346495,1,9.543464504186478,3.7412646478888223,5.245997888261016,1,1 +200,16804.810318023505,14415.448392709497,16.638436097238515,1,7.577907827185454,2.0460858798134725,5.030922549176221,0,1 +200,18294.956501209545,19050.193731017633,16.73384594698778,1,7.088605833425862,5.5902165433946145,4.458018309644155,1,1 +200,16950.35034183826,15527.511291768711,14.962906491158591,1,2.107607528211808,5.366250769734473,3.692501233164936,1,1 +200,9855.486345801282,13953.146596134951,13.381368748837813,0,2.8656655667037123,4.079367205635964,0.08297954396763986,1,1 +200,27567.53831876324,25416.33280471371,17.22918353058505,1,9.596654155217937,0.42975877947174607,9.196752505551265,1,1 +200,10911.098736145399,10483.797058773967,13.644745968011327,1,2.140639278783543,7.263238749724915,9.097573958726361,0,1 +200,10900.489909243186,11976.56631379606,14.673964622141154,1,5.603348242057016,4.1888107855155905,2.123504477102424,1,0 +200,8964.818050573082,11460.521583962702,15.113214546839025,1,7.395513024342368,6.803381779286967,4.526589431541404,0,1 +200,5335.16141873416,10053.204382659993,15.271481773853608,1,7.691896780377903,3.7353323454127163,8.435161092531496,0,1 +200,20678.951552258313,16375.40945306294,18.528239079292266,1,7.850108947290144,3.360691471623861,7.644893823202224,0,0 +200,7505.816733423624,6717.539342591004,13.273888075498943,0,4.540563581450756,1.0122686244075572,8.244585808405096,0,1 +200,8421.758265195354,14903.52019047372,13.68497714345657,0,2.7792412005278297,4.410727817982586,2.1884496752574454,0,1 +200,13336.35854199575,12190.61838016666,14.714739787922827,1,4.13820664123158,7.625045346555478,2.0529246899867366,1,1 +200,11855.081009261896,12598.777735636415,13.838841404275712,1,2.5815764689447604,8.93730010719896,7.053073774519614,0,0 +200,26494.75579088935,21928.34416732542,17.662710067585607,1,6.726585324472071,7.449233241192208,5.398050293970185,0,0 +200,5958.175034960825,7016.507671375174,15.049361750932064,0,7.9186494894534,7.9703618293917184,3.872423662745276,1,1 +200,11524.350565893483,12413.806485378433,15.009913976895387,1,6.024387939558229,7.420291688318153,3.9390402296651645,0,1 +200,21157.810129054113,20599.228344587184,14.498577197888427,1,2.6474902828318903,6.322640766207243,2.371032133634554,0,0 +200,18976.41704517491,15143.160757094203,17.454626156583252,1,7.704948008390015,3.390644803350197,5.252389597549633,1,0 +200,20518.90868802735,17137.207738200817,15.913036097576063,1,7.424807484579822,3.522582871166086,5.728261257375138,0,1 +200,15883.545656882052,15971.999002280625,15.701021276849122,1,4.330225450892959,1.176458909069459,5.58978825143452,1,1 +200,6827.705059982319,7010.872127784807,11.144837609760392,1,1.245279248047586,4.983588588810913,3.9507044873409667,1,1 +200,6202.143439618309,8149.541166089684,14.62608903120947,1,7.071736434980718,7.411837300196832,2.0517114909158787,1,0 +200,6157.286698573333,7122.588320682675,13.052717541912152,1,4.171913183980421,7.721899655826307,5.7129551269405985,1,1 +200,10041.566982926312,10756.806801492614,16.040980567352204,1,6.486261471953715,5.268217302827755,0.5614389989821496,0,1 +200,15847.644528301007,14640.586108341708,15.19173189210099,1,4.225319467208315,3.483347212306582,1.4851276475626516,1,0 +200,20494.340012082517,18546.94537094055,16.853035593819975,1,6.870192700236892,7.009415030275688,2.1780928892416243,1,1 +200,9971.665294350536,12041.395213304795,14.820833101118406,0,4.669404747979894,8.518511600993799,2.1730182191119334,0,0 +200,16732.17656896973,14806.876339355596,14.674472765743165,1,4.03469627651173,4.054010832055208,5.3021636287500105,0,1 +200,10503.197377222577,10136.704050771586,14.801357049987525,1,5.314638003431375,4.892932897141423,8.819838672110826,0,1 +200,13701.239434680874,14731.05386247037,15.431274637110244,1,4.204422398694544,6.2500264797780725,1.315797420368382,1,1 +200,15385.354996706206,14096.836686655057,14.962427465084145,1,3.368207978784787,8.938698286787112,6.20940296122607,0,1 +200,13790.521789428753,14149.726620577354,14.17094075139025,0,4.11415469236427,4.126517223067106,7.412291656336717,0,1 +200,17976.821947309516,17996.076675953183,15.987380432650369,1,4.97700325782903,7.300974570491798,2.375348353446779,0,0 +300,12165.25896801418,13745.081836954652,13.004163704906903,1,1.6617264642314922,5.040121019122167,3.6635920989564204,1,1 +300,29560.536381920163,26419.082407771337,15.856120093493818,1,4.629976371704361,3.6207683939785023,6.261422395689906,1,1 +300,17374.235610580523,16973.600625535022,14.835582041723546,0,2.6396033820922264,4.0178387018989605,5.4040023449439465,1,1 +300,24892.296216935887,20269.825350697396,14.797419496491433,0,2.839364576459753,6.094729752325873,6.541649402607643,1,0 +300,36934.88731664107,34616.55521743809,17.891509000730583,1,7.7617685810247625,5.589637113640483,4.236060571010272,0,1 +300,20868.22127890274,28548.88422844236,16.648225619507915,1,5.494400202216409,4.437682784421077,3.217983764611276,1,1 +300,14488.796286477133,18477.58469248013,13.359280217134923,0,2.25108557848423,2.531111934962899,5.202934116389359,0,1 +300,39683.23282798002,35945.22689134028,16.72970418013026,1,3.6954807818868995,5.467223480836103,5.584700359588863,1,0 +300,34333.47249963378,28250.486304266604,17.077632384009025,1,4.200258253252075,6.929401572872285,4.478275468974257,1,0 +300,16751.534711677505,17411.43858346646,14.947182976443564,1,3.1350212559480855,3.7090609575495517,5.088687166765212,1,1 +300,9619.636227971045,11759.57741890867,13.491367114322879,1,2.434675062610122,4.085322095444034,6.148479772559879,1,1 +300,19188.1719762519,15549.928072402376,15.453715354617241,1,4.853887165436772,7.371187022395759,2.890849833707267,0,1 +300,25700.502408292003,24749.615863820854,17.4091333026635,1,7.020862321610841,8.253907683776733,7.960494367764381,1,1 +300,9619.119436670162,14740.100384777015,14.630932211305485,0,5.6379414903468845,3.190985625331063,8.61896124453149,0,1 +300,18484.07661831599,15179.431495729576,15.583431298308739,1,4.43676640344995,6.824294067056863,3.734191770394882,0,1 +300,43030.19016596144,39086.11399032283,16.84818549206475,1,6.084032002386403,3.43669617970646,5.1528624170765625,1,1 +300,11432.293409223617,12223.807567400952,16.37899786658579,1,7.15352656260047,2.4390673059526313,7.365815930196188,1,1 +300,14788.212552158493,16662.94385412065,15.518735766553528,1,4.604091565641033,6.716874181565721,7.113973871746401,1,1 +300,8829.733507983281,12689.179038732791,15.638528788813334,1,6.269573902003725,5.300218269373902,1.850123326607941,1,1 +300,12292.189439992066,14803.18080169706,14.549352142780462,0,2.026822942112406,6.08817608428792,2.0970640378291523,0,1 +300,17006.253623937708,15708.777557644493,14.921788931651792,1,4.298409400922215,3.396004534900472,5.3768777868000575,0,1 +300,12924.818173286343,12863.580528254368,15.033241079839536,1,3.8270792459470466,9.103567379697994,6.7240001525964175,0,0 +300,18559.90371057664,17763.59700760282,15.288648459276487,1,5.550678791770228,6.826154353143589,7.348021939577631,0,1 +300,44567.84080224804,33432.07036763524,16.947752791255844,1,6.000169835053462,3.952816394428615,7.209389704558836,1,1 +300,18763.3607975295,17997.864147176275,16.041325034210473,1,4.651602924563358,6.922770087948479,2.425500953628389,1,1 +300,9814.15659399835,12353.61999476267,13.193179033877126,1,2.915907862324824,1.8814824999165274,1.684465936218574,0,0 +300,21296.834569946594,18359.31251842986,14.849416487028757,0,2.5156432827750628,4.6118607822564055,0.641408073829599,1,1 +300,20568.022152649137,25888.81331449512,15.812643052297409,1,5.781996178866821,8.487143793392615,6.402313694039802,1,1 +300,13075.206958453306,12182.757828853315,16.672487575073657,1,8.40048136626599,4.46844532337232,7.238352946982388,1,0 +300,14898.726344480012,15821.547402211978,14.294764574439125,1,2.8634155725666597,7.438535803779879,5.940933618633566,1,0 +300,12753.378190907843,13382.892254585382,14.268392294347946,1,3.9242596900443747,4.375838393803196,2.2166819711255124,0,0 +300,26195.33398489505,21134.480052694806,15.665688025653429,1,5.926644108504782,0.3933298053620754,3.9645184192736975,1,1 +300,18395.08090198922,17022.577246115514,15.067799891631802,0,3.4647164923990923,2.6343309109246564,9.082468631388727,0,0 +300,24996.12693951809,32876.11811739291,16.529276537784614,1,5.342642143333594,5.626436333236472,6.526712213882454,0,1 +300,12568.470177859681,16176.795130705468,15.087009307364623,1,4.865752240243183,8.56511039731245,8.06812297764113,1,1 +300,9718.897627895272,10871.595534390233,13.28527994140492,1,2.8906799366458773,3.361911854078738,5.9264275494811125,0,1 +300,29537.102201026875,30886.80404958155,17.880673169789773,1,7.246560465897039,5.7749268012615484,4.817665601417173,1,1 +300,5748.317521008416,10493.913209133614,15.077040221604033,1,7.283089125551737,2.432882837758738,2.3223183383235653,0,1 +300,17838.099514477006,17371.880412025632,15.833595038944392,1,7.704183374014861,2.3133674733023186,3.4543547183696734,1,1 +300,38904.400890718076,34799.199545053045,18.743678268035595,1,8.227392282518487,2.8880078054774536,4.867129079954179,1,1 +300,12126.031558462973,14460.883137235047,13.426686294888468,0,3.5938432837800587,8.423523397425729,5.791876936307208,1,0 +300,43377.02216007129,34490.8552719332,15.83688162300297,1,3.706895886358846,7.509462167201736,4.906296596454219,0,1 +300,7005.142322531736,9650.785611885938,13.677665835042351,1,5.733833762553269,6.638782260351767,4.498913887263775,1,1 +300,11925.567661657413,13899.363650192088,15.540496743228358,1,6.734468087347215,7.907987987806808,5.516547138538815,0,1 +300,11959.857898880386,14964.633365871654,15.17647257490661,0,4.04863733927543,3.8158169108431657,3.545503753451011,0,1 +300,35522.85169145109,28967.390450166477,16.164566044937096,1,3.8187641409057793,7.067366001666958,3.514554633597788,0,0 +300,41957.05651835512,34838.87034648197,16.024806154838156,1,3.296469747910344,5.589778299646108,7.282999936454018,1,1 +300,22241.85505243707,20584.398580215282,16.750532411304047,1,8.627622221640676,2.2392226465321285,5.132376098907868,0,1 +300,12451.717282616864,14233.801638864388,14.930843288817625,0,4.528075480811905,2.7543733680791127,4.764200353465234,0,1 +300,14632.683466621782,19096.35208461179,15.721529700531459,1,5.107787028373085,5.141175285446637,2.9798381199576958,1,1 +300,10897.621569217765,16057.783563925308,13.853278070613952,1,2.2155937050106393,5.5785851792987735,4.3036442293887935,1,1 +300,23364.067846544007,24189.290991920418,16.090336255742358,1,6.077461802019259,4.0991438960012685,2.1550438106450778,1,1 +300,22533.33982104565,18813.671456836437,14.30608385927204,0,0.6896993061766031,2.3592574332800034,2.2387799092641254,1,1 +300,16348.520198082508,15413.56041245594,16.108660022490888,1,7.5440156427450304,0.5640192066928705,7.606480599426786,0,1 +300,20327.45810498077,24072.308500236308,14.765527416619864,1,1.0807770397385408,6.186394138034357,5.354996530307087,0,0 +300,22855.996972034824,25806.558430781588,14.572548972055998,1,2.9225827340522663,4.171458275162509,2.089146347359691,1,1 +300,23636.628741208933,22375.416810805305,16.66340396186959,1,5.4564926112612335,6.520740165186025,6.720098748394086,1,0 +300,18665.420740570087,20382.577953255146,14.998891940851745,1,3.209478314271692,1.2648712872783994,7.023874537039008,0,0 +300,14294.714844867749,15375.280360516288,14.007925547640715,1,3.452299218247541,1.802109132281902,4.365080790565605,0,1 +300,20342.76175050648,16384.000464138884,16.895741609965025,1,5.9336224187940605,4.6861743661032556,3.820054390158627,1,1 +300,28227.645669854206,23495.813584564352,14.884109740551832,1,2.2171834467231566,1.495581819163721,4.723558914087529,0,1 +300,15143.83733171464,15400.198968041026,15.6987241438911,1,4.757931015073547,0.6725436621264774,6.130259422369127,0,1 +300,9283.50055410312,11033.194577460996,15.264649380754301,1,6.3336155523310325,7.12772681267332,7.168472583471895,0,1 +300,18996.88719875676,23348.886234339578,18.191866500357616,1,8.993967426578921,7.415473573596883,8.805576350871716,1,1 +300,15991.829833488313,17094.48373520319,16.14121961444791,1,6.262393409089084,2.2825534156164955,3.5865623275184944,1,1 +300,32572.41468155073,24359.008171044192,16.959322274648766,1,4.990856917557221,4.235984988949531,2.315407834582683,1,1 +300,11614.311802989258,10036.388323199299,12.474055649487644,0,0.4237968696579822,2.051815976220322,5.284341717596561,0,0 +300,23736.642545036328,20401.76873747153,14.751792421531182,1,1.8605677508677991,5.887202316443309,3.804387258062752,0,1 +300,22839.364781942804,19649.74791535477,15.751825567998678,0,4.105776088873533,4.916283501748959,4.316689386087194,0,0 +300,20492.683056024984,22153.71705528489,17.262372259827295,1,6.947166342534725,2.660408191070896,3.668840261243314,1,0 +300,17456.697454357836,18763.345165358118,14.873232369664345,1,4.095946812192366,2.8957858010046698,3.0575771013751623,1,1 +300,18493.25151258258,19127.267929701557,16.563554232524545,1,6.506039270330609,2.2100533158516895,4.40570161481345,1,0 +300,28055.62758893708,23892.86502942624,14.56517611441008,1,2.206178944213633,6.216751686831437,8.886794671961196,1,1 +300,16285.975048650585,14577.343587046016,15.59762232687645,1,4.2302181066561015,6.578835771847997,5.8467884303050734,1,0 +300,42142.31553441419,32825.28309272522,16.619981304551285,1,5.610415468942813,6.052879680192601,6.354888332778655,1,1 +300,8057.927864664029,12023.981722982855,14.54586877219256,1,3.9941379748886567,2.725292598430851,7.264507761508025,1,1 +300,17547.989347323324,15885.48889334137,16.197887550492915,1,5.318046878823711,0.9080504397950627,9.417750052546483,1,0 +300,10668.338741419853,10874.128033369358,13.846035245602971,1,3.159702149508177,6.471909019833805,7.1077320950150895,0,1 +300,12611.213844034357,14343.163816051598,16.218599584540165,1,6.047026420444653,4.501474769652831,1.4696811707999218,0,1 +300,26614.15505534205,21584.120035431843,16.03683907538272,1,4.7714393663982015,4.888886706073818,2.274491626620848,0,1 +300,10963.347143918963,9932.969316967865,15.04207946796538,1,4.867294036548311,7.722366397516628,1.1944458754084462,1,1 +300,18143.93236787625,14522.633895319585,13.812672628569397,1,0.709878654109487,2.6022112312043184,0.1303831272393341,1,1 +300,14399.596258630094,17591.60580374889,14.613631103894086,1,3.152145266452795,7.96982998964193,3.627865317595385,1,0 +300,12773.033607591628,16379.629769155965,12.996606850411446,1,1.3595385163875793,3.8464918010929723,6.1036394288398395,1,1 +300,15830.261441853803,12921.363688189946,12.941861300069709,0,1.1688051672647148,3.0504867447611668,8.049855848878297,0,1 +300,22538.231172463747,21306.77343223975,14.465658277973791,1,3.6274361867491525,4.42108988235164,3.579141120969666,0,1 +300,41143.342518825644,32641.791986715947,16.159338776424054,1,4.547106756612444,6.09006546985033,4.619683455639551,0,0 +300,10026.25456445505,12624.711271869193,15.387661509590945,1,5.796119451164186,4.416976683569073,5.980699097346058,1,1 +300,9475.48020257441,9979.983853911916,15.839557676877337,1,7.854861496049223,2.58539619493704,5.6352229205570765,1,0 +300,18094.876190014995,23309.455348879965,15.707245624349541,1,6.238591142785923,4.209373585429786,2.895540453102141,1,1 +300,9637.50186573593,9434.096854494011,16.98344353258493,1,7.676586479187717,3.5880638764397457,6.994490111986153,1,1 +300,10905.433262159897,10412.420297190769,14.437575454348057,0,3.5403118719719506,6.270010832128166,6.511340189024205,0,1 +300,13414.68561944681,12302.565090408878,15.744692331253592,1,4.136590519113031,4.523355801742015,4.190405389288239,0,0 +300,12067.329074494255,12211.30123825197,17.0376853169457,1,7.8413821125192005,6.885694329337884,1.8652530569161323,1,1 +300,21828.826025910188,20834.30449147564,15.647355841529734,1,5.003405403324509,6.351253759436382,6.742973183571793,1,0 +300,21035.18448537458,18035.49051405953,13.72420595960963,0,1.0558358377240693,6.775107056113479,8.531054609182933,1,1 +300,24442.853035245673,21743.76663201518,14.231482777916375,0,2.716303896599326,6.802164483799482,8.444941598769688,0,1 +300,12220.207631252648,13190.771528298525,16.737331216118008,1,7.666308334112778,0.9725964441999302,7.3473008639358195,0,0 +300,10527.280218634103,11609.786851672057,14.716516532807573,1,3.316254578128906,5.011734217832878,3.656434015517927,0,0 +300,15643.107979285553,24379.053550504603,15.470561617765615,1,5.934283378860381,8.868922645556612,3.5268301749575315,0,1 diff --git a/data/d_sim_emax.rda b/data/d_sim_emax.rda index 4baaae285f5fe4dff35ed5fc8eca768ef665af97..9ca26929d7ae71a914e5a9a2cf2379e0a162873d 100644 GIT binary patch literal 18006 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 literal 15640 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 Date: Wed, 17 Sep 2025 14:19:48 +1000 Subject: [PATCH 15/57] use renamed exposure_1 in placebo test --- tests/testthat/test-placebo_handling.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index 90a363a..738a3a6 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -42,7 +42,7 @@ for(r in 1:nrow(cases)) { set.seed(123L) suppressWarnings( m[[r]] <- d |> f( - var_exposure = "exposure", + var_exposure = "exposure_1", var_resp = cases$var_resp[r], options_placebo_handling = o, chains = 1, From 2e45d0f56782bcba52a9b02269c947c6e4ed2bbf Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 16:02:12 +1000 Subject: [PATCH 16/57] placebo handling data tests now cover metric selection functions --- tests/testthat/test-placebo_handling.R | 151 ++++++++++++++++++------- 1 file changed, 109 insertions(+), 42 deletions(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index 738a3a6..b8ed9c7 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -5,93 +5,160 @@ dat <- list( noplacebo = d_sim_emax |> dplyr::filter(dose != 0) |> dplyr::slice_sample(n = 10, by = dose) ) +# two versions of the placebo handling options +opts <- list( + drop_placebo = list(include_placebo = FALSE), + use_placebo = list(include_placebo = TRUE) +) + # four versions of the modelling function dev_ermod <- list( - dev_ermod_bin = dev_ermod_bin, dev_ermod_lin = dev_ermod_lin, + dev_ermod_bin = dev_ermod_bin, dev_ermod_emax = dev_ermod_emax, dev_ermod_bin_emax = dev_ermod_bin_emax ) -# two versions of the placebo handling options -opts <- list( - drop_placebo = list(include_placebo = FALSE), - use_placebo = list(include_placebo = TRUE) +# four versions of the exposure metric selection function +dev_expsel <- list( + dev_ermod_lin_exp_sel = dev_ermod_lin_exp_sel, + dev_ermod_bin_exp_sel = dev_ermod_bin_exp_sel, + dev_ermod_emax_exp_sel = dev_ermod_emax_exp_sel, + dev_ermod_bin_emax_exp_sel = dev_ermod_bin_emax_exp_sel ) -# all 16 test cases -cases <- tidyr::expand_grid( +# all test cases for basic er model +cases_ermod <- tidyr::expand_grid( dat = names(dat), dev_ermod = names(dev_ermod), opts = names(opts), ) |> dplyr::mutate( var_resp = dplyr::case_when( - dev_ermod == "dev_ermod_bin" ~ "response_2", dev_ermod == "dev_ermod_lin" ~ "response_1", + dev_ermod == "dev_ermod_bin" ~ "response_2", dev_ermod == "dev_ermod_emax" ~ "response_1", dev_ermod == "dev_ermod_bin_emax" ~ "response_2" ) ) -# fit the model for each case +# all test cases for exposure selection functions +cases_expsel <- tidyr::expand_grid( + dat = names(dat), + dev_expsel = names(dev_expsel), + opts = names(opts), +) |> dplyr::mutate( + var_resp = dplyr::case_when( + dev_expsel == "dev_ermod_lin_exp_sel" ~ "response_1", + dev_expsel == "dev_ermod_bin_exp_sel" ~ "response_2", + dev_expsel == "dev_ermod_emax_exp_sel" ~ "response_1", + dev_expsel == "dev_ermod_bin_emax_exp_sel" ~ "response_2" + ) +) + +# helper function to inspect internal data objects +internal_stan_data_rows <- function(object) { + if (inherits(object, "stanemax") | inherits(object, "stanemaxbin")) { + return(object$standata$N) + } + return(nrow(object$data)) +} + +# fit the model for each basic er model case m <- list() -for(r in 1:nrow(cases)) { - f <- dev_ermod[[cases$dev_ermod[r]]] - d <- dat[[cases$dat[r]]] - o <- opts[[cases$opts[r]]] +for(r in 1:nrow(cases_ermod)) { + f <- dev_ermod[[cases_ermod$dev_ermod[r]]] + d <- dat[[cases_ermod$dat[r]]] + o <- opts[[cases_ermod$opts[r]]] set.seed(123L) - suppressWarnings( + suppressWarnings(suppressMessages( m[[r]] <- d |> f( var_exposure = "exposure_1", - var_resp = cases$var_resp[r], + var_resp = cases_ermod$var_resp[r], options_placebo_handling = o, chains = 1, iter = 100 ) - ) + )) } -cases$mod <- m +cases_ermod$mod <- m -# helper function to inspect internal data objects -internal_stan_data_rows <- function(object) { - if (inherits(object, "stanemax") | inherits(object, "stanemaxbin")) { - return(object$standata$N) - } - return(nrow(object$data)) +# fit the model for each exposure-selection model case +m <- list() +for(r in 1:nrow(cases_expsel)) { + f <- dev_expsel[[cases_expsel$dev_expsel[r]]] + d <- dat[[cases_expsel$dat[r]]] + o <- opts[[cases_expsel$opts[r]]] + set.seed(123L) + suppressWarnings(suppressMessages( + m[[r]] <- d |> f( + var_exp_candidates = c("exposure_1", "exposure_2"), + var_resp = cases_expsel$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) + )) } +cases_expsel$mod <- m -cases$inner_n <- numeric(nrow(cases)) -cases$outer_n <- numeric(nrow(cases)) -for(r in 1:nrow(cases)) { - cases$inner_n[r] <- internal_stan_data_rows(cases$mod[[r]]$mod) - cases$outer_n[r] <- nrow(cases$mod[[r]]$data) +# record number of rows in the inner and outer data sets (basic models) +cases_ermod$inner_n <- numeric(nrow(cases_ermod)) +cases_ermod$outer_n <- numeric(nrow(cases_ermod)) +for(r in 1:nrow(cases_ermod)) { + cases_ermod$inner_n[r] <- internal_stan_data_rows(cases_ermod$mod[[r]]$mod) + cases_ermod$outer_n[r] <- nrow(cases_ermod$mod[[r]]$data) } +# record number of rows in the inner and outer data sets (metric selection) +cases_expsel$inner_n <- numeric(nrow(cases_expsel)) +cases_expsel$outer_n <- numeric(nrow(cases_expsel)) +for(r in 1:nrow(cases_expsel)) { + cases_expsel$inner_n[r] <- internal_stan_data_rows(cases_expsel$mod[[r]]$mod) + cases_expsel$outer_n[r] <- nrow(cases_expsel$mod[[r]]$data) +} + + # the "stan" data set should only include placebo samples if the data set # originally contained a placebo group, and the options specify that the # placebo group is to be used during model fitting -test_that("internal stan data respects placebo options", { - - for(r in 1:nrow(cases)) { - if (cases$dat[r] == "placebo" & cases$opts[r] == "use_placebo") { - expect_equal(cases$inner_n[r], 40L) +test_that("internal data respects placebo options (basic models)", { + for(r in 1:nrow(cases_ermod)) { + if (cases_ermod$dat[r] == "placebo" & cases_ermod$opts[r] == "use_placebo") { + expect_equal(cases_ermod$inner_n[r], 40L) } else { - expect_equal(cases$inner_n[r], 30L) + expect_equal(cases_ermod$inner_n[r], 30L) } } - }) +test_that("internal data respects placebo options (metric selection)", { + for(r in 1:nrow(cases_expsel)) { + if (cases_expsel$dat[r] == "placebo" & cases_expsel$opts[r] == "use_placebo") { + expect_equal(cases_expsel$inner_n[r], 40L) + } else { + expect_equal(cases_expsel$inner_n[r], 30L) + } + } +}) + # the "user facing" data set should only include placebo samples if the data set # originally contained a placebo group, regardless of the placebo handling settings -test_that("outer data preserves all data rows", { - - for(r in 1:nrow(cases)) { - if (cases$dat[r] == "placebo") { - expect_equal(cases$outer_n[r], 40L) +test_that("outer data preserves all data rows (basic models)", { + for(r in 1:nrow(cases_ermod)) { + if (cases_ermod$dat[r] == "placebo") { + expect_equal(cases_ermod$outer_n[r], 40L) } else { - expect_equal(cases$outer_n[r], 30L) + expect_equal(cases_ermod$outer_n[r], 30L) } } - }) +test_that("outer data preserves all data rows (metric selection)", { + for(r in 1:nrow(cases_expsel)) { + if (cases_expsel$dat[r] == "placebo") { + expect_equal(cases_expsel$outer_n[r], 40L) + } else { + expect_equal(cases_expsel$outer_n[r], 30L) + } + } +}) + From c8dd5b21b57774459f1742b678f03140a68725d8 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 16:22:03 +1000 Subject: [PATCH 17/57] placebo handling data tests now cover covariate selection functions --- tests/testthat/test-placebo_handling.R | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index b8ed9c7..3c9aca4 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -27,6 +27,12 @@ dev_expsel <- list( dev_ermod_bin_emax_exp_sel = dev_ermod_bin_emax_exp_sel ) +# two versions of the covariate selection function +dev_covsel <- list( + dev_ermod_lin_cov_sel = dev_ermod_lin_cov_sel, + dev_ermod_bin_cov_sel = dev_ermod_bin_cov_sel +) + # all test cases for basic er model cases_ermod <- tidyr::expand_grid( dat = names(dat), @@ -55,6 +61,20 @@ cases_expsel <- tidyr::expand_grid( ) ) +# all test cases for covariate selection functions +cases_covsel <- tidyr::expand_grid( + dat = names(dat), + dev_covsel = names(dev_covsel), + opts = names(opts), +) |> dplyr::mutate( + var_resp = dplyr::case_when( + dev_covsel == "dev_ermod_lin_cov_sel" ~ "response_1", + dev_covsel == "dev_ermod_bin_cov_sel" ~ "response_2", + # dev_covsel == "dev_ermod_emax_cov_sel" ~ "response_1", + # dev_covsel == "dev_ermod_bin_emax_cov_sel" ~ "response_2" + ) +) + # helper function to inspect internal data objects internal_stan_data_rows <- function(object) { if (inherits(object, "stanemax") | inherits(object, "stanemaxbin")) { @@ -101,6 +121,26 @@ for(r in 1:nrow(cases_expsel)) { } cases_expsel$mod <- m +# fit the model for each covariate-selection model case +m <- list() +for(r in 1:nrow(cases_covsel)) { + f <- dev_covsel[[cases_covsel$dev_covsel[r]]] + d <- dat[[cases_covsel$dat[r]]] + o <- opts[[cases_covsel$opts[r]]] + set.seed(123L) + suppressWarnings(suppressMessages( + m[[r]] <- d |> f( + var_exposure = "exposure_1", + var_cov_candidates = c("cnt_a", "cnt_b"), + var_resp = cases_expsel$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) + )) +} +cases_covsel$mod <- m + # record number of rows in the inner and outer data sets (basic models) cases_ermod$inner_n <- numeric(nrow(cases_ermod)) cases_ermod$outer_n <- numeric(nrow(cases_ermod)) @@ -117,6 +157,13 @@ for(r in 1:nrow(cases_expsel)) { cases_expsel$outer_n[r] <- nrow(cases_expsel$mod[[r]]$data) } +# record number of rows in the inner and outer data sets (covariate selection) +cases_covsel$inner_n <- numeric(nrow(cases_covsel)) +cases_covsel$outer_n <- numeric(nrow(cases_covsel)) +for(r in 1:nrow(cases_covsel)) { + cases_covsel$inner_n[r] <- internal_stan_data_rows(cases_covsel$mod[[r]]$mod) + cases_covsel$outer_n[r] <- nrow(cases_covsel$mod[[r]]$data) +} # the "stan" data set should only include placebo samples if the data set # originally contained a placebo group, and the options specify that the @@ -139,6 +186,15 @@ test_that("internal data respects placebo options (metric selection)", { } } }) +test_that("internal data respects placebo options (covariate selection)", { + for(r in 1:nrow(cases_covsel)) { + if (cases_covsel$dat[r] == "placebo" & cases_covsel$opts[r] == "use_placebo") { + expect_equal(cases_covsel$inner_n[r], 40L) + } else { + expect_equal(cases_covsel$inner_n[r], 30L) + } + } +}) # the "user facing" data set should only include placebo samples if the data set @@ -161,4 +217,13 @@ test_that("outer data preserves all data rows (metric selection)", { } } }) +test_that("outer data preserves all data rows (covariate selection)", { + for(r in 1:nrow(cases_covsel)) { + if (cases_covsel$dat[r] == "placebo") { + expect_equal(cases_covsel$outer_n[r], 40L) + } else { + expect_equal(cases_covsel$outer_n[r], 30L) + } + } +}) From 680bb86d9a48b745d8b8dd97d1c13ae7afec1e35 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 16:45:02 +1000 Subject: [PATCH 18/57] use placebo options in examples/test --- R/dev_ermod_lin.R | 3 ++- man/d_sim_emax.Rd | 3 ++- man/dev_ermod_bin_exp_sel.Rd | 3 ++- tests/testthat/test-dev_ermod_emax.R | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index d48d4a6..fccf38e 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -370,7 +370,8 @@ dev_ermod_lin <- function( #' ermod_lin_exp_sel <- dev_ermod_lin_exp_sel( #' data = d_sim_lin, #' var_resp = "response", -#' var_exp_candidates = c("AUCss", "Cmaxss") +#' var_exp_candidates = c("AUCss", "Cmaxss"), +#' options_placebo_handling = list(use_placebo = TRUE) #' ) #' #' ermod_lin_exp_sel diff --git a/man/d_sim_emax.Rd b/man/d_sim_emax.Rd index 894854c..2c63380 100644 --- a/man/d_sim_emax.Rd +++ b/man/d_sim_emax.Rd @@ -8,7 +8,8 @@ A data frame with columns: \describe{ \item{dose}{Nominal dose, units not specified} -\item{exposure}{Exposure value, units and metric not specified} +\item{exposure_1}{Exposure value, units and metric not specified} +\item{exposure_2}{Exposure value, units and metric not specified, but different from exposure_1} \item{response_1}{Continuous response value (units not specified)} \item{response_2}{Binary response value (group labels not specified)} \item{cnt_a}{Continuous valued covariate} diff --git a/man/dev_ermod_bin_exp_sel.Rd b/man/dev_ermod_bin_exp_sel.Rd index 2aac225..b67301d 100644 --- a/man/dev_ermod_bin_exp_sel.Rd +++ b/man/dev_ermod_bin_exp_sel.Rd @@ -94,7 +94,8 @@ data(d_sim_lin) ermod_lin_exp_sel <- dev_ermod_lin_exp_sel( data = d_sim_lin, var_resp = "response", - var_exp_candidates = c("AUCss", "Cmaxss") + var_exp_candidates = c("AUCss", "Cmaxss"), + options_placebo_handling = list(use_placebo = TRUE) ) ermod_lin_exp_sel diff --git a/tests/testthat/test-dev_ermod_emax.R b/tests/testthat/test-dev_ermod_emax.R index 3ec8f72..f4311d6 100644 --- a/tests/testthat/test-dev_ermod_emax.R +++ b/tests/testthat/test-dev_ermod_emax.R @@ -52,6 +52,7 @@ ermod_emax_exp_sel <- data = data_er_cont, var_resp = "response", var_exp_candidates = c("exposure", "exposure2"), + options_placebo_handling = list(use_placebo = TRUE), emax_fix = 100, e0_fix = 0, verbosity_level = 0, From 98b46e6e236f75bdc3d6b9f10c7c2f6aa1f8b5c5 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 18:10:04 +1000 Subject: [PATCH 19/57] attempt covsel bug fix --- R/dev_ermod_lin.R | 10 +++++++--- tests/testthat/test-dev_ermod_emax.R | 16 +++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index fccf38e..4b74e1b 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -394,7 +394,6 @@ dev_ermod_lin_exp_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_lin, - options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux @@ -406,6 +405,7 @@ dev_ermod_lin_exp_sel <- function( var_resp = var_resp, var_exp_candidates = var_exp_candidates, verbosity_level = verbosity_level, + options_placebo_handling = options_placebo_handling, chains = chains, iter = iter, fun_dev_ermod = fun_dev_ermod @@ -454,7 +454,6 @@ dev_ermod_lin_cov_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_lin, - options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux @@ -465,6 +464,7 @@ dev_ermod_lin_cov_sel <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov_candidates = var_cov_candidates, + options_placebo_handling = options_placebo_handling, cv_method = cv_method, k = k, validate_search = validate_search, @@ -486,6 +486,7 @@ dev_ermod_lin_cov_sel <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov_candidates = var_cov_candidates, + options_placebo_handling = options_placebo_handling, var_cov = var_cov, var_selected = var_selected, cv_method = cv_method, @@ -501,6 +502,7 @@ dev_ermod_lin_cov_sel <- function( data, var_resp, var_exp_candidates, + options_placebo_handling, verbosity_level = 1, chains = 4, iter = 2000, @@ -523,7 +525,8 @@ dev_ermod_lin_cov_sel <- function( function(.x) { fun_dev_ermod(data, var_resp, .x, chains = chains, iter = iter, - verbosity_level = verbosity_level + verbosity_level = verbosity_level, + options_placebo_handling = options_placebo_handling, ) }, .progress = verbose @@ -572,6 +575,7 @@ dev_ermod_lin_cov_sel <- function( var_resp, var_exposure, var_cov_candidates, + options_placebo_handling, cv_method = c("LOO", "kfold"), k = 5, validate_search = FALSE, diff --git a/tests/testthat/test-dev_ermod_emax.R b/tests/testthat/test-dev_ermod_emax.R index f4311d6..3956268 100644 --- a/tests/testthat/test-dev_ermod_emax.R +++ b/tests/testthat/test-dev_ermod_emax.R @@ -20,17 +20,18 @@ set.seed(1234) # Test ermod_emax ------------------------------------------------------------ ermod_emax <- - dev_ermod_emax( + suppressWarnings(dev_ermod_emax( data = data_er_cont, var_exposure = "exposure", var_resp = "response", + options_placebo_handling = list(use_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic chains = 2, iter = 1000, seed = 1 - ) + )) ermod_emax_w_cov <- suppressWarnings(dev_ermod_emax( @@ -38,6 +39,7 @@ ermod_emax_w_cov <- var_exposure = "conc", var_resp = "resp", l_var_cov = list(emax = "cov2", ec50 = "cov3", e0 = "cov1"), + options_placebo_handling = list(use_placebo = TRUE), verbosity_level = 0, chains = 2, iter = 200, @@ -46,7 +48,7 @@ ermod_emax_w_cov <- ersim_med_qi <- sim_er(ermod_emax, output_type = "median_qi") - +# TODO ermod_emax_exp_sel <- suppressWarnings(dev_ermod_emax_exp_sel( data = data_er_cont, @@ -64,23 +66,25 @@ ermod_emax_exp_sel <- # Test ermod_bin_emax --------------------------------------------------------- ermod_bin_emax <- - dev_ermod_bin_emax( + suppressWarnings(dev_ermod_bin_emax( data = data_er_bin, var_exposure = "conc", var_resp = "y", + options_placebo_handling = list(use_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic chains = 2, iter = 1000, seed = 1 - ) + )) ermod_bin_emax_w_cov <- suppressWarnings(dev_ermod_bin_emax( data = data_er_bin, var_exposure = "conc", var_resp = "y_cov", + options_placebo_handling = list(use_placebo = TRUE), l_var_cov = list(emax = "sex"), verbosity_level = 0, chains = 2, @@ -96,6 +100,7 @@ ermod_bin_emax_exp_sel <- var_resp = "y", var_exp_candidates = c("conc", "conc2"), verbosity_level = 0, + options_placebo_handling = list(use_placebo = TRUE), chains = 2, iter = 200, seed = 1 @@ -112,6 +117,7 @@ mod_mtcars_emax <- suppressWarnings(dev_ermod_bin_emax( var_resp = "am3", var_exposure = "cyl", verbosity_level = 0, + options_placebo_handling = list(use_placebo = TRUE), # Below option to make the test fast chains = 2, iter = 1000 )) From fd7ada9d24fc763cd8345ae50491d457885e58c0 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 18:20:56 +1000 Subject: [PATCH 20/57] apply same fix to emax --- R/dev_ermod_emax.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index ab7b447..b7e17c9 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -162,7 +162,6 @@ dev_ermod_emax_exp_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_emax, - options_placebo_handling = options_placebo_handling, gamma_fix = gamma_fix, e0_fix = e0_fix, emax_fix = emax_fix, @@ -175,6 +174,7 @@ dev_ermod_emax_exp_sel <- function( data = data, var_resp = var_resp, var_exp_candidates = var_exp_candidates, + options_placebo_handling = options_placebo_handling, verbosity_level = verbosity_level, chains = chains, iter = iter, @@ -341,7 +341,6 @@ dev_ermod_bin_emax_exp_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_bin_emax, - options_placebo_handling = options_placebo_handling, gamma_fix = gamma_fix, e0_fix = e0_fix, emax_fix = emax_fix, @@ -354,6 +353,7 @@ dev_ermod_bin_emax_exp_sel <- function( data = data, var_resp = var_resp, var_exp_candidates = var_exp_candidates, + options_placebo_handling = options_placebo_handling, verbosity_level = verbosity_level, chains = chains, iter = iter, From 4fa0c3f9ecdfbf461ad5ffdafd1635461f39de80 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 18:35:16 +1000 Subject: [PATCH 21/57] test on ci --- R/dev_ermod_lin.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 4b74e1b..d160f0e 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -645,6 +645,7 @@ dev_ermod_lin_cov_sel <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov = var_cov, + options_placebo_handling = options_placebo_handling, verbosity_level = verbosity_level, chains = chains, iter = iter ) From 59c708b0d50263bdf534e2627bf165b26f6cd9eb Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 19:01:44 +1000 Subject: [PATCH 22/57] typo fix --- R/ermod-class.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ermod-class.R b/R/ermod-class.R index ddada32..90b7960 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -224,7 +224,7 @@ new_ermod_bin_cov_sel <- function( var_cov_candidates = var_cov_candidates, var_cov = var_cov, var_selected = var_selected, - options_placebo_handling = list(), + options_placebo_handling = options_placebo_handling, cvvs = cvvs, rk = rk, input_args = input_args, From 53dcaa2b200a8a0f9d9b2c546cc14fbbc9a94a32 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 19:02:35 +1000 Subject: [PATCH 23/57] use placebo handling options in refmodel --- R/dev_ermod_lin.R | 51 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index d160f0e..0078a27 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -523,8 +523,12 @@ dev_ermod_lin_cov_sel <- function( purrr::set_names() |> purrr::map( function(.x) { - fun_dev_ermod(data, var_resp, .x, - chains = chains, iter = iter, + fun_dev_ermod( + data, + var_resp, + .x, + chains = chains, + iter = iter, verbosity_level = verbosity_level, options_placebo_handling = options_placebo_handling, ) @@ -611,6 +615,7 @@ dev_ermod_lin_cov_sel <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov_candidates = var_cov_candidates, + options_placebo_handling = options_placebo_handling, verbosity_level = verbosity_level, chains = chains, iter = iter, fun_family = fun_family, @@ -660,6 +665,7 @@ dev_ermod_lin_cov_sel <- function( var_cov_candidates = var_cov_candidates, var_cov = var_cov, var_selected = as.character(var_selected), + options_placebo_handling = options_placebo_handling, cv_method = cv_method, cvvs = attr(var_selected, "cvvs"), rk = attr(var_selected, "rk") @@ -690,12 +696,19 @@ NULL #' [.dev_ermod_refmodel()]: The reference model object that can be used #' for variable selection. .dev_ermod_refmodel <- function( - data, var_resp, var_exposure, var_cov_candidates, - verbosity_level = 1, chains = 4, iter = 2000, + data, + var_resp, + var_exposure, + var_cov_candidates, + options_placebo_handling, + verbosity_level = 1, + chains = 4, + iter = 2000, fun_family = quote(stats::binomial()), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE)) { + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -710,6 +723,8 @@ NULL var_cov_candidates = var_cov_candidates ) + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) + varnames <- paste(c(var_exposure, var_cov_candidates), collapse = " + ") formula_full <- stats::formula(paste(var_resp, "~", varnames)) @@ -717,11 +732,17 @@ NULL # Need to construct call and then evaluate. Directly calling # rstanarm::stan_glm with formula_full does not work for the cross-validation call_fit_ref <- - rlang::call2(rstanarm::stan_glm, + rlang::call2( + rstanarm::stan_glm, formula = formula_full, - family = fun_family, data = quote(data), QR = TRUE, - refresh = refresh, chains = chains, iter = iter, - prior = prior, prior_intercept = prior_intercept, + family = fun_family, + data = quote(stan_data), + QR = TRUE, + refresh = refresh, + chains = chains, + iter = iter, + prior = prior, + prior_intercept = prior_intercept, prior_aux = prior_aux ) fit_ref <- eval(call_fit_ref) @@ -741,7 +762,9 @@ NULL #' @return #' [.select_cov_projpred()]: The selected variables .select_cov_projpred <- function( - refm_obj, var_exposure, var_cov_candidates, + refm_obj, + var_exposure, + var_cov_candidates, nterms_max = NULL, cv_method = c("LOO", "kfold"), k = 5, @@ -814,7 +837,6 @@ NULL return(var_selected) } - .reduce_cvvs_size <- function(cvvs) { family <- cvvs$refmodel$family cvvs$refmodel <- NULL @@ -825,9 +847,14 @@ NULL } check_data_columns <- function( - data, var_resp = NULL, var_exp_candidates = NULL, - var_exposure = NULL, var_cov_candidates = NULL, var_cov = NULL, + data, + var_resp = NULL, + var_exp_candidates = NULL, + var_exposure = NULL, + var_cov_candidates = NULL, + var_cov = NULL, is_binary = FALSE) { + if (!is.data.frame(data)) { stop("data should be a data frame") } From 21ccf4c0b61061c6d3e5e1f55a504040088c243f Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 19:14:07 +1000 Subject: [PATCH 24/57] roxygenise --- man/dev_ermod_bin_cov_functions.Rd | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/man/dev_ermod_bin_cov_functions.Rd b/man/dev_ermod_bin_cov_functions.Rd index 6b2dbee..78aaf47 100644 --- a/man/dev_ermod_bin_cov_functions.Rd +++ b/man/dev_ermod_bin_cov_functions.Rd @@ -12,6 +12,7 @@ for binary endpoint} var_resp, var_exposure, var_cov_candidates, + options_placebo_handling, verbosity_level = 1, chains = 4, iter = 2000, @@ -42,6 +43,25 @@ for binary endpoint} \item{var_cov_candidates}{Candidate covariate names in character vector} +\item{options_placebo_handling}{List of for placebo handling. +Possible options include: +\itemize{ +\item \code{include_placebo}: Logical, whether the placebo group should be +used when estimating the model. Default is observed data. Default +is \code{FALSE}. +\item \code{method}: Character, specifying the method used to detect placebo +group samples. Possible values include \code{"zero_exposure_as_placebo"} +(the default), in which rows with zero values for the exposure +variable are automatically assigned to a placebo group, +\code{"var_placebo"}, indicating that the user will supply the name of +a data column specifying the placebo group, and \code{"none"}, in which +case no placebo handling takes place. +\item \code{var_placebo}: Character, specifying the name of a column in the +data set that indicates which rows belong to the placebo group. This +column is interpreted as a logical vector. This value is ignored +unless \code{method = "var_placebo"}. +}} + \item{verbosity_level}{Verbosity level. 0: No output, 1: Display steps, 2: Display progress in each step, 3: Display MCMC sampling.} From 62ecb951d7fe475296ec4e0199a9a1c8dcea03b8 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 19:14:34 +1000 Subject: [PATCH 25/57] don't use partial for placebo handling --- R/dev_ermod_lin.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 0078a27..5927b2c 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -157,7 +157,6 @@ dev_ermod_bin_exp_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_bin, - options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept ) @@ -167,6 +166,7 @@ dev_ermod_bin_exp_sel <- function( data = data, var_resp = var_resp, var_exp_candidates = var_exp_candidates, + options_placebo_handling = options_placebo_handling, verbosity_level = verbosity_level, chains = chains, iter = iter, From 29210b324b3e031c56935a6966c79084294b7f9c Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 20:17:31 +1000 Subject: [PATCH 26/57] don't use partial for placebo handling in dev_ermod_bin_cov_sel --- R/dev_ermod_lin.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 5927b2c..f8ddbd3 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -240,7 +240,6 @@ dev_ermod_bin_cov_sel <- function( fun_dev_ermod <- purrr::partial( dev_ermod_bin, - options_placebo_handling = options_placebo_handling, prior = prior, prior_intercept = prior_intercept ) @@ -250,6 +249,7 @@ dev_ermod_bin_cov_sel <- function( var_resp = var_resp, var_exposure = var_exposure, var_cov_candidates = var_cov_candidates, + options_placebo_handling = options_placebo_handling, cv_method = cv_method, k = k, validate_search = validate_search, @@ -272,6 +272,7 @@ dev_ermod_bin_cov_sel <- function( var_cov_candidates = var_cov_candidates, var_cov = var_cov, var_selected = var_selected, + options_placebo_handling = options_placebo_handling, cv_method = cv_method, cvvs = cvvs, rk = rk, From f67fb32b2242321cd917069a9a6f7fa4b0d6d191 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 20:17:47 +1000 Subject: [PATCH 27/57] update example --- R/dev_ermod_emax.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index b7e17c9..a76ef3f 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -139,7 +139,8 @@ dev_ermod_emax <- function( #' dev_ermod_emax_exp_sel( #' data = data_er_cont, #' var_resp = "response", -#' var_exp_candidates = c("exposure", "exposure2") +#' var_exp_candidates = c("exposure", "exposure2"), +#' options_placebo_handling = list(use_placebo = TRUE) #' ) #' #' ermod_emax_exp_sel From 5c6699be22caae57e60373716871c255c5bbbc29 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 20:26:01 +1000 Subject: [PATCH 28/57] roxygenise --- man/dev_ermod_emax_exp_sel.Rd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/dev_ermod_emax_exp_sel.Rd b/man/dev_ermod_emax_exp_sel.Rd index bf718fd..e6f41c6 100644 --- a/man/dev_ermod_emax_exp_sel.Rd +++ b/man/dev_ermod_emax_exp_sel.Rd @@ -104,7 +104,8 @@ ermod_emax_exp_sel <- dev_ermod_emax_exp_sel( data = data_er_cont, var_resp = "response", - var_exp_candidates = c("exposure", "exposure2") + var_exp_candidates = c("exposure", "exposure2"), + options_placebo_handling = list(use_placebo = TRUE) ) ermod_emax_exp_sel From 3a45d092faf3a9e8be7fe5bce4ba6217365de82b Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 20:40:46 +1000 Subject: [PATCH 29/57] pass placebo handling --- tests/testthat/test-dev_ermod_lin.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-dev_ermod_lin.R b/tests/testthat/test-dev_ermod_lin.R index ea1602f..a12368d 100644 --- a/tests/testthat/test-dev_ermod_lin.R +++ b/tests/testthat/test-dev_ermod_lin.R @@ -83,6 +83,7 @@ if (requireNamespace("projpred")) { var_resp = var_resp, var_exposure = "AUCss_1000", var_cov_candidates = var_cov_ae_covsel_test, + options_placebo_handling = list(use_placebo = TRUE), verbosity_level = 0, # Below option to make the test fast chains = 2, iter = 1000 From db3802a32c2c7f652a75c3d04ef0590d9190ac03 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 20:51:36 +1000 Subject: [PATCH 30/57] fix option name --- R/dev_ermod_emax.R | 2 +- R/dev_ermod_lin.R | 2 +- man/dev_ermod_bin_exp_sel.Rd | 2 +- man/dev_ermod_emax_exp_sel.Rd | 2 +- tests/testthat/test-dev_ermod_emax.R | 14 +++++++------- tests/testthat/test-dev_ermod_lin.R | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index a76ef3f..08ffe23 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -140,7 +140,7 @@ dev_ermod_emax <- function( #' data = data_er_cont, #' var_resp = "response", #' var_exp_candidates = c("exposure", "exposure2"), -#' options_placebo_handling = list(use_placebo = TRUE) +#' options_placebo_handling = list(include_placebo = TRUE) #' ) #' #' ermod_emax_exp_sel diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index f8ddbd3..bf4947f 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -372,7 +372,7 @@ dev_ermod_lin <- function( #' data = d_sim_lin, #' var_resp = "response", #' var_exp_candidates = c("AUCss", "Cmaxss"), -#' options_placebo_handling = list(use_placebo = TRUE) +#' options_placebo_handling = list(include_placebo = TRUE) #' ) #' #' ermod_lin_exp_sel diff --git a/man/dev_ermod_bin_exp_sel.Rd b/man/dev_ermod_bin_exp_sel.Rd index b67301d..8b6f541 100644 --- a/man/dev_ermod_bin_exp_sel.Rd +++ b/man/dev_ermod_bin_exp_sel.Rd @@ -95,7 +95,7 @@ ermod_lin_exp_sel <- dev_ermod_lin_exp_sel( data = d_sim_lin, var_resp = "response", var_exp_candidates = c("AUCss", "Cmaxss"), - options_placebo_handling = list(use_placebo = TRUE) + options_placebo_handling = list(include_placebo = TRUE) ) ermod_lin_exp_sel diff --git a/man/dev_ermod_emax_exp_sel.Rd b/man/dev_ermod_emax_exp_sel.Rd index e6f41c6..347cbc2 100644 --- a/man/dev_ermod_emax_exp_sel.Rd +++ b/man/dev_ermod_emax_exp_sel.Rd @@ -105,7 +105,7 @@ ermod_emax_exp_sel <- data = data_er_cont, var_resp = "response", var_exp_candidates = c("exposure", "exposure2"), - options_placebo_handling = list(use_placebo = TRUE) + options_placebo_handling = list(include_placebo = TRUE) ) ermod_emax_exp_sel diff --git a/tests/testthat/test-dev_ermod_emax.R b/tests/testthat/test-dev_ermod_emax.R index 3956268..0460c98 100644 --- a/tests/testthat/test-dev_ermod_emax.R +++ b/tests/testthat/test-dev_ermod_emax.R @@ -24,7 +24,7 @@ ermod_emax <- data = data_er_cont, var_exposure = "exposure", var_resp = "response", - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic @@ -39,7 +39,7 @@ ermod_emax_w_cov <- var_exposure = "conc", var_resp = "resp", l_var_cov = list(emax = "cov2", ec50 = "cov3", e0 = "cov1"), - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, chains = 2, iter = 200, @@ -54,7 +54,7 @@ ermod_emax_exp_sel <- data = data_er_cont, var_resp = "response", var_exp_candidates = c("exposure", "exposure2"), - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), emax_fix = 100, e0_fix = 0, verbosity_level = 0, @@ -70,7 +70,7 @@ ermod_bin_emax <- data = data_er_bin, var_exposure = "conc", var_resp = "y", - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic @@ -84,7 +84,7 @@ ermod_bin_emax_w_cov <- data = data_er_bin, var_exposure = "conc", var_resp = "y_cov", - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), l_var_cov = list(emax = "sex"), verbosity_level = 0, chains = 2, @@ -100,7 +100,7 @@ ermod_bin_emax_exp_sel <- var_resp = "y", var_exp_candidates = c("conc", "conc2"), verbosity_level = 0, - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), chains = 2, iter = 200, seed = 1 @@ -117,7 +117,7 @@ mod_mtcars_emax <- suppressWarnings(dev_ermod_bin_emax( var_resp = "am3", var_exposure = "cyl", verbosity_level = 0, - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), # Below option to make the test fast chains = 2, iter = 1000 )) diff --git a/tests/testthat/test-dev_ermod_lin.R b/tests/testthat/test-dev_ermod_lin.R index a12368d..a5be93c 100644 --- a/tests/testthat/test-dev_ermod_lin.R +++ b/tests/testthat/test-dev_ermod_lin.R @@ -83,7 +83,7 @@ if (requireNamespace("projpred")) { var_resp = var_resp, var_exposure = "AUCss_1000", var_cov_candidates = var_cov_ae_covsel_test, - options_placebo_handling = list(use_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Below option to make the test fast chains = 2, iter = 1000 From 58a42c08e1ee7e2ca66a4e9ddc8ed4f6c44f9f7d Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:02:13 +1000 Subject: [PATCH 31/57] suppress warnings --- tests/testthat/test-loo_kfold.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-loo_kfold.R b/tests/testthat/test-loo_kfold.R index 2316a49..1cc7756 100644 --- a/tests/testthat/test-loo_kfold.R +++ b/tests/testthat/test-loo_kfold.R @@ -38,7 +38,7 @@ if (.if_run_ex_eval_mod()) { set.seed(1234) ermod_emax_w_cov <- - dev_ermod_emax( + suppressWarnings(dev_ermod_emax( data = data_er_cont_cov, var_exposure = "conc", var_resp = "resp", @@ -47,7 +47,7 @@ if (.if_run_ex_eval_mod()) { chains = 2, iter = 1000, seed = 1 - ) + )) ermod_bin_emax <- suppressWarnings(dev_ermod_bin_emax( From 1ac88aeea9fbc50c23dab108263b80729cfb3c13 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:02:32 +1000 Subject: [PATCH 32/57] pass placebo handling --- tests/testthat/test-dev_ermod_lin.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-dev_ermod_lin.R b/tests/testthat/test-dev_ermod_lin.R index a5be93c..a0e3984 100644 --- a/tests/testthat/test-dev_ermod_lin.R +++ b/tests/testthat/test-dev_ermod_lin.R @@ -277,6 +277,7 @@ test_that("No ER case", { var_resp = var_resp, var_exposure = "AUCss_1000", var_cov_candidates = c("BAGE_10", "BWT_10"), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Below option to make the test fast chains = 2, iter = 1000 From e0cf8e0cf8ee69eb628b779cb97c797decd359d1 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:19:46 +1000 Subject: [PATCH 33/57] don't test covsel if projpred unavailable --- tests/testthat/test-placebo_handling.R | 113 +++++++++++++------------ 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index 3c9aca4..f48cf60 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -61,19 +61,19 @@ cases_expsel <- tidyr::expand_grid( ) ) -# all test cases for covariate selection functions -cases_covsel <- tidyr::expand_grid( - dat = names(dat), - dev_covsel = names(dev_covsel), - opts = names(opts), -) |> dplyr::mutate( - var_resp = dplyr::case_when( - dev_covsel == "dev_ermod_lin_cov_sel" ~ "response_1", - dev_covsel == "dev_ermod_bin_cov_sel" ~ "response_2", - # dev_covsel == "dev_ermod_emax_cov_sel" ~ "response_1", - # dev_covsel == "dev_ermod_bin_emax_cov_sel" ~ "response_2" +if (require("projpred")) { + # all test cases for covariate selection functions + cases_covsel <- tidyr::expand_grid( + dat = names(dat), + dev_covsel = names(dev_covsel), + opts = names(opts), + ) |> dplyr::mutate( + var_resp = dplyr::case_when( + dev_covsel == "dev_ermod_lin_cov_sel" ~ "response_1", + dev_covsel == "dev_ermod_bin_cov_sel" ~ "response_2", + ) ) -) +} # helper function to inspect internal data objects internal_stan_data_rows <- function(object) { @@ -122,24 +122,26 @@ for(r in 1:nrow(cases_expsel)) { cases_expsel$mod <- m # fit the model for each covariate-selection model case -m <- list() -for(r in 1:nrow(cases_covsel)) { - f <- dev_covsel[[cases_covsel$dev_covsel[r]]] - d <- dat[[cases_covsel$dat[r]]] - o <- opts[[cases_covsel$opts[r]]] - set.seed(123L) - suppressWarnings(suppressMessages( - m[[r]] <- d |> f( - var_exposure = "exposure_1", - var_cov_candidates = c("cnt_a", "cnt_b"), - var_resp = cases_expsel$var_resp[r], - options_placebo_handling = o, - chains = 1, - iter = 100 - ) - )) +if (require("projpred")) { + m <- list() + for(r in 1:nrow(cases_covsel)) { + f <- dev_covsel[[cases_covsel$dev_covsel[r]]] + d <- dat[[cases_covsel$dat[r]]] + o <- opts[[cases_covsel$opts[r]]] + set.seed(123L) + suppressWarnings(suppressMessages( + m[[r]] <- d |> f( + var_exposure = "exposure_1", + var_cov_candidates = c("cnt_a", "cnt_b"), + var_resp = cases_expsel$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) + )) + } + cases_covsel$mod <- m } -cases_covsel$mod <- m # record number of rows in the inner and outer data sets (basic models) cases_ermod$inner_n <- numeric(nrow(cases_ermod)) @@ -157,12 +159,14 @@ for(r in 1:nrow(cases_expsel)) { cases_expsel$outer_n[r] <- nrow(cases_expsel$mod[[r]]$data) } -# record number of rows in the inner and outer data sets (covariate selection) -cases_covsel$inner_n <- numeric(nrow(cases_covsel)) -cases_covsel$outer_n <- numeric(nrow(cases_covsel)) -for(r in 1:nrow(cases_covsel)) { - cases_covsel$inner_n[r] <- internal_stan_data_rows(cases_covsel$mod[[r]]$mod) - cases_covsel$outer_n[r] <- nrow(cases_covsel$mod[[r]]$data) +if (require("projpred")) { + # record number of rows in the inner and outer data sets (covariate selection) + cases_covsel$inner_n <- numeric(nrow(cases_covsel)) + cases_covsel$outer_n <- numeric(nrow(cases_covsel)) + for(r in 1:nrow(cases_covsel)) { + cases_covsel$inner_n[r] <- internal_stan_data_rows(cases_covsel$mod[[r]]$mod) + cases_covsel$outer_n[r] <- nrow(cases_covsel$mod[[r]]$data) + } } # the "stan" data set should only include placebo samples if the data set @@ -186,16 +190,17 @@ test_that("internal data respects placebo options (metric selection)", { } } }) -test_that("internal data respects placebo options (covariate selection)", { - for(r in 1:nrow(cases_covsel)) { - if (cases_covsel$dat[r] == "placebo" & cases_covsel$opts[r] == "use_placebo") { - expect_equal(cases_covsel$inner_n[r], 40L) - } else { - expect_equal(cases_covsel$inner_n[r], 30L) +if (require("projpred")) { + test_that("internal data respects placebo options (covariate selection)", { + for(r in 1:nrow(cases_covsel)) { + if (cases_covsel$dat[r] == "placebo" & cases_covsel$opts[r] == "use_placebo") { + expect_equal(cases_covsel$inner_n[r], 40L) + } else { + expect_equal(cases_covsel$inner_n[r], 30L) + } } - } -}) - + }) +} # the "user facing" data set should only include placebo samples if the data set # originally contained a placebo group, regardless of the placebo handling settings @@ -217,13 +222,15 @@ test_that("outer data preserves all data rows (metric selection)", { } } }) -test_that("outer data preserves all data rows (covariate selection)", { - for(r in 1:nrow(cases_covsel)) { - if (cases_covsel$dat[r] == "placebo") { - expect_equal(cases_covsel$outer_n[r], 40L) - } else { - expect_equal(cases_covsel$outer_n[r], 30L) +if (require("projpred")) { + test_that("outer data preserves all data rows (covariate selection)", { + for(r in 1:nrow(cases_covsel)) { + if (cases_covsel$dat[r] == "placebo") { + expect_equal(cases_covsel$outer_n[r], 40L) + } else { + expect_equal(cases_covsel$outer_n[r], 30L) + } } - } -}) - + }) +} + \ No newline at end of file From 95557f3d6b0f3b4e4e5b4ef0653e9ad4f342440a Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:37:55 +1000 Subject: [PATCH 34/57] linting fixes --- R/dev_ermod_emax.R | 8 +-- R/dev_ermod_lin.R | 92 ++++++++++++------------ R/ermod-class.R | 98 +++++++++++++------------- data-raw/d_sim_emax.R | 2 +- tests/testthat/test-dev_ermod_emax.R | 14 ++-- tests/testthat/test-placebo_handling.R | 35 +++++---- 6 files changed, 124 insertions(+), 125 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index 08ffe23..1f3d21d 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -64,7 +64,7 @@ dev_ermod_emax <- function( chains = 4, iter = 2000, seed = sample.int(.Machine$integer.max, 1)) { - + input_args <- capture_selected_args( c( "gamma_fix", "e0_fix", "emax_fix", @@ -159,7 +159,7 @@ dev_ermod_emax_exp_sel <- function( emax_fix = NULL, priors = NULL, seed = sample.int(.Machine$integer.max, 1)) { - + fun_dev_ermod <- purrr::partial( dev_ermod_emax, @@ -225,7 +225,7 @@ dev_ermod_bin_emax <- function( chains = 4, iter = 2000, seed = sample.int(.Machine$integer.max, 1)) { - + # Warn when e0_fix is set if (!is.null(e0_fix) && e0_fix == 0) { warning( @@ -338,7 +338,7 @@ dev_ermod_bin_emax_exp_sel <- function( emax_fix = NULL, priors = NULL, seed = sample.int(.Machine$integer.max, 1)) { - + fun_dev_ermod <- purrr::partial( dev_ermod_bin_emax, diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index bf4947f..eb108ec 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -13,19 +13,19 @@ #' @param var_cov Covariate variable names in character vector #' @param options_placebo_handling List of for placebo handling. #' Possible options include: -#' - `include_placebo`: Logical, whether the placebo group should be -#' used when estimating the model. Default is observed data. Default +#' - `include_placebo`: Logical, whether the placebo group should be +#' used when estimating the model. Default is observed data. Default #' is `FALSE`. #' - `method`: Character, specifying the method used to detect placebo #' group samples. Possible values include `"zero_exposure_as_placebo"` -#' (the default), in which rows with zero values for the exposure -#' variable are automatically assigned to a placebo group, -#' `"var_placebo"`, indicating that the user will supply the name of +#' (the default), in which rows with zero values for the exposure +#' variable are automatically assigned to a placebo group, +#' `"var_placebo"`, indicating that the user will supply the name of #' a data column specifying the placebo group, and `"none"`, in which #' case no placebo handling takes place. #' - `var_placebo`: Character, specifying the name of a column in the #' data set that indicates which rows belong to the placebo group. This -#' column is interpreted as a logical vector. This value is ignored +#' column is interpreted as a logical vector. This value is ignored #' unless `method = "var_placebo"`. #' @param prior,prior_intercept,prior_aux See [rstanarm::stan_glm()] #' @param verbosity_level Verbosity level. 0: No output, 1: Display steps, @@ -60,7 +60,7 @@ dev_ermod_bin <- function( verbosity_level = 1, chains = 4, iter = 2000) { - + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -68,7 +68,7 @@ dev_ermod_bin <- function( c("chains", "iter"), environment() ) - + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) check_data_columns( @@ -85,7 +85,7 @@ dev_ermod_bin <- function( stats::formula( paste(var_resp, "~", paste(var_full, collapse = " + ")) ) - + stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) # Need to construct call and then evaluate. Directly calling @@ -151,16 +151,16 @@ dev_ermod_bin_exp_sel <- function( verbosity_level = 1, chains = 4, iter = 2000) { - + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) - + fun_dev_ermod <- purrr::partial( dev_ermod_bin, prior = prior, prior_intercept = prior_intercept ) - + l_out <- .dev_ermod_exp_sel( data = data, @@ -236,7 +236,7 @@ dev_ermod_bin_cov_sel <- function( iter = 2000) { options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) - + fun_dev_ermod <- purrr::partial( dev_ermod_bin, @@ -310,7 +310,7 @@ dev_ermod_lin <- function( verbosity_level = 1, chains = 4, iter = 2000) { - + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -336,7 +336,7 @@ dev_ermod_lin <- function( ) stan_data <- .apply_placebo_handling(data, options_placebo_handling, var_exposure) - + mod <- rstanarm::stan_glm( formula_final, family = stats::gaussian(), @@ -389,7 +389,7 @@ dev_ermod_lin_exp_sel <- function( verbosity_level = 1, chains = 4, iter = 2000) { - + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) fun_dev_ermod <- @@ -449,9 +449,9 @@ dev_ermod_lin_cov_sel <- function( verbosity_level = 1, chains = 4, iter = 2000) { - + options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) - + fun_dev_ermod <- purrr::partial( dev_ermod_lin, @@ -500,15 +500,15 @@ dev_ermod_lin_cov_sel <- function( # Internal functions ---------------------------------------------------------- .dev_ermod_exp_sel <- function( - data, - var_resp, + data, + var_resp, var_exp_candidates, options_placebo_handling, - verbosity_level = 1, - chains = 4, + verbosity_level = 1, + chains = 4, iter = 2000, fun_dev_ermod) { - + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) verbose <- dplyr::if_else(verbosity_level == 2, TRUE, FALSE) @@ -525,10 +525,10 @@ dev_ermod_lin_cov_sel <- function( purrr::map( function(.x) { fun_dev_ermod( - data, - var_resp, + data, + var_resp, .x, - chains = chains, + chains = chains, iter = iter, verbosity_level = verbosity_level, options_placebo_handling = options_placebo_handling, @@ -594,7 +594,7 @@ dev_ermod_lin_cov_sel <- function( prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE)) { - + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) rlang::check_installed("projpred") @@ -697,19 +697,19 @@ NULL #' [.dev_ermod_refmodel()]: The reference model object that can be used #' for variable selection. .dev_ermod_refmodel <- function( - data, - var_resp, - var_exposure, + data, + var_resp, + var_exposure, var_cov_candidates, options_placebo_handling, - verbosity_level = 1, - chains = 4, + verbosity_level = 1, + chains = 4, iter = 2000, fun_family = quote(stats::binomial()), prior = rstanarm::default_prior_coef(stats::binomial()), prior_intercept = rstanarm::default_prior_intercept(stats::binomial()), prior_aux = rstanarm::exponential(autoscale = TRUE)) { - + stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -736,13 +736,13 @@ NULL rlang::call2( rstanarm::stan_glm, formula = formula_full, - family = fun_family, - data = quote(stan_data), + family = fun_family, + data = quote(stan_data), QR = TRUE, - refresh = refresh, - chains = chains, + refresh = refresh, + chains = chains, iter = iter, - prior = prior, + prior = prior, prior_intercept = prior_intercept, prior_aux = prior_aux ) @@ -763,8 +763,8 @@ NULL #' @return #' [.select_cov_projpred()]: The selected variables .select_cov_projpred <- function( - refm_obj, - var_exposure, + refm_obj, + var_exposure, var_cov_candidates, nterms_max = NULL, cv_method = c("LOO", "kfold"), @@ -848,14 +848,14 @@ NULL } check_data_columns <- function( - data, - var_resp = NULL, + data, + var_resp = NULL, var_exp_candidates = NULL, - var_exposure = NULL, - var_cov_candidates = NULL, + var_exposure = NULL, + var_cov_candidates = NULL, var_cov = NULL, is_binary = FALSE) { - + if (!is.data.frame(data)) { stop("data should be a data frame") } @@ -918,7 +918,7 @@ capture_selected_args <- function(arg_names, env) { # do nothing if user wants to retain placebo if (options$include_placebo) return(data) - + # "none" method: no filtering, also do nothing if (options$method == "none") return(data) diff --git a/R/ermod-class.R b/R/ermod-class.R index 90b7960..d524297 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -19,17 +19,17 @@ new_ermod_lin <- function( var_cov = NULL, input_args = list(), options_placebo_handling = list()) { - + coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) check_input_new_ermod( - mod = mod, - data = data, + mod = mod, + data = data, var_resp = var_resp, - var_exposure = var_exposure, + var_exposure = var_exposure, var_cov = var_cov, - input_args = input_args, + input_args = input_args, options_placebo_handling = options_placebo_handling, coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" @@ -85,22 +85,22 @@ new_ermod_lin_cov_sel <- function( cvvs = NULL, rk = NULL, input_args = list()) { - + cv_method <- match.arg(cv_method) coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) check_input_new_ermod( - mod = mod, - data = data, - var_resp = var_resp, + mod = mod, + data = data, + var_resp = var_resp, var_exposure = var_exposure, - var_cov_candidates = var_cov_candidates, + var_cov_candidates = var_cov_candidates, var_cov = var_cov, - var_selected = var_selected, + var_selected = var_selected, options_placebo_handling = options_placebo_handling, - cvvs = cvvs, + cvvs = cvvs, rk = rk, - input_args = input_args, + input_args = input_args, coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -140,23 +140,23 @@ new_ermod_lin_cov_sel <- function( #' @param input_args Captured inputs #' @param options_placebo_handling List specifying how placebo groups are handled new_ermod_bin <- function( - mod, - data, - var_resp = character(), - var_exposure = character(), - var_cov = NULL, - input_args = list(), - options_placebo_handling = list() - ) { - + mod, + data, + var_resp = character(), + var_exposure = character(), + var_cov = NULL, + input_args = list(), + options_placebo_handling = list() +) { + coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) - + check_input_new_ermod( - mod = mod, - data = data, + mod = mod, + data = data, var_resp = var_resp, - input_args = input_args, + input_args = input_args, options_placebo_handling = options_placebo_handling, coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" @@ -212,22 +212,22 @@ new_ermod_bin_cov_sel <- function( cvvs = NULL, rk = NULL, input_args = list()) { - + cv_method <- match.arg(cv_method) coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) check_input_new_ermod( - mod = mod, - data = data, - var_resp = var_resp, + mod = mod, + data = data, + var_resp = var_resp, var_exposure = var_exposure, - var_cov_candidates = var_cov_candidates, + var_cov_candidates = var_cov_candidates, var_cov = var_cov, - var_selected = var_selected, + var_selected = var_selected, options_placebo_handling = options_placebo_handling, - cvvs = cvvs, + cvvs = cvvs, rk = rk, - input_args = input_args, + input_args = input_args, coef_exp_draws = coef_exp_draws, basemodclass = "stanreg" ) @@ -273,14 +273,14 @@ new_ermod_emax <- function( options_placebo_handling = list(), l_var_cov = NULL, input_args = list()) { - + check_input_new_ermod( - mod = mod, - data = data, - var_resp = var_resp, + mod = mod, + data = data, + var_resp = var_resp, var_exposure = var_exposure, options_placebo_handling = options_placebo_handling, - l_var_cov = l_var_cov, + l_var_cov = l_var_cov, basemodclass = "stanemax" ) @@ -333,14 +333,14 @@ new_ermod_bin_emax <- function( options_placebo_handling = list(), l_var_cov = NULL, input_args = list()) { - + check_input_new_ermod( - mod = mod, - data = data, - var_resp = var_resp, + mod = mod, + data = data, + var_resp = var_resp, var_exposure = var_exposure, options_placebo_handling = options_placebo_handling, - l_var_cov = l_var_cov, + l_var_cov = l_var_cov, basemodclass = "stanemaxbin" ) @@ -396,7 +396,7 @@ check_input_new_ermod <- function( options_placebo_handling = list(), coef_exp_draws = NULL, basemodclass = "stanreg") { - + stopifnot(inherits(mod, basemodclass)) stopifnot(is.data.frame(data)) stopifnot(is.character(var_resp)) @@ -418,12 +418,12 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { ll <- l_ermod_exp_sel check_input_new_ermod( - mod = ll$mod, - data = ll$data, + mod = ll$mod, + data = ll$data, var_resp = ll$var_resp, - var_exp_candidates = ll$var_exp_candidates, + var_exp_candidates = ll$var_exp_candidates, var_exposure = ll$var_exposure, - l_mod_exposures = ll$l_mod_exposures, + l_mod_exposures = ll$l_mod_exposures, basemodclass = basemodclass ) } diff --git a/data-raw/d_sim_emax.R b/data-raw/d_sim_emax.R index 4fd98dd..f4adc16 100644 --- a/data-raw/d_sim_emax.R +++ b/data-raw/d_sim_emax.R @@ -56,7 +56,7 @@ simulate_data <- function(seed = 123) { ) # conditional on a dose group, generate data; include multiple exposure metrics - # but treat the first one as source of ground truth. exposures are strongly + # but treat the first one as source of ground truth. exposures are strongly # correlated but on the same scale make_dose_data <- function(dose, n, par) { tibble::tibble( diff --git a/tests/testthat/test-dev_ermod_emax.R b/tests/testthat/test-dev_ermod_emax.R index 0460c98..0a442f4 100644 --- a/tests/testthat/test-dev_ermod_emax.R +++ b/tests/testthat/test-dev_ermod_emax.R @@ -24,7 +24,7 @@ ermod_emax <- data = data_er_cont, var_exposure = "exposure", var_resp = "response", - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic @@ -39,7 +39,7 @@ ermod_emax_w_cov <- var_exposure = "conc", var_resp = "resp", l_var_cov = list(emax = "cov2", ec50 = "cov3", e0 = "cov1"), - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, chains = 2, iter = 200, @@ -54,7 +54,7 @@ ermod_emax_exp_sel <- data = data_er_cont, var_resp = "response", var_exp_candidates = c("exposure", "exposure2"), - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), emax_fix = 100, e0_fix = 0, verbosity_level = 0, @@ -70,7 +70,7 @@ ermod_bin_emax <- data = data_er_bin, var_exposure = "conc", var_resp = "y", - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), verbosity_level = 0, # Increase iter for better convergence as exact reproducibility # over different machines doesn't seem realistic @@ -84,7 +84,7 @@ ermod_bin_emax_w_cov <- data = data_er_bin, var_exposure = "conc", var_resp = "y_cov", - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), l_var_cov = list(emax = "sex"), verbosity_level = 0, chains = 2, @@ -100,7 +100,7 @@ ermod_bin_emax_exp_sel <- var_resp = "y", var_exp_candidates = c("conc", "conc2"), verbosity_level = 0, - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), chains = 2, iter = 200, seed = 1 @@ -117,7 +117,7 @@ mod_mtcars_emax <- suppressWarnings(dev_ermod_bin_emax( var_resp = "am3", var_exposure = "cyl", verbosity_level = 0, - options_placebo_handling = list(include_placebo = TRUE), + options_placebo_handling = list(include_placebo = TRUE), # Below option to make the test fast chains = 2, iter = 1000 )) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index f48cf60..f7b6c63 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -77,15 +77,15 @@ if (require("projpred")) { # helper function to inspect internal data objects internal_stan_data_rows <- function(object) { - if (inherits(object, "stanemax") | inherits(object, "stanemaxbin")) { + if (inherits(object, "stanemax") || inherits(object, "stanemaxbin")) { return(object$standata$N) - } + } return(nrow(object$data)) } # fit the model for each basic er model case m <- list() -for(r in 1:nrow(cases_ermod)) { +for (r in seq_len(nrow(cases_ermod))) { f <- dev_ermod[[cases_ermod$dev_ermod[r]]] d <- dat[[cases_ermod$dat[r]]] o <- opts[[cases_ermod$opts[r]]] @@ -98,13 +98,13 @@ for(r in 1:nrow(cases_ermod)) { chains = 1, iter = 100 ) - )) + )) } cases_ermod$mod <- m # fit the model for each exposure-selection model case m <- list() -for(r in 1:nrow(cases_expsel)) { +for (r in seq_len(nrow(cases_expsel))) { f <- dev_expsel[[cases_expsel$dev_expsel[r]]] d <- dat[[cases_expsel$dat[r]]] o <- opts[[cases_expsel$opts[r]]] @@ -117,14 +117,14 @@ for(r in 1:nrow(cases_expsel)) { chains = 1, iter = 100 ) - )) + )) } cases_expsel$mod <- m # fit the model for each covariate-selection model case if (require("projpred")) { m <- list() - for(r in 1:nrow(cases_covsel)) { + for (r in seq_len(nrow(cases_covsel))) { f <- dev_covsel[[cases_covsel$dev_covsel[r]]] d <- dat[[cases_covsel$dat[r]]] o <- opts[[cases_covsel$opts[r]]] @@ -138,7 +138,7 @@ if (require("projpred")) { chains = 1, iter = 100 ) - )) + )) } cases_covsel$mod <- m } @@ -146,7 +146,7 @@ if (require("projpred")) { # record number of rows in the inner and outer data sets (basic models) cases_ermod$inner_n <- numeric(nrow(cases_ermod)) cases_ermod$outer_n <- numeric(nrow(cases_ermod)) -for(r in 1:nrow(cases_ermod)) { +for (r in seq_len(nrow(cases_ermod))) { cases_ermod$inner_n[r] <- internal_stan_data_rows(cases_ermod$mod[[r]]$mod) cases_ermod$outer_n[r] <- nrow(cases_ermod$mod[[r]]$data) } @@ -154,7 +154,7 @@ for(r in 1:nrow(cases_ermod)) { # record number of rows in the inner and outer data sets (metric selection) cases_expsel$inner_n <- numeric(nrow(cases_expsel)) cases_expsel$outer_n <- numeric(nrow(cases_expsel)) -for(r in 1:nrow(cases_expsel)) { +for (r in seq_len(nrow(cases_expsel))) { cases_expsel$inner_n[r] <- internal_stan_data_rows(cases_expsel$mod[[r]]$mod) cases_expsel$outer_n[r] <- nrow(cases_expsel$mod[[r]]$data) } @@ -163,7 +163,7 @@ if (require("projpred")) { # record number of rows in the inner and outer data sets (covariate selection) cases_covsel$inner_n <- numeric(nrow(cases_covsel)) cases_covsel$outer_n <- numeric(nrow(cases_covsel)) - for(r in 1:nrow(cases_covsel)) { + for (r in seq_len(nrow(cases_covsel))) { cases_covsel$inner_n[r] <- internal_stan_data_rows(cases_covsel$mod[[r]]$mod) cases_covsel$outer_n[r] <- nrow(cases_covsel$mod[[r]]$data) } @@ -173,7 +173,7 @@ if (require("projpred")) { # originally contained a placebo group, and the options specify that the # placebo group is to be used during model fitting test_that("internal data respects placebo options (basic models)", { - for(r in 1:nrow(cases_ermod)) { + for (r in seq_len(nrow(cases_ermod))) { if (cases_ermod$dat[r] == "placebo" & cases_ermod$opts[r] == "use_placebo") { expect_equal(cases_ermod$inner_n[r], 40L) } else { @@ -182,7 +182,7 @@ test_that("internal data respects placebo options (basic models)", { } }) test_that("internal data respects placebo options (metric selection)", { - for(r in 1:nrow(cases_expsel)) { + for (r in seq_len(nrow(cases_expsel))) { if (cases_expsel$dat[r] == "placebo" & cases_expsel$opts[r] == "use_placebo") { expect_equal(cases_expsel$inner_n[r], 40L) } else { @@ -192,7 +192,7 @@ test_that("internal data respects placebo options (metric selection)", { }) if (require("projpred")) { test_that("internal data respects placebo options (covariate selection)", { - for(r in 1:nrow(cases_covsel)) { + for (r in seq_len(nrow(cases_covsel))) { if (cases_covsel$dat[r] == "placebo" & cases_covsel$opts[r] == "use_placebo") { expect_equal(cases_covsel$inner_n[r], 40L) } else { @@ -205,7 +205,7 @@ if (require("projpred")) { # the "user facing" data set should only include placebo samples if the data set # originally contained a placebo group, regardless of the placebo handling settings test_that("outer data preserves all data rows (basic models)", { - for(r in 1:nrow(cases_ermod)) { + for (r in seq_len(nrow(cases_ermod))) { if (cases_ermod$dat[r] == "placebo") { expect_equal(cases_ermod$outer_n[r], 40L) } else { @@ -214,7 +214,7 @@ test_that("outer data preserves all data rows (basic models)", { } }) test_that("outer data preserves all data rows (metric selection)", { - for(r in 1:nrow(cases_expsel)) { + for (r in seq_len(nrow(cases_expsel))) { if (cases_expsel$dat[r] == "placebo") { expect_equal(cases_expsel$outer_n[r], 40L) } else { @@ -224,7 +224,7 @@ test_that("outer data preserves all data rows (metric selection)", { }) if (require("projpred")) { test_that("outer data preserves all data rows (covariate selection)", { - for(r in 1:nrow(cases_covsel)) { + for (r in seq_len(nrow(cases_covsel))) { if (cases_covsel$dat[r] == "placebo") { expect_equal(cases_covsel$outer_n[r], 40L) } else { @@ -233,4 +233,3 @@ if (require("projpred")) { } }) } - \ No newline at end of file From 7abc55b702ff40eff7c5d03b3c51768b8dd57d47 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:48:09 +1000 Subject: [PATCH 35/57] additional linting fixes --- R/dev_ermod_emax.R | 4 ++-- R/dev_ermod_lin.R | 12 ++++++------ R/ermod-class.R | 6 +++--- R/yyy.R | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/dev_ermod_emax.R b/R/dev_ermod_emax.R index 1f3d21d..9ddea3d 100644 --- a/R/dev_ermod_emax.R +++ b/R/dev_ermod_emax.R @@ -73,7 +73,7 @@ dev_ermod_emax <- function( environment() ) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) @@ -262,7 +262,7 @@ dev_ermod_bin_emax <- function( environment() ) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) stopifnot(verbosity_level %in% c(0, 1, 2, 3)) refresh <- dplyr::if_else(verbosity_level >= 3, iter %/% 4, 0) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index eb108ec..3389276 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -69,7 +69,7 @@ dev_ermod_bin <- function( environment() ) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) check_data_columns( data = data, @@ -152,7 +152,7 @@ dev_ermod_bin_exp_sel <- function( chains = 4, iter = 2000) { - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) fun_dev_ermod <- purrr::partial( @@ -235,7 +235,7 @@ dev_ermod_bin_cov_sel <- function( chains = 4, iter = 2000) { - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) fun_dev_ermod <- purrr::partial( @@ -319,7 +319,7 @@ dev_ermod_lin <- function( environment() ) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) check_data_columns( data = data, @@ -390,7 +390,7 @@ dev_ermod_lin_exp_sel <- function( chains = 4, iter = 2000) { - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) fun_dev_ermod <- purrr::partial( @@ -450,7 +450,7 @@ dev_ermod_lin_cov_sel <- function( chains = 4, iter = 2000) { - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) fun_dev_ermod <- purrr::partial( diff --git a/R/ermod-class.R b/R/ermod-class.R index d524297..feb4768 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -21,7 +21,7 @@ new_ermod_lin <- function( options_placebo_handling = list()) { coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) check_input_new_ermod( mod = mod, @@ -150,7 +150,7 @@ new_ermod_bin <- function( ) { coef_exp_draws <- .get_coef_exp_draws(mod, var_exposure) - options_placebo_handling <- .apply_placebo_handling_defaults(options_placebo_handling) + options_placebo_handling <- .apply_placebo_defaults(options_placebo_handling) check_input_new_ermod( mod = mod, @@ -432,7 +432,7 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { posterior::as_draws_df(mod)[[var_exposure]] } -.apply_placebo_handling_defaults <- function(options) { +.apply_placebo_defaults <- function(options) { utils::modifyList( list( include_placebo = FALSE, diff --git a/R/yyy.R b/R/yyy.R index b83f85b..57f9d39 100644 --- a/R/yyy.R +++ b/R/yyy.R @@ -38,7 +38,7 @@ if (getRversion() >= "2.15.1") { # sim data gen utils::globalVariables(c( - "exposure", "cnt_a", "cnt_b", "cnt_c", "bin_d", "bin_pred", "bin_prob" + "exposure_1", "exposure_2", "cnt_a", "cnt_b", "cnt_c", "bin_d", "bin_pred", "bin_prob" )) } From 4f5475ebb0f8ca857490e3190688a7ce1130c8d5 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Wed, 17 Sep 2025 21:59:42 +1000 Subject: [PATCH 36/57] don't quote --- R/dev_ermod_lin.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index 3389276..f23a510 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -94,7 +94,7 @@ dev_ermod_bin <- function( rstanarm::stan_glm, formula = formula_final, family = stats::binomial(), - data = quote(stan_data), + data = stan_data, prior = prior, prior_intercept = prior_intercept, QR = dplyr::if_else(length(var_full) > 1, TRUE, FALSE), @@ -737,7 +737,7 @@ NULL rstanarm::stan_glm, formula = formula_full, family = fun_family, - data = quote(stan_data), + data = stan_data, QR = TRUE, refresh = refresh, chains = chains, From f92cddc79b9d549d5bc836c06905eadeb761d5e8 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 11:41:13 +1000 Subject: [PATCH 37/57] strips back example code --- other/placebo-example.R | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/other/placebo-example.R b/other/placebo-example.R index b0999a0..d2c326c 100644 --- a/other/placebo-example.R +++ b/other/placebo-example.R @@ -1,22 +1,12 @@ library(BayesERtools) -# a data set that includes a placebo group -dat <- dplyr::bind_rows( - readr::read_csv("data-raw/d_sim_emax.csv"), # current emax data set in pacakge - readr::read_csv("other/d_sim_emax_placebo.csv") # placebo data from same model -) |> - dplyr::mutate(placebo = dose == 0) # represent the placebo group explicitly - -# scenario 1: default is to implicitly drop placebo, assuming that the placebo -# group maps onto the zero exposure rows -mod1 <- dat |> +# logistic regression, no placebo +d_sim_emax |> dev_ermod_bin( var_resp = "response_2", - var_exposure = "exposure" - ) - -mod1 |> - sim_er_curve(output_type = "median_qi") |> + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ) |> plot_er( show_orig_data = TRUE, options_orig_data = list(var_group = "dose") From 4126bb58264ebbcd80f4bc4df83f56e9c6c72d33 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 12:18:38 +1000 Subject: [PATCH 38/57] placebo handling tests contain a no_error check --- tests/testthat/test-placebo_handling.R | 143 +++++++++++++++---------- 1 file changed, 88 insertions(+), 55 deletions(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index f7b6c63..2a27f35 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -1,4 +1,6 @@ +# setup cases to test ---------------------------------------------------- + # two versions of the data to test dat <- list( placebo = d_sim_emax |> dplyr::slice_sample(n = 10, by = dose), @@ -75,72 +77,102 @@ if (require("projpred")) { ) } -# helper function to inspect internal data objects -internal_stan_data_rows <- function(object) { - if (inherits(object, "stanemax") || inherits(object, "stanemaxbin")) { - return(object$standata$N) - } - return(nrow(object$data)) -} +# tests that the model fitting runs without error ------------------------ -# fit the model for each basic er model case -m <- list() -for (r in seq_len(nrow(cases_ermod))) { - f <- dev_ermod[[cases_ermod$dev_ermod[r]]] - d <- dat[[cases_ermod$dat[r]]] - o <- opts[[cases_ermod$opts[r]]] - set.seed(123L) - suppressWarnings(suppressMessages( - m[[r]] <- d |> f( - var_exposure = "exposure_1", - var_resp = cases_ermod$var_resp[r], - options_placebo_handling = o, - chains = 1, - iter = 100 - ) - )) -} -cases_ermod$mod <- m +test_that("basic model fitting works with and without placebo", { + mods <- list() + for (r in seq_len(nrow(cases_ermod))) { -# fit the model for each exposure-selection model case -m <- list() -for (r in seq_len(nrow(cases_expsel))) { - f <- dev_expsel[[cases_expsel$dev_expsel[r]]] - d <- dat[[cases_expsel$dat[r]]] - o <- opts[[cases_expsel$opts[r]]] - set.seed(123L) - suppressWarnings(suppressMessages( - m[[r]] <- d |> f( - var_exp_candidates = c("exposure_1", "exposure_2"), - var_resp = cases_expsel$var_resp[r], - options_placebo_handling = o, - chains = 1, - iter = 100 + # which function, dataset, and options to use + f <- purrr::quietly(dev_ermod[[cases_ermod$dev_ermod[r]]]) + d <- dat[[cases_ermod$dat[r]]] + o <- opts[[cases_ermod$opts[r]]] + set.seed(123L) + + # estimate the model quietly, test that it runs without error + expect_no_error( + m <- d |> f( + var_exposure = "exposure_1", + var_resp = cases_ermod$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) ) - )) -} -cases_expsel$mod <- m + mods[[r]] <- m + } -# fit the model for each covariate-selection model case -if (require("projpred")) { - m <- list() - for (r in seq_len(nrow(cases_covsel))) { - f <- dev_covsel[[cases_covsel$dev_covsel[r]]] - d <- dat[[cases_covsel$dat[r]]] - o <- opts[[cases_covsel$opts[r]]] + # keep a copy in the cases_ermod data frame so that the models + # persist without the test environment + cases_ermod$mod <<- mods +}) + +test_that("exposure selection fitting works with and without placebo", { + mods <- list() + for (r in seq_len(nrow(cases_expsel))) { + + # which function, dataset, and options to use + f <- purrr::quietly(dev_expsel[[cases_expsel$dev_expsel[r]]]) + d <- dat[[cases_expsel$dat[r]]] + o <- opts[[cases_expsel$opts[r]]] set.seed(123L) - suppressWarnings(suppressMessages( - m[[r]] <- d |> f( - var_exposure = "exposure_1", - var_cov_candidates = c("cnt_a", "cnt_b"), + + # estimate the model quietly, test that it runs without error + expect_no_error( + m <- d |> f( + var_exp_candidates = c("exposure_1", "exposure_2"), var_resp = cases_expsel$var_resp[r], options_placebo_handling = o, chains = 1, iter = 100 ) - )) + ) + mods[[r]] <- m } - cases_covsel$mod <- m + + # keep a copy in the cases_expsel data frame so that the models + # persist without the test environment + cases_expsel$mod <<- mods +}) + +if (require("projpred")) { + test_that("covariate selection fitting works with and without placebo", { + mods <- list() + for (r in seq_len(nrow(cases_covsel))) { + + # which function, dataset, and options to use + f <- purrr::quietly(dev_covsel[[cases_covsel$dev_covsel[r]]]) + d <- dat[[cases_covsel$dat[r]]] + o <- opts[[cases_covsel$opts[r]]] + set.seed(123L) + + # estimate the model quietly, test that it runs without error + expect_no_error( + m <- d |> f( + var_exposure = "exposure_1", + var_cov_candidates = c("cnt_a", "cnt_b"), + var_resp = cases_covsel$var_resp[r], + options_placebo_handling = o, + chains = 1, + iter = 100 + ) + ) + mods[[r]] <- m + } + # keep a copy in the cases_covsel data frame so that the models + # persist without the test environment + cases_covsel$mod <<- mods + }) +} + +# tests to examine placebo data handling --------------------------------- + +# helper function to inspect internal data objects +internal_stan_data_rows <- function(object) { + if (inherits(object, "stanemax") || inherits(object, "stanemaxbin")) { + return(object$standata$N) + } + return(nrow(object$data)) } # record number of rows in the inner and outer data sets (basic models) @@ -233,3 +265,4 @@ if (require("projpred")) { } }) } + From f2993333683848a66ee4f0fe5e03320d0a434141 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 12:22:52 +1000 Subject: [PATCH 39/57] whitespace fixes for linter --- tests/testthat/test-placebo_handling.R | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index 2a27f35..cc9f00a 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -102,9 +102,9 @@ test_that("basic model fitting works with and without placebo", { mods[[r]] <- m } - # keep a copy in the cases_ermod data frame so that the models + # keep a copy in the cases_ermod data frame so that the models # persist without the test environment - cases_ermod$mod <<- mods + cases_ermod$mod <<- mods }) test_that("exposure selection fitting works with and without placebo", { @@ -130,9 +130,9 @@ test_that("exposure selection fitting works with and without placebo", { mods[[r]] <- m } - # keep a copy in the cases_expsel data frame so that the models + # keep a copy in the cases_expsel data frame so that the models # persist without the test environment - cases_expsel$mod <<- mods + cases_expsel$mod <<- mods }) if (require("projpred")) { @@ -145,7 +145,7 @@ if (require("projpred")) { d <- dat[[cases_covsel$dat[r]]] o <- opts[[cases_covsel$opts[r]]] set.seed(123L) - + # estimate the model quietly, test that it runs without error expect_no_error( m <- d |> f( @@ -159,7 +159,7 @@ if (require("projpred")) { ) mods[[r]] <- m } - # keep a copy in the cases_covsel data frame so that the models + # keep a copy in the cases_covsel data frame so that the models # persist without the test environment cases_covsel$mod <<- mods }) @@ -265,4 +265,3 @@ if (require("projpred")) { } }) } - From 4da2618f30ccf31d644f9b9ee4aae91728f57663 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 14:02:23 +1000 Subject: [PATCH 40/57] extract_data.ermod permits inner data extraction --- R/ermod-methods.R | 7 +- R/ersim-methods.R | 4 +- R/s3_generics.R | 3 +- man/extract_ermod.Rd | 2 +- man/extract_ersim.Rd | 4 +- man/extract_method.Rd | 4 +- tests/testthat/test-placebo_handling.R | 113 +++++++++++++++---------- 7 files changed, 82 insertions(+), 55 deletions(-) diff --git a/R/ermod-methods.R b/R/ermod-methods.R index 1775761..336a4ad 100644 --- a/R/ermod-methods.R +++ b/R/ermod-methods.R @@ -172,7 +172,12 @@ plot.ermod_cov_sel <- function(x, ...) { #' @inherit extract_method return #' @param x An object of class \code{ermod_*} #' -extract_data.ermod <- function(x) x$data +extract_data.ermod <- function(x, ..., internal_data = FALSE) { + if (!internal_data) return(x$data) + if (inherits(x$mod, "stanreg")) return(x$mod$data) + if (inherits(x$mod, "stanemax")) return(as.data.frame(x$mod$standata)) + if (inherits(x$mod, "stanemaxbin")) return(as.data.frame(x$mod$standata)) +} #' @export #' @rdname extract_ermod diff --git a/R/ersim-methods.R b/R/ersim-methods.R index f7fc153..d268ca0 100644 --- a/R/ersim-methods.R +++ b/R/ersim-methods.R @@ -29,11 +29,11 @@ plot.ersim_med_qi <- function(x, show_orig_data = FALSE, ...) { #' @keywords internal #' @inherit extract_method return #' @param x An object of class \code{ersim_*} -extract_data.ersim <- function(x) attr(x, "origdata") +extract_data.ersim <- function(x, ...) attr(x, "origdata") #' @export #' @rdname extract_ersim -extract_data.ersim_med_qi <- function(x) attr(x, "origdata") +extract_data.ersim_med_qi <- function(x, ...) attr(x, "origdata") #' @export #' @rdname extract_ersim diff --git a/R/s3_generics.R b/R/s3_generics.R index d89935c..ce081f5 100644 --- a/R/s3_generics.R +++ b/R/s3_generics.R @@ -5,6 +5,7 @@ #' #' @name extract_method #' @param x An object to extract elements from +#' @param ... Additional arguments passed to methods #' @return #' - [extract_data()] extracts data used for the model fit. #' - [extract_mod()] extracts the model fit object. @@ -21,7 +22,7 @@ NULL #' @export #' @rdname extract_method -extract_data <- function(x) UseMethod("extract_data") +extract_data <- function(x, ...) UseMethod("extract_data") #' @export #' @rdname extract_method diff --git a/man/extract_ermod.Rd b/man/extract_ermod.Rd index d2e6da4..14c1463 100644 --- a/man/extract_ermod.Rd +++ b/man/extract_ermod.Rd @@ -12,7 +12,7 @@ \alias{extract_var_selected.ermod_cov_sel} \title{Extract elements from an object of class \code{ermod_*}} \usage{ -\method{extract_data}{ermod}(x) +\method{extract_data}{ermod}(x, ..., internal_data = FALSE) \method{extract_mod}{ermod}(x) diff --git a/man/extract_ersim.Rd b/man/extract_ersim.Rd index 6d64b69..6d394e6 100644 --- a/man/extract_ersim.Rd +++ b/man/extract_ersim.Rd @@ -12,9 +12,9 @@ \alias{extract_var_cov.ersim_med_qi} \title{Extract elements from objects of the classes \verb{ersim_*} and `ersim_med_qi_*``} \usage{ -\method{extract_data}{ersim}(x) +\method{extract_data}{ersim}(x, ...) -\method{extract_data}{ersim_med_qi}(x) +\method{extract_data}{ersim_med_qi}(x, ...) \method{extract_var_resp}{ersim}(x) diff --git a/man/extract_method.Rd b/man/extract_method.Rd index 7cea0e9..a51aca8 100644 --- a/man/extract_method.Rd +++ b/man/extract_method.Rd @@ -12,7 +12,7 @@ \alias{extract_var_selected} \title{Extract elements from S3 objects} \usage{ -extract_data(x) +extract_data(x, ...) extract_mod(x) @@ -30,6 +30,8 @@ extract_var_selected(x) } \arguments{ \item{x}{An object to extract elements from} + +\item{...}{Additional arguments passed to methods} } \value{ \itemize{ diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index cc9f00a..c9ecf52 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -46,8 +46,11 @@ cases_ermod <- tidyr::expand_grid( dev_ermod == "dev_ermod_bin" ~ "response_2", dev_ermod == "dev_ermod_emax" ~ "response_1", dev_ermod == "dev_ermod_bin_emax" ~ "response_2" - ) + ), + inner_n = NA_integer_, + outer_n = NA_integer_ ) +n_cases_ermod <- nrow(cases_ermod) # all test cases for exposure selection functions cases_expsel <- tidyr::expand_grid( @@ -60,8 +63,11 @@ cases_expsel <- tidyr::expand_grid( dev_expsel == "dev_ermod_bin_exp_sel" ~ "response_2", dev_expsel == "dev_ermod_emax_exp_sel" ~ "response_1", dev_expsel == "dev_ermod_bin_emax_exp_sel" ~ "response_2" - ) + ), + inner_n = NA_integer_, + outer_n = NA_integer_ ) +n_cases_expsel <- nrow(cases_expsel) if (require("projpred")) { # all test cases for covariate selection functions @@ -73,15 +79,18 @@ if (require("projpred")) { var_resp = dplyr::case_when( dev_covsel == "dev_ermod_lin_cov_sel" ~ "response_1", dev_covsel == "dev_ermod_bin_cov_sel" ~ "response_2", - ) + ), + inner_n = NA_integer_, + outer_n = NA_integer_ ) + n_cases_covsel <- nrow(cases_covsel) } # tests that the model fitting runs without error ------------------------ test_that("basic model fitting works with and without placebo", { mods <- list() - for (r in seq_len(nrow(cases_ermod))) { + for (r in seq_len(n_cases_ermod)) { # which function, dataset, and options to use f <- purrr::quietly(dev_ermod[[cases_ermod$dev_ermod[r]]]) @@ -99,7 +108,7 @@ test_that("basic model fitting works with and without placebo", { iter = 100 ) ) - mods[[r]] <- m + mods[[r]] <- m$result } # keep a copy in the cases_ermod data frame so that the models @@ -109,7 +118,7 @@ test_that("basic model fitting works with and without placebo", { test_that("exposure selection fitting works with and without placebo", { mods <- list() - for (r in seq_len(nrow(cases_expsel))) { + for (r in seq_len(n_cases_expsel)) { # which function, dataset, and options to use f <- purrr::quietly(dev_expsel[[cases_expsel$dev_expsel[r]]]) @@ -127,7 +136,7 @@ test_that("exposure selection fitting works with and without placebo", { iter = 100 ) ) - mods[[r]] <- m + mods[[r]] <- m$result } # keep a copy in the cases_expsel data frame so that the models @@ -138,7 +147,7 @@ test_that("exposure selection fitting works with and without placebo", { if (require("projpred")) { test_that("covariate selection fitting works with and without placebo", { mods <- list() - for (r in seq_len(nrow(cases_covsel))) { + for (r in seq_len(n_cases_covsel)) { # which function, dataset, and options to use f <- purrr::quietly(dev_covsel[[cases_covsel$dev_covsel[r]]]) @@ -157,7 +166,7 @@ if (require("projpred")) { iter = 100 ) ) - mods[[r]] <- m + mods[[r]] <- m$result } # keep a copy in the cases_covsel data frame so that the models # persist without the test environment @@ -165,47 +174,57 @@ if (require("projpred")) { }) } -# tests to examine placebo data handling --------------------------------- -# helper function to inspect internal data objects -internal_stan_data_rows <- function(object) { - if (inherits(object, "stanemax") || inherits(object, "stanemaxbin")) { - return(object$standata$N) - } - return(nrow(object$data)) -} +# tests to extract internal data --------------------------------- -# record number of rows in the inner and outer data sets (basic models) -cases_ermod$inner_n <- numeric(nrow(cases_ermod)) -cases_ermod$outer_n <- numeric(nrow(cases_ermod)) -for (r in seq_len(nrow(cases_ermod))) { - cases_ermod$inner_n[r] <- internal_stan_data_rows(cases_ermod$mod[[r]]$mod) - cases_ermod$outer_n[r] <- nrow(cases_ermod$mod[[r]]$data) -} +test_that("extract_data.ermod respects internal_data argument (ermod)", { + for (r in seq_len(n_cases_ermod)) { + print(r) + m <- cases_ermod$mod[[r]] + expect_no_error(extract_data(m, internal_data = TRUE)) + expect_no_error(extract_data(m, internal_data = FALSE)) + inner_data <- extract_data(m, internal_data = TRUE) + outer_data <- extract_data(m, internal_data = FALSE) + expect_true(inherits(inner_data, "data.frame")) + expect_true(inherits(outer_data, "data.frame")) + cases_ermod$inner_n[r] <<- nrow(inner_data) + cases_ermod$outer_n[r] <<- nrow(outer_data) + } +}) -# record number of rows in the inner and outer data sets (metric selection) -cases_expsel$inner_n <- numeric(nrow(cases_expsel)) -cases_expsel$outer_n <- numeric(nrow(cases_expsel)) -for (r in seq_len(nrow(cases_expsel))) { - cases_expsel$inner_n[r] <- internal_stan_data_rows(cases_expsel$mod[[r]]$mod) - cases_expsel$outer_n[r] <- nrow(cases_expsel$mod[[r]]$data) -} +test_that("extract_data.ermod respects internal_data argument (expsel)", { + for (r in seq_len(n_cases_ermod)) { + m <- cases_expsel$mod[[r]] + expect_no_error(extract_data(m, internal_data = TRUE)) + expect_no_error(extract_data(m, internal_data = FALSE)) + inner_data <- extract_data(m, internal_data = TRUE) + outer_data <- extract_data(m, internal_data = FALSE) + cases_expsel$inner_n[r] <<- nrow(inner_data) + cases_expsel$outer_n[r] <<- nrow(outer_data) + } +}) if (require("projpred")) { - # record number of rows in the inner and outer data sets (covariate selection) - cases_covsel$inner_n <- numeric(nrow(cases_covsel)) - cases_covsel$outer_n <- numeric(nrow(cases_covsel)) - for (r in seq_len(nrow(cases_covsel))) { - cases_covsel$inner_n[r] <- internal_stan_data_rows(cases_covsel$mod[[r]]$mod) - cases_covsel$outer_n[r] <- nrow(cases_covsel$mod[[r]]$data) - } + test_that("extract_data.ermod respects internal_data argument (covsel)", { + for (r in seq_len(n_cases_covsel)) { + m <- cases_covsel$mod[[r]] + expect_no_error(extract_data(m, internal_data = TRUE)) + expect_no_error(extract_data(m, internal_data = FALSE)) + inner_data <- extract_data(m, internal_data = TRUE) + outer_data <- extract_data(m, internal_data = FALSE) + cases_covsel$inner_n[r] <<- nrow(inner_data) + cases_covsel$outer_n[r] <<- nrow(outer_data) + } + }) } -# the "stan" data set should only include placebo samples if the data set -# originally contained a placebo group, and the options specify that the -# placebo group is to be used during model fitting +# tests to examine placebo data handling --------------------------------- + +# the inner "stan" data set should only include placebo samples if the +# data set originally contained a placebo group, and the options specify +# that the placebo group is to be used during model fitting test_that("internal data respects placebo options (basic models)", { - for (r in seq_len(nrow(cases_ermod))) { + for (r in seq_len(n_cases_ermod)) { if (cases_ermod$dat[r] == "placebo" & cases_ermod$opts[r] == "use_placebo") { expect_equal(cases_ermod$inner_n[r], 40L) } else { @@ -214,7 +233,7 @@ test_that("internal data respects placebo options (basic models)", { } }) test_that("internal data respects placebo options (metric selection)", { - for (r in seq_len(nrow(cases_expsel))) { + for (r in seq_len(n_cases_expsel)) { if (cases_expsel$dat[r] == "placebo" & cases_expsel$opts[r] == "use_placebo") { expect_equal(cases_expsel$inner_n[r], 40L) } else { @@ -224,7 +243,7 @@ test_that("internal data respects placebo options (metric selection)", { }) if (require("projpred")) { test_that("internal data respects placebo options (covariate selection)", { - for (r in seq_len(nrow(cases_covsel))) { + for (r in seq_len(n_cases_covsel)) { if (cases_covsel$dat[r] == "placebo" & cases_covsel$opts[r] == "use_placebo") { expect_equal(cases_covsel$inner_n[r], 40L) } else { @@ -237,7 +256,7 @@ if (require("projpred")) { # the "user facing" data set should only include placebo samples if the data set # originally contained a placebo group, regardless of the placebo handling settings test_that("outer data preserves all data rows (basic models)", { - for (r in seq_len(nrow(cases_ermod))) { + for (r in seq_len(n_cases_ermod)) { if (cases_ermod$dat[r] == "placebo") { expect_equal(cases_ermod$outer_n[r], 40L) } else { @@ -246,7 +265,7 @@ test_that("outer data preserves all data rows (basic models)", { } }) test_that("outer data preserves all data rows (metric selection)", { - for (r in seq_len(nrow(cases_expsel))) { + for (r in seq_len(n_cases_expsel)) { if (cases_expsel$dat[r] == "placebo") { expect_equal(cases_expsel$outer_n[r], 40L) } else { @@ -256,7 +275,7 @@ test_that("outer data preserves all data rows (metric selection)", { }) if (require("projpred")) { test_that("outer data preserves all data rows (covariate selection)", { - for (r in seq_len(nrow(cases_covsel))) { + for (r in seq_len(n_cases_covsel)) { if (cases_covsel$dat[r] == "placebo") { expect_equal(cases_covsel$outer_n[r], 40L) } else { From 2e65112b305093152aefa5bf1307f18b69ffc99f Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 14:14:40 +1000 Subject: [PATCH 41/57] tidies the internal_data tests --- tests/testthat/test-placebo_handling.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index c9ecf52..d8ef2e1 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -199,6 +199,8 @@ test_that("extract_data.ermod respects internal_data argument (expsel)", { expect_no_error(extract_data(m, internal_data = FALSE)) inner_data <- extract_data(m, internal_data = TRUE) outer_data <- extract_data(m, internal_data = FALSE) + expect_true(inherits(inner_data, "data.frame")) + expect_true(inherits(outer_data, "data.frame")) cases_expsel$inner_n[r] <<- nrow(inner_data) cases_expsel$outer_n[r] <<- nrow(outer_data) } @@ -212,6 +214,8 @@ if (require("projpred")) { expect_no_error(extract_data(m, internal_data = FALSE)) inner_data <- extract_data(m, internal_data = TRUE) outer_data <- extract_data(m, internal_data = FALSE) + expect_true(inherits(inner_data, "data.frame")) + expect_true(inherits(outer_data, "data.frame")) cases_covsel$inner_n[r] <<- nrow(inner_data) cases_covsel$outer_n[r] <<- nrow(outer_data) } From 4025d15a93b80cfde04e9ee42a419fbe04fb5012 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 14:44:56 +1000 Subject: [PATCH 42/57] updates examples --- other/placebo-example.R | 99 +++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 13 deletions(-) diff --git a/other/placebo-example.R b/other/placebo-example.R index d2c326c..4082335 100644 --- a/other/placebo-example.R +++ b/other/placebo-example.R @@ -1,32 +1,105 @@ library(BayesERtools) +# linear regression, no placebo +mod <- d_sim_emax |> + dev_ermod_lin( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + +# linear regression, with placebo +mod <- d_sim_emax |> + dev_ermod_lin( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + # logistic regression, no placebo -d_sim_emax |> +mod <- d_sim_emax |> dev_ermod_bin( var_resp = "response_2", var_exposure = "exposure_1", options_placebo_handling = list(include_placebo = FALSE) - ) |> + ) +mod |> plot_er( show_orig_data = TRUE, options_orig_data = list(var_group = "dose") ) - -# scenario 2: model should n -mod2 <- dat |> +# logistic regression, with placebo +mod <- d_sim_emax |> dev_ermod_bin( var_resp = "response_2", - var_exposure = "exposure", - options_placebo_handling = list( - include_placebo = TRUE, - method = "var_placebo", - var_placebo = "placebo" - ) + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") ) -mod2 |> - sim_er_curve(output_type = "median_qi") |> + +# emax regression, continuous response, no placebo +mod <- d_sim_emax |> + dev_ermod_emax( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + +# emax regression, continuous response, with placebo +mod <- d_sim_emax |> + dev_ermod_emax( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + +# emax regression, binary response, no placebo +mod <- d_sim_emax |> + dev_ermod_bin_emax( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ) +mod |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + +# emax regression, binary response, with placebo +mod <- d_sim_emax |> + dev_ermod_bin_emax( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ) +mod |> plot_er( show_orig_data = TRUE, options_orig_data = list(var_group = "dose") From ba1089465a937c3e462621a1aeab914274e7dba6 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 15:48:53 +1000 Subject: [PATCH 43/57] eval_ermod tests supply placebo options explicitly --- tests/testthat/test-eval_ermod.R | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/testthat/test-eval_ermod.R b/tests/testthat/test-eval_ermod.R index 1530668..734251e 100644 --- a/tests/testthat/test-eval_ermod.R +++ b/tests/testthat/test-eval_ermod.R @@ -6,11 +6,13 @@ if (.if_run_ex_eval_mod()) { d_train <- rsample::training(d_split) d_test <- rsample::testing(d_split) + opts_placebo <- list(include_placebo = TRUE) # allow zeros in test ermod_bin <- dev_ermod_bin( data = d_train |> head(100), var_resp = "AEFLAG", var_exposure = "AUCss_1000", var_cov = "BHBA1C_5", + options_placebo_handling = opts_placebo, chains = 2, iter = 500 ) @@ -30,6 +32,7 @@ if (.if_run_ex_eval_mod()) { var_exposure = "conc", var_resp = "y_cov", l_var_cov = list(emax = "sex"), + options_placebo_handling = opts_placebo, verbosity_level = 0, chains = 2, iter = 200, @@ -48,6 +51,7 @@ if (.if_run_ex_eval_mod()) { var_resp = "response", var_exposure = "AUCss", var_cov = c("SEX", "BAGE"), + options_placebo_handling = opts_placebo, chains = 2, iter = 500 ) @@ -67,6 +71,7 @@ if (.if_run_ex_eval_mod()) { var_exposure = "conc", var_resp = "resp", l_var_cov = list(emax = "cov2", ec50 = "cov3", e0 = "cov1"), + options_placebo_handling = opts_placebo, verbosity_level = 0, chains = 2, iter = 200, From a6e387c91c1922d7e8f2c2537aeaf026d5d9e620 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:05:29 +1000 Subject: [PATCH 44/57] ersim class stores placebo options --- R/ersim-class.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/ersim-class.R b/R/ersim-class.R index c7090c5..774c091 100644 --- a/R/ersim-class.R +++ b/R/ersim-class.R @@ -26,6 +26,7 @@ new_ersim <- function(simdata, ermod, nrow_cov_data) { attr(ersim, "coef_exp_draws") <- ermod$coef_exp_draws attr(ersim, "ermod_class") <- class(ermod) attr(ersim, "endpoint_type") <- ermod$endpoint_type + attr(ersim, "options_placebo_handling") <- ermod$options_placebo_handling # Add ersim class class(ersim) <- c("ersim", class(ersim)) From 7d919bf758df1103cfc8bd8e78fec1cdb342d31f Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:07:04 +1000 Subject: [PATCH 45/57] fixes dropped placebo options during exposure selection bug --- R/dev_ermod_lin.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/dev_ermod_lin.R b/R/dev_ermod_lin.R index f23a510..223cb29 100644 --- a/R/dev_ermod_lin.R +++ b/R/dev_ermod_lin.R @@ -568,6 +568,7 @@ dev_ermod_lin_cov_sel <- function( var_resp = var_resp, var_exp_candidates = var_exp_candidates, var_exposure = var_exposure, + options_placebo_handling = options_placebo_handling, l_mod_exposures = l_mod_exposures, loo_comp_exposures = loo_comp_exposures, input_args = l_mod_exposures[[var_exposure]]$input_args From e878f022743ebe3e260876caa8aea9d286680e46 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:12:26 +1000 Subject: [PATCH 46/57] extract_data has a method argument --- R/ermod-methods.R | 27 +++++++++++++++++++++----- R/ersim-methods.R | 24 +++++++++++++++++++++-- tests/testthat/test-placebo_handling.R | 24 +++++++++++------------ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/R/ermod-methods.R b/R/ermod-methods.R index 336a4ad..10f33bf 100644 --- a/R/ermod-methods.R +++ b/R/ermod-methods.R @@ -171,12 +171,29 @@ plot.ermod_cov_sel <- function(x, ...) { #' @keywords internal #' @inherit extract_method return #' @param x An object of class \code{ermod_*} +#' @param options_placebo_handling This is exposed to allow user to override placebo settings +#' @param method This is exposed to allow extraction of data in different ways: "raw" returns +#' the original data object, "processed" returns the data after placebo handling has been +#' applied, "internal" is for testing purposes only and extracts data from the masked stan +#' object #' -extract_data.ermod <- function(x, ..., internal_data = FALSE) { - if (!internal_data) return(x$data) - if (inherits(x$mod, "stanreg")) return(x$mod$data) - if (inherits(x$mod, "stanemax")) return(as.data.frame(x$mod$standata)) - if (inherits(x$mod, "stanemaxbin")) return(as.data.frame(x$mod$standata)) +extract_data.ermod <- function(x, ..., method = "raw") { + if (method == "raw") return(x$data) + if (method == "processed") { + opt <- .apply_placebo_defaults(x$options_placebo_handling) + dat <- .apply_placebo_handling( + data = x$data, + options = opt, + var_exposure = extract_var_exposure(x) + ) + return(dat) + } + if (method == "internal") { + if (inherits(x$mod, "stanreg")) return(x$mod$data) + if (inherits(x$mod, "stanemax")) return(as.data.frame(x$mod$standata)) + if (inherits(x$mod, "stanemaxbin")) return(as.data.frame(x$mod$standata)) + } + stop("unknown `method`", call. = FALSE) } #' @export diff --git a/R/ersim-methods.R b/R/ersim-methods.R index d268ca0..95c0857 100644 --- a/R/ersim-methods.R +++ b/R/ersim-methods.R @@ -29,11 +29,31 @@ plot.ersim_med_qi <- function(x, show_orig_data = FALSE, ...) { #' @keywords internal #' @inherit extract_method return #' @param x An object of class \code{ersim_*} -extract_data.ersim <- function(x, ...) attr(x, "origdata") +extract_data.ersim <- function(x, ..., method = "raw") { + dat <- attr(x, "origdata") + if (method == "raw") return(dat) + if (method == "processed") { + opt <- .apply_placebo_defaults(attr(x, "options_placebo_handling")) + exp <- extract_var_exposure(x) + dat <- .apply_placebo_handling(dat, opt, exp) + return(dat) + } + stop("unknown `method`", call. = FALSE) +} #' @export #' @rdname extract_ersim -extract_data.ersim_med_qi <- function(x, ...) attr(x, "origdata") +extract_data.ersim_med_qi <- function(x, ..., method = "raw") { + dat <- attr(x, "origdata") + if (method == "raw") return(dat) + if (method == "processed") { + opt <- .apply_placebo_defaults(attr(x, "options_placebo_handling")) + exp <- extract_var_exposure(x) + dat <- .apply_placebo_handling(dat, opt, exp) + return(dat) + } + stop("unknown `method`", call. = FALSE) +} #' @export #' @rdname extract_ersim diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index d8ef2e1..2935adb 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -181,10 +181,10 @@ test_that("extract_data.ermod respects internal_data argument (ermod)", { for (r in seq_len(n_cases_ermod)) { print(r) m <- cases_ermod$mod[[r]] - expect_no_error(extract_data(m, internal_data = TRUE)) - expect_no_error(extract_data(m, internal_data = FALSE)) - inner_data <- extract_data(m, internal_data = TRUE) - outer_data <- extract_data(m, internal_data = FALSE) + expect_no_error(extract_data(m, method = "internal")) + expect_no_error(extract_data(m, method = "raw")) + inner_data <- extract_data(m, method = "internal") + outer_data <- extract_data(m, method = "raw") expect_true(inherits(inner_data, "data.frame")) expect_true(inherits(outer_data, "data.frame")) cases_ermod$inner_n[r] <<- nrow(inner_data) @@ -195,10 +195,10 @@ test_that("extract_data.ermod respects internal_data argument (ermod)", { test_that("extract_data.ermod respects internal_data argument (expsel)", { for (r in seq_len(n_cases_ermod)) { m <- cases_expsel$mod[[r]] - expect_no_error(extract_data(m, internal_data = TRUE)) - expect_no_error(extract_data(m, internal_data = FALSE)) - inner_data <- extract_data(m, internal_data = TRUE) - outer_data <- extract_data(m, internal_data = FALSE) + expect_no_error(extract_data(m, method = "internal")) + expect_no_error(extract_data(m, method = "raw")) + inner_data <- extract_data(m, method = "internal") + outer_data <- extract_data(m, method = "raw") expect_true(inherits(inner_data, "data.frame")) expect_true(inherits(outer_data, "data.frame")) cases_expsel$inner_n[r] <<- nrow(inner_data) @@ -210,10 +210,10 @@ if (require("projpred")) { test_that("extract_data.ermod respects internal_data argument (covsel)", { for (r in seq_len(n_cases_covsel)) { m <- cases_covsel$mod[[r]] - expect_no_error(extract_data(m, internal_data = TRUE)) - expect_no_error(extract_data(m, internal_data = FALSE)) - inner_data <- extract_data(m, internal_data = TRUE) - outer_data <- extract_data(m, internal_data = FALSE) + expect_no_error(extract_data(m, method = "internal")) + expect_no_error(extract_data(m, method = "raw")) + inner_data <- extract_data(m, method = "internal") + outer_data <- extract_data(m, method = "raw") expect_true(inherits(inner_data, "data.frame")) expect_true(inherits(outer_data, "data.frame")) cases_covsel$inner_n[r] <<- nrow(inner_data) From 805135c74909e591493ad21036eb845bee6c5140 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:27:12 +1000 Subject: [PATCH 47/57] default exposure ranges in sim_er_curve and sim_er_curve_marg respects placebo options --- R/sim_ermod.R | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/R/sim_ermod.R b/R/sim_ermod.R index 71b5eb8..1d07b2f 100644 --- a/R/sim_ermod.R +++ b/R/sim_ermod.R @@ -252,13 +252,13 @@ sim_er_curve <- function( seed_sample_draws = NULL, output_type = c("draws", "median_qi"), qi_width = 0.95) { + if (is.null(exposure_range)) { - exposure_range <- - range(extract_data(ermod)[[extract_var_exposure(ermod)]]) + exposure_range <- .default_exposure_range(ermod) } else { stopifnot(length(exposure_range) == 2) } - + exposure_to_sim_vec <- seq(exposure_range[1], exposure_range[2], length.out = num_exposures) @@ -273,6 +273,11 @@ sim_er_curve <- function( ) } +.default_exposure_range <- function(ermod) { + exp <- extract_var_exposure(ermod) + dat <- extract_data(ermod, method = "processed") + range(dat[[exp]]) +} #' Calculate marginal expected response for specified exposure values #' @@ -439,8 +444,7 @@ sim_er_curve_marg <- function( output_type = c("draws", "median_qi"), qi_width = 0.95) { if (is.null(exposure_range)) { - exposure_range <- - range(extract_data(ermod)[[extract_var_exposure(ermod)]]) + exposure_range <- .default_exposure_range(ermod) } else { stopifnot(length(exposure_range) == 2) } From 6202801b674c6e3b959f45ccfcde6d3f24c68132 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:29:31 +1000 Subject: [PATCH 48/57] linter whitespace --- R/ermod-methods.R | 6 +++--- R/sim_ermod.R | 6 +++--- tests/testthat/test-eval_ermod.R | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/R/ermod-methods.R b/R/ermod-methods.R index 10f33bf..e7f939f 100644 --- a/R/ermod-methods.R +++ b/R/ermod-methods.R @@ -174,7 +174,7 @@ plot.ermod_cov_sel <- function(x, ...) { #' @param options_placebo_handling This is exposed to allow user to override placebo settings #' @param method This is exposed to allow extraction of data in different ways: "raw" returns #' the original data object, "processed" returns the data after placebo handling has been -#' applied, "internal" is for testing purposes only and extracts data from the masked stan +#' applied, "internal" is for testing purposes only and extracts data from the masked stan #' object #' extract_data.ermod <- function(x, ..., method = "raw") { @@ -182,8 +182,8 @@ extract_data.ermod <- function(x, ..., method = "raw") { if (method == "processed") { opt <- .apply_placebo_defaults(x$options_placebo_handling) dat <- .apply_placebo_handling( - data = x$data, - options = opt, + data = x$data, + options = opt, var_exposure = extract_var_exposure(x) ) return(dat) diff --git a/R/sim_ermod.R b/R/sim_ermod.R index 1d07b2f..96b503b 100644 --- a/R/sim_ermod.R +++ b/R/sim_ermod.R @@ -252,13 +252,13 @@ sim_er_curve <- function( seed_sample_draws = NULL, output_type = c("draws", "median_qi"), qi_width = 0.95) { - + if (is.null(exposure_range)) { - exposure_range <- .default_exposure_range(ermod) + exposure_range <- .default_exposure_range(ermod) } else { stopifnot(length(exposure_range) == 2) } - + exposure_to_sim_vec <- seq(exposure_range[1], exposure_range[2], length.out = num_exposures) diff --git a/tests/testthat/test-eval_ermod.R b/tests/testthat/test-eval_ermod.R index 734251e..37b2620 100644 --- a/tests/testthat/test-eval_ermod.R +++ b/tests/testthat/test-eval_ermod.R @@ -51,7 +51,7 @@ if (.if_run_ex_eval_mod()) { var_resp = "response", var_exposure = "AUCss", var_cov = c("SEX", "BAGE"), - options_placebo_handling = opts_placebo, + options_placebo_handling = opts_placebo, chains = 2, iter = 500 ) From 1ac3dd8ad8963d6728a5ddd1f65fdea92318fc64 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 19:38:37 +1000 Subject: [PATCH 49/57] roxygenise --- man/extract_ermod.Rd | 9 ++++++++- man/extract_ersim.Rd | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/man/extract_ermod.Rd b/man/extract_ermod.Rd index 14c1463..24f7e37 100644 --- a/man/extract_ermod.Rd +++ b/man/extract_ermod.Rd @@ -12,7 +12,7 @@ \alias{extract_var_selected.ermod_cov_sel} \title{Extract elements from an object of class \code{ermod_*}} \usage{ -\method{extract_data}{ermod}(x, ..., internal_data = FALSE) +\method{extract_data}{ermod}(x, ..., method = "raw") \method{extract_mod}{ermod}(x) @@ -30,6 +30,13 @@ } \arguments{ \item{x}{An object of class \code{ermod_*}} + +\item{method}{This is exposed to allow extraction of data in different ways: "raw" returns +the original data object, "processed" returns the data after placebo handling has been +applied, "internal" is for testing purposes only and extracts data from the masked stan +object} + +\item{options_placebo_handling}{This is exposed to allow user to override placebo settings} } \value{ \itemize{ diff --git a/man/extract_ersim.Rd b/man/extract_ersim.Rd index 6d394e6..2860fdd 100644 --- a/man/extract_ersim.Rd +++ b/man/extract_ersim.Rd @@ -12,9 +12,9 @@ \alias{extract_var_cov.ersim_med_qi} \title{Extract elements from objects of the classes \verb{ersim_*} and `ersim_med_qi_*``} \usage{ -\method{extract_data}{ersim}(x, ...) +\method{extract_data}{ersim}(x, ..., method = "raw") -\method{extract_data}{ersim_med_qi}(x, ...) +\method{extract_data}{ersim_med_qi}(x, ..., method = "raw") \method{extract_var_resp}{ersim}(x) From 6b94151b813ed2b9256a62d90f490ccfef10d050 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 20:38:57 +1000 Subject: [PATCH 50/57] plot_er() now inherits placebo handling options --- R/plot_ermod.R | 4 ++-- R/plot_ermod_exp_cov_sel.R | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/plot_ermod.R b/R/plot_ermod.R index cd850ab..76ef9cf 100644 --- a/R/plot_ermod.R +++ b/R/plot_ermod.R @@ -118,7 +118,7 @@ plot_er.ersim_med_qi <- function( options_caption ) - origdata <- extract_data(x) + origdata <- extract_data(x, method = "processed") var_exposure <- extract_var_exposure(x) add_boxplot <- options_orig_data$add_boxplot boxplot_height <- options_orig_data$boxplot_height @@ -721,7 +721,7 @@ set_pos_ci_annot <- function(x, pos_x, pos_y, var_exposure, var_resp) { if (attr(x, "endpoint_type") == "binary") { pos_y <- 0.9 } else { - pos_y <- max(extract_data(x)[[var_resp]]) + pos_y <- max(extract_data(x, method = "processed")[[var_resp]]) } } return(c(pos_x, pos_y)) diff --git a/R/plot_ermod_exp_cov_sel.R b/R/plot_ermod_exp_cov_sel.R index 2e101c1..36c7a2e 100644 --- a/R/plot_ermod_exp_cov_sel.R +++ b/R/plot_ermod_exp_cov_sel.R @@ -93,7 +93,7 @@ plot_er_exp_sel <- function(x, n_draws_sim = NULL) { ) origdata <- - extract_data(x) |> + extract_data(x, method = "processed") |> tidyr::pivot_longer(dplyr::all_of(var_exp_order), names_to = ".exp_metric", values_to = ".exposure" ) |> From ba08288503c229e5d683d0d343023c73218f8bee Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 20:39:22 +1000 Subject: [PATCH 51/57] adds to the examples --- other/placebo-example.R | 275 +++++++++++++++++++++++++--------------- 1 file changed, 171 insertions(+), 104 deletions(-) diff --git a/other/placebo-example.R b/other/placebo-example.R index 4082335..929d10b 100644 --- a/other/placebo-example.R +++ b/other/placebo-example.R @@ -1,106 +1,173 @@ library(BayesERtools) -# linear regression, no placebo -mod <- d_sim_emax |> - dev_ermod_lin( - var_resp = "response_1", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = FALSE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# linear regression, with placebo -mod <- d_sim_emax |> - dev_ermod_lin( - var_resp = "response_1", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = TRUE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# logistic regression, no placebo -mod <- d_sim_emax |> - dev_ermod_bin( - var_resp = "response_2", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = FALSE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# logistic regression, with placebo -mod <- d_sim_emax |> - dev_ermod_bin( - var_resp = "response_2", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = TRUE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - - -# emax regression, continuous response, no placebo -mod <- d_sim_emax |> - dev_ermod_emax( - var_resp = "response_1", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = FALSE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# emax regression, continuous response, with placebo -mod <- d_sim_emax |> - dev_ermod_emax( - var_resp = "response_1", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = TRUE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# emax regression, binary response, no placebo -mod <- d_sim_emax |> - dev_ermod_bin_emax( - var_resp = "response_2", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = FALSE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) - -# emax regression, binary response, with placebo -mod <- d_sim_emax |> - dev_ermod_bin_emax( - var_resp = "response_2", - var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = TRUE) - ) -mod |> - plot_er( - show_orig_data = TRUE, - options_orig_data = list(var_group = "dose") - ) + +# fit ER models -------------------------------------------- + +fit_ermods <- list( + + # linear regression + lin_drop = d_sim_emax |> + dev_ermod_lin( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ), + lin_keep = d_sim_emax |> + dev_ermod_lin( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ), + + # logistic regression + bin_drop = d_sim_emax |> + dev_ermod_bin( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE) + ), + bin_keep = d_sim_emax |> + dev_ermod_bin( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE) + ), + + # emax continuous + emax_drop = suppressWarnings(d_sim_emax |> + dev_ermod_emax( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )), + emax_keep = suppressWarnings(d_sim_emax |> + dev_ermod_emax( + var_resp = "response_1", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = TRUE), + chains = 2, + iter = 500, + )), + + # emax binary + emax_bin_drop = suppressWarnings(d_sim_emax |> + dev_ermod_bin_emax( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )), + emax_bin_keep = suppressWarnings(d_sim_emax |> + dev_ermod_bin_emax( + var_resp = "response_2", + var_exposure = "exposure_1", + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )) + +) + +# plot ER models -------------------------------------------- + +plt_ermods <- fit_ermods |> + purrr::imap(\(m, idx) { + m |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + + ggplot2::labs(title = idx) + }) + +for(p in plt_ermods) print(p) + + +# fit expsel models ---------------------------------------- + +fit_expsel <- list( + + # linear regression + lin_drop = d_sim_emax |> + dev_ermod_lin_exp_sel( + var_resp = "response_1", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = FALSE) + ), + lin_keep = d_sim_emax |> + dev_ermod_lin_exp_sel( + var_resp = "response_1", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = TRUE) + ), + + # logistic regression + bin_drop = d_sim_emax |> + dev_ermod_bin_exp_sel( + var_resp = "response_2", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = FALSE) + ), + bin_keep = d_sim_emax |> + dev_ermod_bin_exp_sel( + var_resp = "response_2", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = TRUE) + ), + + # emax continuous + emax_drop = suppressWarnings(d_sim_emax |> + dev_ermod_emax_exp_sel( + var_resp = "response_1", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )), + emax_keep = suppressWarnings(d_sim_emax |> + dev_ermod_emax_exp_sel( + var_resp = "response_1", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = TRUE), + chains = 2, + iter = 500, + )), + + # emax binary + emax_bin_drop = suppressWarnings(d_sim_emax |> + dev_ermod_bin_emax_exp_sel( + var_resp = "response_2", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )), + emax_bin_keep = suppressWarnings(d_sim_emax |> + dev_ermod_bin_emax_exp_sel( + var_resp = "response_2", + var_exp_candidates = c("exposure_1", "exposure_2"), + options_placebo_handling = list(include_placebo = FALSE), + chains = 2, + iter = 500 + )) + +) + +# plot expsel models -------------------------------------------- + +plt_expsel <- fit_expsel |> + purrr::imap(\(m, idx) { + m |> + plot_er( + show_orig_data = TRUE, + options_orig_data = list(var_group = "dose") + ) + + ggplot2::labs(title = idx) + }) + +for(p in plt_expsel) print(p) + + From 5527e39d92265c039dcefff54b1724c53b9dec1c Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 20:50:33 +1000 Subject: [PATCH 52/57] removes unnecessary printing --- tests/testthat/test-placebo_handling.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat/test-placebo_handling.R b/tests/testthat/test-placebo_handling.R index 2935adb..4fdce30 100644 --- a/tests/testthat/test-placebo_handling.R +++ b/tests/testthat/test-placebo_handling.R @@ -179,7 +179,6 @@ if (require("projpred")) { test_that("extract_data.ermod respects internal_data argument (ermod)", { for (r in seq_len(n_cases_ermod)) { - print(r) m <- cases_ermod$mod[[r]] expect_no_error(extract_data(m, method = "internal")) expect_no_error(extract_data(m, method = "raw")) From e9630fc4c7466d69a8213e56c39fedb25a686c3f Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 21:31:28 +1000 Subject: [PATCH 53/57] typo fix --- other/placebo-example.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/other/placebo-example.R b/other/placebo-example.R index 929d10b..730b727 100644 --- a/other/placebo-example.R +++ b/other/placebo-example.R @@ -64,7 +64,7 @@ fit_ermods <- list( dev_ermod_bin_emax( var_resp = "response_2", var_exposure = "exposure_1", - options_placebo_handling = list(include_placebo = FALSE), + options_placebo_handling = list(include_placebo = TRUE), chains = 2, iter = 500 )) @@ -149,7 +149,7 @@ fit_expsel <- list( dev_ermod_bin_emax_exp_sel( var_resp = "response_2", var_exp_candidates = c("exposure_1", "exposure_2"), - options_placebo_handling = list(include_placebo = FALSE), + options_placebo_handling = list(include_placebo = TRUE), chains = 2, iter = 500 )) From 7d523cfa9c92269510b9e4cba1886c938119bc16 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 21:32:47 +1000 Subject: [PATCH 54/57] supply defaults if options are NULL --- R/ermod-class.R | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/R/ermod-class.R b/R/ermod-class.R index feb4768..3467a6d 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -433,12 +433,11 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { } .apply_placebo_defaults <- function(options) { - utils::modifyList( - list( + placebo_defaults <- list( include_placebo = FALSE, method = "zero_exposure_as_placebo", # alternatives: "var_placebo", "none" var_placebo = NULL # if specified must be a string referring to a logical vector - ), - options - ) + ) + if (is.null(options)) return(placebo_defaults) + utils::modifyList(placebo_defaults, options) } From 645fbba1b7d75f2374f4daccfa6047ae463736be Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 21:33:43 +1000 Subject: [PATCH 55/57] tidies documentation --- R/ermod-methods.R | 8 +++----- R/ersim-methods.R | 13 +++++++++---- man/extract_ermod.Rd | 9 +++------ man/extract_ersim.Rd | 4 ++++ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/R/ermod-methods.R b/R/ermod-methods.R index e7f939f..930c025 100644 --- a/R/ermod-methods.R +++ b/R/ermod-methods.R @@ -171,11 +171,9 @@ plot.ermod_cov_sel <- function(x, ...) { #' @keywords internal #' @inherit extract_method return #' @param x An object of class \code{ermod_*} -#' @param options_placebo_handling This is exposed to allow user to override placebo settings -#' @param method This is exposed to allow extraction of data in different ways: "raw" returns -#' the original data object, "processed" returns the data after placebo handling has been -#' applied, "internal" is for testing purposes only and extracts data from the masked stan -#' object +#' @param method If \code{method="raw"} (the default), the original data set is returned. +#' When \code{method="processed"}, the data set returned is one that has the placebo handling +#' options applied. A \code{method="internal"} option also exists, used for internal testing. #' extract_data.ermod <- function(x, ..., method = "raw") { if (method == "raw") return(x$data) diff --git a/R/ersim-methods.R b/R/ersim-methods.R index 95c0857..1a6b373 100644 --- a/R/ersim-methods.R +++ b/R/ersim-methods.R @@ -29,12 +29,16 @@ plot.ersim_med_qi <- function(x, show_orig_data = FALSE, ...) { #' @keywords internal #' @inherit extract_method return #' @param x An object of class \code{ersim_*} +#' @param method If \code{method="raw"} (the default), the original data set is returned. +#' When \code{method="processed"}, the data set returned is one that has the placebo handling +#' options applied. extract_data.ersim <- function(x, ..., method = "raw") { dat <- attr(x, "origdata") if (method == "raw") return(dat) if (method == "processed") { - opt <- .apply_placebo_defaults(attr(x, "options_placebo_handling")) - exp <- extract_var_exposure(x) + opt <- attr(x, "options_placebo_handling") + opt <- .apply_placebo_defaults(opt) + exp <- extract_var_exposure(x) dat <- .apply_placebo_handling(dat, opt, exp) return(dat) } @@ -47,8 +51,9 @@ extract_data.ersim_med_qi <- function(x, ..., method = "raw") { dat <- attr(x, "origdata") if (method == "raw") return(dat) if (method == "processed") { - opt <- .apply_placebo_defaults(attr(x, "options_placebo_handling")) - exp <- extract_var_exposure(x) + opt <- attr(x, "options_placebo_handling") + opt <- .apply_placebo_defaults(opt) + exp <- extract_var_exposure(x) dat <- .apply_placebo_handling(dat, opt, exp) return(dat) } diff --git a/man/extract_ermod.Rd b/man/extract_ermod.Rd index 24f7e37..dad7723 100644 --- a/man/extract_ermod.Rd +++ b/man/extract_ermod.Rd @@ -31,12 +31,9 @@ \arguments{ \item{x}{An object of class \code{ermod_*}} -\item{method}{This is exposed to allow extraction of data in different ways: "raw" returns -the original data object, "processed" returns the data after placebo handling has been -applied, "internal" is for testing purposes only and extracts data from the masked stan -object} - -\item{options_placebo_handling}{This is exposed to allow user to override placebo settings} +\item{method}{If \code{method="raw"} (the default), the original data set is returned. +When \code{method="processed"}, the data set returned is one that has the placebo handling +options applied. A \code{method="internal"} option also exists, used for internal testing.} } \value{ \itemize{ diff --git a/man/extract_ersim.Rd b/man/extract_ersim.Rd index 2860fdd..2597a1d 100644 --- a/man/extract_ersim.Rd +++ b/man/extract_ersim.Rd @@ -30,6 +30,10 @@ } \arguments{ \item{x}{An object of class \code{ersim_*}} + +\item{method}{If \code{method="raw"} (the default), the original data set is returned. +When \code{method="processed"}, the data set returned is one that has the placebo handling +options applied.} } \value{ \itemize{ From 31045fdfea94df7e5e98075ee7eccdbad38345d0 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 21:42:38 +1000 Subject: [PATCH 56/57] partially reenable loo and kfold tests --- tests/testthat/test-loo_kfold.R | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/testthat/test-loo_kfold.R b/tests/testthat/test-loo_kfold.R index 559bbbf..b660df4 100644 --- a/tests/testthat/test-loo_kfold.R +++ b/tests/testthat/test-loo_kfold.R @@ -81,7 +81,7 @@ if (.if_run_ex_eval_mod()) { # Test ---------------------------------------------------------------------- test_that("loo", { - skip("temporarily disable loo test") + #skip("temporarily disable loo test") loo_ermod_bin <- loo(ermod_bin) loo_ermod_emax_w_cov <- suppressWarnings(loo(ermod_emax_w_cov)) @@ -89,13 +89,14 @@ if (.if_run_ex_eval_mod()) { expect_equal( loo_ermod_bin$estimates[, 1], - c(elpd_loo = -38.5289466, p_loo = 3.3262640, looic = 77.0578931) - ) - expect_equal( - loo_ermod_emax_w_cov$estimates[, 1], - c(elpd_loo = -216.539552, p_loo = 7.765598, looic = 433.079103), + c(elpd_loo = -38.5289466, p_loo = 3.3262640, looic = 77.0578931), tolerance = 0.1 ) + # expect_equal( + # loo_ermod_emax_w_cov$estimates[, 1], + # c(elpd_loo = -216.539552, p_loo = 7.765598, looic = 433.079103), + # tolerance = 0.1 + # ) expect_equal( loo_ermod_bin_emax$estimates[, 1], c(elpd_loo = -60.787274, p_loo = 1.427765, looic = 121.574548), @@ -107,22 +108,23 @@ if (.if_run_ex_eval_mod()) { test_that("kfold", { - skip("temporarily disable kfold test") + #skip("temporarily disable kfold test") expect_gt(comp[[2, 1]], -0.5) expect_equal( kfold_ermod_bin$estimates[, 1], - c(elpd_kfold = -38.242947, p_kfold = 3.040264, kfoldic = 76.485893) + c(elpd_kfold = -38.242947, p_kfold = 3.040264, kfoldic = 76.485893), + tolerance = .01 ) expect_equal( class(extract_kfold_loo(kfold_ermod_bin)), c("kfold", "loo") ) - expect_equal( - kfold_ermod_emax$estimates[, 1], - c(elpd_kfold = -218, p_kfold = 9, kfoldic = 435), - tolerance = 0.1 - ) + # expect_equal( + # kfold_ermod_emax$estimates[, 1], + # c(elpd_kfold = -218, p_kfold = 9, kfoldic = 435), + # tolerance = 0.1 + # ) }) # Test for other models are covered in test-eval_ermod.R with kfold-cv eval From e1f59e490b8a47bf9ab3eb1ee5ad5387c5e54566 Mon Sep 17 00:00:00 2001 From: Danielle Navarro Date: Fri, 3 Oct 2025 21:47:44 +1000 Subject: [PATCH 57/57] linter fixes --- R/ermod-class.R | 8 ++++---- tests/testthat/test-loo_kfold.R | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/R/ermod-class.R b/R/ermod-class.R index 3467a6d..edc30fd 100644 --- a/R/ermod-class.R +++ b/R/ermod-class.R @@ -434,10 +434,10 @@ check_l_ermod_exp_sel <- function(l_ermod_exp_sel, basemodclass = "stanreg") { .apply_placebo_defaults <- function(options) { placebo_defaults <- list( - include_placebo = FALSE, - method = "zero_exposure_as_placebo", # alternatives: "var_placebo", "none" - var_placebo = NULL # if specified must be a string referring to a logical vector - ) + include_placebo = FALSE, + method = "zero_exposure_as_placebo", # alternatives: "var_placebo", "none" + var_placebo = NULL # if specified must be a string referring to a logical vector + ) if (is.null(options)) return(placebo_defaults) utils::modifyList(placebo_defaults, options) } diff --git a/tests/testthat/test-loo_kfold.R b/tests/testthat/test-loo_kfold.R index b660df4..f554dcc 100644 --- a/tests/testthat/test-loo_kfold.R +++ b/tests/testthat/test-loo_kfold.R @@ -81,8 +81,6 @@ if (.if_run_ex_eval_mod()) { # Test ---------------------------------------------------------------------- test_that("loo", { - #skip("temporarily disable loo test") - loo_ermod_bin <- loo(ermod_bin) loo_ermod_emax_w_cov <- suppressWarnings(loo(ermod_emax_w_cov)) loo_ermod_bin_emax <- loo(ermod_bin_emax) @@ -92,11 +90,13 @@ if (.if_run_ex_eval_mod()) { c(elpd_loo = -38.5289466, p_loo = 3.3262640, looic = 77.0578931), tolerance = 0.1 ) - # expect_equal( - # loo_ermod_emax_w_cov$estimates[, 1], - # c(elpd_loo = -216.539552, p_loo = 7.765598, looic = 433.079103), - # tolerance = 0.1 - # ) + if (FALSE) { # temporarily disabled + expect_equal( + loo_ermod_emax_w_cov$estimates[, 1], + c(elpd_loo = -216.539552, p_loo = 7.765598, looic = 433.079103), + tolerance = 0.1 + ) + } expect_equal( loo_ermod_bin_emax$estimates[, 1], c(elpd_loo = -60.787274, p_loo = 1.427765, looic = 121.574548), @@ -108,23 +108,23 @@ if (.if_run_ex_eval_mod()) { test_that("kfold", { - #skip("temporarily disable kfold test") - expect_gt(comp[[2, 1]], -0.5) expect_equal( kfold_ermod_bin$estimates[, 1], - c(elpd_kfold = -38.242947, p_kfold = 3.040264, kfoldic = 76.485893), + c(elpd_kfold = -38.242947, p_kfold = 3.040264, kfoldic = 76.485893), tolerance = .01 ) expect_equal( class(extract_kfold_loo(kfold_ermod_bin)), c("kfold", "loo") ) - # expect_equal( - # kfold_ermod_emax$estimates[, 1], - # c(elpd_kfold = -218, p_kfold = 9, kfoldic = 435), - # tolerance = 0.1 - # ) + if (FALSE) { # temporarily disabled + expect_equal( + kfold_ermod_emax$estimates[, 1], + c(elpd_kfold = -218, p_kfold = 9, kfoldic = 435), + tolerance = 0.1 + ) + } }) # Test for other models are covered in test-eval_ermod.R with kfold-cv eval