Skip to content

Commit 90eca39

Browse files
aassuied-psedelaruagithub-actions[bot]dependabot-preview[bot]
authored
201 new figure figure 14 (#209)
* First draft First draft (not fully working) * New push Now the results are correct. Colors in the table are missing and the order of the group is not correct. * Delete width= in geom_errorbar To avoid warning `position_dodge()` requires non-overlapping x intervals * Update Put example in comments @examples * Update fda-fig_14 and argument convention * tests Update setup.R to add ggplot2 * quarto page * _quarto.yml and NEWS.md * typo * Put PARAMCD in code mode * Remove id_var, add visit_var, reverse order of table rows * [skip actions] Restyle files * Add to index * [skip actions] Restyle files * Empty commit * Fix unrelated broken template * [skip actions] Roxygen Man Pages Auto Update * Empty commit * Fix lint * Fix imports/exports * Update template --------- Co-authored-by: Emily de la Rua <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com>
1 parent 1cef836 commit 90eca39

21 files changed

+1455
-39
lines changed

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export(alt_counts_df_preproc)
44
export(basic_table_annot)
55
export(make_fig_01)
66
export(make_fig_02)
7+
export(make_fig_14)
78
export(make_table_02)
89
export(make_table_02_gtsum)
910
export(make_table_02_tplyr)

NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
`make_table_06`, `make_table_07`, `make_table_08`, `make_table_09`, `make_table_10`, `make_table_11`, `make_table_12`,
66
`make_table_13`, `make_table_14`, `make_table_15`, `make_table_16`, `make_table_17`, `make_table_18`, `make_table_20`,
77
`make_table_21`, `make_table_22`, `make_table_32`, `make_table_33`, `make_table_34`, `make_table_35`.
8-
* Added new functions for creating standard FDA figures: `make_fig_01`, `make_fig_02`.
8+
* Added new functions for creating standard FDA figures: `make_fig_01`, `make_fig_02`, `make_fig_14`.
99
* Added helper functions used within table functions:
1010
* `basic_table_annot` for adding basic table annotations (titles, footnotes, column counts).
1111
* `split_cols_by_arm` for splitting columns by arm with option to add total column.

R/argument_convention.R

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
#' @param xticks (`vector` of `numeric`)\cr x-axis tick positions. If `NA` (default), tick mark positions are
5252
#' automatically calculated.
5353
#' @param x_lab (`character`)\cr x-axis label.
54+
#' @param yticks (`vector` of `numeric`)\cr y-axis tick positions. If `NA` (default), tick mark positions are
55+
#' automatically calculated.
5456
#' @param y_lab (`character`)\cr y-axis label.
5557
#'
5658
#' @name argument_convention

R/fda-fig_14.R

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#' FDA Figure 14: Mean and 95% Confidence Interval of Systolic Blood Pressure Over Time
2+
#' by Treatment Arm, Safety Population, Trial X
3+
#'
4+
#' @details
5+
#' * `df` must contain the variables `AVAL` and `PARAMCD`, and the variables specified by `arm_var`,
6+
#' `saffl_var`, `visit_var`, and `add_cond`.
7+
#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in
8+
#' flag variables are treated as `"N"`.
9+
#' * It is assumed that `df` contains one unique record per patient.
10+
#'
11+
#' @inheritParams argument_convention
12+
#' @param add_table (`flag`)\cr whether "Mean Value" and "Number of Patients" tables should be printed under the plot
13+
#' @param visit_var (`character`)\cr visit variable to put on the x-axis
14+
#' @param paramcd_val (`character`)\cr value of `PARAMCD` to plot
15+
#' @param add_cond (`expr`)\cr expression that provides additional filters for the analysis
16+
#' (for instance on `ATPT` or `VSPOS`)
17+
#' @param annotations (named `list` of `character`)\cr list of annotations to add to the figure. Valid annotation types
18+
#' are `title`, `subtitles`, and `caption`. Each name-value pair should use the annotation type as name and the
19+
#' desired string as value.
20+
#'
21+
#' @return A `ggplot2` object.
22+
#'
23+
#' @examples
24+
#' advs <- random.cdisc.data::cadvs
25+
#'
26+
#' fig <- make_fig_14(
27+
#' df = advs,
28+
#' add_cond = bquote("ONTRTFL == 'Y' | ABLFL == 'Y'"),
29+
#' add_table = TRUE,
30+
#' yticks = c(135, 140, 145, 150, 155, 160)
31+
#' )
32+
#' fig
33+
#'
34+
#' @export
35+
make_fig_14 <- function(df,
36+
arm_var = "ARM",
37+
saffl_var = "SAFFL",
38+
visit_var = "AVISIT",
39+
paramcd_val = "SYSBP",
40+
add_cond = NULL,
41+
x_lab = "",
42+
y_lab = NULL,
43+
yticks = NA,
44+
ggtheme = NULL,
45+
add_table = TRUE,
46+
annotations = NULL) {
47+
checkmate::assert_subset(c(arm_var, saffl_var, visit_var), names(df))
48+
assert_flag_variables(df, saffl_var)
49+
50+
df <- df %>%
51+
as_tibble() %>%
52+
filter(
53+
.data[[saffl_var]] == "Y",
54+
PARAMCD == {{ paramcd_val }},
55+
!is.na(AVAL)
56+
) %>%
57+
df_explicit_na()
58+
59+
if (!(is.null({{ add_cond }}))) {
60+
df <- df %>%
61+
filter(!!rlang::parse_expr(add_cond))
62+
}
63+
64+
if (is.null({{ y_lab }})) {
65+
y_param <- unique(df$PARAM)
66+
y_avalu <- unique(df$AVALU)
67+
68+
y_lab <- paste0("Mean Value (95% CI)", "\n", y_param, " (", y_avalu, ")")
69+
}
70+
71+
df <- df %>%
72+
group_by(!!sym(arm_var), !!sym(visit_var), .drop = TRUE) %>%
73+
summarise(
74+
mean = mean(AVAL, na.rm = TRUE),
75+
sd = sd(AVAL, na.rm = TRUE),
76+
n = n()
77+
) %>%
78+
mutate(
79+
se = sd / sqrt(n),
80+
lower_ci = mean - qt(1 - (0.05 / 2), n - 1) * se,
81+
upper_ci = mean + qt(1 - (0.05 / 2), n - 1) * se
82+
) %>%
83+
ungroup()
84+
85+
g <-
86+
ggplot(
87+
data = df,
88+
aes(
89+
x = !!sym(visit_var),
90+
y = mean,
91+
group = .data[[arm_var]],
92+
color = .data[[arm_var]]
93+
)
94+
) +
95+
geom_point(position = position_dodge(width = 0.5)) +
96+
geom_line(position = position_dodge(width = 0.5)) +
97+
geom_errorbar(
98+
aes(
99+
ymin = lower_ci,
100+
ymax = upper_ci
101+
),
102+
position = position_dodge(width = 0.5)
103+
) +
104+
labs(
105+
title = annotations[["title"]],
106+
subtitle = annotations[["subtitle"]],
107+
caption = annotations[["caption"]],
108+
x = x_lab,
109+
y = y_lab
110+
) +
111+
theme(
112+
legend.position = "bottom",
113+
legend.title = element_blank(),
114+
plot.margin = unit(c(0.05, 0.05, 0, 0.025), "npc")
115+
)
116+
117+
if (any(!is.na(yticks))) {
118+
g <- g +
119+
scale_y_continuous(breaks = yticks, limits = c(min(yticks), max(yticks)))
120+
}
121+
122+
if (!is.null(ggtheme)) g <- g + ggtheme
123+
124+
if (add_table) {
125+
g_legend <- cowplot::get_legend(g)
126+
g <- g + theme(legend.position = "none")
127+
128+
tbl_n <- df %>%
129+
mutate(meanr = sprintf("%.1f", mean)) %>%
130+
arrange(desc(!!sym(arm_var)))
131+
132+
g_tbl1 <- ggplot(tbl_n, aes(x = !!sym(visit_var), y = !!sym(arm_var))) +
133+
theme(
134+
axis.title.x = element_blank(),
135+
axis.title.y = element_blank(),
136+
axis.ticks.x = element_blank(),
137+
axis.ticks.y = element_blank(),
138+
panel.background = element_blank(),
139+
axis.text.x = element_blank(),
140+
panel.border = element_rect(color = "black", fill = NA, linewidth = 0.5),
141+
plot.margin = unit(c(0.1, 0.05, 0, 0.025), "npc"),
142+
plot.title = element_text(size = 10)
143+
) +
144+
labs(title = "Mean Value")
145+
146+
for (i in seq_len(nrow(tbl_n))) {
147+
g_tbl1 <- g_tbl1 +
148+
annotate("text", label = as.character(tbl_n$meanr[i]), x = tbl_n[[visit_var]][i], y = tbl_n[[arm_var]][i])
149+
}
150+
151+
g_tbl2 <- ggplot(tbl_n, aes(x = !!sym(visit_var), y = !!sym(arm_var))) +
152+
theme(
153+
axis.title.x = element_blank(),
154+
axis.title.y = element_blank(),
155+
axis.ticks.x = element_blank(),
156+
axis.ticks.y = element_blank(),
157+
panel.background = element_blank(),
158+
axis.text.x = element_blank(),
159+
panel.border = element_rect(color = "black", fill = NA, linewidth = 0.2),
160+
plot.margin = unit(c(0.1, 0.05, 0, 0.025), "npc"),
161+
plot.title = element_text(size = 10)
162+
) +
163+
labs(title = "Number of Patients with Data")
164+
165+
for (i in seq_len(nrow(tbl_n))) {
166+
g_tbl2 <- g_tbl2 +
167+
annotate("text", label = as.character(tbl_n$n[i]), x = tbl_n[[visit_var]][i], y = tbl_n[[arm_var]][i])
168+
}
169+
170+
cowplot::plot_grid(
171+
g,
172+
g_tbl1,
173+
g_tbl2,
174+
g_legend,
175+
align = "v",
176+
axis = "l",
177+
ncol = 1,
178+
rel_heights = c(0.60, 0.15, 0.15, 0.1)
179+
)
180+
} else {
181+
g
182+
}
183+
}

R/fda-table_22.R

+3-5
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,16 @@
1818
#' @examples
1919
#' library(dplyr)
2020
#'
21-
#' adsl <- scda::synthetic_cdisc_dataset("rcd_2022_10_13", "adsl") %>%
21+
#' adsl <- random.cdisc.data::cadsl %>%
2222
#' mutate(AGEGR1 = as.factor(case_when(
2323
#' AGE >= 17 & AGE < 65 ~ ">=17 to <65",
2424
#' AGE >= 65 ~ ">=65",
2525
#' AGE >= 65 & AGE < 75 ~ ">=65 to <75",
2626
#' AGE >= 75 ~ ">=75"
2727
#' )) %>% formatters::with_label("Age Group, years")) %>%
28-
#' formatters::var_relabel(
29-
#' AGE = "Age, years"
30-
#' )
28+
#' formatters::var_relabel(AGE = "Age, years")
3129
#'
32-
#' adae <- scda::synthetic_cdisc_dataset("rcd_2022_10_13", "adae")
30+
#' adae <- random.cdisc.data::cadae
3331
#'
3432
#' df <- left_join(adsl, adae, by = intersect(names(adsl), names(adae)))
3533
#'

_quarto.yml

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ website:
105105
- quarto/table-templates/template-table_35.qmd
106106
- quarto/figure-templates/template-fig_01.qmd
107107
- quarto/figure-templates/template-fig_02.qmd
108+
- quarto/figure-templates/template-fig_14.qmd
108109
- text: About
109110
file: quarto/about.qmd
110111
- text: Resources

man/argument_convention.Rd

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/make_fig_14.Rd

+79
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/make_table_22.Rd

+3-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
169 KB
Loading

0 commit comments

Comments
 (0)