Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gs_design_ahr() derives info of all infinity values #301

Closed
nanxstats opened this issue Dec 22, 2023 · 4 comments · Fixed by #304
Closed

gs_design_ahr() derives info of all infinity values #301

nanxstats opened this issue Dec 22, 2023 · 4 comments · Fixed by #304
Assignees
Labels
bug Something isn't working

Comments

@nanxstats
Copy link
Collaborator

POC:

library(gsDesign2)

gs_design_ahr(
  enroll_rate = define_enroll_rate(
    duration = c(2, 2, 10),
    rate = c(3, 6, 9),
  ),
  fail_rate = define_fail_rate(
    duration = 40,
    fail_rate = 0.0495,
    dropout_rate = 0.001,
    hr = 1
  ),
  alpha = 0.0125,
  beta = 0.2,
  info_frac = c(0.4, 0.8, 1),
  analysis_time = 36,
  ratio = 1,
  binding = FALSE,
  upper = gs_spending_bound,
  upar = list(
    sf = gsDesign::sfLDOF,
    sfupar = 1,
    total_spend = 0.0125,
    param = NULL,
    timing = NULL
  ),
  lower = gs_b,
  lpar = c(0, -Inf, -Inf),
  r = 18,
  tol = 1e-6
)

This yields:

Error in if (min(info - fastlag(info, first = 0)) <= 0) { : 
  missing value where TRUE/FALSE needed

The call stack is:

6.
check_info(info) at gs_power_npe.R#253
5.
gs_power_npe(theta = theta, theta0 = theta0, theta1 = theta1,
info = info * min_x, info0 = info0 * min_x, info1 = info *
min_x, info_scale = info_scale, upper = upper, upar = upar,
test_upper = test_upper, lower = lower, lpar = lpar, test_lower = test_lower, ... at gs_design_npe.R#375
4.
gs_design_npe(theta = y$theta, theta0 = 0, theta1 = theta1, info = y$info,
info0 = y$info0, info1 = info1, info_scale = info_scale,
alpha = alpha, beta = beta, binding = binding, upper = upper,
upar = upar, test_upper = test_upper, lower = lower, lpar = lpar, ... at gs_design_ahr.R#323
3.
withCallingHandlers(expr, message = function(c) if (inherits(c,
classes)) tryInvokeRestart("muffleMessage"))
2.
suppressMessages(allout <- gs_design_npe(theta = y$theta, theta0 = 0,
theta1 = theta1, info = y$info, info0 = y$info0, info1 = info1,
info_scale = info_scale, alpha = alpha, beta = beta, binding = binding,
upper = upper, upar = upar, test_upper = test_upper, lower = lower, ... at gs_design_ahr.R#323
1.
gs_design_ahr(enroll_rate = define_enroll_rate(duration = c(2,
2, 10), rate = c(3, 6, 9), ), fail_rate = define_fail_rate(duration = 40,
fail_rate = 0.0495, dropout_rate = 0.001, hr = 1), alpha = 0.0125,
beta = 0.2, info_frac = c(0.4, 0.8, 1), analysis_time = 36, ...

When I insert print(info) before the if call in check_info(), it looks like info has become purely Inf:

[1]  7.983019 15.966057 19.957571
[1]  7.983019 15.966057 19.957571
[1]  7.983019 15.966057 19.957571
[1] Inf Inf Inf
Error in if (min(info - fastlag(info, first = 0)) <= 0) { : 
  missing value where TRUE/FALSE needed

Naturally,

info <- c(Inf, Inf, Inf)
min(info - fastlag(info, first = 0)) <= 0

returns NA.

@nanxstats nanxstats added the bug Something isn't working label Dec 22, 2023
@nanxstats
Copy link
Collaborator Author

It appears using NULL for info_frac makes it work. However, the output does not work with to_integer():

library(gsDesign2)

design <- gs_design_ahr(
  enroll_rate = define_enroll_rate(
    duration = c(2, 2, 10),
    rate = c(3, 6, 9),
  ),
  fail_rate = define_fail_rate(
    duration = 40,
    fail_rate = 0.0495,
    dropout_rate = 0.001,
    hr = 1
  ),
  alpha = 0.0125,
  beta = 0.2,
  info_frac = NULL,
  analysis_time = 36,
  ratio = 1,
  binding = FALSE,
  upper = gs_spending_bound,
  upar = list(
    sf = gsDesign::sfLDOF,
    sfupar = 1,
    total_spend = 0.0125,
    param = NULL,
    timing = NULL
  ),
  lower = gs_b,
  lpar = c(0, -Inf, -Inf),
  r = 18,
  tol = 1e-6
)

design |> to_integer()
Error in if (cond1 || cond2 || cond3) { : 
  missing value where TRUE/FALSE needed
In addition: Warning messages:
1: In c(floor(event[1:(n_analysis - 1)]), ceiling(event[n_analysis])) %>%  :
  NAs introduced by coercion to integer range
2: In (ceiling(x$analysis$n[n_analysis]/multiply_factor) * multiply_factor) %>%  :
  NAs introduced by coercion to integer range

@jdblischak
Copy link
Collaborator

I checked some previous commits to see if this is a recent bug. I can only go back so far since the example uses define_enroll_rate() and define_fail_rate() (added about 6 months ago).

Running the example above with either commits 03d6a52 or 107265a, I get the same error from check_info():

Error in if (min(info - lag(info, default = 0)) <= 0) { : 
  missing value where TRUE/FALSE needed

> traceback()
6: check_info(info) at gs_power_npe.R#253
5: gs_power_npe(theta = theta, theta0 = theta0, theta1 = theta1, 
       info = info * min_x, info0 = info0 * min_x, info1 = info * 
           min_x, info_scale = info_scale, upper = upper, upar = upar, 
       test_upper = test_upper, lower = lower, lpar = lpar, test_lower = test_lower, 
       binding = binding, r = r, tol = tol) at gs_design_npe.R#375
4: gs_design_npe(theta = y$theta, theta0 = 0, theta1 = theta1, info = y$info, 
       info0 = y$info0, info1 = info1, info_scale = info_scale, 
       alpha = alpha, beta = beta, binding = binding, upper = upper, 
       upar = upar, test_upper = test_upper, lower = lower, lpar = lpar, 
       test_lower = test_lower, r = r, tol = tol) at gs_design_ahr.R#322
3: withCallingHandlers(expr, message = function(c) if (inherits(c, 
       classes)) tryInvokeRestart("muffleMessage"))
2: suppressMessages(allout <- gs_design_npe(theta = y$theta, theta0 = 0, 
       theta1 = theta1, info = y$info, info0 = y$info0, info1 = info1, 
       info_scale = info_scale, alpha = alpha, beta = beta, binding = binding, 
       upper = upper, upar = upar, test_upper = test_upper, lower = lower, 
       lpar = lpar, test_lower = test_lower, r = r, tol = tol)) at gs_design_ahr.R#322
1: gs_design_ahr(enroll_rate = define_enroll_rate(duration = c(2, 
       2, 10), rate = c(3, 6, 9), ), fail_rate = define_fail_rate(duration = 40, 
       fail_rate = 0.0495, dropout_rate = 0.001, hr = 1), alpha = 0.0125, 
       beta = 0.2, info_frac = c(0.4, 0.8, 1), analysis_time = 36, 
       ratio = 1, binding = FALSE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, 
           sfupar = 1, total_spend = 0.0125, param = NULL, timing = NULL), 
       lower = gs_b, lpar = c(0, -Inf, -Inf), r = 18, tol = 1e-06)

@LittleBeannie
Copy link
Collaborator

gs_design_ahr(
  enroll_rate = define_enroll_rate(
    duration = c(2, 2, 10),
    rate = c(3, 6, 9),
  ),
  fail_rate = define_fail_rate(
    duration = 40,
    fail_rate = 0.0495,
    dropout_rate = 0.001,
    hr = 1
  ),
  alpha = 0.0125,
  beta = 0.2,
  info_frac = c(0.4, 0.8, 1),
  analysis_time = 36,
  ratio = 1,
  binding = FALSE,
  upper = gs_spending_bound,
  upar = list(
    sf = gsDesign::sfLDOF,
    sfupar = 1,
    total_spend = 0.0125,
    param = NULL,
    timing = NULL
  ),
  lower = gs_b,
  lpar = c(0, -Inf, -Inf),
  r = 18,
  tol = 1e-6
)

Hello @nanxstats , thank you for raising this important question. I would like to understand the reason behind setting hr = 1. In practical scenarios, such settings are uncommon. If we were to change it to a positive number smaller than 1, it would yield the desired results. Please inform me if this response addresses your question, allowing us to appropriately close this matter.

@nanxstats
Copy link
Collaborator Author

@LittleBeannie Sure, from Keaven:

hr must not be equal to 1 throughout the study as this is the null hypothesis.
We could check this at input to avoid confusing output.
For gs_power_ahr() this should NOT be an issue as it would just be approximating the Type I error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants