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

Redirect as_gt() to simtrial when it is masked by gsDesign2::as_gt() #467

Merged
merged 1 commit into from
Oct 4, 2024

Conversation

jdblischak
Copy link
Collaborator

Counterpart to Merck/simtrial#287 (xref: Merck/simtrial#284)

cc: @yihui

Fixes the S3 redirection when gsDesign2::as_gt() masks simtrial::as_gt(), as below:

library("simtrial")
library("gsDesign2")
##
## Attaching package: ‘gsDesign2’
##
## The following object is masked from ‘package:simtrial’:
##
##   as_gt
##

# Parameters for enrollment
enroll_rampup_duration <- 4 # Duration for enrollment ramp up
enroll_duration <- 16 # Total enrollment duration
enroll_rate <- define_enroll_rate(
  duration = c(
    enroll_rampup_duration, enroll_duration - enroll_rampup_duration),
  rate = c(10, 30))

# Parameters for treatment effect
delay_effect_duration <- 3 # Delay treatment effect in months
median_ctrl <- 9 # Survival median of the control arm
median_exp <- c(9, 14) # Survival median of the experimental arm
dropout_rate <- 0.001
fail_rate <- define_fail_rate(
  duration = c(delay_effect_duration, 100),
  fail_rate = log(2) / median_ctrl,
  hr = median_ctrl / median_exp,
  dropout_rate = dropout_rate)

# Other related parameters
alpha <- 0.025 # Type I error
beta <- 0.1 # Type II error
ratio <- 1 # Randomization ratio (experimental:control)

# Build a one-sided group sequential design
design <- gs_design_ahr(
  enroll_rate = enroll_rate, fail_rate = fail_rate,
  ratio = ratio, alpha = alpha, beta = beta,
  analysis_time = c(12, 24, 36),
  upper = gs_spending_bound,
  upar = list(sf = gsDesign::sfLDOF, total_spend = alpha),
  lower = gs_b,
  lpar = rep(-Inf, 3))

# Define cuttings of 2 IAs and 1 FA
ia1_cut <- create_cut(target_event_overall = ceiling(design$analysis$event[1]))
ia2_cut <- create_cut(target_event_overall = ceiling(design$analysis$event[2]))
fa_cut <- create_cut(target_event_overall = ceiling(design$analysis$event[3]))

# Run simulations
simulation <- sim_gs_n(
  n_sim = 3,
  sample_size = ceiling(design$analysis$n[3]),
  enroll_rate = design$enroll_rate,
  fail_rate = design$fail_rate,
  test = wlr,
  cut = list(ia1 = ia1_cut, ia2 = ia2_cut, fa = fa_cut),
  weight = fh(rho = 0, gamma = 0.5))

# Summarize simulation and compare with the planned design
simulation |> summary(design = design) |> as_gt()
## Error in UseMethod("as_gt", x) :
##   no applicable method for 'as_gt' applied to an object of class "c('simtrial_gs_wlr', 'data.frame')"
simulation |> summary(design = design) |> simtrial::as_gt()

Copy link
Collaborator

@LittleBeannie LittleBeannie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @jdblischak !

@LittleBeannie
Copy link
Collaborator

Hi @jdblischak, it looks this PR is still in progress. Is it ready for merge now?

@jdblischak jdblischak marked this pull request as ready for review October 4, 2024 19:48
@LittleBeannie
Copy link
Collaborator

Note: we are going to try these short-term fixes for now.

@LittleBeannie LittleBeannie merged commit f965dae into Merck:main Oct 4, 2024
7 checks passed
@jdblischak jdblischak deleted the as-gt branch October 4, 2024 20:07
@yihui
Copy link
Contributor

yihui commented Oct 4, 2024

I'm okay with merging these two PRs at the moment. In the long run, I'd still like to explore the possibility of print() methods (after we settle on the class names), so that users could get a table automatically in the R console or R Markdown just by summary(design).

I could also ask the author of gt to provide an S3 generic in gt, but I think it's too late now (the world will be even messier if gt::as_gt() is provided---three as_gt() functions in three packages).

@jdblischak
Copy link
Collaborator Author

I could also ask the author of gt to provide an S3 generic in gt, but I think it's too late now (the world will be even messier if gt::as_gt() is provided---three as_gt() functions in three packages).

IIUC I think this strategy could work. gsDesign2 already has gt in Imports. simtrial might need to be move it from Suggests to Imports though.

The r-lib/generics docs explicitly recommend re-exporting the generic. So if the gt package added an as_gt() generic, both gsDesign2 and simtrial could re-export and add their own methods. Then as_gt() should resolve S3 redirection the same as base::summary()

To use generics with your package, we recommend that you import and re-export the generic(s) of interest.

@nanxstats
Copy link
Collaborator

Honestly, I'm not sure if making gt a hard dependency is ideal. For one example: gt depends on juicyjuice, which depends on V8. It creates installation issues sometimes in the real-world: rstudio/gt#1179

However, I'm not a maintainer or active contributor to any of these packages, so YMMV 😁

@yihui
Copy link
Contributor

yihui commented Oct 7, 2024

I don't think the presentation of results as tables is a core function of this package, so we shouldn't take a hard dependency on gt. Recently I tried to install gt in a fresh R installation, and I was impressed by the number of packages being dragged into my system. Although personally I'm not interested in tables, someday I might experiment on an alternative lightweight implementation. (Re: rstudio/gt#1179, I've never liked the idea of fully inlining CSS---it's a crime in my eyes).

P.S. Technically, if gt does provide an as_gt() generic, we don't need to take a hard dependency on it. Instead, we could conditionally register our S3 methods (i.e., if gt is available, our methods will work).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants