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

Time to ae #92

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Imports:
rlang,
shiny,
stringr,
survival,
survminer,
Tendril,
Tplyr
Suggests:
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ export(safetyOutlierExplorer_ui)
export(safety_outlier_explorer)
export(safety_results_over_time)
export(tendril_chart)
export(timeToAE)
import(Tendril)
import(Tplyr)
import(dplyr)
import(ggplot2)
import(htmlwidgets)
import(rlang)
import(shiny)
import(survival)
import(survminer)
importFrom(huxtable,as_hux)
importFrom(huxtable,set_align)
importFrom(huxtable,set_bold)
Expand Down
20 changes: 20 additions & 0 deletions R/meta.R
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,23 @@
#' @source Created for this package

"meta_hepExplorer"

#' Metadata data frame containing information about the data mapping used to configure safetyGraphics for the Time to AE Chart. One record per unique data mapping
#'
#' @format A data frame with X rows and 10 columns
#' \describe{
#' \item{domain}{Data domain}
#' \item{text_key}{Text key indicating the setting name. \code{'--'} delimiter indicates a field level data mapping}
#' \item{col_key}{Key for the column mapping}
#' \item{field_key}{Key for the field mapping (if any)}
#' \item{type}{type of mapping - "field" or "column"}
#' \item{label}{Label}
#' \item{description}{Description}
#' \item{multiple}{Mapping supports multiple columns/fields }
#' \item{standard_adam}{Default values for the ADaM data standard}
#' \item{standard_sdtm}{Default values for the SDTM data standard}
#' }
#'
#' @source Created for this package

"meta_timeToAE"
2 changes: 1 addition & 1 deletion R/mod_demogRTF.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@ demogRTF_table <- function(data, settings) {
pharmaRTF::set_column_header_buffer(top=1)

return(doc)
}
}
85 changes: 85 additions & 0 deletions R/mod_timeToAE.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
timeToAE_ui <- function(id) {
ns <- NS(id)

sidebar <- sidebarPanel(
selectizeInput(
ns('ae'),
'Time to',
multiple = FALSE,
choices = NULL
),
selectizeInput(
ns('stratum'),
'Stratum',
multiple = FALSE,
choices = NULL
)
)

main <- mainPanel(
plotOutput(ns('survival_plot'))
)

ui <- fluidPage(
sidebarLayout(
sidebar,
main,
position = c('right'),
fluid = TRUE
)
)

return(ui)
}

timeToAE_server <- function(input, output, session, params) {
ns <- session$ns

observe({
params <- params()
data <- params$data
settings <- params$settings

ae_choices <- data$aes %>%
group_by(!!sym(settings$aes$term_col)) %>%
tally %>%
arrange(desc(n)) %>%
pull(!!sym(settings$aes$term_col))

updateSelectizeInput(
session,
'ae',
choices = c('Any AE', ae_choices),
selected = 'Any AE'
)
})

observe({
params <- params()
data <- params$data
settings <- params$settings

updateSelectizeInput(
session,
'stratum',
choices = c(
'None',
settings$dm$treatment_col,
settings$dm$sex_col,
settings$dm$race_col
),
selected = 'None'
)
})

output$survival_plot <- renderPlot({
params <- params()

timeToAE(
params$data,
params$settings,
input$ae,
input$stratum
)
})
}
98 changes: 98 additions & 0 deletions R/timeToAE.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#' Time to AE
#'
#' @param data list of data frames including dataframes named `aes` (adverse events) and `dm` (demographics)
#' @param settings named list of domain-specific settings with the parameters specified below.
#' @param ae AE of interest. Default="Any ae"
#' @param stratum Default='None'
#'
#' @return returns a chart object
#'
#' @import survival
#' @import survminer
#' @import dplyr
#'
#' @export
#'

