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

Refactor methods by passing table metadata as attributes #497

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jdblischak
Copy link
Collaborator

This is an alternative approach to #482 to refactor the classes/methods as discussed in #457

This PR refactors the fixed_design_X() functions to define their own design_display, title, and footnote as attributes, which are then used by summary(), as_gt(), and as_rtf(). This idea was proposed by @yihui, which I described in #482 (comment)

By using the above strategy, I was able to make the following improvements to the classes/methods:

  • summary.fixed_design() no longer adds a method class to its output object (eg "ahr") since this is no longer necessary. This was only used to constructed the table metadata, which is now already defined in the attributes of the object produced the respective fixed_design_X() function
  • summary.fixed_design() returns an object of class "fixed_design_summary" to distinguish it from the output of a fixed_design_X() function (with class "fixed_design")

Below is example code to test out the changes in this PR:

devtools::load_all(".")

# ahr
x <- fixed_design_ahr(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = c(4, 100),
    fail_rate = log(2) / 12,
    hr = c(1, .6),
    dropout_rate = .001
  ),
  study_duration = 36
)
attributes(x)
## $names
## [1] "input"       "enroll_rate" "fail_rate"   "analysis"    "design"
##
## $design_display
## [1] "Average hazard ratio"
##
## $title
## [1] "Fixed Design under AHR Method"
##
## $footnote
## [1] "Power computed with average hazard ratio method."
##
## $class
## [1] "fixed_design" "list"
xsum <- summary(x)
attributes(xsum)
## $row.names
## [1] 1
##
## $names
## [1] "Design" "N"      "Events" "Time"   "Bound"  "alpha"  "Power"
##
## $class
## [1] "fixed_design_summary" "tbl_df"               "tbl"                  "data.frame"
##
## $title
## [1] "Fixed Design under AHR Method"
##
## $footnote
## [1] "Power computed with average hazard ratio method."
as_gt(xsum)
as_gt(xsum, title = "Custom title", footnote = "Custom footnote")
as_rtf(xsum, file = "refactor.rtf")
as_rtf(xsum, file = "refactor.rtf", title = "Custom title", footnote = "Custom footnote")

# fh
x <- fixed_design_fh(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = c(4, 100),
    fail_rate = log(2) / 12,
    hr = c(1, .6),
    dropout_rate = .001
  ),
  study_duration = 36,
  rho = 1, gamma = 1
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# mb
x <- fixed_design_mb(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = c(4, 100),
    fail_rate = log(2) / 12,
    hr = c(1, .6),
    dropout_rate = .001
  ),
  study_duration = 36,
  tau = 4,
  w_max = 2
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# lf
x <- fixed_design_lf(
  alpha = .025, power = .9,
  enroll_rate = define_enroll_rate(duration = 18, rate = 1),
  fail_rate = define_fail_rate(
    duration = 100,
    fail_rate = log(2) / 12,
    hr = .7,
    dropout_rate = .001
  ),
  study_duration = 36
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# rd
x <- fixed_design_rd(
  alpha = 0.025, power = 0.9, p_c = .15, p_e = .1,
  rd0 = 0, ratio = 1
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# maxcombo
x <- fixed_design_maxcombo(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = c(4, 100),
    fail_rate = log(2) / 12,
    hr = c(1, .6),
    dropout_rate = .001
  ),
  study_duration = 36,
  rho = c(0, 0.5), gamma = c(0, 0), tau = c(-1, -1)
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# milestone
x <- fixed_design_milestone(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = 100,
    fail_rate = log(2) / 12,
    hr = .7,
    dropout_rate = .001
  ),
  study_duration = 36,
  tau = 18
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

# rmst
x <- fixed_design_rmst(
  alpha = .025,
  enroll_rate = define_enroll_rate(duration = 18, rate = 20),
  fail_rate = define_fail_rate(
    duration = 100,
    fail_rate = log(2) / 12,
    hr = .7,
    dropout_rate = .001
  ),
  study_duration = 36,
  tau = 18
)
attributes(x)
xsum <- summary(x)
attributes(xsum)
as_gt(xsum)
as_rtf(xsum, file = "refactor.rtf")

@jdblischak jdblischak self-assigned this Jan 31, 2025
@nanxstats
Copy link
Collaborator

This looks clear to me. I apologize for the complexity - if we could have written this in classical OOP, things would have been much more straightforward. This is one of the few things where I think Python gets it right but base R didn't.

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.

2 participants