From bd3c307c7b09b2749a0cc2b2667010e19c0534eb Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Fri, 6 Feb 2026 18:59:28 -0500 Subject: [PATCH 1/9] add robust parsing for temperature, time, and dosage --- R/module-statmodel-server.R | 44 +++++++++++++++++++++++++++++++++---- R/utils.R | 2 +- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 40f66cd..6222286 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -202,10 +202,46 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r return(contrast$matrix) } -#' @importFrom MSstatsResponse convertGroupToNumericDose build_response_curve_matrix = function(condition_list) { - condition_to_metadata_table = convertGroupToNumericDose(condition_list) - return(data.frame(GROUP = condition_list, condition_to_metadata_table)) + tibble(GROUP = as.character(condition_list)) %>% + mutate( + is_control = str_detect(str_to_upper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), + + drug = if_else( + is_control, + GROUP, + str_extract(GROUP, "^[^_0-9]+") %>% str_trim() + ), + + measurements = str_extract_all(GROUP, "[0-9.]+[a-zA-Z]+") + ) %>% + # Only unnest for non-controls + { + controls <- filter(., is_control) %>% + select(GROUP, drug) + + treatments <- filter(., !is_control) %>% + unnest_longer(measurements, indices_to = "measurement_idx") %>% + mutate( + value = as.numeric(str_extract(measurements, "[0-9.]+")), + unit = str_extract(measurements, "[a-zA-Z]+"), + + measurement_type = case_when( + unit %in% c("nM", "uM", "mM", "M", "mg", "ug") ~ "dose", + unit %in% c("h", "hr", "min", "d", "day") ~ "time", + unit %in% c("C", "F") ~ "temperature", + TRUE ~ "other" + ) + ) %>% + pivot_wider( + id_cols = c(GROUP, drug), + names_from = measurement_type, + values_from = c(value, unit), + names_glue = "{measurement_type}_{.value}" + ) + + bind_rows(controls, treatments) + } } #' Update a matrix or data frame from a DT cell edit event @@ -707,7 +743,7 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, protein_level_data <- merge(preprocess_data()$ProteinLevelData, matrix, by = "GROUP") dia_prepared <- MSstatsPrepareDoseResponseFit( data = protein_level_data, - dose_column = "dose_nM", + dose_column = "dose_value", drug_column = "drug", protein_column = "Protein", log_abundance_column = "LogIntensities", diff --git a/R/utils.R b/R/utils.R index e2dee6b..cb12928 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1307,7 +1307,7 @@ fitResponseCurves <- function(statmodel_input, matrix, input_data) { protein_level_data <- merge(input_data$ProteinLevelData, matrix, by = "GROUP") dia_prepared <- MSstatsPrepareDoseResponseFit( data = protein_level_data, - dose_column = "dose_nM", + dose_column = "dose_value", drug_column = "drug", protein_column = "Protein", log_abundance_column = "LogIntensities", From ca907e3541012427dd43ee60843fb6eb189271e8 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 16:41:58 -0500 Subject: [PATCH 2/9] add pivot_wider dependency --- NAMESPACE | 2 +- R/MSstatsShiny.R | 4 +- R/module-statmodel-server.R | 77 +++++++++++++++++++++---------------- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 1690c4b..ae3644a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,7 +49,6 @@ importFrom(MSstatsPTM,SpectronauttoMSstatsPTMFormat) importFrom(MSstatsPTM,dataProcessPlotsPTM) importFrom(MSstatsPTM,groupComparisonPlotsPTM) importFrom(MSstatsResponse,MSstatsPrepareDoseResponseFit) -importFrom(MSstatsResponse,convertGroupToNumericDose) importFrom(MSstatsResponse,doseResponseFit) importFrom(MSstatsResponse,visualizeResponseProtein) importFrom(arrow,read_parquet) @@ -191,6 +190,7 @@ importFrom(stats,hclust) importFrom(stats,median) importFrom(stats,na.omit) importFrom(stats,qt) +importFrom(tidyr,pivot_wider) importFrom(tidyr,unite) importFrom(tools,file_ext) importFrom(utils,capture.output) diff --git a/R/MSstatsShiny.R b/R/MSstatsShiny.R index c378098..47d461c 100644 --- a/R/MSstatsShiny.R +++ b/R/MSstatsShiny.R @@ -32,8 +32,8 @@ #' @importFrom htmltools attachDependencies #' @importFrom uuid UUIDgenerate #' @importFrom Hmisc describe -#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate -#' @importFrom tidyr unite +#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate +#' @importFrom tidyr unite pivot_wider #' @importFrom MSstatsConvert MSstatsLogsSettings #' @importFrom MSstatsPTM dataProcessPlotsPTM groupComparisonPlotsPTM MaxQtoMSstatsPTMFormat PDtoMSstatsPTMFormat FragPipetoMSstatsPTMFormat SkylinetoMSstatsPTMFormat SpectronauttoMSstatsPTMFormat #' @importFrom utils capture.output head packageVersion read.csv read.delim write.csv diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 6222286..df2ebc8 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -203,45 +203,56 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r } build_response_curve_matrix = function(condition_list) { - tibble(GROUP = as.character(condition_list)) %>% + matrix = data.frame(GROUP = as.character(condition_list)) + matrix = matrix %>% mutate( + is_control = str_detect(str_to_upper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), + measurements = str_extract_all(GROUP, "[0-9.]+[a-zA-Z]+") + ) + controls = matrix %>% filter(is_control) %>% select(GROUP) + treatments = matrix %>% filter(!is_control) %>% mutate( - is_control = str_detect(str_to_upper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), - - drug = if_else( - is_control, - GROUP, - str_extract(GROUP, "^[^_0-9]+") %>% str_trim() - ), - - measurements = str_extract_all(GROUP, "[0-9.]+[a-zA-Z]+") + value = as.numeric(str_extract(measurements, "[0-9.]+")), + unit = str_extract(measurements, "[a-zA-Z]+"), + measurement_type = case_when( + unit %in% c("nM", "uM", "mM", "M", "mg", "ug") ~ "dose", + unit %in% c("h", "hr", "hrs", "min", "d", "day") ~ "time", + unit %in% c("C", "F", "K") ~ "temperature", + TRUE ~ "other" + ) ) %>% - # Only unnest for non-controls - { - controls <- filter(., is_control) %>% - select(GROUP, drug) - - treatments <- filter(., !is_control) %>% - unnest_longer(measurements, indices_to = "measurement_idx") %>% + pivot_wider( + id_cols = c(GROUP), + names_from = measurement_type, + values_from = c(value, unit), + names_glue = "{measurement_type}_{.value}" + ) + matrix = bind_rows(controls, treatments) + if ("dose_value" %in% colnames(matrix)) { + matrix = matrix %>% mutate( - value = as.numeric(str_extract(measurements, "[0-9.]+")), - unit = str_extract(measurements, "[a-zA-Z]+"), - - measurement_type = case_when( - unit %in% c("nM", "uM", "mM", "M", "mg", "ug") ~ "dose", - unit %in% c("h", "hr", "min", "d", "day") ~ "time", - unit %in% c("C", "F") ~ "temperature", - TRUE ~ "other" + drug = if_else( + is_control, + GROUP, + str_extract(GROUP, "^[^_0-9]+") %>% str_trim() ) - ) %>% - pivot_wider( - id_cols = c(GROUP, drug), - names_from = measurement_type, - values_from = c(value, unit), - names_glue = "{measurement_type}_{.value}" ) - - bind_rows(controls, treatments) } + + return(matrix) +} + +prepare_dose_response_fit = function(data) { + required_cols = c(dose_column, drug_column, protein_column, + log_abundance_column) + missing_cols = setdiff(required_cols, names(data)) + if (length(missing_cols) > 0) { + stop("Missing required column(s): ", paste(missing_cols, + collapse = ", ")) + } + subset_df = data[, c(protein_column, drug_column, dose_column, + log_abundance_column)] + colnames(subset_df) = c("protein", "drug", "dose", "response") + return(subset_df) } #' Update a matrix or data frame from a DT cell edit event From c36cd3f57c00ec1aef1c74d2d9f4b8bc326633b4 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 17:29:29 -0500 Subject: [PATCH 3/9] finalizing code for now to handle different perturbations --- NAMESPACE | 6 ++++- R/MSstatsShiny.R | 3 ++- R/module-statmodel-server.R | 44 +++++++++++++++++++++---------------- R/utils.R | 11 ++-------- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index ae3644a..da36dc2 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -48,12 +48,12 @@ importFrom(MSstatsPTM,SkylinetoMSstatsPTMFormat) importFrom(MSstatsPTM,SpectronauttoMSstatsPTMFormat) importFrom(MSstatsPTM,dataProcessPlotsPTM) importFrom(MSstatsPTM,groupComparisonPlotsPTM) -importFrom(MSstatsResponse,MSstatsPrepareDoseResponseFit) importFrom(MSstatsResponse,doseResponseFit) importFrom(MSstatsResponse,visualizeResponseProtein) importFrom(arrow,read_parquet) importFrom(data.table,copy) importFrom(dplyr,`%>%`) +importFrom(dplyr,case_when) importFrom(dplyr,filter) importFrom(dplyr,group_by) importFrom(dplyr,mutate) @@ -190,6 +190,10 @@ importFrom(stats,hclust) importFrom(stats,median) importFrom(stats,na.omit) importFrom(stats,qt) +importFrom(stringr,str_detect) +importFrom(stringr,str_extract) +importFrom(stringr,str_extract_all) +importFrom(stringr,str_trim) importFrom(tidyr,pivot_wider) importFrom(tidyr,unite) importFrom(tools,file_ext) diff --git a/R/MSstatsShiny.R b/R/MSstatsShiny.R index 47d461c..8b8d586 100644 --- a/R/MSstatsShiny.R +++ b/R/MSstatsShiny.R @@ -32,7 +32,7 @@ #' @importFrom htmltools attachDependencies #' @importFrom uuid UUIDgenerate #' @importFrom Hmisc describe -#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate +#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate case_when #' @importFrom tidyr unite pivot_wider #' @importFrom MSstatsConvert MSstatsLogsSettings #' @importFrom MSstatsPTM dataProcessPlotsPTM groupComparisonPlotsPTM MaxQtoMSstatsPTMFormat PDtoMSstatsPTMFormat FragPipetoMSstatsPTMFormat SkylinetoMSstatsPTMFormat SpectronauttoMSstatsPTMFormat @@ -41,6 +41,7 @@ #' @importFrom methods is #' @importFrom readxl read_excel #' @importFrom plotly plotlyOutput plot_ly layout renderPlotly +#' @importFrom stringr str_detect str_extract_all str_extract str_trim #' @import mockery #' #' @name MSstatsShiny diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index df2ebc8..df1a5e1 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -205,7 +205,7 @@ build_all_pair_contrast = function(input, condition_list, contrast, comp_list, r build_response_curve_matrix = function(condition_list) { matrix = data.frame(GROUP = as.character(condition_list)) matrix = matrix %>% mutate( - is_control = str_detect(str_to_upper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), + is_control = str_detect(toupper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), measurements = str_extract_all(GROUP, "[0-9.]+[a-zA-Z]+") ) controls = matrix %>% filter(is_control) %>% select(GROUP) @@ -217,7 +217,7 @@ build_response_curve_matrix = function(condition_list) { unit %in% c("nM", "uM", "mM", "M", "mg", "ug") ~ "dose", unit %in% c("h", "hr", "hrs", "min", "d", "day") ~ "time", unit %in% c("C", "F", "K") ~ "temperature", - TRUE ~ "other" + TRUE ~ "treatment" ) ) %>% pivot_wider( @@ -226,11 +226,11 @@ build_response_curve_matrix = function(condition_list) { values_from = c(value, unit), names_glue = "{measurement_type}_{.value}" ) - matrix = bind_rows(controls, treatments) + matrix = rbind(controls, treatments) if ("dose_value" %in% colnames(matrix)) { matrix = matrix %>% mutate( - drug = if_else( + drug = ifelse( is_control, GROUP, str_extract(GROUP, "^[^_0-9]+") %>% str_trim() @@ -241,17 +241,28 @@ build_response_curve_matrix = function(condition_list) { return(matrix) } +# A hacky function to make metadata compatible with MSstatsResponse format +# based on build_response_curve_matrix output prepare_dose_response_fit = function(data) { - required_cols = c(dose_column, drug_column, protein_column, - log_abundance_column) - missing_cols = setdiff(required_cols, names(data)) - if (length(missing_cols) > 0) { - stop("Missing required column(s): ", paste(missing_cols, - collapse = ", ")) + if (!("drug" %in% colnames(data))) { + column_names = colnames(data) + intervention_cols = grep("time|temperature|treatment", column_names, + ignore.case = TRUE, value = TRUE) + if (length(intervention_cols) > 0) { + intervention_type = sub("_.*", "", intervention_cols[1]) + data$drug = intervention_type + intervention_value = paste0(intervention_type, "_value") + } else { + stop("No intervention columns found (time, temperature, or treatment)") + } + } else { + intervention_value = "dose_value" } - subset_df = data[, c(protein_column, drug_column, dose_column, - log_abundance_column)] + + # Create subset with renamed columns + subset_df = data[, c("Protein", "drug", intervention_value, "LogIntensities")] colnames(subset_df) = c("protein", "drug", "dose", "response") + return(subset_df) } @@ -752,13 +763,8 @@ statmodelServer = function(id, parent_session, loadpage_input, qc_input, CONSTANTS_STATMODEL$plot_type_response_curve) { matrix = contrast$matrix protein_level_data <- merge(preprocess_data()$ProteinLevelData, matrix, by = "GROUP") - dia_prepared <- MSstatsPrepareDoseResponseFit( - data = protein_level_data, - dose_column = "dose_value", - drug_column = "drug", - protein_column = "Protein", - log_abundance_column = "LogIntensities", - transform_nM_to_M = TRUE + dia_prepared <- prepare_dose_response_fit( + data = protein_level_data ) output$comp_plots = renderPlot({ visualizeResponseProtein( diff --git a/R/utils.R b/R/utils.R index cb12928..778458f 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1302,17 +1302,10 @@ dataComparison <- function(statmodel_input,qc_input,loadpage_input,matrix,input_ return(model) } -#' @importFrom MSstatsResponse MSstatsPrepareDoseResponseFit doseResponseFit +#' @importFrom MSstatsResponse doseResponseFit fitResponseCurves <- function(statmodel_input, matrix, input_data) { protein_level_data <- merge(input_data$ProteinLevelData, matrix, by = "GROUP") - dia_prepared <- MSstatsPrepareDoseResponseFit( - data = protein_level_data, - dose_column = "dose_value", - drug_column = "drug", - protein_column = "Protein", - log_abundance_column = "LogIntensities", - transform_nM_to_M = TRUE - ) + dia_prepared <- prepare_dose_response_fit(protein_level_data) response_results <- doseResponseFit( data = dia_prepared, increasing = FALSE, From 7a47a4cc7f749fd4cb30906badb33353fb391621 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 17:36:40 -0500 Subject: [PATCH 4/9] add a warning notification initially for multiple units --- R/module-statmodel-server.R | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index df1a5e1..5870bed 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -219,13 +219,23 @@ build_response_curve_matrix = function(condition_list) { unit %in% c("C", "F", "K") ~ "temperature", TRUE ~ "treatment" ) - ) %>% - pivot_wider( - id_cols = c(GROUP), - names_from = measurement_type, - values_from = c(value, unit), - names_glue = "{measurement_type}_{.value}" - ) + ) + if (length(unique(treatments$unit)) > 1) { + showNotification( + paste("Multiple units of measurement detected in group names: ", + paste(unique(treatments$unit), collapse = ", "), + " Edit the metadata table to ensure consistent units."), + type = "warning", + duration = 10 + ) + } + treatments = treatments %>% + pivot_wider( + id_cols = c(GROUP), + names_from = measurement_type, + values_from = c(value, unit), + names_glue = "{measurement_type}_{.value}" + ) matrix = rbind(controls, treatments) if ("dose_value" %in% colnames(matrix)) { matrix = matrix %>% From f6f983348b2bce02c3a529ceb6ecc16661386fb2 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 17:59:29 -0500 Subject: [PATCH 5/9] bugs related to dose response not working now --- NAMESPACE | 1 + R/MSstatsShiny.R | 2 +- R/module-statmodel-server.R | 21 +++++++++++---------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index da36dc2..15e2803 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -53,6 +53,7 @@ importFrom(MSstatsResponse,visualizeResponseProtein) importFrom(arrow,read_parquet) importFrom(data.table,copy) importFrom(dplyr,`%>%`) +importFrom(dplyr,bind_rows) importFrom(dplyr,case_when) importFrom(dplyr,filter) importFrom(dplyr,group_by) diff --git a/R/MSstatsShiny.R b/R/MSstatsShiny.R index 8b8d586..e61eeca 100644 --- a/R/MSstatsShiny.R +++ b/R/MSstatsShiny.R @@ -32,7 +32,7 @@ #' @importFrom htmltools attachDependencies #' @importFrom uuid UUIDgenerate #' @importFrom Hmisc describe -#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate case_when +#' @importFrom dplyr `%>%` filter summarise n_distinct group_by ungroup select n mutate case_when bind_rows #' @importFrom tidyr unite pivot_wider #' @importFrom MSstatsConvert MSstatsLogsSettings #' @importFrom MSstatsPTM dataProcessPlotsPTM groupComparisonPlotsPTM MaxQtoMSstatsPTMFormat PDtoMSstatsPTMFormat FragPipetoMSstatsPTMFormat SkylinetoMSstatsPTMFormat SpectronauttoMSstatsPTMFormat diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 5870bed..9366bf2 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -208,7 +208,7 @@ build_response_curve_matrix = function(condition_list) { is_control = str_detect(toupper(GROUP), "^(DMSO|CONTROL|VEHICLE)$"), measurements = str_extract_all(GROUP, "[0-9.]+[a-zA-Z]+") ) - controls = matrix %>% filter(is_control) %>% select(GROUP) + controls = matrix %>% filter(is_control) %>% select(GROUP, is_control) treatments = matrix %>% filter(!is_control) %>% mutate( value = as.numeric(str_extract(measurements, "[0-9.]+")), @@ -221,22 +221,22 @@ build_response_curve_matrix = function(condition_list) { ) ) if (length(unique(treatments$unit)) > 1) { - showNotification( - paste("Multiple units of measurement detected in group names: ", - paste(unique(treatments$unit), collapse = ", "), - " Edit the metadata table to ensure consistent units."), - type = "warning", - duration = 10 - ) + # showNotification( + # paste("Multiple units of measurement detected in group names: ", + # paste(unique(treatments$unit), collapse = ", "), + # " Edit the metadata table to ensure consistent units."), + # type = "warning", + # duration = 10 + # ) } treatments = treatments %>% pivot_wider( - id_cols = c(GROUP), + id_cols = c(GROUP, is_control), names_from = measurement_type, values_from = c(value, unit), names_glue = "{measurement_type}_{.value}" ) - matrix = rbind(controls, treatments) + matrix = bind_rows(controls, treatments) if ("dose_value" %in% colnames(matrix)) { matrix = matrix %>% mutate( @@ -247,6 +247,7 @@ build_response_curve_matrix = function(condition_list) { ) ) } + matrix = matrix %>% select(-is_control) return(matrix) } From 8d1d5054f8f2a12b3c8f05c7c05c42d70233ae20 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 18:07:37 -0500 Subject: [PATCH 6/9] modify response curves to work with og data --- R/module-statmodel-server.R | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index 9366bf2..c751662 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -221,13 +221,13 @@ build_response_curve_matrix = function(condition_list) { ) ) if (length(unique(treatments$unit)) > 1) { - # showNotification( - # paste("Multiple units of measurement detected in group names: ", - # paste(unique(treatments$unit), collapse = ", "), - # " Edit the metadata table to ensure consistent units."), - # type = "warning", - # duration = 10 - # ) + showNotification( + paste("Multiple units of measurement detected in group names: ", + paste(unique(treatments$unit), collapse = ", "), + " Edit the metadata table to ensure consistent units."), + type = "warning", + duration = 10 + ) } treatments = treatments %>% pivot_wider( @@ -237,6 +237,10 @@ build_response_curve_matrix = function(condition_list) { names_glue = "{measurement_type}_{.value}" ) matrix = bind_rows(controls, treatments) + value_cols = grep("_value$", colnames(matrix), value = TRUE) + for (col in value_cols) { + matrix[[col]][matrix$is_control] = 0 + } if ("dose_value" %in% colnames(matrix)) { matrix = matrix %>% mutate( From 55208ebbc8e5b0d7d784e0c336adf672d0b13fad Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Sat, 7 Feb 2026 18:18:50 -0500 Subject: [PATCH 7/9] fix whichdrug problem --- R/module-statmodel-server.R | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/R/module-statmodel-server.R b/R/module-statmodel-server.R index c751662..a73bab0 100644 --- a/R/module-statmodel-server.R +++ b/R/module-statmodel-server.R @@ -273,11 +273,16 @@ prepare_dose_response_fit = function(data) { } else { intervention_value = "dose_value" } - - # Create subset with renamed columns - subset_df = data[, c("Protein", "drug", intervention_value, "LogIntensities")] - colnames(subset_df) = c("protein", "drug", "dose", "response") - + + cols_to_use <- c( + protein = if("Protein" %in% colnames(data)) "Protein" else NA, + drug = "drug", + dose = intervention_value, + response = if("LogIntensities" %in% colnames(data)) "LogIntensities" else NA + ) + cols_to_use <- cols_to_use[!is.na(cols_to_use)] + subset_df <- data[, cols_to_use, drop = FALSE] + colnames(subset_df) <- names(cols_to_use) return(subset_df) } @@ -368,11 +373,11 @@ render_group_comparison_plot_inputs = function(output, session, rownames, get_da output[[NAMESPACE_STATMODEL$visualization_response_curve_which_drug]] = renderUI({ if (input[[NAMESPACE_STATMODEL$visualization_plot_type]] == CONSTANTS_STATMODEL$plot_type_response_curve) { - response_curve_setup_matrix = contrast$matrix + response_curve_setup_matrix = prepare_dose_response_fit(contrast$matrix) unique_drugs = unique(response_curve_setup_matrix$drug) unique_drugs_without_control = unique_drugs[unique_drugs != "DMSO"] selectInput(session$ns(NAMESPACE_STATMODEL$visualization_response_curve_which_drug), - label = h5("Select Drug"), + label = h5("Select Treatment"), unique_drugs_without_control, selected = unique_drugs_without_control[[1]]) } else { NULL From 24c5f8929fa2c438e248ed686600e96790f3a3c0 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Tue, 10 Feb 2026 14:12:17 -0500 Subject: [PATCH 8/9] add dependency on stringr --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index e9a357a..1209299 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -27,7 +27,7 @@ Depends: R (>= 4.2) Imports: shiny, shinyBS, shinyjs, shinybusy, dplyr, ggplot2, plotly, data.table, Hmisc, shinyFiles, MSstats,MSstatsBig, MSstatsTMT, MSstatsPTM, MSstatsConvert, gplots, marray, DT, readxl, ggrepel, uuid, utils, stats, htmltools, methods, tidyr, grDevices, graphics, mockery, MSstatsBioNet, - shinydashboard, arrow, tools, MSstatsResponse + shinydashboard, arrow, tools, MSstatsResponse, stringr Suggests: rmarkdown, tinytest, From 0e7f38b30d8810d608c214cf5c163cbcb639b9ca Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Tue, 10 Feb 2026 14:45:44 -0500 Subject: [PATCH 9/9] add unit tests --- tests/testthat/test-utils-statmodel-server.R | 34 ++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-utils-statmodel-server.R b/tests/testthat/test-utils-statmodel-server.R index 69c9e47..b4ffe96 100644 --- a/tests/testthat/test-utils-statmodel-server.R +++ b/tests/testthat/test-utils-statmodel-server.R @@ -379,14 +379,44 @@ test_that("get_contrast_panel_ui returns correct UI for each mode", { test_that("build_response_curve_matrix returns correct columns", { condition_list = c("Dasatinib_001nM", "Dasatinib_001uM", "DMSO") + mock_warning_different_units = mock() + stub(build_response_curve_matrix, "showNotification", mock_warning_different_units) + result = build_response_curve_matrix(condition_list) + + # This test requires the MSstatsResponse package to be installed + expect_equal(nrow(result), 3) + expect_equal(ncol(result), 4) + expect_true("GROUP" %in% colnames(result)) + expect_true("drug" %in% colnames(result)) + expect_true("dose_value" %in% colnames(result)) + expect_true("dose_unit" %in% colnames(result)) + expect_called(mock_warning_different_units, 1) +}) + +test_that("build_response_curve_matrix returns correct columns for time", { + condition_list = c("time_1h", "time_5hrs", "time_3h") + stub(build_response_curve_matrix, "showNotification", function(...) {}) result <- build_response_curve_matrix(condition_list) # This test requires the MSstatsResponse package to be installed expect_equal(nrow(result), 3) expect_equal(ncol(result), 3) expect_true("GROUP" %in% colnames(result)) - expect_true("drug" %in% colnames(result)) - expect_true("dose_nM" %in% colnames(result)) + expect_true("time_value" %in% colnames(result)) + expect_true("time_unit" %in% colnames(result)) +}) + +test_that("build_response_curve_matrix returns correct columns for temperature", { + condition_list = c("exp_5F", "time_3F") + stub(build_response_curve_matrix, "showNotification", function(...) {}) + result <- build_response_curve_matrix(condition_list) + + # This test requires the MSstatsResponse package to be installed + expect_equal(nrow(result), 2) + expect_equal(ncol(result), 3) + expect_true("GROUP" %in% colnames(result)) + expect_true("temperature_value" %in% colnames(result)) + expect_true("temperature_unit" %in% colnames(result)) }) # ============================================================================