timeToAE <- function(data, settings, ae = 'Any AE', stratum = 'None') {

# Participant-level data
participants <- data$dm %>%
filter(!is.na(RFSTDTC)) %>%
mutate(
RFSTDT = as.Date(RFSTDTC),
RFENDT = as.Date(RFENDTC)
)

# Event-level data
aes <- data$aes %>%
filter(
ae == 'Any AE' | !!sym(settings$aes$term_col) == ae
) %>%
mutate(
AESTDT = as.Date(ASTDT)
)

# Get first instance of adverse event for each participant.
first_ae <- aes %>%
left_join(
participants,
settings$dm$id_col
) %>%
filter(RFSTDT <= AESTDT) %>%
arrange(!!sym(settings$dm$id_col), AESTDT) %>%
group_by(!!sym(settings$dm$id_col)) %>%
filter(row_number() == 1) %>%
ungroup %>%
select(!!sym(settings$dm$id_col), AESTDT)

# Get list of participants without adverse event.
censored <- setdiff(
participants[[settings$dm$id_col]],
first_ae[[settings$dm$id_col]]
)

# Merge all participants with participants who experienced an event and define time to event.
tte <- participants %>%
left_join(
first_ae,
settings$dm$id_col
) %>%
mutate(
stdt = RFSTDT,
endt = coalesce(AESTDT, RFENDT),
time = (endt - stdt + 1) %>% as.numeric,
cnsr = (!!sym(settings$dm$id_col) %in% censored) %>% as.numeric,
event = !as.logical(cnsr) %>% as.numeric
)

# Define survival formula.
fit <- NULL
legend.labs <- NULL
if (stratum == 'None' | is.null(stratum))
fit = survfit(
Surv(time, event) ~ 1,
data = tte
)
else {
tte$stratum <- tte[[stratum]]
legend.labs = unique(tte$stratum)
fit = survfit(
Surv(time, event) ~ stratum,
data = tte
)
}

# Plot survival curve.
p <- ggsurvplot(
fit = fit,
data = tte,
title = paste('Time to', ae),
xlab = 'Study Day',
ylab = 'Survival probability',
risk.table = TRUE,
legend.labs = legend.labs
)

return(p)
}
6 changes: 5 additions & 1 deletion data-raw/makeMeta.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
library(tidyverse)
library(usethis)

# brackets after read_csv to remove spec_tbl_df class per https://www.tidyverse.org/blog/2018/12/readr-1-3-1/
# brackets after read_csv to remove spec_tbl_df class per https://www.tidyverse.org/blog/2018/12/readr-1-3-1/

#Copy metadata to /data
#ecg
Expand All @@ -24,3 +24,7 @@ usethis::use_data(meta_dm, overwrite = TRUE)
#hepExplorer
meta_hepExplorer<-read_csv("data-raw/meta_hepExplorer.csv")[]
usethis::use_data(meta_hepExplorer, overwrite = TRUE)

#time to AE
meta_timeToAE<-read_csv("data-raw/meta_timeToAE.csv")[]
usethis::use_data(meta_timeToAE, overwrite = TRUE)
15 changes: 15 additions & 0 deletions data-raw/meta_timeToAE.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
text_key,domain,col_key,field_key,type,label,description,multiple,standard_adam,standard_sdtm
id_col,dm,id_col,,column,ID column,Unique subject identifier,FALSE,USUBJID,USUBJID
treatment_col,dm,treatment_col,,column,Treatment column,Treatment group,FALSE,ARM,ARM
sex_col,dm,sex_col,,column,Sex column,Sex,FALSE,SEX,SEX
race_col,dm,race_col,,column,Race column,Race,FALSE,RACE,RACE
stdt_col,dm,stdt_col,,column,Study start date column,Study start date,FALSE,TRTSDT,RFSTDTC
endt_col,dm,endt_col,,column,Study end date column,Study end date,FALSE,TRTEDT,RFENDTC
id_col,aes,id_col,,column,ID column,Unique subject identifier,FALSE,USUBJID,USUBJID
seq_col,aes,seq_col,,column,Sequence column,Event sequence number,FALSE,ASEQ,AESEQ
stdt_col,aes,stdt_col,,column,AE start day column,Event start date,FALSE,ASTDT,AESTDT
endt_col,aes,endt_col,,column,AE end day column,Event end date,FALSE,AENDT,AEENDT
stdy_col,aes,stdy_col,,column,AE start day column,Event start day,FALSE,ASTDY,AESTDY
endy_col,aes,endy_col,,column,AE end day column,Event end day,FALSE,AENDY,AEENDY
term_col,aes,term_col,,column,Dictionary-derived term column,Dictionary-derived term,FALSE,AEDECOD,AEDECOD
bodsys_col,aes,bodsys_col,,column,Body system or organ class column,Body system or organ class,FALSE,AEBODSYS,AEBODSYS
Binary file added data/meta_timeToAE.rda
Binary file not shown.
12 changes: 12 additions & 0 deletions inst/config/mod_timeToAE.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
env: safetyGraphics
label: Time to Adverse Event - Module
type: module
package: safetyCharts
export: true
order: 2.2
domain:
- aes
- dm
workflow:
ui: timeToAE_ui
server: timeToAE_server
11 changes: 11 additions & 0 deletions inst/config/timeToAE.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
env: safetyGraphics
label: Time to Adverse Event
type: plot
package: safetyCharts
export: true
order: 2.1
domain:
- aes
- dm
workflow:
main: timeToAE
31 changes: 31 additions & 0 deletions man/meta_timeToAE.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/timeToAE.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.