diff --git a/ClinicoPathDescriptives b/ClinicoPathDescriptives
index acb9ced5..db8c8d0c 160000
--- a/ClinicoPathDescriptives
+++ b/ClinicoPathDescriptives
@@ -1 +1 @@
-Subproject commit acb9ced54614cf4944a00dcb9bb7c932ad1794fb
+Subproject commit db8c8d0c85da37c53a77e0a70f54256e8be4d10b
diff --git a/ClinicoPathLinuxDescriptives b/ClinicoPathLinuxDescriptives
index 3ade1ada..97a17c5e 160000
--- a/ClinicoPathLinuxDescriptives
+++ b/ClinicoPathLinuxDescriptives
@@ -1 +1 @@
-Subproject commit 3ade1ada7272ce475ca3aa4f772bf20c0ba1baa2
+Subproject commit 97a17c5ec6f030b186a7c271c7dcb7585649e9d6
diff --git a/DESCRIPTION b/DESCRIPTION
index 4a77b247..f9acb6e7 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -70,8 +70,6 @@ Imports:
gtExtras,
labelled,
PMCMRplus
-Remotes:
- nbarrowman/vtree@ffa53d4ea5050fa9b26918f4bb30595e91a0f489
VignetteBuilder:
knitr
Encoding: UTF-8
diff --git a/R/multisurvival.b.R b/R/multisurvival.b.R
index d602f418..bdb1c63a 100644
--- a/R/multisurvival.b.R
+++ b/R/multisurvival.b.R
@@ -9,205 +9,155 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
inherit = multisurvivalBase,
private = list(
- # .todo = function() {
- # # If no variable selected Initial Message ----
- #
- # if (
- #
- # (is.null(self$options$outcome) && !(self$options$multievent)) ||
- #
- # (self$options$multievent && (is.null(self$options$dod) && is.null(self$options$dooc) && is.null(self$options$awd) && is.null(self$options$awod))) ||
- #
- # (is.null(self$options$elapsedtime) && !(self$options$tint)) ||
- #
- # (self$options$tint && (is.null(self$options$dxdate) || is.null(self$options$fudate))) ||
- #
- # is.null(self$options$explanatory)
- #
- # # ||
- #
- # # (!is.null(self$options$explanatory) && is.null(self$options$contexpl))
- #
- #
- # )
- # {
- # # TODO ----
- #
- # todo <- glue::glue(
- # "
- #
Welcome to ClinicoPath
- #
- # This tool will help you perform a multivariable survival analysis.
- #
- # Explanatory variables can be categorical (ordinal or nominal) or continuous.
- #
- # Select outcome level from Outcome variable.
- #
- # Outcome Level: if patient is dead or event (recurrence) occured. You may also use advanced outcome options depending on your analysis type.
- #
- # Survival time should be numeric, continuous, and in months. You may also use dates to calculate survival time in advanced elapsed time options.
- #
- # This function uses finalfit, survival, survminer and ggstatsplot packages. Please cite jamovi and the packages as given below.
- #
- # "
- # )
- # # https://finalfit.org/articles/all_tables_examples.html#cox-proportional-hazards-model-survival-time-to-event
- #
- #
- # html <- self$results$todo
- # html$setContent(todo)
- # # return()
- #
- # } else {
- # if (nrow(self$data) == 0)
- # stop('Data contains no (complete) rows')
- # }
- #
- # }
- # ,
-
-
- .cleandata = function() {
- # Common Definitions ----
- contin <- c("integer", "numeric", "double")
+ # init ----
+ .init = function() {
- # Read Data ----
+ }
+ # getData ----
+ ,
+ .getData = function() {
mydata <- self$data
- # Read Arguments ----
+ mydata$row_names <- rownames(mydata)
- elapsedtime <- self$options$elapsedtime
- outcome <- self$options$outcome
- explanatory <- self$options$explanatory
- contexpl <- self$options$contexpl
- outcomeLevel <- self$options$outcomeLevel
- tint <- self$options$tint
+ original_names <- names(mydata)
- # Define Outcome ----
+ labels <- setNames(original_names, original_names)
- multievent <- self$options$multievent
+ mydata <- mydata %>% janitor::clean_names()
- outcome1 <- self$options$outcome
- outcome1 <- self$data[[outcome1]]
+ corrected_labels <-
+ setNames(original_names, names(mydata))
+ mydata <- labelled::set_variable_labels(
+ .data = mydata,
+ .labels = corrected_labels
+ )
- if (!multievent) {
- if (inherits(outcome1, contin)) {
- if (!((length(unique(
- outcome1[!is.na(outcome1)]
- )) == 2) && (sum(unique(
- outcome1[!is.na(outcome1)]
- )) == 1))) {
- stop(
- 'When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0.'
- )
-
- }
-
- mydata[["myoutcome"]] <-
- mydata[[self$options$outcome]]
-
+ all_labels <- labelled::var_label(mydata)
- } else if (inherits(outcome1, "factor")) {
- # mydata[[self$options$outcome]] <-
- # ifelse(test = outcome1 == outcomeLevel,
- # yes = 1,
- # no = 0)
+ mytime <-
+ names(all_labels)[all_labels == self$options$elapsedtime]
+ myoutcome <-
+ names(all_labels)[all_labels == self$options$outcome]
- mydata[["myoutcome"]] <-
- ifelse(
- test = outcome1 == outcomeLevel,
- yes = 1,
- no = 0
- )
+ mydxdate <-
+ names(all_labels)[all_labels == self$options$dxdate]
+ myfudate <-
+ names(all_labels)[all_labels == self$options$fudate]
- } else {
- stop(
- 'When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0. If you are using a factor as an outcome, please check the levels and content.'
- )
+ labels_explanatory <- self$options$explanatory
- }
-
- } else if (multievent) {
- analysistype <- self$options$analysistype
+ myexplanatory <-
+ names(all_labels)[match(labels_explanatory,
+ all_labels)]
- dod <- self$options$dod
- dooc <- self$options$dooc
- awd <- self$options$awd
- awod <- self$options$awod
-
-
-
- if (analysistype == 'overall') {
- # (Alive) <=> (Dead of Disease & Dead of Other Causes)
-
-
- mydata[["myoutcome"]] <- NA_integer_
-
- mydata[["myoutcome"]][outcome1 == awd] <- 0
- mydata[["myoutcome"]][outcome1 == awod] <- 0
- mydata[["myoutcome"]][outcome1 == dod] <- 1
- mydata[["myoutcome"]][outcome1 == dooc] <- 1
+ labels_contexpl <- self$options$contexpl
+ mycontexpl <-
+ names(all_labels)[match(labels_contexpl,
+ all_labels)]
+ return(list(
+ "mydata_labelled" = mydata,
+ "mytime_labelled" = mytime,
+ "myoutcome_labelled" = myoutcome,
+ "mydxdate_labelled" = mydxdate,
+ "myfudate_labelled" = myfudate,
+ "mycontexpl_labelled" = mycontexpl,
+ "myexplanatory_labelled" = myexplanatory
+ ))
+ }
- } else if (analysistype == 'cause') {
- # (Alive & Dead of Other Causes) <=> (Dead of Disease)
+ # todo ----
+ ,
+ .todo = function() {
+ # todo ----
+
+ todo <- glue::glue(
+ "
+
Welcome to ClinicoPath
+
+ This tool will help you perform a multivariable survival analysis.
+
+ Explanatory variables can be categorical (ordinal or nominal) or continuous.
+
+ Select outcome level from Outcome variable.
+
+ Outcome Level: if patient is dead or event (recurrence) occured. You may also use advanced outcome options depending on your analysis type.
+
+ Survival time should be numeric, continuous, and in months. You may also use dates to calculate survival time in advanced elapsed time options.
+
+ This function uses finalfit, survival, survminer and ggstatsplot packages. Please cite jamovi and the packages as given below.
+
+ "
+ )
+ # https://finalfit.org/articles/all_tables_examples.html#cox-proportional-hazards-model-survival-time-to-event
- mydata[["myoutcome"]] <- NA_integer_
+ html <- self$results$todo
+ html$setContent(todo)
+ return()
- mydata[["myoutcome"]][outcome1 == awd] <- 0
- mydata[["myoutcome"]][outcome1 == awod] <- 0
- mydata[["myoutcome"]][outcome1 == dod] <- 1
- mydata[["myoutcome"]][outcome1 == dooc] <- 0
+ }
- } else if (analysistype == 'compete') {
- # Alive <=> Dead of Disease accounting for Dead of Other Causes
- mydata[["myoutcome"]] <- NA_integer_
- mydata[["myoutcome"]][outcome1 == awd] <- 0
- mydata[["myoutcome"]][outcome1 == awod] <- 0
- mydata[["myoutcome"]][outcome1 == dod] <- 1
- mydata[["myoutcome"]][outcome1 == dooc] <- 2
+ # Define Survival Time ----
+ ,
+ .definemytime = function() {
- }
+ ## Read Labelled Data ----
- }
+ labelled_data <- private$.getData()
+ mydata <- labelled_data$mydata_labelled
+ mytime_labelled <- labelled_data$mytime_labelled
+ mydxdate_labelled <- labelled_data$mydxdate_labelled
+ myfudate_labelled <- labelled_data$myfudate_labelled
- # Define Survival Time ----
+ tint <- self$options$tint
if (!tint) {
- ## Use precalculated time ----
-
- mydata[[self$options$elapsedtime]] <-
- jmvcore::toNumeric(mydata[[self$options$elapsedtime]])
+ ### Precalculated Time ----
mydata[["mytime"]] <-
- jmvcore::toNumeric(mydata[[self$options$elapsedtime]])
+ jmvcore::toNumeric(mydata[[mytime_labelled]])
} else if (tint) {
- ## Calculate Time Interval ----
+ ### Time Interval ----
- dxdate <- self$options$dxdate
- fudate <- self$options$fudate
+ dxdate <- mydxdate_labelled
+ fudate <- myfudate_labelled
timetypedata <- self$options$timetypedata
- # stopifnot(inherits(mydata[[dxdate]], c("POSIXct", "POSIXt", "POSIXlt")))
- # stopifnot(inherits(mydata[[fudate]], c("POSIXct", "POSIXt", "POSIXlt")))
+ # # Define a mapping from timetypedata to lubridate functions
+ # lubridate_functions <- list(
+ # ymdhms = lubridate::ymd_hms,
+ # ymd = lubridate::ymd,
+ # ydm = lubridate::ydm,
+ # mdy = lubridate::mdy,
+ # myd = lubridate::myd,
+ # dmy = lubridate::dmy,
+ # dym = lubridate::dym
+ # )
+ # # Apply the appropriate lubridate function based on timetypedata
+ # if (timetypedata %in% names(lubridate_functions)) {
+ # func <- lubridate_functions[[timetypedata]]
+ # mydata[["start"]] <- func(mydata[[dxdate]])
+ # mydata[["end"]] <- func(mydata[[fudate]])
+ # }
if (timetypedata == "ymdhms") {
@@ -247,6 +197,7 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
}
+
timetypeoutput <-
jmvcore::constructFormula(terms = self$options$timetypeoutput)
@@ -257,240 +208,479 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
stopifnot(lubridate::is.interval(mydata[["interval"]]))
mydata <- mydata %>%
- dplyr::mutate(mytime = lubridate::time_length(interval, timetypeoutput))
+ dplyr::mutate(mytime = lubridate::time_length(interval,
+ timetypeoutput))
+
}
+ df_time <- mydata %>% jmvcore::select(c("row_names", "mytime"))
+ return(df_time)
- # Define Explanatory ----
- myexplanatory <- NULL
+ }
- if(!is.null(self$options$explanatory)) {
+ # Define Outcome ----
+ ,
+ .definemyoutcome = function() {
- myexplanatory <- as.vector(self$options$explanatory)
- }
+ labelled_data <- private$.getData()
+ mydata <- labelled_data$mydata_labelled
+ myoutcome_labelled <- labelled_data$myoutcome_labelled
- mycontexpl <- NULL
- if(!is.null(self$options$contexpl)) {
+ contin <- c("integer", "numeric", "double")
- mycontexpl <- as.vector(self$options$contexpl)
+ outcomeLevel <- self$options$outcomeLevel
+ multievent <- self$options$multievent
- }
+ outcome1 <- mydata[[myoutcome_labelled]]
+ if (!multievent) {
+ if (inherits(outcome1, contin)) {
+ if (!((length(unique(
+ outcome1[!is.na(outcome1)]
+ )) == 2) && (sum(unique(
+ outcome1[!is.na(outcome1)]
+ )) == 1))) {
+ stop(
+ 'When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0.'
+ )
- myfactors <- c(myexplanatory, mycontexpl)
+ }
+ mydata[["myoutcome"]] <- mydata[[myoutcome_labelled]]
+ # mydata[[self$options$outcome]]
- self$results$mydataview$setContent(
- list(
- head(mydata, n = 10),
- myexplanatory = myexplanatory,
- mycontexpl = mycontexpl,
- myfactors = myfactors
- )
- )
+ } else if (inherits(outcome1, "factor")) {
+ mydata[["myoutcome"]] <-
+ ifelse(
+ test = outcome1 == outcomeLevel,
+ yes = 1,
+ no = 0
+ )
+ } else {
+ stop(
+ 'When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0. If you are using a factor as an outcome, please check the levels and content.'
+ )
- # Add Redefined Outcome to Data ----
+ }
- # if (self$options$multievent) {
- #
- # if (self$options$outcomeredifened &&
- # self$results$outcomeredifened$isNotFilled()) {
- # self$results$outcomeredifened$setValues(mydata[["myoutcome"]])
- # }
- # }
+ } else if (multievent) {
+ analysistype <- self$options$analysistype
- # Add Calculated Time to Data ----
+ dod <- self$options$dod
+ dooc <- self$options$dooc
+ awd <- self$options$awd
+ awod <- self$options$awod
- # if (self$options$tint) {
- #
- # if (self$options$calculatedtime &&
- # self$results$calculatedtime$isNotFilled()) {
- # self$results$calculatedtime$setValues(mydata[["mytime"]])
- # }
- # }
+ if (analysistype == 'overall') {
+ # Overall ----
+ # (Alive) <=> (Dead of Disease & Dead of Other Causes)
+
+
+ mydata[["myoutcome"]] <- NA_integer_
+
+ mydata[["myoutcome"]][outcome1 == awd] <- 0
+ mydata[["myoutcome"]][outcome1 == awod] <- 0
+ mydata[["myoutcome"]][outcome1 == dod] <- 1
+ mydata[["myoutcome"]][outcome1 == dooc] <- 1
+ } else if (analysistype == 'cause') {
+ # Cause Specific ----
+ # (Alive & Dead of Other Causes) <=> (Dead of Disease)
- # Landmark ----
- # https://www.emilyzabor.com/tutorials/survival_analysis_in_r_tutorial.html#landmark_method
- if (self$options$uselandmark) {
- landmark <- jmvcore::toNumeric(self$options$landmark)
+ mydata[["myoutcome"]] <- NA_integer_
+
+ mydata[["myoutcome"]][outcome1 == awd] <- 0
+ mydata[["myoutcome"]][outcome1 == awod] <- 0
+ mydata[["myoutcome"]][outcome1 == dod] <- 1
+ mydata[["myoutcome"]][outcome1 == dooc] <- 0
+
+ } else if (analysistype == 'compete') {
+ # Competing Risks ----
+ # Alive <=> Dead of Disease accounting for Dead of Other Causes
+
+ # https://www.emilyzabor.com/tutorials/survival_analysis_in_r_tutorial.html#part_3:_competing_risks
+
+
+ mydata[["myoutcome"]] <- NA_integer_
+
+ mydata[["myoutcome"]][outcome1 == awd] <- 0
+ mydata[["myoutcome"]][outcome1 == awod] <- 0
+ mydata[["myoutcome"]][outcome1 == dod] <- 1
+ mydata[["myoutcome"]][outcome1 == dooc] <- 2
+
+ }
- mydata <- mydata %>%
- dplyr::filter(mytime >= landmark) %>%
- dplyr::mutate(mytime = mytime - landmark)
}
+ df_outcome <- mydata %>% jmvcore::select(c("row_names", "myoutcome"))
+ return(df_outcome)
+
+ }
+ # Define Factor ----
+ ,
+ .definemyfactor = function() {
+ labelled_data <- private$.getData()
+ mydata_labelled <- labelled_data$mydata_labelled
+ myexplanatory_labelled <- labelled_data$myexplanatory_labelled
+ mycontexpl_labelled <- labelled_data$mycontexpl_labelled
- # Define Data For Analysis ----
+ mydata <- mydata_labelled
- mydata <- jmvcore::select(df = mydata, columnNames = c("mytime", "myoutcome", myfactors))
+ df_factor <- mydata %>%
+ jmvcore::select(c("row_names",
+ myexplanatory_labelled,
+ mycontexpl_labelled
+ )
+ )
# self$results$mydataview$setContent(
# list(
- # head(mydata, n = 30)
+ # df_factor = head(df_factor),
+ # myexplanatory_labelled = myexplanatory_labelled,
+ # mycontexpl_labelled = mycontexpl_labelled,
+ # mydata = head(mydata)
# )
# )
+ return(df_factor)
- # naOmit ----
+ }
- mydata <- jmvcore::naOmit(mydata)
+ # Clean Data ----
+ ,
+ .cleandata = function() {
+ ## Common Definitions ----
+
+ contin <- c("integer", "numeric", "double")
+ ## Read Data ----
- # Send cleaned mydata to other functions ----
+ labelled_data <- private$.getData()
+ mydata_labelled <- labelled_data$mydata_labelled
+ mytime_labelled <- labelled_data$mytime_labelled
+ myoutcome_labelled <- labelled_data$myoutcome_labelled
+ mydxdate_labelled <- labelled_data$mydxdate_labelled
+ myfudate_labelled <- labelled_data$myfudate_labelled
+ myexplanatory_labelled <- labelled_data$myexplanatory_labelled
+ mycontexpl_labelled <- labelled_data$mycontexpl_labelled
- return(list("mydata" = mydata))
+ time <- private$.definemytime()
+ outcome <- private$.definemyoutcome()
+ factor <- private$.definemyfactor()
+ ## Clean Data ----
+ cleanData <- dplyr::left_join(time, outcome, by = "row_names") %>%
+ dplyr::left_join(factor, by = "row_names")
+
+ ## Landmark ----
+
+ # https://www.emilyzabor.com/tutorials/survival_analysis_in_r_tutorial.html#landmark_method
+
+ if (self$options$uselandmark) {
+
+ landmark <- jmvcore::toNumeric(self$options$landmark)
+
+ cleanData <- cleanData %>%
+ dplyr::filter(mytime >= landmark) %>%
+ dplyr::mutate(mytime = mytime - landmark)
+ }
+
+ ## Names cleanData ----
+
+ if (self$options$tint) {
+ name1time <- "CalculatedTime"
+ }
+
+ if (!self$options$tint &&
+ !is.null(self$options$elapsedtime)) {
+ name1time <- mytime_labelled
+ }
+
+ name2outcome <- myoutcome_labelled
+
+ if (self$options$tint) {
+ name2outcome <- "CalculatedOutcome"
+ }
+
+ if (!is.null(self$options$explanatory)
+ ) {
+ name3expl <- myexplanatory_labelled
+ }
+
+
+ if (!is.null(self$options$contexpl)
+ ) {
+ name3contexpl <- mycontexpl_labelled
+ }
+
+
+ # cleanData <- cleanData %>%
+ # dplyr::rename(
+ # !!name1time := mytime,
+ # !!name2outcome := myoutcome,
+ # !!name3contexpl := myfactor
+ # )
+
+ # naOmit ----
+
+ cleanData <- jmvcore::naOmit(cleanData)
+
+ # Return Data ----
+
+ return(
+ list(
+ "name1time" = name1time,
+ "name2outcome" = name2outcome,
+ "name3contexpl" = name3contexpl,
+ "name3expl" = name3expl,
+ "cleanData" = cleanData,
+ "mytime_labelled" = mytime_labelled,
+ "myoutcome_labelled" = myoutcome_labelled,
+ "mydxdate_labelled" = mydxdate_labelled,
+ "myfudate_labelled" = myfudate_labelled,
+ "myexplanatory_labelled" = myexplanatory_labelled,
+ "mycontexpl_labelled" = mycontexpl_labelled
+ )
+ )
+
+
+ # self$results$mydataview$setContent(
+ # list(
+ # # labelled_data = head(labelled_data),
+ # # time = head(time),
+ # # outcome = head(outcome),
+ # # factor = head(factor),
+ # mydata_labelled = head(mydata_labelled),
+ # mytime_labelled = mytime_labelled,
+ # myoutcome_labelled = myoutcome_labelled,
+ # mydxdate_labelled = mydxdate_labelled,
+ # myfudate_labelled = myfudate_labelled,
+ # myexplanatory_labelled = myexplanatory_labelled,
+ # mycontexpl_labelled = mycontexpl_labelled,
+ # # cleanData = head(cleanData),
+ # name1time = name1time,
+ # name2outcome = name2outcome,
+ # name3expl = name3expl,
+ # name3contexpl = name3contexpl
+ # )
+ # )
}
+
+ # run ----
,
.run = function() {
+ # Errors, Warnings ----
+ ## No variable todo ----
- # Errors ----
- # if (
- #
- # (is.null(self$options$outcome) && !(self$options$multievent)) ||
- #
- # (self$options$multievent && (is.null(self$options$dod) && is.null(self$options$dooc) && is.null(self$options$awd) && is.null(self$options$awod))) ||
- #
- # (self$options$tint && (is.null(self$options$dxdate) || is.null(self$options$fudate))) ||
- #
- # is.null(self$options$explanatory)
- #
- # #
- # #
- # # (!is.null(self$options$explanatory) && is.null(self$options$contexpl))
- #
- # ) {
- # private$.todo()
- # # return()
- # }
+ ## Define subconditions ----
+
+ subcondition1a <- !is.null(self$options$outcome)
+ subcondition1b1 <- !is.null(self$options$multievent)
+ subcondition1b2 <- !is.null(self$options$dod)
+ subcondition1b3 <- !is.null(self$options$dooc)
+ subcondition1b4 <- !is.null(self$options$awd)
+ subcondition1b5 <- !is.null(self$options$awod)
+ subcondition2a <- !is.null(self$options$elapsedtime)
+ subcondition2b1 <- !is.null(self$options$tint)
+ subcondition2b2 <- !is.null(self$options$dxdate)
+ subcondition2b3 <- !is.null(self$options$fudate)
+ condition3a <- !is.null(self$options$contexpl)
+ condition3b <- !is.null(self$options$explanatory)
+
+ condition1 <- subcondition1a || (subcondition1b1 && (subcondition1b2 || subcondition1b3 || subcondition1b4 || subcondition1b5))
+
+ condition2 <- subcondition2a || (subcondition2b1 && subcondition2b2 && subcondition2b3)
+
+ condition3 <- condition3a || condition3b
+
+ not_continue_analysis <- !(condition1 && condition2 && condition3)
+
+
+ if (not_continue_analysis) {
+ private$.todo()
+ self$results$text$setVisible(FALSE)
+ self$results$text2$setVisible(FALSE)
+ self$results$plot$setVisible(FALSE)
+ self$results$plot3$setVisible(FALSE)
+ self$results$todo$setVisible(TRUE)
+ return()
+ } else {
+ self$results$todo$setVisible(FALSE)
+ }
+
+
+ ## Stop if Empty Data ----
if (nrow(self$data) == 0)
stop('Data contains no (complete) rows')
- # Calculate mydata ----
+ ## mydata ----
cleaneddata <- private$.cleandata()
- mydata <- cleaneddata$mydata
+ name1time <- cleaneddata$name1time
+ name2outcome <- cleaneddata$name2outcome
+ name3contexpl <- cleaneddata$name3contexpl
+ name3expl <- cleaneddata$name3expl
+ mydata <- cleanData <- cleaneddata$cleanData
+ mytime_labelled <- cleaneddata$mytime_labelled
+ myoutcome_labelled <- cleaneddata$myoutcome_labelled
+ mydxdate_labelled <- cleaneddata$mydxdate_labelled
+ myfudate_labelled <- cleaneddata$myfudate_labelled
+ myexplanatory_labelled <- cleaneddata$myexplanatory_labelled
+ mycontexpl_labelled <- cleaneddata$mycontexpl_labelled
+ # Cox ----
+ private$.cox()
- # Cox ----
- private$.cox(mydata)
+ # Prepare Data For Plots ----
+
+ image <- self$results$plot
+ image$setState(cleaneddata)
+
+ image3 <- self$results$plot3
+ image3$setState(cleaneddata)
+
+
+ # image4 <- self$results$plot4
+ # image4$setState(mydata)
+
+ # imageKM <- self$results$plotKM
+ # imageKM$setState(mydata)
+
+ # image7 <- self$results$plot7
+ # image7$setState(mydata)
# View mydata ----
# self$results$mydataview$setContent(
- # list(head(mydata, n = 30))
+ # list(
+ # head(cleanData)
+ # )
# )
+ # Add Calculated Time to Data ----
+
+ if (self$options$tint && self$options$calculatedtime && self$results$calculatedtime$isNotFilled()) {
+ self$results$calculatedtime$setRowNums(cleanData$row_names)
+ self$results$calculatedtime$setValues(cleanData$mytime)
+ }
- # Prepare Data For Plots ----
- image <- self$results$plot
- image$setState(mydata)
- image3 <- self$results$plot3
- image3$setState(mydata)
+ # Add Redefined Outcome to Data ----
+
+ if (self$options$multievent && self$options$outcomeredifened && self$results$outcomeredifened$isNotFilled()) {
+ self$results$outcomeredifened$setRowNums(cleanData$row_names)
+ self$results$outcomeredifened$setValues(cleanData$myoutcome)
+ }
- # image4 <- self$results$plot4
- # image4$setState(mydata)
- # imageKM <- self$results$plotKM
- # imageKM$setState(mydata)
- # image7 <- self$results$plot7
- # image7$setState(mydata)
+ }
+ # cox ----
+ ,
+ .cox = function() {
- },
+ cleaneddata <- private$.cleandata()
+ name1time <- cleaneddata$name1time
+ name2outcome <- cleaneddata$name2outcome
- .cox = function(mydata) {
+ name3contexpl <- cleaneddata$name3contexpl
+ name3expl <- cleaneddata$name3expl
+ mydata <- cleanData <- cleaneddata$cleanData
- # prepare formula ----
+ mytime_labelled <- cleaneddata$mytime_labelled
+ myoutcome_labelled <- cleaneddata$myoutcome_labelled
+ mydxdate_labelled <- cleaneddata$mydxdate_labelled
+ myfudate_labelled <- cleaneddata$myfudate_labelled
+ myexplanatory_labelled <- cleaneddata$myexplanatory_labelled
+ mycontexpl_labelled <- cleaneddata$mycontexpl_labelled
- myexplanatory <- NULL
+ ### prepare formula ----
- if(!is.null(self$options$explanatory)) {
- myexplanatory <- as.vector(self$options$explanatory)
+ myexplanatory <- NULL
+ if(!is.null(self$options$explanatory)) {
+ myexplanatory <- as.vector(myexplanatory_labelled)
}
mycontexpl <- NULL
-
if(!is.null(self$options$contexpl)) {
- mycontexpl <- as.vector(self$options$contexpl)
+ mycontexpl <- as.vector(mycontexpl_labelled)
}
formula2 <- c(myexplanatory, mycontexpl)
- # formula2 <-c(as.vector(self$options$explanatory),
- # as.vector(self$options$contexpl)
- # )
- # formulaL <-
- # jmvcore::constructFormula(terms = self$options$elapsedtime)
- #
- # formulaL <- jmvcore::toNumeric(formulaL)
- #
- # formulaL <-
- # jmvcore::constructFormula(terms = self$options$elapsedtime)
+ myformula <-
+ paste("Surv( mytime, myoutcome ) ~ ",
+ paste(formula2, collapse = " + ")
+ )
- # formulaR <- jmvcore::constructFormula(terms = self$options$outcome)
+ myformula <- as.formula(myformula)
- # formulaR <- jmvcore::toNumeric(formulaR)
+ # self$results$mydataview$setContent(
+ # list(
+ # mydata = head(mydata, n = 30),
+ # myformula = myformula,
+ # myexplanatory = myexplanatory,
+ # mycontexpl = mycontexpl,
+ # formula2 = formula2
+ # )
+ # )
- myformula <-
- paste("Surv(mytime, myoutcome)")
- # finalfit Multivariable table ----
+ ## finalfit Multivariable table ----
finalfit::finalfit(
.data = mydata,
- dependent = myformula,
- explanatory = formula2,
+ formula = myformula,
+ # dependent = myformula,
+ # explanatory = formula2,
metrics = TRUE
) -> tMultivariable
@@ -533,7 +723,7 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
self$results$text$setContent(results1)
- # Cox2 ----
+ ## coxph ----
LHT <- "survival::Surv(mytime, myoutcome)"
@@ -693,19 +883,53 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
,
.plot = function(image, ggtheme, theme, ...) {
+ if (!self$options$hr) {
+ return()
+ }
+
+ if (!(self$options$sty == "t1")) {
+ return()
+ }
plotData <- image$state
- # prepare formula ----
+ if (is.null(plotData)) {
+ return()
+ }
+
+ name1time <- plotData$name1time
+ name2outcome <- plotData$name2outcome
+ name3contexpl <- plotData$name3contexpl
+ name3expl <- plotData$name3expl
- formula2 <-
- jmvcore::constructFormula(terms = c(self$options$explanatory, self$options$contexpl))
+ mydata <- cleanData <- plotData$cleanData
- # formula2 <- as.vector(self$options$explanatory)
+ mytime_labelled <- plotData$mytime_labelled
+ myoutcome_labelled <- plotData$myoutcome_labelled
+ mydxdate_labelled <- plotData$mydxdate_labelled
+ myfudate_labelled <- plotData$myfudate_labelled
+ myexplanatory_labelled <- plotData$myexplanatory_labelled
+ mycontexpl_labelled <- plotData$mycontexpl_labelled
+ ### prepare formula ----
+
+ myexplanatory <- NULL
+ if(!is.null(self$options$explanatory)) {
+ myexplanatory <- as.vector(myexplanatory_labelled)
+ }
+
+ mycontexpl <- NULL
+ if(!is.null(self$options$contexpl)) {
+ mycontexpl <- as.vector(mycontexpl_labelled)
+ }
+
+ formula2 <- c(myexplanatory, mycontexpl)
+
myformula <-
- paste("survival::Surv(mytime, myoutcome)")
+ paste0('Surv( mytime, myoutcome )')
+
+ # myformula <- as.formula(myformula)
# hr_plot ----
@@ -713,7 +937,7 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
plot <-
finalfit::hr_plot(
- .data = plotData,
+ .data = mydata,
dependent = myformula,
explanatory = formula2,
dependent_label = "Survival",
@@ -721,8 +945,9 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
title_text_size = 14,
plot_opts = list(
ggplot2::xlab("HR, 95% CI"),
- ggplot2::theme(axis.title =
- ggplot2::element_text(size = 12))
+ ggplot2::theme(
+ axis.title =
+ ggplot2::element_text(size = 12))
)
)
@@ -802,20 +1027,72 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
,
.plot3 = function(image3, ggtheme, theme, ...) {
+ if (!self$options$hr) {
+ return()
+ }
+
+ if (!(self$options$sty == "t3")) {
+ return()
+ }
+
plotData <- image3$state
+ if (is.null(plotData)) {
+ return()
+ }
+
+ name1time <- plotData$name1time
+ name2outcome <- plotData$name2outcome
+ name3contexpl <- plotData$name3contexpl
+ name3expl <- plotData$name3expl
+
+ mydata <- cleanData <- plotData$cleanData
- formula2 <-
- jmvcore::constructFormula(terms = c(self$options$explanatory, self$options$contexpl))
+ mytime_labelled <- plotData$mytime_labelled
+ myoutcome_labelled <- plotData$myoutcome_labelled
+ mydxdate_labelled <- plotData$mydxdate_labelled
+ myfudate_labelled <- plotData$myfudate_labelled
+ myexplanatory_labelled <- plotData$myexplanatory_labelled
+ mycontexpl_labelled <- plotData$mycontexpl_labelled
- formula3 <-
- paste("survival::Surv(mytime, myoutcome) ~ ", formula2)
- formula3 <- as.formula(formula3)
+ ### prepare formula ----
+
+ myexplanatory <- NULL
+ if(!is.null(self$options$explanatory)) {
+ myexplanatory <- as.vector(myexplanatory_labelled)
+ }
+
+ mycontexpl <- NULL
+ if(!is.null(self$options$contexpl)) {
+ mycontexpl <- as.vector(mycontexpl_labelled)
+ }
+
+ formula2 <- c(myexplanatory, mycontexpl)
+
+ myformula <-
+ paste("survival::Surv(mytime, myoutcome) ~ ",
+ paste(formula2, collapse = " + ")
+ )
+
+
+ # self$results$mydataview$setContent(
+ # list(
+ # "myformula" = myformula,
+ # "mydata" = head(mydata),
+ # myexplanatory = myexplanatory,
+ # mycontexpl = mycontexpl,
+ # formula2 = formula2
+ # )
+ # )
+
+
+
+ myformula <- as.formula(myformula)
mod <-
- survival::coxph(formula = formula3,
- data = plotData)
+ survival::coxph(formula = myformula,
+ data = mydata)
# plot
@@ -830,8 +1107,9 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
# ggforest ----
+
plot3 <- survminer::ggforest(model = mod,
- data = plotData)
+ data = mydata)
# print plot ----
@@ -1026,7 +1304,7 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
#
# # https://stackoverflow.com/questions/55404550/computing-se-or-ci-for-ggadjustedcurves
#
- # # print plot -----
+ # ## print plot -----
#
# print(plot7)
# TRUE
@@ -1038,904 +1316,3 @@ multisurvivalClass <- if (requireNamespace('jmvcore'))
)
)
-
-
-
-
-
-# # Define Survival Time ----
-#
-# .definemytime = function() {
-#
-# mydata <- self$data
-#
-# tint <- self$options$tint
-#
-#
-# if (!tint) {
-#
-# # Precalculated Time ----
-#
-# # mydata[[self$options$elapsedtime]] <- jmvcore::toNumeric(mydata[[self$options$elapsedtime]])
-#
-# mydata[["mytime"]] <- jmvcore::toNumeric(mydata[[self$options$elapsedtime]])
-#
-#
-# } else if (tint) {
-#
-# # Time Interval ----
-#
-# dxdate <- self$options$dxdate
-# fudate <- self$options$fudate
-# timetypedata <- self$options$timetypedata
-#
-#
-# if (timetypedata == "ymdhms") {
-# mydata[["start"]] <- lubridate::ymd_hms(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::ymd_hms(mydata[[fudate]])
-# }
-# if (timetypedata == "ymd") {
-# mydata[["start"]] <- lubridate::ymd(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::ymd(mydata[[fudate]])
-# }
-# if (timetypedata == "ydm") {
-# mydata[["start"]] <- lubridate::ydm(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::ydm(mydata[[fudate]])
-# }
-# if (timetypedata == "mdy") {
-# mydata[["start"]] <- lubridate::mdy(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::mdy(mydata[[fudate]])
-# }
-# if (timetypedata == "myd") {
-# mydata[["start"]] <- lubridate::myd(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::myd(mydata[[fudate]])
-# }
-# if (timetypedata == "dmy") {
-# mydata[["start"]] <- lubridate::dmy(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::dmy(mydata[[fudate]])
-# }
-# if (timetypedata == "dym") {
-# mydata[["start"]] <- lubridate::dym(mydata[[dxdate]])
-# mydata[["end"]] <- lubridate::dym(mydata[[fudate]])
-# }
-#
-#
-#
-# timetypeoutput <- jmvcore::constructFormula(terms = self$options$timetypeoutput)
-#
-#
-# mydata <- mydata %>%
-# dplyr::mutate(
-# interval = lubridate::interval(start, end)
-# )
-#
-# stopifnot(lubridate::is.interval(mydata[["interval"]]))
-#
-# mydata <- mydata %>%
-# dplyr::mutate(
-# mytime = lubridate::time_length(interval, timetypeoutput)
-# )
-#
-#
-# }
-#
-#
-# return(mydata[["mytime"]])
-#
-#
-# }
-#
-# # Define Outcome ----
-# ,
-# .definemyoutcome = function() {
-#
-# mydata <- self$data
-#
-# contin <- c("integer", "numeric", "double")
-#
-# multievent <- self$options$multievent
-# outcome1 <- self$options$outcome
-# outcome1 <- self$data[[outcome1]]
-#
-# if (!multievent) {
-#
-# if (inherits(outcome1, contin)) {
-#
-# if (
-# !((length(unique(outcome1[!is.na(outcome1)])) == 2) && (sum(unique(outcome1[!is.na(outcome1)])) == 1) )
-# ) {
-# stop('When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0.')
-#
-# }
-#
-# mydata[["myoutcome"]] <- mydata[[self$options$outcome]]
-#
-# } else if (inherits(outcome1, "factor")) {
-#
-# mydata[["myoutcome"]] <-
-# ifelse(test = outcome1 == outcomeLevel,
-# yes = 1,
-# no = 0)
-#
-# } else {
-#
-# stop('When using continuous variable as an outcome, it must only contain 1s and 0s. If patient is dead or event (recurrence) occured it is 1. If censored (patient is alive or free of disease) at the last visit it is 0. If you are using a factor as an outcome, please check the levels and content.')
-#
-# }
-#
-# } else if (multievent) {
-#
-#
-# analysistype <- self$options$analysistype
-#
-# dod <- self$options$dod
-# dooc <- self$options$dooc
-# awd <- self$options$awd
-# awod <- self$options$awod
-#
-# if (analysistype == 'overall') {
-#
-# # (Alive) <=> (Dead of Disease & Dead of Other Causes)
-#
-#
-# mydata[["myoutcome"]] <- NA_integer_
-#
-# mydata[["myoutcome"]][outcome1 == awd] <- 0
-# mydata[["myoutcome"]][outcome1 == awod] <- 0
-# mydata[["myoutcome"]][outcome1 == dod] <- 1
-# mydata[["myoutcome"]][outcome1 == dooc] <- 1
-#
-#
-#
-# } else if (analysistype == 'cause') {
-#
-# # (Alive & Dead of Other Causes) <=> (Dead of Disease)
-#
-#
-# mydata[["myoutcome"]] <- NA_integer_
-#
-# mydata[["myoutcome"]][outcome1 == awd] <- 0
-# mydata[["myoutcome"]][outcome1 == awod] <- 0
-# mydata[["myoutcome"]][outcome1 == dod] <- 1
-# mydata[["myoutcome"]][outcome1 == dooc] <- 0
-#
-# } else if (analysistype == 'compete') {
-#
-# # Alive <=> Dead of Disease accounting for Dead of Other Causes
-#
-#
-#
-# mydata[["myoutcome"]] <- NA_integer_
-#
-# mydata[["myoutcome"]][outcome1 == awd] <- 0
-# mydata[["myoutcome"]][outcome1 == awod] <- 0
-# mydata[["myoutcome"]][outcome1 == dod] <- 1
-# mydata[["myoutcome"]][outcome1 == dooc] <- 2
-#
-# }
-#
-# }
-#
-#
-# return(mydata[["myoutcome"]])
-#
-# }
-#
-# # Define Factor ----
-# ,
-# .definemyfactor = function() {
-#
-# mydata <- self$data
-#
-# # 1 Explanatory Factor ----
-#
-# if ( length(self$options$explanatory) == 1 ) {
-#
-# expl <- self$options$explanatory
-#
-# mydata[["myfactor"]] <- mydata[[expl]]
-#
-# return(mydata[["myfactor"]])
-#
-# }
-#
-# # > 1 Explanatory Factor ----
-#
-# if ( length(self$options$explanatory) > 1 ) {
-#
-# thefactor <- jmvcore::constructFormula(terms = self$options$explanatory)
-#
-# return(thefactor)
-#
-# }
-#
-# # single arm ----
-#
-# sas <- self$options$sas
-#
-# if (sas) {
-# thefactor <- 1
-# return(thefactor)
-# }
-#
-#
-# }
-#
-#
-# # Clean Data For Analysis ----
-# ,
-# .cleandata = function() {
-#
-#
-# time <- private$.definemytime()
-# outcome <- private$.definemyoutcome()
-#
-#
-# if ( length(self$options$explanatory) == 1 ) {
-# factor <- private$.definemyfactor()
-#
-# cleanData <- data.frame(
-# "mytime" = time,
-# "myoutcome" = outcome,
-# "factor" = factor
-# )
-# }
-#
-#
-# if ( length(self$options$explanatory) > 1 || self$options$sas ) {
-# factor <- private$.definemyfactor()
-# factor <- jmvcore::select(df = self$data, columnNames = factor)
-#
-# cleanData <- data.frame(
-# "mytime" = time,
-# "myoutcome" = outcome,
-# factor
-# )
-#
-# }
-#
-#
-#
-# # naOmit ----
-#
-# cleanData <- jmvcore::naOmit(cleanData)
-#
-#
-# # View mydata ----
-#
-# self$results$mydataview$setContent(
-# list(time,
-# outcome,
-# factor,
-# head(cleanData, n = 30)
-# )
-# )
-#
-#
-# # Prepare Data For Plots ----
-#
-# plotData <- cleanData
-#
-# image <- self$results$plot
-# image$setState(plotData)
-#
-# image2 <- self$results$plot2
-# image2$setState(plotData)
-#
-# image3 <- self$results$plot3
-# image3$setState(plotData)
-#
-# image6 <- self$results$plot6
-# image6$setState(plotData)
-#
-# }
-#
-#
-#
-#
-#
-# ,
-# .run = function() {
-#
-#
-# # Common Errors, Warnings ----
-#
-# # No variable ----
-# if ( is.null(self$options$outcome) ||
-#
-# (is.null(self$options$elapsedtime) && !(self$options$tint))
-#
-# || is.null(self$options$explanatory)
-#
-# ) {
-#
-# todo <- glue::glue("
-#
Welcome to ClinicoPath
-#
-# This tool will help you calculate median survivals and 1,3,5-yr survivals for a given fisk factor.
-#
-# Explanatory variable should be categorical (ordinal or nominal).
-#
-# Select outcome level from Outcome variable.
-#
-# Outcome Level: if patient is dead or event (recurrence) occured. You may also use advanced outcome options depending on your analysis type.
-#
-# Survival time should be numeric and continuous. You may also use dates to calculate survival time in advanced elapsed time options.
-#
-# This function uses survival, survminer, and finalfit packages. Please cite jamovi and the packages as given below.
-#