Skip to content

Add RM-ANOVA #246

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

Draft
wants to merge 3 commits into
base: devel
Choose a base branch
from
Draft
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 R/mod_tableGen_fct_methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ app_methods <- function(agg, column, week, group, data, totals, filter = NA) {
app_freq(column, group, data, totals)
} else if (agg == "ANOVA") {
app_anova(column, week, group, data)
} else if (agg == "RM_ANOVA") {
app_rmanova(column, week, group, data)
} else if (agg == "NESTED_FREQ_DSC"){
app_nested_freq(column, week, group, data, totals, sort = "desc_tot")
} else if (agg == "NESTED_FREQ_ABC"){
Expand Down
168 changes: 168 additions & 0 deletions R/mod_tableGen_fct_rmanova.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#' Generate RM-ANOVA using table generator blocks
#'
#' @param column the variable to perform RM-ANOVA on,
#' this also contains the class of the column
#' based on the data file the column came from
#' @param week filter the variable by certain week
#' @param group the groups to compare for the RM-ANOVA
#' @param data the data to use
#'
#' @return an RM-ANOVA table of grouped variables
#' @family tableGen Functions
#' @keywords tabGen
#'
#' @noRd
app_rmanova <- function(column, week, group, data) {
UseMethod("app_rmanova", column)
}


#' @return NULL
#' @rdname app_rmanova
#' @family tableGen Functions
#' @noRd

app_rmanova.default <- function(column, week, group, data) {
rlang::abort(glue::glue(
"Can't calculate mean because data is not classified as ADLB, BDS or OCCDS",
))
}

#' if ADSL supplied look for the column to take mean of
#' and look for a grouping variable to group_by
#'
#' @importFrom rlang sym !!
#' @import dplyr
#' @return an RM-ANOVA table of grouped variables
#' @rdname app_rmanova
#' @family tableGen Functions
#'
#' @noRd

app_rmanova.ADAE <- app_rmanova.ADSL <- function(column, week, group = NULL, data) {

column <- as.character(column)

if (!is.numeric(data[[column]])) {
stop(paste("Can't calculate RM-ANOVA, ", column, " is not numeric"))
}

if (is.null(group)) {

stop(paste("Can't calculate RM-ANOVA without grouping data"))

} else {
group <- rlang::sym(group)
column <- rlang::sym(column)

all_dat <- data %>% dplyr::distinct(!!column, !!group, USUBJID)

ttest <- summary(aov(all_dat[[paste(column)]] ~ all_dat[[paste(group)]] + Error(factor(USUBJID)), data=all_dat))[[1]][[1]] %>%
tidyr::as_tibble()

group_n <- length(unique(all_dat[[paste(group)]])) + 2

anova_df <- data.frame(matrix(NA, ncol=group_n, nrow=4))

anova_df[1,1] <- "p-value"
anova_df[2,1] <- "Test Statistic"
anova_df[3,1] <- "Mean Sum of Squares"
anova_df[4,1] <- "Sum of Squares"
anova_df[1, group_n] <- round(ttest$`Pr(>F)`[1], 3)
anova_df[2, group_n] <- round(ttest$`F value`[1], 2)
anova_df[3, group_n] <- round(ttest$`Mean Sq`[1], 2)
anova_df[4, group_n] <- round(ttest$`Sum Sq`[1], 2)

anova_df <- dplyr::mutate_all(anova_df, as.character) %>%
dplyr::mutate_all(dplyr::coalesce, "")

anova_df
}


}


#' if BDS filter by paramcd and week
#' We need to calculate the difference in N for this
#' and report missing values from the mean if any
#'
#' @importFrom rlang sym !!
#' @import dplyr
#' @return an ANOVA table of grouped variables
#' @rdname app_rmanova
#' @family tableGen Functions
#'
#' @noRd

app_rmanova.BDS <- function(column, week, group = NULL, data) {

column <- as.character(column)

if (!column %in% data[["PARAMCD"]]) {
stop(paste("Can't calculate RM-ANOVA, ", column, " has no AVAL"))
}

if (week == "NONE") {
stop(paste("Select week from dropdown to calculate RM-ANOVA"))
}


if (is.null(group)) {
stop(paste("Can't calculate RM-ANOVA without grouping data"))
} else {
group <- sym(group)

all_dat <- data %>% filter(PARAMCD == column & AVISIT == week)

if (length(unique(all_dat[[paste(group)]])) == 1) stop(glue::glue("Only one {group} in data selected, choose another week for RM-ANOVA"))

ttest <- summary(aov(all_dat$AVAL ~ all_dat[[paste(group)]] + Error(factor(USUBJID)), data=all_dat))[[1]][[1]] %>%
tidyr::as_tibble()

group_n <- length(unique(all_dat[[paste(group)]])) + 2

anova_df <- data.frame(matrix(NA, ncol=group_n, nrow=4))
anova_df[1,1] <- "p-value"
anova_df[2,1] <- "Test Statistic"
anova_df[3,1] <- "Mean Sum of Squares"
anova_df[4,1] <- "Sum of Squares"
anova_df[1, group_n] <- round(ttest$`Pr(>F)`[1], 3)
anova_df[2, group_n] <- round(ttest$`F value`[1], 2)
anova_df[3, group_n] <- round(ttest$`Mean Sq`[1], 2)
anova_df[4, group_n] <- round(ttest$`Sum Sq`[1], 2)

anova_df <- dplyr::mutate_all(anova_df, as.character) %>%
dplyr::mutate_all(dplyr::coalesce, "")
anova_df
}

}

#' @return NULL
#' @rdname app_rmanova
#' @family tableGen Functions
#'
#' @noRd

app_rmanova.OCCDS <- function(column, week = NULL, group = NULL, data) {
rlang::abort(glue::glue(
"Currently no method to perform RM-ANOVA on OCCDS"
))
}





#' @return NULL
#' @rdname app_rmanova
#' @family tableGen Functions
#'
#' @noRd

app_rmanova.custom <- function(column, week = NULL, group = NULL, data) {
rlang::abort(glue::glue(
"Can't calculate RM-ANOVA, data is not classified as ADLB, BDS or OCCDS"
))
}
4 changes: 4 additions & 0 deletions R/mod_tableGen_ui.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ mod_tableGen_ui <- function(id){
class = "ui-state-default agg", id = "anova",
div(tippy(div("ANOVA"), "ANOVA"))
),
tags$li(
class = "ui-state-default agg", id = "rm_anova",
div(tippy(div("RM-ANOVA"), "Repeated Measures ANOVA"))
),
tags$li(
class = "ui-state-default agg", id = "chg",
div(tippy(div("CHG"), "Change from Baseline"))
Expand Down
Binary file modified R/sysdata.rda
Binary file not shown.
5 changes: 3 additions & 2 deletions data-raw/internal-data.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pretty_blocks <- tidyr::tibble(
Pattern = c("MEAN", "FREQ", "CHG", "Y_FREQ", "MAX_FREQ", "NON_MISSING",
Pattern = c("RM_ANOVA", "MEAN", "FREQ", "CHG", "Y_FREQ", "MAX_FREQ", "NON_MISSING",
"NESTED_FREQ_DSC", "NESTED_FREQ_ABC"),
Replacement = c("Descriptive Statistics",
Replacement = c("Repeated Measures ANOVA",
"Descriptive Statistics",
"Summary Counts",
"Descriptive Statistics of Change from Baseline",
"Subject Count for those with 'Y' values",
Expand Down
4 changes: 3 additions & 1 deletion inst/app/www/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ $(function() {
var draggableId = ui.draggable.attr("id");
var newid = getNewId(draggableId);
if (weeks_array) {
if (draggableId.includes("anova")) {
if (draggableId === "anova") {
$(this).append(selectBlock(newid, "ANOVA", week_opts));
} else if (draggableId === "rm_anova") {
$(this).append(selectBlock(newid, "RM_ANOVA", week_opts));
} else if (draggableId.includes("chg")) {
$(this).append(selectBlock(newid, "CHG", week_opts));
} else if (draggableId.includes("mean")) {
Expand Down