insightsengineering / teal

Exploratory Web Apps for Analyzing Clinical Trial Data
https://insightsengineering.github.io/teal/
Other
184 stars 39 forks source link

cdisc_data/cdisc_dataset error when using vars at cdisc_dataset #267

Closed imazubi closed 3 years ago

imazubi commented 3 years ago

When testing efficacy app, the following error appears when I add vars argument in cdisc_dataset(dataname = "ADSL", x = ADSL, vars = list(char_vars_asl = char_vars_asl).

I am just using code in 'cdisc_data'. Error: 'code' argument should be specified only in the 'cdisc_data' or in 'cdisc_dataset' but not in both

App's code:

# Next two lines are for using NEST packages on BEE (r.roche.com)
source("https://raw.github.roche.com/NEST/nest_on_bee/master/bee_nest_utils.R")
bee_use_nest(release = "UAT_2021_09_29")

library(rtables)
library(teal.modules.general)
library(teal.modules.clinical)

## Log app usage
log_app_usage(ta = "Oncology", molecule = "Tecentriq", ind = "NSCLC", anl_type = "Exploratory")

# code>
## Generate Data
path <- "/opt/bee/analyses/stream2/master/2.11/stream2/doc/examples/molecule/project/efficacy/task01/outdata_vad/"
adsl_filename <- "adsl.sas7bdat"
adtte_filename <- "adtte.sas7bdat"
adrs_filename <- "adrs.sas7bdat"
adlb_filename <- "adlb.sas7bdat"

ADSL <- haven::read_sas(paste0(path, adsl_filename)) 
ADTTE <- haven::read_sas(paste0(path, adtte_filename)) 
ADRS <- haven::read_sas(paste0(path, adrs_filename)) 
ADLB <- haven::read_sas(paste0(path, adlb_filename)) 

adrs_labels <- rtables::var_labels(ADRS)
ADRS <- filter(ADRS, PARAMCD == "CBOR" & !(AVISITN == 999))
var_labels(ADRS) <- adrs_labels

adlb_labels <- rtables::var_labels(ADLB)
ADLB <- ADLB %>%
  distinct(STUDYID, USUBJID, PARAMCD, AVISIT, .keep_all = TRUE) %>% #if not mmrm gives an error saying there are duplicates for each visit
  filter(ABLFL != "Y") %>%
  filter(AVISIT %in% c("CYCLE 1 DAY 1", "CYCLE 1 DAY 8", "CYCLE 1 DAY 15")) %>%
  mutate(
    AVISIT = as.factor(AVISIT),
    AVISITN = rank(AVISITN) %>%
      as.factor() %>%
      as.numeric() %>%
      as.factor() 
  )
var_labels(ADLB) <- adlb_labels

ADSL <- df_explicit_na(ADSL)

# <code

## Reusable Configuration For Modules
arm_vars <- c("ARMCD", "ARM")
strata_vars <- c("RACE", "AGEGR1")
facet_vars <- c("AGEGR1", "SEX", "COUNTRY")
cov_vars <- c("SEX")
visit_vars <- c("AVISIT", "AVISITN")

cs_arm_var <- choices_selected(
  choices = variable_choices(ADSL, subset = arm_vars),
  selected = "ARM"
)

cs_strata_var <- choices_selected(
  choices = variable_choices(ADSL, subset = strata_vars),
  selected = "RACE"
)

cs_facet_var <- choices_selected(
  choices = variable_choices(ADSL, subset = facet_vars),
  selected = "AGEGR1"
)

cs_cov_var <- choices_selected(
  choices = variable_choices(ADSL, subset = cov_vars),
  selected = "SEX"
)

cs_paramcd_tte <- choices_selected(
  choices = value_choices(ADTTE, "PARAMCD", "PARAM"),
  selected = "OS"
)

cs_paramcd_rsp <- choices_selected(
  choices = value_choices(ADRS, "PARAMCD", "PARAM"),
  selected = "CBOR"
)

cs_paramcd_adlb <- choices_selected(
  choices = value_choices(ADLB, "PARAMCD", "PARAM"),
  selected = "ALBUMCV"
)

cs_visit_var_adlb <- choices_selected(
  choices = variable_choices(ADLB, subset = visit_vars),
  selected = "AVISIT"
)

# cs_formula_mmrm <- choices_selected(
#   choices = c('BASE + AVISITN + ARMCD + ARMCD*AVISITN + SEX',
#               'BASE + AVISIT + ARMCD + ARMCD*AVISIT + SEX',
#               'BASE + AVISIT + ARM + ARM*AVISIT + SEX'),
#   selected = 'BASE + AVISIT + ARM + ARM*AVISIT + SEX')

# fact_vars_asl <- names(Filter(isTRUE, sapply(ADSL, is.factor)))
# fact_vars_asl_orig <- fact_vars_asl[!fact_vars_asl %in% char_vars_asl]

fact_vars_asl <- names(Filter(isTRUE, sapply(ADSL, is.factor)))
char_vars_asl <- names(Filter(isTRUE, sapply(ADSL, is.character)))

date_vars_asl <- names(ADSL)[vapply(ADSL, function(x) inherits(x, c("Date", "POSIXct", "POSIXlt")), logical(1))]
demog_vars_asl <- names(ADSL)[!(names(ADSL) %in% c("USUBJID", "STUDYID", date_vars_asl))]

# reference & comparison arm selection when switching the arm variable
# ARMCD is given in a delayed fashion using value choices and
# ARM is given with the ref and comp levels supplied explicitly
arm_ref_comp <- list(
  ARMCD = list(ref = value_choices("ADSL", var_choices = "ARMCD", var_label = "ARM", subset = "A"), 
               comp = value_choices("ADSL", var_choices = "ARMCD", var_label = "ARM", subset = c("B", "C"))),
  ARM = list(ref = "ARM A", comp = c("ARM B", "ARM C"))
)

## Setup App
app <- init(
  data = cdisc_data(
    cdisc_dataset(dataname = "ADSL", x = ADSL, vars = list(char_vars_asl = char_vars_asl)),
    cdisc_dataset(dataname = "ADRS", x = ADRS, keys = c(get_cdisc_keys("ADRS"), "RSSEQ")),
    cdisc_dataset("ADTTE", ADTTE),
    cdisc_dataset(dataname = "ADLB", x = ADLB, keys = c(get_cdisc_keys("ADLB"), "LBSEQ")), 
    code = get_code("app.R",exclude_comments = TRUE, read_sources = TRUE), 
    check = TRUE
  ),
  modules = root_modules(
    module(
      label = "Study Information",
      server = function(input, output, session, datasets) {},
      ui = function(id, ...) {
        tagList(
          tags$p("Info about data source:"),
          tags$p(
            "Random data are used that has been created with the ",
            tags$code("random.cdisc.data"), "R package."
          )
        )
      },
      filters = "all"
    ),
    tm_data_table("Data Table"),
    tm_variable_browser("Variable Browser"),
    tm_t_summary(
      label = "Demographic Table",
      dataname = "ADSL",
      arm_var = cs_arm_var,
      summarize_vars = choices_selected(
        choices = variable_choices(ADSL, demog_vars_asl),
        selected = c("SEX", "AGE", "RACE")
      )
    ),
    modules(
      "Forest Plots",
      tm_g_forest_tte(
        label = "Survival Forest Plot",
        dataname = "ADTTE",
        arm_var = cs_arm_var,
        strata_var = cs_strata_var,
        subgroup_var = cs_facet_var,
        paramcd = cs_paramcd_tte,
        plot_height = c(800L, 200L, 4000L)
      ),
      tm_g_forest_rsp(
        label = "Response Forest Plot",
        dataname = "ADRS",
        arm_var = cs_arm_var,
        strata_var = cs_strata_var,
        subgroup_var = cs_facet_var,
        paramcd = cs_paramcd_rsp,
        plot_height = c(800L, 200L, 4000L)
      )
    ),
    tm_g_km(
      label = "Kaplan Meier Plot",
      dataname = "ADTTE",
      arm_var = cs_arm_var,
      arm_ref_comp = arm_ref_comp,
      paramcd = cs_paramcd_tte,
      facet_var = cs_facet_var,
      strata_var = cs_strata_var,
      plot_height = c(1800L, 200L, 4000L)
    ),
    tm_t_rsp(
      label = "Response Table",
      dataname = "ADRS",
      arm_var = cs_arm_var,
      arm_ref_comp = arm_ref_comp,
      paramcd = cs_paramcd_rsp,
      strata_var = cs_strata_var
    ),
    tm_t_tte(
      label = "Time To Event Table",
      dataname = "ADTTE",
      arm_var = cs_arm_var,
      paramcd = cs_paramcd_tte,
      strata_var = cs_strata_var,
      time_points = choices_selected(c(182, 365, 547), 182),
      event_desc_var = choices_selected(
        choices = variable_choices("ADTTE", "EVNTDESC"), 
        selected = "EVNTDESC", 
        fixed = TRUE
      )
    ),
    tm_t_crosstable(
      "Cross Table",
      x = data_extract_spec(
        dataname = "ADSL",
        select = select_spec(
          choices = variable_choices(ADSL, fact_vars_asl),
          selected = fact_vars_asl[fact_vars_asl == "RACE"]
        )
      ),
      y = data_extract_spec(
        dataname = "ADSL",
        select = select_spec(
          choices = variable_choices(ADSL, fact_vars_asl),
          selected = fact_vars_asl[fact_vars_asl == "ETHNIC"]
        )
      )
    ),
    tm_t_coxreg(
      label = "Cox Reg",
      dataname = "ADTTE",
      arm_var = cs_arm_var,
      arm_ref_comp = arm_ref_comp,
      paramcd = cs_paramcd_tte,
      strata_var = cs_strata_var,
      cov_var = cs_cov_var
    ),
    tm_t_logistic(
      label = "Logistic Reg",
      dataname = "ADRS",
      arm_var = cs_arm_var,
      arm_ref_comp = NULL,
      paramcd = cs_paramcd_rsp,
      cov_var = cs_cov_var
    ),
    tm_a_mmrm(
      label = "MMRM",
      dataname = "ADLB",
      aval_var = choices_selected(c("AVAL", "CHG"), "AVAL"),
      id_var = choices_selected(c("USUBJID", "SUBJID"), "USUBJID"),
      arm_var = cs_arm_var,
      visit_var = cs_visit_var_adlb,
      arm_ref_comp = arm_ref_comp,
      paramcd = cs_paramcd_adlb,
      cov_var = choices_selected(c("BASE", "SEX", "BASE*AVISIT", "ARM:SEX"), NULL),
      conf_level = choices_selected(c(0.95, 0.9, 0.8), 0.95)
    ),
    tm_t_binary_outcome(
      label = "Binary Response",
      dataname = "ADRS",
      arm_var = cs_arm_var,
      paramcd = cs_paramcd_rsp,
      strata_var = cs_strata_var
    ),
    tm_t_ancova(
      label = "ANCOVA",
      dataname = "ADLB",
      avisit = choices_selected(value_choices(ADLB, "AVISIT"), "CYCLE 1 DAY 1"),
      arm_var = cs_arm_var,
      arm_ref_comp = arm_ref_comp,
      aval_var = choices_selected(variable_choices(ADLB, c("AVAL", "CHG", "PCHG")), "CHG"),
      cov_var = choices_selected(variable_choices(ADLB, c("BASE", "SEX")), "BASE"),
      paramcd = cs_paramcd_adlb
    )
  ),
  header = div(
    class = "",
    style = "margin-bottom: 2px;",
    tags$h1("Example App with teal.modules.clinical modules", tags$span("SPA", class = "pull-right"))
  ),
  footer = tags$p(class = "text-muted", "Source: agile-R website")
)

shinyApp(app$ui, app$server)
pawelru commented 3 years ago

I looked into your code and error message is correct -> you cannot submit code on both dataset and data level because then it's impossible to specify which one should go first while creating final output to ShowRCode. Note that specifying vars arguments is nothing more that adding some code upfront.

> dataset("iris", iris, code = "iris", vars = list(x = 1))$get_code() %>% cat()
x <- 1
iris

Combining above with the code on data level (code = get_code("app.R",exclude_comments = TRUE, read_sources = TRUE)) we have such situation and here comes the error message.

To me all is good here.

imazubi commented 3 years ago

@pawelru but where I am introducing code at cdisc_dataset level? So I am not allowed to use vars argument either?

pawelru commented 3 years ago

Basically vars are being translated into the code so yes you are indirectly providing a code. Actually I don't see the need to use this arg if you are providing an overall code. Can you came up with some meaningful minimal example when it would be needed?

imazubi commented 3 years ago

@pawelru this is what I am obtaining with tm_variable_browser if I do not pass the character variable names with var argument. image

pawelru commented 3 years ago

above looks like this is a separate issue already reported and being worked on -> https://github.com/insightsengineering/coredev-tasks/issues/359

Can you please fix the dates column and check again?

pawelru commented 3 years ago

The tmg issue has been resolved. Can you please check now if you still have the error?

imazubi commented 3 years ago

Sorry for this late reply @pawelru. I will try in tomorrow's UAT release efficacy app as the correction should be available there then.

imazubi commented 3 years ago

@pawelru it is working properly now under UAT_2021_10_06.

pawelru commented 3 years ago

ok closing this then