Skip to content

Commit 5c5e25f

Browse files
ddsjobergedelarua
andauthored
Adding ard_survival_survdiff() (#119)
**What changes are proposed in this pull request?** * Adding `ard_survival_survdiff()` for creating results from `survival::survdiff()`. (#113) **Reference GitHub issue associated with pull request.** _e.g., 'closes #<issue number>'_ closes #113 -------------------------------------------------------------------------------- Pre-review Checklist (if item does not apply, mark is as complete) - [x] **All** GitHub Action workflows pass with a ✅ - [x] PR branch has pulled the most recent updates from master branch: `usethis::pr_merge_main()` - [x] If a bug was fixed, a unit test was added. - [x] If a new `ard_*()` function was added, it passes the ARD structural checks from `cards::check_ard_structure()`. - [x] Code coverage is suitable for any new functions/features (generally, 100% coverage for new code): `devtools::test_coverage()` - [x] If a new `ard_*()` function was added, `set_cli_abort_call()` has been set. - [x] If a new `ard_*()` function was added and it depends on another package (such as, `broom`), `is_pkg_installed("broom", reference_pkg = "cardx")` has been set in the function call and the following added to the roxygen comments: `@examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom"", reference_pkg = "cardx"))` Reviewer Checklist (if item does not apply, mark is as complete) - [x] If a bug was fixed, a unit test was added. - [x] Code coverage is suitable for any new functions/features: `devtools::test_coverage()` When the branch is ready to be merged: - [x] Update `NEWS.md` with the changes from this pull request under the heading "`# cardx (development version)`". If there is an issue associated with the pull request, reference it in parentheses at the end update (see `NEWS.md` for examples). - [x] **All** GitHub Action workflows pass with a ✅ - [x] Approve Pull Request - [ ] Merge the PR. Please use "Squash and merge" or "Rebase and merge". --------- Co-authored-by: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Co-authored-by: Emily de la Rua <emily.de_la_rua@contractors.roche.com>
1 parent 84cf6eb commit 5c5e25f

File tree

11 files changed

+278
-36
lines changed

11 files changed

+278
-36
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Pre-review Checklist (if item does not apply, mark is as complete)
1313
- [ ] PR branch has pulled the most recent updates from master branch: `usethis::pr_merge_main()`
1414
- [ ] If a bug was fixed, a unit test was added.
1515
- [ ] If a new `ard_*()` function was added, it passes the ARD structural checks from `cards::check_ard_structure()`.
16+
- [ ] If a new `ard_*()` function was added, `set_cli_abort_call()` has been set.
17+
- [ ] If a new `ard_*()` function was added and it depends on another package (such as, `broom`), `is_pkg_installed("broom", reference_pkg = "cardx")` has been set in the function call and the following added to the roxygen comments: `@examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom"", reference_pkg = "cardx"))`
1618
- [ ] Code coverage is suitable for any new functions/features (generally, 100% coverage for new code): `devtools::test_coverage()`
1719

1820
Reviewer Checklist (if item does not apply, mark is as complete)

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: cardx
22
Title: Extra Analysis Results Data Utilities
3-
Version: 0.1.0.9019
3+
Version: 0.1.0.9018
44
Authors@R: c(
55
person("Daniel", "Sjoberg", , "danield.sjoberg@gmail.com", role = c("aut", "cre")),
66
person("Abinaya", "Yogasekaram", , "abinaya.yogasekaram@contractors.roche.com", role = "aut"),
@@ -31,6 +31,7 @@ Suggests:
3131
car (>= 3.0-11),
3232
effectsize (>= 0.6.0),
3333
geepack (>= 1.3.2),
34+
ggsurvfit (>= 1.0.0),
3435
lme4 (>= 1.1-31),
3536
parameters (>= 0.20.2),
3637
smd (>= 0.6.6),

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export(ard_survey_svychisq)
3434
export(ard_survey_svycontinuous)
3535
export(ard_survey_svyranktest)
3636
export(ard_survey_svyttest)
37+
export(ard_survival_survdiff)
3738
export(ard_survival_survfit)
3839
export(contains)
3940
export(ends_with)

NEWS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# cardx 0.1.0.9019
1+
# cardx 0.1.0.9018
22

33
### Breaking Changes
44

@@ -39,8 +39,9 @@ ard_moodtest() -> ard_stats_mood_test()
3939

4040
* Updated `ard_stats_t_test()` and `ard_stats_wilcox_test()` to no longer require the `by` argument, which yields central estimates with their confidence intervals. (#82)
4141

42-
* Import cli call environment functions from `https://github.com/ddsjoberg/standalone/blob/main/R/standalone-cli_call_env.R` and implement `set_cli_abort_call` in user-facing functions. (#111, @edelarua)
42+
* Imported cli call environment functions from `https://github.com/ddsjoberg/standalone/blob/main/R/standalone-cli_call_env.R` and implemented `set_cli_abort_call` in user-facing functions. (#111)
4343

44+
* Added `ard_survival_survdiff()` for creating results from `survival::survdiff()`. (#113)
4445

4546
# cardx 0.1.0
4647

R/ard_survival_survdiff.R

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#' ARD for Difference in Survival
2+
#'
3+
#' @description
4+
#' Analysis results data for comparison of survival using [survival::survdiff()].
5+
#'
6+
#' @param formula (`formula`)\cr
7+
#' a formula
8+
#' @param data (`data.frame`)\cr
9+
#' a data frame
10+
#' @param rho (`scalar numeric`)\cr
11+
#' numeric scalar passed to `survival::survdiff(rho)`. Default is `rho=0`.
12+
#' @param ... additional arguments passed to `survival::survdiff()`
13+
#'
14+
#' @return an ARD data frame of class 'card'
15+
#' @export
16+
#'
17+
#' @examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = c("survival", "broom", "ggsurvfit"), reference_pkg = "cardx"))
18+
#' library(survival)
19+
#' library(ggsurvfit)
20+
#'
21+
#' ard_survival_survdiff(Surv_CNSR(AVAL, CNSR) ~ TRTA, data = cards::ADTTE)
22+
ard_survival_survdiff <- function(formula, data, rho = 0, ...) {
23+
set_cli_abort_call()
24+
25+
# check installed packages ---------------------------------------------------
26+
check_pkg_installed(c("survival", "broom"), reference_pkg = "cardx")
27+
28+
# check/process inputs -------------------------------------------------------
29+
check_not_missing(formula)
30+
check_class(formula, cls = "formula")
31+
if (!missing(data)) check_class(data, cls = "data.frame")
32+
check_scalar(rho)
33+
check_class(rho, cls = "numeric")
34+
35+
# assign method
36+
method <- dplyr::case_when(
37+
rho == 0 ~ "Log-rank test",
38+
rho == 1.5 ~ "Tarone-Ware test",
39+
rho == 1 ~ "Peto & Peto modification of Gehan-Wilcoxon test",
40+
.default = glue::glue("G-rho test (\U03C1 = {rho})")
41+
) |>
42+
as.character()
43+
44+
# calculate survdiff() results -----------------------------------------------
45+
lst_glance <-
46+
cards::eval_capture_conditions(
47+
survival::survdiff(formula = formula, data = data, rho = rho, ...) |>
48+
broom::glance() |>
49+
dplyr::mutate(method = .env$method)
50+
)
51+
52+
# tidy results up in an ARD format -------------------------------------------
53+
# extract variable names from formula
54+
variables <- stats::terms(formula) |>
55+
attr("term.labels") |>
56+
.strip_backticks()
57+
58+
# if there was an error, return results early
59+
if (is.null(lst_glance[["result"]])) {
60+
# if no variables in formula, then return an error
61+
# otherwise, if we do have variable names, then we can construct an empty ARD which will be done below
62+
if (is_empty(variables)) {
63+
cli::cli_abort(
64+
message =
65+
c("There was an error in {.fun survival::survdiff}. See below:",
66+
"x" = lst_glance[["error"]]
67+
),
68+
call = get_cli_abort_call()
69+
)
70+
}
71+
}
72+
73+
.variables_to_survdiff_ard(
74+
variables = variables,
75+
method = method,
76+
# styler: off
77+
stat_names =
78+
if (!is.null(lst_glance[["result"]])) names(lst_glance[["result"]])
79+
else c("statistic", "df", "p.value", "method"),
80+
stats =
81+
if (!is.null(lst_glance[["result"]])) unname(as.list(lst_glance[["result"]]))
82+
else rep_along(c("statistic", "df", "p.value"), list(NULL)) |> c(list(method = method))
83+
# styler: on
84+
) |>
85+
.add_survdiff_stat_labels() |>
86+
dplyr::mutate(
87+
context = "survival_survdiff",
88+
warning = lst_glance["warning"],
89+
error = lst_glance["error"],
90+
fmt_fn = map(
91+
.data$stat,
92+
function(x) {
93+
if (is.numeric(x)) return(1L) # styler: off
94+
NULL
95+
}
96+
)
97+
) |>
98+
cards::tidy_ard_column_order() %>%
99+
{structure(., class = c("card", class(.)))} # styler: off
100+
}
101+
102+
.variables_to_survdiff_ard <- function(variables,
103+
method,
104+
stat_names,
105+
stats) {
106+
len <- length(variables)
107+
108+
df_vars <- dplyr::tibble(!!!rev(variables)) |>
109+
set_names(
110+
ifelse(
111+
len > 1L,
112+
c(paste0("group_", rev(seq_len(len - 1L))), "variable"),
113+
"variable"
114+
)
115+
)
116+
117+
dplyr::bind_cols(
118+
df_vars,
119+
dplyr::tibble(
120+
stat_name = .env$stat_names,
121+
stat = .env$stats
122+
)
123+
)
124+
}
125+
126+
.add_survdiff_stat_labels <- function(x) {
127+
x |>
128+
dplyr::left_join(
129+
dplyr::tribble(
130+
~stat_name, ~stat_label,
131+
"statistic", "X^2 Statistic",
132+
"df", "Degrees of Freedom",
133+
"p.value", "p-value"
134+
),
135+
by = "stat_name"
136+
) |>
137+
dplyr::mutate(stat_label = dplyr::coalesce(.data$stat_label, .data$stat_name))
138+
}
139+
140+
.strip_backticks <- function(x) {
141+
ifelse(
142+
str_detect(x, "^`.*`$"),
143+
substr(x, 2, nchar(x) - 1),
144+
x
145+
)
146+
}

R/ard_survival_survfit.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@
3434
#'
3535
#' @examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = c("survival", "broom"), reference_pkg = "cardx"))
3636
#' library(survival)
37+
#' library(ggsurvfit)
3738
#'
38-
#' survfit(Surv(AVAL, CNSR) ~ TRTA, cards::ADTTE) |>
39+
#' survfit(Surv_CNSR(AVAL, CNSR) ~ TRTA, cards::ADTTE) |>
3940
#' ard_survival_survfit(times = c(60, 180))
4041
#'
41-
#' survfit(Surv(AVAL, CNSR) ~ TRTA, cards::ADTTE) |>
42+
#' survfit(Surv_CNSR(AVAL, CNSR) ~ TRTA, cards::ADTTE) |>
4243
#' ard_survival_survfit(probs = c(0.25, 0.5, 0.75))
4344
#'
4445
#' # Competing Risks Example ---------------------------

_pkgdown.yml

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ authors:
2222

2323
reference:
2424
- title: "ARD Creation"
25-
26-
- subtitle: "{stats} package"
25+
- subtitle: "Inference"
2726
- contents:
27+
- ard_aod_wald_test
28+
- ard_car_anova
2829
- ard_stats_anova
2930
- ard_stats_aov
3031
- ard_stats_chisq_test
@@ -36,41 +37,22 @@ reference:
3637
- ard_stats_prop_test
3738
- ard_stats_t_test
3839
- ard_stats_wilcox_test
39-
40-
- subtitle: "{aod} package"
41-
- contents:
42-
- ard_aod_wald_test
43-
44-
- subtitle: "{car} package"
45-
- contents:
46-
- ard_car_anova
47-
- ard_car_vif
48-
49-
- subtitle: "{effectsize} package"
50-
- contents:
51-
- ard_effectsize_cohens_d
52-
- ard_effectsize_hedges_g
53-
54-
- subtitle: "{smd} package"
55-
- contents:
56-
- ard_smd_smd
57-
58-
- subtitle: "{survey} package"
59-
- contents:
6040
- ard_survey_svychisq
61-
- ard_survey_svycontinuous
6241
- ard_survey_svyranktest
6342
- ard_survey_svyttest
43+
- ard_survival_survdiff
6444

65-
- subtitle: "{survival} package"
66-
- contents:
67-
- ard_survival_survfit
68-
69-
- subtitle: "Other ARD functions"
45+
- subtitle: "Estimation"
7046
- contents:
47+
- ard_car_vif
48+
- ard_effectsize_cohens_d
49+
- ard_effectsize_hedges_g
7150
- ard_proportion_ci
7251
- ard_regression
7352
- ard_regression_basic
53+
- ard_smd_smd
54+
- ard_survival_survfit
55+
- ard_survey_svycontinuous
7456

7557
- title: "Helpers"
7658
- contents:

man/ard_survival_survdiff.Rd

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ard_survival_survfit.Rd

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-ard_stats_anova.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,14 @@ test_that("ard_stats_anova.data.frame() works", {
129129
ard_anova_geeglm
130130
)
131131
})
132+
133+
test_that("ard_stats_anova.data.frame() error messaging", {
134+
expect_error(
135+
ard_stats_anova(
136+
x = mtcars,
137+
formulas = list(mpg ~ am, mpg ~ am + hp),
138+
fn = "base::lm"
139+
),
140+
"cannot be namespaced"
141+
)
142+
})

0 commit comments

Comments
 (0)