Skip to content
Merged
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
40 changes: 34 additions & 6 deletions R/code_generator_processQFeatures.R
Original file line number Diff line number Diff line change
Expand Up @@ -369,19 +369,33 @@ codeGeneratorFiltering <- function(qf, condition, type, step_number) {
for (i in 1:length(condition)) {
annotation <- as_r_string_literal(condition[[i]]$annotation)
if (condition[[i]]$annotation == ".qfeaturesgui_rowname") {
if (condition[[i]]$operator == "==") {
if (is_missingness_filter_operator(condition[[i]]$operator)) {
build_condition <- if (condition[[i]]$operator == "is_missing") {
"is.na(rownames(rowData(se)))"
} else {
"!is.na(rownames(rowData(se)))"
}
vector <- ""
} else if (condition[[i]]$operator == "==") {
build_condition <- paste0("rownames(rowData(se)) %in% ")
vector <- as_r_vector_literal(condition[[i]]$value)
} else {
build_condition <- paste0("!(rownames(rowData(se)) %in% ")
vector <- paste0(as_r_vector_literal(condition[[i]]$value), ")")
}
} else {
if (condition[[i]]$operator == "==") {
if (is_missingness_filter_operator(condition[[i]]$operator)) {
build_condition <- if (condition[[i]]$operator == "is_missing") {
paste0("is.na(rowData(se)[[", annotation, "]])")
} else {
paste0("!is.na(rowData(se)[[", annotation, "]])")
}
vector <- ""
} else if (condition[[i]]$operator == "==") {
build_condition <- paste0("rowData(se)[[", annotation, "]] %in% ")
vector <- as_r_vector_literal(condition[[i]]$value)
} else if (condition[[i]]$operator == "!=") {
build_condition <- paste0("!(rowData(se)[[", annotation, "]] %in% ")
build_condition <- paste0("!is.na(rowData(se)[[", annotation, "]]) & !(rowData(se)[[", annotation, "]] %in% ")
vector <- paste0(as_r_vector_literal(condition[[i]]$value), ")")
} else {
build_condition <- paste0("rowData(se)[[", annotation, "]] ", condition[[i]]$operator, " ")
Expand Down Expand Up @@ -418,19 +432,33 @@ for(i in 1:length(step%s_setNames)){
for (i in 1:length(condition)) {
annotation <- as_r_string_literal(condition[[i]]$annotation)
if (condition[[i]]$annotation == ".qfeaturesgui_rowname") {
if (condition[[i]]$operator == "==") {
if (is_missingness_filter_operator(condition[[i]]$operator)) {
build_condition <- if (condition[[i]]$operator == "is_missing") {
"is.na(rownames(colData(se)))"
} else {
"!is.na(rownames(colData(se)))"
}
vector <- ""
} else if (condition[[i]]$operator == "==") {
build_condition <- paste0("rownames(colData(se)) %in% ")
vector <- as_r_vector_literal(condition[[i]]$value)
} else {
build_condition <- paste0("!(rownames(colData(se)) %in% ")
vector <- paste0(as_r_vector_literal(condition[[i]]$value), ")")
}
} else {
if (condition[[i]]$operator == "==") {
if (is_missingness_filter_operator(condition[[i]]$operator)) {
build_condition <- if (condition[[i]]$operator == "is_missing") {
paste0("is.na(colData(se)[[", annotation, "]])")
} else {
paste0("!is.na(colData(se)[[", annotation, "]])")
}
vector <- ""
} else if (condition[[i]]$operator == "==") {
build_condition <- paste0("colData(se)[[", annotation, "]] %in% ")
vector <- as_r_vector_literal(condition[[i]]$value)
} else if (condition[[i]]$operator == "!=") {
build_condition <- paste0("!(colData(se)[[", annotation, "]] %in% ")
build_condition <- paste0("!is.na(colData(se)[[", annotation, "]]) & !(colData(se)[[", annotation, "]] %in% ")
vector <- paste0(as_r_vector_literal(condition[[i]]$value), ")")
} else {
build_condition <- paste0("colData(se)[[", annotation, "]] ", condition[[i]]$operator, " ")
Expand Down
139 changes: 135 additions & 4 deletions R/server_module_filtering_box.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
">" = "is greater than",
">=" = "is greater than or equal to",
"==" = "is equal to",
"!=" = "is not equal to"
"!=" = "is not equal to",
"is_missing" = "is missing",
"is_not_missing" = "is not missing"
)
operator_choices_all <- c(
"Less than" = "<",
"Less than or equal to" = "<=",
"Greater than" = ">",
"Greater than or equal to" = ">=",
"Equal to" = "==",
"Not equal to" = "!="
"Not equal to" = "!=",
"Is missing" = "is_missing",
"Is not missing" = "is_not_missing"
)
operator_choices_categorical <- c(
"Equal to" = "==",
"Not equal to" = "!="
"Not equal to" = "!=",
"Is missing" = "is_missing",
"Is not missing" = "is_not_missing"
)

combined_samples_annotations <- reactive({
Expand Down Expand Up @@ -142,6 +148,9 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
req(input$filter_operator)
is_categorical <- annotations_type() %in% c("character", "factor")
is_equality_operator <- input$filter_operator %in% c("==", "!=")
if (is_missingness_filter_operator(input$filter_operator)) {
return(FALSE)
}
if (!(is_categorical && is_equality_operator)) {
return(FALSE)
}
Expand All @@ -154,6 +163,10 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
if (is.null(state_filter_value) && !is.null(state)) {
state_filter_value <- state$filter_value
}
req(input$filter_operator)
if (is_missingness_filter_operator(input$filter_operator)) {
return(NULL)
}
is_categorical <- annotations_type() %in% c("character", "factor")
is_equality_operator <- input$filter_operator %in% c("==", "!=")
if (is_categorical) {
Expand Down Expand Up @@ -204,6 +217,9 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
req(input$annotation_selection)
req(input$filter_operator)
req(annotations_type())
if (is_missingness_filter_operator(input$filter_operator)) {
return()
}
is_categorical <- annotations_type() %in% c("character", "factor")
if (!is_categorical) {
return()
Expand Down Expand Up @@ -271,6 +287,12 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
} else {
input$annotation_selection
}
if (is_missingness_filter_operator(input$filter_operator)) {
return(paste(
annotation_label,
operator_labels[[input$filter_operator]]
))
}
if (annotations_type() %in% c("character", "factor") &&
input$filter_operator %in% c("==", "!=")) {
selected_values <- as.character(input[[paste0("filter_ui_", type)]])
Expand Down Expand Up @@ -299,6 +321,13 @@ server_module_filtering_box <- function(id, assays_to_process, type, state) {
req(input$annotation_selection)
req(input$filter_operator)
req(input$filter_operator %in% names(operator_labels))
if (is_missingness_filter_operator(input$filter_operator)) {
return(list(
annotation = input$annotation_selection,
operator = input$filter_operator,
value = NULL
))
}
filter_value <- input[[paste0("filter_ui_", type)]]
if (is.null(filter_value) || is_empty_categorical_multiselect()) {
return(NULL)
Expand Down Expand Up @@ -386,6 +415,18 @@ server_module_annotation_plot <- function(
req(annotation_values())
selected_operator <- filter_operator()
req(selected_operator)
if (is_missingness_filter_operator(selected_operator)) {
condition_mask <- apply_filter_operator(
values = annotation_values(),
operator = selected_operator,
target = NULL
)
plot_values <- missingness_filter_plot_values(
values = annotation_values(),
operator = selected_operator
)
return(plot_values[condition_mask])
}
condition_mask <- apply_filter_operator(
values = annotation_values(),
operator = selected_operator,
Expand All @@ -395,7 +436,16 @@ server_module_annotation_plot <- function(
annotation_values()[condition_mask]
})
output$plot <- renderPlotly({
annotation <- annotation_values()
selected_operator <- filter_operator()
req(selected_operator)
if (is_missingness_filter_operator(selected_operator)) {
annotation <- missingness_filter_plot_values(
values = annotation_values(),
operator = selected_operator
)
} else {
annotation <- annotation_values()
}
filtered <- filtered_annotation()
selected <- selected_annotation()

Expand All @@ -413,6 +463,21 @@ server_module_annotation_plot <- function(
} else {
selected
}
if (is_missingness_filter_operator(selected_operator)) {
operator_label <- if (selected_operator == "is_missing") {
"Is missing"
} else {
"Is not missing"
}
return(error_handler(
missingness_annotation_plot_wrapper,
component_name = "annotation_plot (filtering_box)",
annotation = annotation,
filtered_annotation = filtered,
assay_name = plot_title,
annotation_name = paste0(operator_label, " (", annotation_label, ")")
))
}

error_handler(
annotation_plot_wrapper,
Expand All @@ -426,6 +491,72 @@ server_module_annotation_plot <- function(
})
}

missingness_filter_plot_values <- function(values, operator) {
condition_mask <- apply_filter_operator(
values = values,
operator = operator,
target = NULL
)
if (operator == "is_missing") {
false_label <- "Is not missing"
true_label <- "Is missing"
} else if (operator == "is_not_missing") {
false_label <- "Is missing"
true_label <- "Is not missing"
} else {
stop(paste0("Unsupported missingness operator: ", operator))
}
factor(
ifelse(condition_mask, true_label, false_label),
levels = c(false_label, true_label)
)
}

missingness_annotation_plot_wrapper <- function(
annotation,
filtered_annotation,
assay_name,
annotation_name
) {
categories <- levels(annotation)
annotation <- factor(annotation, levels = categories)
before_counts <- as.integer(table(annotation))

plot <- plot_ly() %>%
plotly::add_trace(
x = categories,
y = before_counts,
type = "bar",
name = "Before Filtering"
) %>%
layout(
barmode = "group",
xaxis = list(title = paste0("Filter Result: ", annotation_name)),
yaxis = list(title = "Number of appearances"),
title = assay_name
) %>%
config(displaylogo = FALSE, toImageButtonOptions = list(
format = "svg",
filename = "annotation_plot",
height = 500,
width = 700,
scale = 1
))

if (length(filtered_annotation) > 0) {
filtered_annotation <- factor(filtered_annotation, levels = categories)
after_counts <- as.integer(table(filtered_annotation))
plot <- plot %>%
plotly::add_trace(
x = categories,
y = after_counts,
type = "bar",
name = "After Filtering"
)
}
plot
}

#' @title Annotation plot wrapper
#'
#' @param annotation_df A data.frame that contains the annotation values
Expand Down
22 changes: 21 additions & 1 deletion R/server_module_filtering_tab.R
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ server_module_filtering_tab <- function(
filtering_condition_specs[[paste0("condition_spec_", i)]]
})
specs <- Filter(function(spec) {
if (is.list(spec) &&
!is.null(spec$annotation) &&
!is.null(spec$operator) &&
is_missingness_filter_operator(spec$operator)) {
return(TRUE)
}
is.list(spec) &&
!is.null(spec$annotation) &&
!is.null(spec$operator) &&
Expand Down Expand Up @@ -326,6 +332,12 @@ feature_filtering <- function(qfeatures, condition_specs) {
#' @keywords internal
#'
apply_filter_operator <- function(values, operator, target) {
if (operator == "is_missing") {
return(is.na(values))
}
if (operator == "is_not_missing") {
return(!is.na(values))
}
if (length(target) == 0) {
return(rep(FALSE, length(values)))
}
Expand All @@ -334,7 +346,7 @@ apply_filter_operator <- function(values, operator, target) {
if (operator == "==") {
return(values %in% target_values)
}
return(!(values %in% target_values))
return(!is.na(values) & !(values %in% target_values))
}
operator_functions <- list(
"==" = `==`,
Expand All @@ -349,3 +361,11 @@ apply_filter_operator <- function(values, operator, target) {
}
operator_functions[[operator]](values, target)
}

missingness_filter_operators <- function() {
c("is_missing", "is_not_missing")
}

is_missingness_filter_operator <- function(operator) {
operator %in% missingness_filter_operators()
}
Loading
Loading