-
Notifications
You must be signed in to change notification settings - Fork 34
/
tlf-efficacy-km.qmd
118 lines (94 loc) · 3.53 KB
/
tlf-efficacy-km.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Efficacy figure
```{r, include=FALSE}
source("_common.R")
```
Following the [ICH E3 guidance](https://database.ich.org/sites/default/files/E3_Guideline.pdf),
primary and secondary efficacy endpoints need to be summarized
in Section 11.4, Efficacy Results and Tabulations of Individual Participant.
```{r}
library(haven) # Read SAS data
library(dplyr) # Manipulate data
library(r2rtf) # Reporting in RTF format
library(survival) # Fit survival model
```
In this chapter, we illustrate how to create a simplified Kaplan-Meier plot in a study.
For the survival analysis in efficacy, time to dermatologic event (TTDE) will be analyzed.
::: {.callout-note}
R packages such as
[visR](https://cran.r-project.org/package=visR) and
[survminer](https://cran.r-project.org/package=survminer)
can create more informative Kaplan-Meier plots.
Interested readers can find examples on their websites.
:::
## Analysis dataset
To prepare the analysis, the `adtte` dataset is required.
```{r}
adtte <- read_sas("data-adam/adtte.sas7bdat")
```
First, to prepare the analysis ready data,
filter all records for the efficacy endpoint of time to event of interest (`TTDE`)
using `PARAMCD` (or `PARAM`, `PRAMN`), then select the survival analysis related variables:
- `TRTP`: treatment arm (using corresponding numeric code `TRTAN` to re-order the levels, "Placebo" will be the reference level)
- `AVAL`: time-to-event analysis value
- `CNSR`: event (censoring) status
```{r}
adtte_ttde <- adtte %>%
filter(PARAMCD == "TTDE") %>%
select(TRTP, TRTAN, AVAL, CNSR) %>%
mutate(
TRTP = forcats::fct_reorder(TRTP, TRTAN), # Recorder levels
AVAL_m = AVAL / 30.4367 # Convert Day to Month
)
```
## Create Kaplan-Meier curve
The survival package is used to obtain the K-M estimate.
```{r}
# Fit survival model, convert the time value from Days to Month
fit <- survfit(Surv(AVAL_m, 1 - CNSR) ~ TRTP, data = adtte_ttde)
```
We save the simplified K-M plot into a `.png` file using code below.
```{r, results = FALSE}
# Save as a PNG file
png(
file = "tlf/fig_km.png",
width = 3000,
height = 2000,
res = 300
)
plot(
fit,
xlab = "Time in Months",
ylab = "Survival probability",
mark.time = TRUE,
lwd = 2,
col = c(2, 3, 4),
lty = c(1, 2, 3)
)
dev.off()
```
Now, we can use the r2rtf package to create a formatted RTF figure.
More details can be found on the [r2rtf website](https://merck.github.io/r2rtf/articles/example-figure.html).
```{r}
# Create RTF figure
rtf_read_figure("tlf/fig_km.png") %>% # Read the PNG file from the file path
rtf_title(
"Kaplan-Meier Plot for Time to First Dermatologic Event by Treatment Group",
"All Participants"
) %>% # Add title or subtitle
rtf_footnote("footnote") %>% # Add footnote
rtf_source("[datasource: adam-adtte]") %>% # Add data source
rtf_figure(fig_width = 6, fig_height = 4) %>% # Set proportional figure size to the original PNG figure size
rtf_encode(doc_type = "figure") %>% # Encode figure as rtf
write_rtf(file = "tlf/tlf_km.rtf")
```
```{r, include=FALSE}
rtf2pdf("tlf/tlf_km.rtf")
```
```{r, out.width = "100%", out.height = if (knitr::is_html_output()) "400px", echo = FALSE, fig.align = "center"}
knitr::include_graphics("tlf/tlf_km.pdf")
```
In conclusion, the steps to create a K-M plot are as follows.
- Step 1: Read the data `adtte` into R.
- Step 2: Define the analysis-ready dataset. In this example, we define the analysis dataset for the TTDE endpoint `adtte_ttde`.
- Step 3: Save figures into `png` files based on required analysis specification.
- Step 4: Create RTF output using the r2rtf package.