server <- shiny::shinyServer(function(input, output, session) {
count.not.null <- 0
if (!is.null(stress.ident1)) count.not.null <- count.not.null + 1
if (!is.null(stress.ident2)) count.not.null <- count.not.null + 1
if (!is.null(notstress.ident3)) count.not.null <- count.not.null + 1
if (!is.null(notstress.ident4)) count.not.null <- count.not.null + 1
w <- 1000
if (count.not.null == 3) w <- 750
if (count.not.null == 2) w <- 500
if (count.not.null == 1) w <- 250
# dataframes for stress assignment per GO term
if (!is.null(stress.ident1)) {
df.data.stress.ident1 <- shiny::reactive({
i <- input$"t.stress.ident1"
df <- data.frame(gr.av.stress.scores1 = average.vec$"gr.av.stress.scores1", assignment = F)
df$assignment[df$"gr.av.stress.scores1" > i] <- TRUE
df
})
}
if (!is.null(stress.ident2)) {
df.data.stress.ident2 <- shiny::reactive({
i <- input$"t.stress.ident2"
df <- data.frame(gr.av.stress.scores2 = average.vec$"gr.av.stress.scores2", assignment = F)
df$assignment[df$"gr.av.stress.scores2" > i] <- TRUE
df
})
}
if (!is.null(notstress.ident3)) {
df.data.notstress.ident3 <- shiny::reactive({
i <- input$"t.notstress.ident3"
df <- data.frame(gr.av.notstress.scores3 = average.vec$"gr.av.notstress.scores3", assignment = F)
df$assignment[df$"gr.av.notstress.scores3" > i] <- TRUE
df
})
}
if (!is.null(notstress.ident4)) {
df.data.notstress.ident4 <- shiny::reactive({
i <- input$"t.notstress.ident4"
df <- data.frame(gr.av.notstress.scores4 = average.vec$"gr.av.notstress.scores4", assignment = F)
df$assignment[df$"gr.av.notstress.scores4" > i] <- TRUE
df
})
}
# Stress Filtering & Assignment
# Cells are considered stressed if their scores are above the threshold for any of the stress identifiers
# and not above the threshold for any of the non-stress identifiers
obj2.data <- shiny::reactive({
if (!is.null(stress.ident1)) i.stress.ident1 <- input$"t.stress.ident1"
if (!is.null(stress.ident2)) i.stress.ident2 <- input$"t.stress.ident2"
if (!is.null(notstress.ident3)) i.notstress.ident3 <- input$"t.notstress.ident3"
if (!is.null(notstress.ident4)) i.notstress.ident4 <- input$"t.notstress.ident4"
obj2 <- obj
meta2 <- obj2@meta.data
gr.av.scores.1 <- meta2[, idents$"stress.ident1"]
gr.av.scores.2 <- meta2[, idents$"stress.ident2"]
if (!is.null(stress.ident1)) {
i1.bool <- gr.av.scores.1 > i.stress.ident1
if (!is.null(stress.ident2)) {
i2.bool <- gr.av.scores.2 > i.stress.ident2
stress.bool <- i1.bool | i2.bool # Combine both boolean vectors for stress determination
} else {
stress.bool <- i1.bool # Use only stress.ident1 for stress determination
}
} else {
# Process only the second stress identifier if the first one is null
if (!is.null(stress.ident2)) {
i2.bool <- gr.av.scores.2 > i.stress.ident2
stress.bool <- i2.bool # Use only stress.ident2 for stress determination
}
}
# Process not stress identifiers similarly
notstress.bool <- NULL
gr.av.scores.3 <- meta2[, idents$"notstress.ident3"]
gr.av.scores.4 <- meta2[, idents$"notstress.ident4"]
# Determine not stressed cells based on the thresholds for notstress.ident3 and potentially notstress.ident4
if (!is.null(notstress.ident3)) {
i3.bool <- gr.av.scores.3 > i.notstress.ident3
if (!is.null(notstress.ident4)) {
i4.bool <- gr.av.scores.4 > i.notstress.ident4
notstress.bool <- i3.bool | i4.bool # Combine boolean vectors for notstress.ident3 and notstress.ident4
} else {
notstress.bool <- i3.bool # Use only notstress.ident3 for not stress determination
}
} else {
if (!is.null(notstress.ident4)) {
i4.bool <- gr.av.scores.4 > i.notstress.ident4
notstress.bool <- i4.bool
}
}
# Final assignment of stressed cells
if (!is.null(notstress.bool)) {
obj2$"is.Stressed" <- stress.bool & !notstress.bool
} else {
obj2$"is.Stressed" <- stress.bool
}
obj2
})
obj2.data.part.GO <- shiny::reactive({
if (!is.null(stress.ident1)) i.stress.ident1 <- input$"t.stress.ident1"
if (!is.null(stress.ident2)) i.stress.ident2 <- input$"t.stress.ident2"
if (!is.null(notstress.ident3)) i.notstress.ident3 <- input$"t.notstress.ident3"
if (!is.null(notstress.ident4)) i.notstress.ident4 <- input$"t.notstress.ident4"
obj2 <- obj
meta2 <- obj2@meta.data
if (!is.null(stress.ident1)) {
gr.av.scores.1 <- meta2[, idents$"stress.ident1"]
obj2$"stress.ident1.thresh_cluster" <- gr.av.scores.1 > i.stress.ident1
# obj2$"stress.ident1.thresh_cluster"[obj2$"stress.ident1.thresh_cluster" == FALSE] <- F
# obj2$"stress.ident1.thresh_cluster"[obj2$"stress.ident1.thresh_cluster" == TRUE] <- T
}
if (!is.null(stress.ident2)) {
gr.av.scores.2 <- meta2[, idents$"stress.ident2"]
obj2$"stress.ident2.thresh_cluster" <- gr.av.scores.2 > i.stress.ident2
# obj2$"stress.ident2.thresh_cluster"[obj2$"stress.ident2.thresh_cluster" == FALSE] <- F
# obj2$"stress.ident2.thresh_cluster"[obj2$"stress.ident2.thresh_cluster" == TRUE] <- T
}
if (!is.null(notstress.ident3)) {
gr.av.scores.3 <- meta2[, idents$"notstress.ident3"]
obj2$"notstress.ident3.thresh_cluster" <- gr.av.scores.3 > i.notstress.ident3
# obj2$"notstress.ident3.thresh_cluster"[obj2$"notstress.ident3.thresh_cluster" == FALSE] <- F
# obj2$"notstress.ident3.thresh_cluster"[obj2$"notstress.ident3.thresh_cluster" == TRUE] <- T
}
if (!is.null(notstress.ident4)) {
gr.av.scores.4 <- meta2[, idents$"notstress.ident4"]
obj2$"notstress.ident4.thresh_cluster" <- gr.av.scores.4 > i.notstress.ident4
# obj2$"notstress.ident4.thresh_cluster"[obj2$"notstress.ident4.thresh_cluster" == FALSE] <- F
# obj2$"notstress.ident4.thresh_cluster"[obj2$"notstress.ident4.thresh_cluster" == TRUE] <- T
}
obj2
})
#------ Output Plots --------#
colorz <- Seurat.utils::gg_color_hue(2)[2:1]
# GO score histograms
if (!is.null(stress.ident1)) {
output$"hist.stress.ident1" <- shiny::renderPlot({
# In Shiny, reactive expressions are used to create reactive sources of data that
# automatically update outputs (like plots) when inputs change.
df <- df.data.stress.ident1()
ggplot2::ggplot(df, ggplot2::aes(x = gr.av.stress.scores1, fill = factor(assignment))) +
ggplot2::scale_fill_manual(values = colorz) +
ggplot2::geom_histogram(binwidth = (2 * IQR(gr.av.stress.scores1) / length(gr.av.stress.scores1)^(1 / 3))) +
ggplot2::theme_minimal() +
ggplot2::geom_vline(ggplot2::aes(xintercept = quantile(gr.av.stress.scores1, 0.9)), colour = "black") +
ggplot2::ylab("Granule count") +
ggplot2::geom_text(hjust = -.1, vjust = 10, mapping = ggplot2::aes(x = quantile(gr.av.stress.scores1, 0.9), y = Inf, label = "90% quantile")) +
ggplot2::coord_cartesian(xlim = c(sliders$"min.x.stress.ident1", sliders$"max.x.stress.ident1")) +
ggplot2::xlab("GO Score") +
ggplot2::guides(fill = ggplot2::guide_legend(title = "assignment"))
})
}
if (!is.null(stress.ident2)) {
output$"hist.stress.ident2" <- shiny::renderPlot({
df <- df.data.stress.ident2() # Shiny reactive expressions
ggplot2::ggplot(df, ggplot2::aes(x = gr.av.stress.scores2, fill = factor(assignment))) +
ggplot2::scale_fill_manual(values = colorz) +
ggplot2::geom_histogram(binwidth = (2 * IQR(gr.av.stress.scores2) / length(gr.av.stress.scores2)^(1 / 3))) +
ggplot2::theme_minimal() +
ggplot2::geom_vline(ggplot2::aes(xintercept = quantile(gr.av.stress.scores2, 0.9)), colour = "black") +
ggplot2::ylab("Granule count") +
ggplot2::geom_text(hjust = -.1, vjust = 10, mapping = ggplot2::aes(x = quantile(gr.av.stress.scores2, 0.9), y = Inf, label = "90% quantile")) +
ggplot2::coord_cartesian(xlim = c(sliders$"min.x.stress.ident2", sliders$"max.x.stress.ident2")) +
ggplot2::xlab("GO Score") +
ggplot2::guides(fill = ggplot2::guide_legend(title = "assignment"))
})
}
if (!is.null(notstress.ident3)) {
output$"hist.notstress.ident3" <- shiny::renderPlot({
df <- df.data.notstress.ident3() # Shiny reactive expressions
ggplot2::ggplot(df, ggplot2::aes(x = gr.av.notstress.scores3, fill = factor(assignment))) +
ggplot2::scale_fill_manual(values = rev(colorz)) +
ggplot2::geom_histogram(binwidth = (2 * IQR(gr.av.notstress.scores3) / length(gr.av.notstress.scores3)^(1 / 3))) +
ggplot2::theme_minimal() +
ggplot2::geom_vline(ggplot2::aes(xintercept = quantile(gr.av.notstress.scores3, 0.9)), colour = "black") +
ggplot2::ylab("Granule count") +
ggplot2::geom_text(hjust = -.1, vjust = 10, mapping = ggplot2::aes(x = quantile(gr.av.notstress.scores3, 0.9), y = Inf, label = "90% quantile")) +
ggplot2::coord_cartesian(xlim = c(sliders$"min.x.notstress.ident3", sliders$"max.x.notstress.ident3")) +
ggplot2::xlab("GO Score") +
ggplot2::guides(fill = ggplot2::guide_legend(title = "assignment"))
})
}
if (!is.null(notstress.ident4)) {
output$"hist.notstress.ident4" <- shiny::renderPlot({
df <- df.data.notstress.ident4() # Shiny reactive expressions
ggplot2::ggplot(df, ggplot2::aes(x = gr.av.notstress.scores4, fill = factor(assignment))) +
ggplot2::scale_fill_manual(values = rev(colorz)) +
ggplot2::geom_histogram(binwidth = (2 * IQR(gr.av.notstress.scores4) / length(gr.av.notstress.scores4)^(1 / 3))) +
ggplot2::theme_minimal() +
ggplot2::geom_vline(ggplot2::aes(xintercept = quantile(gr.av.notstress.scores4, 0.9)), colour = "black") +
ggplot2::ylab("Granule count") +
ggplot2::geom_text(hjust = -.1, vjust = 10, mapping = ggplot2::aes(x = quantile(gr.av.notstress.scores4, 0.9), y = Inf, label = "90% quantile")) +
ggplot2::coord_cartesian(xlim = c(sliders$"min.x.notstress.ident4", sliders$"max.x.notstress.ident4")) +
ggplot2::xlab("GO Score") +
ggplot2::guides(fill = ggplot2::guide_legend(title = "assignment"))
})
}
# stress assignment UMAP
output$stress.umap <- shiny::renderPlot({
obj2 <- obj2.data()
Seurat.utils::clUMAP(obj = obj2, ident = "is.Stressed", label = F, save.plot = F) + Seurat::NoAxes() +
ggplot2::scale_color_manual(values = colorz)
})
# stress assignment barplot cell numbers
output$count.bar <- shiny::renderPlot({
obj2 <- obj2.data()
meta2 <- obj2@meta.data
ggplot2::ggplot(meta2, ggplot2::aes(x = stress.barplot.x.axis, fill = is.Stressed, stat = "count")) +
ggplot2::scale_fill_manual(values = colorz) +
ggplot2::theme_minimal() +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, vjust = 0.5, hjust = 1)) +
ggplot2::geom_bar() +
ggplot2::xlab("") +
ggplot2::ylab("Cells")
})
output$"go.score" <- shiny::renderPlot(
{
obj2 <- obj2.data.part.GO()
ptlist <- list()
count <- 1
if (!is.null(stress.ident1)) {
GOterm <- .parse.GO(stress.ident1)
GOscore <- .convert.GO_term.2.score(GOterm)
ptlist[[count]] <- Seurat::FeaturePlot(object = obj, features = GOscore, min.cutoff = "q01", max.cutoff = "q99") +
Seurat::NoLegend() + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(stress.ident2)) {
GOterm <- .parse.GO(stress.ident2)
GOscore <- .convert.GO_term.2.score(GOterm)
ptlist[[count]] <- Seurat::FeaturePlot(object = obj, features = GOscore, min.cutoff = "q01", max.cutoff = "q99") +
Seurat::NoLegend() + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(notstress.ident3)) {
GOterm <- .parse.GO(notstress.ident3)
GOscore <- .convert.GO_term.2.score(GOterm)
ptlist[[count]] <- Seurat::FeaturePlot(object = obj, features = GOscore, min.cutoff = "q01", max.cutoff = "q99") +
Seurat::NoLegend() + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(notstress.ident4)) {
GOterm <- .parse.GO(notstress.ident4)
GOscore <- .convert.GO_term.2.score(GOterm)
ptlist[[count]] <- Seurat::FeaturePlot(object = obj, features = GOscore, min.cutoff = "q01", max.cutoff = "q99") +
Seurat::NoLegend() + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(stress.ident1)) {
ptlist[[count]] <- Seurat.utils::clUMAP(obj = obj2, ident = "stress.ident1.thresh_cluster", save.plot = F) +
ggplot2::ggtitle(ggplot2::element_blank()) +
ggplot2::scale_color_manual(values = colorz) + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(stress.ident2)) {
ptlist[[count]] <- Seurat.utils::clUMAP(obj = obj2, ident = "stress.ident2.thresh_cluster", save.plot = F) +
ggplot2::ggtitle(ggplot2::element_blank()) +
ggplot2::scale_color_manual(values = colorz) + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(notstress.ident3)) {
ptlist[[count]] <- Seurat.utils::clUMAP(obj = obj2, ident = "notstress.ident3.thresh_cluster", save.plot = F) +
ggplot2::ggtitle(ggplot2::element_blank()) +
ggplot2::scale_color_manual(values = rev(colorz)) + Seurat::NoAxes()
count <- count + 1
}
if (!is.null(notstress.ident4)) {
ptlist[[count]] <- Seurat.utils::clUMAP(obj = obj2, ident = "notstress.ident4.thresh_cluster", save.plot = F) +
ggplot2::ggtitle(ggplot2::element_blank()) +
ggplot2::scale_color_manual(values = rev(colorz)) + Seurat::NoAxes()
count <- count + 1
}
gridExtra::grid.arrange(grobs = ptlist, ncol = ceiling(length(ptlist) / 2), title = "GO score")
},
height = 400,
width = w
)
shiny::observeEvent(input$save_inputs, {
obj <- obj2.data()
if (!is.null(stress.ident1)) {
i.stress.ident1 <- input$"t.stress.ident1"
obj@misc$gruffi$"thresh.stress.ident1" <- i.stress.ident1
}
if (!is.null(stress.ident2)) {
i.stress.ident2 <- input$"t.stress.ident2"
obj@misc$gruffi$"thresh.stress.ident2" <- i.stress.ident2
}
if (!is.null(notstress.ident3)) {
i.notstress.ident3 <- input$"t.notstress.ident3"
obj@misc$gruffi$"thresh.notstress.ident3" <- i.notstress.ident3
}
if (!is.null(notstress.ident4)) {
i.notstress.ident4 <- input$"t.notstress.ident4"
obj@misc$gruffi$"thresh.notstress.ident4" <- i.notstress.ident4
}
shiny::stopApp(returnValue = obj)
})
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.