Skip to content

Commit d0d87e4

Browse files
authored
Merge pull request #1578 from bigomics/devel
Devel
2 parents 1c76701 + a6e8366 commit d0d87e4

File tree

15 files changed

+565
-243
lines changed

15 files changed

+565
-243
lines changed

components/app/R/global.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ opt.default <- list(
184184
APACHE_COOKIE_PATH = OPG,
185185
ALLOW_CUSTOM_FC = FALSE,
186186
DEVMODE = FALSE,
187-
ENABLE_MULTIOMICS = TRUE
187+
ENABLE_MULTIOMICS = TRUE,
188+
ENABLE_COOKIE_LOGIN = TRUE
188189
)
189190

190191
opt.file <- file.path(ETC, "OPTIONS")

components/board.clustering/R/clustering_plot_clusterpca.R

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
## Copyright (c) 2018-2023 BigOmics Analytics SA. All rights reserved.
44
##
55

6-
7-
8-
## Annotate clusters ############
9-
106
clustering_plot_clustpca_ui <- function(
117
id,
128
label = "",
@@ -78,7 +74,6 @@ clustering_plot_clustpca_server <- function(id,
7874
moduleServer(id, function(input, output, session) {
7975
ns <- session$ns
8076

81-
## Plot ############
8277
plot_data <- shiny::reactive({
8378
samples <- selected_samples()
8479
cluster.pos <- pgx$cluster$pos
@@ -87,15 +82,12 @@ clustering_plot_clustpca_server <- function(id,
8782
}
8883
all.pos <- do.call(cbind, cluster.pos)
8984
all.pos <- all.pos[samples, ]
90-
pd <- list(
91-
pos = all.pos
92-
)
93-
85+
pd <- list(pos = all.pos)
9486
return(pd)
9587
})
9688

9789

98-
create_plot <- function(pgx, pos, method, colvar, shapevar, label, cex) {
90+
create_plot <- function(pgx, pos, pca2d.varexp, method, colvar, shapevar, label, cex) {
9991
do3d <- (ncol(pos) == 3)
10092
sel <- rownames(pos)
10193
df <- cbind(pos, pgx$samples[sel, , drop = FALSE])
@@ -114,9 +106,7 @@ clustering_plot_clustpca_server <- function(id,
114106
label.samples <- (label == "sample")
115107

116108
if (!do3d && label.samples) ann.text <- rownames(df)
117-
if (!is.null(colvar)) {
118-
textvar <- factor(colvar)
119-
}
109+
if (!is.null(colvar)) textvar <- factor(colvar)
120110

121111
symbols <- c(
122112
"circle", "square", "star", "triangle-up", "triangle-down", "pentagon",
@@ -130,10 +120,8 @@ clustering_plot_clustpca_server <- function(id,
130120
cex1 <- c(1.0, 0.8, 0.6)[1 + 1 * (nrow(pos) > 30) + 1 * (nrow(pos) > 200)]
131121
clrs.length <- length(unique(colvar))
132122
clrs <- rep(omics_pal_d(palette = "muted_light")(8), ceiling(clrs.length / 8))[1:clrs.length]
133-
## clrs <- clrs[colvar]
134-
123+
135124
if (do3d) {
136-
## 3D plot
137125
plt <- plotly::plot_ly(df, mode = "markers") %>%
138126
plotly::add_markers(
139127
x = df[, 1],
@@ -174,7 +162,7 @@ clustering_plot_clustpca_server <- function(id,
174162
plotly::layout(showlegend = FALSE)
175163
}
176164
} else {
177-
## 2D plot
165+
178166
plt <- plotly::plot_ly(
179167
df,
180168
mode = "markers",
@@ -184,7 +172,7 @@ clustering_plot_clustpca_server <- function(id,
184172
x = df[, 1],
185173
y = df[, 2],
186174
type = "scattergl",
187-
color = colvar, ## size = sizevar, sizes=c(80,140),
175+
color = colvar,
188176
colors = clrs,
189177
marker = list(
190178
size = 16 * cex1 * cex,
@@ -198,13 +186,20 @@ clustering_plot_clustpca_server <- function(id,
198186
x = pos[, 1],
199187
y = pos[, 2],
200188
text = ann.text,
201-
## xref = "x", yref = "y",
202189
showarrow = FALSE
203-
) %>% # add x axis title
204-
plotly::layout(
190+
)
191+
192+
if (method == "pca") {
193+
plt <- plt %>% plotly::layout(
194+
xaxis = list(title = paste0(toupper(method), "1 (", pca2d.varexp[1], "%)")),
195+
yaxis = list(title = paste0(toupper(method), "2 (", pca2d.varexp[2], "%)"))
196+
)
197+
} else {
198+
plt <- plt %>% plotly::layout(
205199
xaxis = list(title = paste0(toupper(method), "1")),
206200
yaxis = list(title = paste0(toupper(method), "2"))
207201
)
202+
}
208203

209204
## add group/cluster annotation labels
210205
if (label == "inside") {
@@ -269,10 +264,11 @@ clustering_plot_clustpca_server <- function(id,
269264
if (do3d) m1 <- paste0(m, "3d")
270265
pos <- pgx$cluster$pos[[m1]]
271266
pos <- pos[samples, ]
272-
267+
pca2d.varexp <- pgx$cluster$pos$pca2d.varexp
273268
plist[[i]] <- create_plot(
274269
pgx = pgx,
275270
pos = pos,
271+
pca2d.varexp = pca2d.varexp,
276272
method = m,
277273
colvar = colvar,
278274
shapevar = shapevar,
@@ -290,11 +286,7 @@ clustering_plot_clustpca_server <- function(id,
290286
} else {
291287
plist <- create_plotlist()
292288
nc <- ceiling(sqrt(length(plist)))
293-
plotly::subplot(
294-
plist,
295-
nrows = nc,
296-
margin = 0.04
297-
)
289+
plotly::subplot(plist, nrows = nc, margin = 0.04)
298290
}
299291
})
300292

components/board.clustering/R/clustering_ui.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ ClusteringUI <- function(id) {
239239
clustering_plot_clustpca_ui(
240240
ns("PCAplot"),
241241
title = "Dimensionality reduction",
242-
info.text = "Using the {Color/label}, {Shape} and {Label} options it is possible to control how the points are colored and shaped (acording to which available phenotypes) and it is possible to control where are the labels located respectively. There is also the option to visualize the three dimensionality reduction techniques at the same time, and the option to visualize the plot in three dimensions.",
242+
info.text = "Using the {Color/label}, {Shape} and {Label} options it is possible to control how the points are colored and shaped (acording to which available phenotypes) and it is possible to control where are the labels located respectively. There is also the option to visualize the three dimensionality reduction techniques at the same time, and the option to visualize the plot in three dimensions. For 2-dimensional principal component analysis, the percentage of variance explained by the first two principal components is reported in the x- and y-axis.",
243243
info.methods = "Relationship (or similarity) between the samples for visual analytics, where similarity is visualized as proximity of the points. Three clustering methods are available, t-SNE (using the Rtsne R package [1]), UMAP (using the uwot R package [2]) and PCA (using the irlba R package [3]). Samples that are ‘similar’ will be placed close to each other.",
244244
info.references = list(
245245
list(

components/board.signature/R/signature_server.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ SignatureBoard <- function(id, pgx,
267267
shiny::withProgress(message = "Computing GSEA ...", value = 0.8, {
268268
res <- lapply(1:ncol(F), function(i) {
269269
set.seed(123)
270+
shiny::validate(shiny::need(any(gmt$gset %in% names(F[, i])), "Signature features not found in the dataset."))
270271
suppressWarnings(suppressMessages(
271272
res <- fgsea::fgsea(gmt, stats = F[, i], nperm = 1000, nproc = 1)
272273
))
@@ -278,6 +279,7 @@ SignatureBoard <- function(id, pgx,
278279
res1 <- data.frame(do.call(rbind, res))
279280
res1$ES <- NULL
280281
} else {
282+
shiny::validate(shiny::need(any(gmt$gset %in% rownames(F)), "Signature features not found in the dataset."))
281283
i <- 1
282284
fx <- 1 * (rownames(F) %in% gmt[[1]])
283285
rho <- cor(apply(F, 2, rank, na.last = "keep"), fx, use = "pairwise")[, 1]

components/board.upload/R/upload_module_computepgx.R

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,10 @@ upload_module_computepgx_server <- function(
466466
}
467467

468468
if (length(ia.ctx) | length(ia.spline.ctx)) {
469-
shinyalert::shinyalert(
470-
title = "Interaction analysis",
471-
text = paste0(
472-
"'", colnames(Y)[sel.time[1]], "' found in samples.csv.\n",
473-
"Interaction with time will be tested for valid contrasts."
474-
),
475-
type = "info"
476-
)
469+
# shinyalert::shinyalert(title = "Interaction analysis",
470+
# text = paste0("'", colnames(Y)[sel.time[1]], "' found in samples.csv.\n",
471+
# "Interaction with time will be tested for valid contrasts."),
472+
# type = "info")
477473

478474
if (length(ia.ctx)) {
479475
ia.ctx <- gsub(":.*", "", ia.ctx)

components/board.upload/R/upload_module_normalization.R

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ upload_module_normalization_server <- function(
221221
value = 0.3,
222222
{
223223
res <- playbase::compare_batchcorrection_methods(
224-
X1, samples,
224+
X1,
225+
samples,
225226
pheno = NULL,
226227
contrasts = contrasts,
227228
batch.pars = batch.pars,
@@ -256,12 +257,13 @@ upload_module_normalization_server <- function(
256257
## standard dim reduction methods
257258
pos <- list()
258259
set.seed(1234)
259-
pos[["pca"]] <- irlba::irlba(scaledX, nu = 2, nv = 0)$u
260+
pca <- irlba::irlba(scaledX, nu = 2, nv = 0)
261+
pos[["pca"]] <- pca$u
260262
for (i in 1:length(pos)) {
261263
rownames(pos[[i]]) <- rownames(scaledX)
262264
colnames(pos[[i]]) <- paste0(names(pos)[i], "_", 1:2)
263265
}
264-
266+
pos[["pca.varexp"]] <- (pca$d^2 / sum(pca$d^2)) * 100
265267
out$pos <- pos
266268
out$corX <- corX
267269
out
@@ -460,6 +462,67 @@ upload_module_normalization_server <- function(
460462
text(0.5, 0.5, "no missing values")
461463
}
462464
}
465+
466+
if (input$missing_plottype == "missingness across features") {
467+
if (any(X2 > 0)) {
468+
par(mfrow = c(1,1), mar = c(2, 3.5, 2, 2), mgp = c(2.5, 0.75, 0))
469+
X3 <- imputedX()$X
470+
pct.na <- round(rowMeans(is.na(X3))*100)
471+
hh <- hist(pct.na, xlim = c(0, 100), col = "grey", main = "",
472+
las = 1, tcl = -0.1, mgp = c(2.5, 0.5, 0), yaxs="i",
473+
xlab = "Missingness across features (%)", ylab = "Number of features")
474+
abline(v = mean(pct.na), col = "red")
475+
abline(v = median(pct.na), col = "blue")
476+
xpos <- 90
477+
ypos <- max(hh$counts) * 0.95
478+
lab1 <- paste0("Mean: ", round(mean(pct.na)), "%")
479+
lab2 <- paste0("Median: ", round(median(pct.na)), "%")
480+
text(xpos, ypos, labels = lab1, col = "red")
481+
text(xpos, ypos-(ypos*8/100), labels = lab2, col = "blue")
482+
title("Distribution of missing values across features"); grid()
483+
rm(X3)
484+
}
485+
else {
486+
plot.new()
487+
text(0.5, 0.5, "no missing values")
488+
}
489+
}
490+
491+
if (input$missing_plottype == "PCA of imputed data") {
492+
if (any(X2 > 0)) {
493+
X3 <- imputedX()$X
494+
if (input$impute) X3 <- log2(imputedX()$counts + imputedX()$prior)
495+
mm <- c("SVD2", "QRILC", "MinProb", "Perseus")
496+
imp <- list()
497+
for(i in 1:length(mm)) imp[[mm[i]]] <- playbase::imputeMissing(X3, mm[i])
498+
scaled.imp <- lapply(imp, function(x) playbase::double_center_scale_fast(x))
499+
par(mfrow = c(2, 2), mar = c(4, 3, 2, 0.5), las = 1, mgp = c(2, 0.4, 0), tcl = -0.1)
500+
cex1 <- cut(ncol(X3),
501+
breaks = c(0, 40, 100, 250, 1000, 999999),
502+
c(1, 0.85, 0.7, 0.55, 0.4))
503+
cex1 <- 2.7 * as.numeric(as.character(cex1))
504+
for(i in 1:length(scaled.imp)) {
505+
set.seed(1234);
506+
pca <- irlba::irlba(scaled.imp[[i]], nu = 2, nv = 0)
507+
pca.pos <- pca$u
508+
pca.var <- (pca$d^2 / sum(pca$d^2)) * 100
509+
plot(pca.pos[,1], pca.pos[,2], col = "black", pch = 20,
510+
cex = cex1, cex.lab = 1, main = names(scaled.imp)[i],
511+
xlab = paste0("PC1 (", round(pca.var[1],2), "%)"),
512+
ylab = paste0("PC2 (", round(pca.var[2],2), "%)"),
513+
asp = 1
514+
)
515+
grid()
516+
rm(pca, pca.pos, pca.var); gc()
517+
}
518+
rm(X3, imp, scaled.imp)
519+
}
520+
else {
521+
plot.new()
522+
text(0.5, 0.5, "no missing values")
523+
}
524+
}
525+
463526
}
464527
}
465528

@@ -537,34 +600,34 @@ upload_module_normalization_server <- function(
537600
}
538601

539602
plot_all_methods <- function() {
540-
res <- results_correction_methods()
541603
out.res <- results_outlier_methods()
604+
res <- results_correction_methods()
542605
shiny::req(res)
543606
shiny::req(out.res)
544607
samples <- r_samples()
545608

546609
methods <- c("uncorrected", sort(c("ComBat", "limma", "RUV", "SVA", "NPM")))
610+
547611
pos.list <- res$pos
548-
## get same positions as after outlier detection
549612
pos0 <- out.res$pos[["pca"]]
613+
550614
pos.list <- c(list("uncorrected" = pos0), pos.list)
551615

552616
colorby_var <- input$colorby_var
553617
colorby_var <- intersect(colorby_var, colnames(samples))
554-
col1 <- factor(samples[, colorby_var]) ## as.numeric(col1)
618+
col1 <- factor(samples[, colorby_var])
555619

556620
pheno <- res$pheno
557621
xdim <- length(pheno)
558-
## col1 <- factor(pheno)
559622
cex1 <- cut(xdim,
560623
breaks = c(0, 40, 100, 250, 1000, 999999),
561624
c(1, 0.85, 0.7, 0.55, 0.4)
562625
)
563626
cex1 <- 2.5 * as.numeric(as.character(cex1))
564-
par(mfrow = c(2, 3), mar = c(2, 2, 2, 1))
627+
par(mfrow = c(2, 3), mar = c(3, 3, 2, 1), mgp = c(1.7, 0.4, 0), tcl = -0.1)
565628
for (m in methods) {
566629
if (m %in% names(pos.list)) {
567-
plot(pos.list[[m]], col = col1, cex = cex1, pch = 20)
630+
plot(pos.list[[m]], col = col1, cex = cex1, pch = 20, las = 1)
568631
} else {
569632
plot.new()
570633
text(0.45, 0.5, "method failed")
@@ -578,9 +641,9 @@ upload_module_normalization_server <- function(
578641
res <- results_correction_methods()
579642
samples <- r_samples()
580643

581-
## get same positions as after outlier detection
582-
## pos0 <- res$pos[["normalized"]]
583644
pos0 <- out.res$pos[["pca"]]
645+
pos0.varexp <- out.res$pos[["pca.varexp"]]
646+
pos1.varexp <- res[["pca.varexp"]]
584647
method <- input$bec_method
585648

586649
if (!method %in% names(res$pos)) {
@@ -596,12 +659,11 @@ upload_module_normalization_server <- function(
596659
}
597660

598661
kk <- intersect(rownames(pos0), rownames(pos1))
599-
pos0 <- pos0[kk, ]
600-
pos1 <- pos1[kk, ]
662+
pos0 <- pos0[kk, , drop = FALSE]
663+
pos1 <- pos1[kk, , drop = FALSE]
601664

602665
pheno <- playbase::contrasts2pheno(r_contrasts(), r_samples())
603666
pheno <- pheno[rownames(pos0)]
604-
# col1 <- factor(pheno)
605667
colorby_var <- input$colorby_var
606668
colorby_var <- intersect(colorby_var, colnames(samples))
607669
samples <- samples[rownames(pos0), , drop = FALSE]
@@ -611,14 +673,18 @@ upload_module_normalization_server <- function(
611673
c(1, 0.85, 0.7, 0.55, 0.4)
612674
)
613675
cex1 <- 2.7 * as.numeric(as.character(cex1))
614-
par(mfrow = c(1, 2), mar = c(3.2, 3, 2, 0.5), mgp = c(2.1, 0.8, 0))
676+
par(mfrow = c(1, 2), mar = c(3.2, 3, 2, 0.5), mgp = c(2.1, 0.4, 0), tcl = -0.1)
615677
plot(pos0,
616-
col = col1, pch = 20, cex = 1.0 * cex1, las = 1,
617-
main = "uncorrected", xlab = "PC1", ylab = "PC2"
678+
col = col1, pch = 20, cex = cex1, las = 1,
679+
main = "uncorrected",
680+
xlab = paste0("PC1 (", round(pos0.varexp[1],2), "%)"),
681+
ylab = paste0("PC2 (", round(pos0.varexp[2],2), "%)")
618682
)
619683
plot(pos1,
620-
col = col1, pch = 20, cex = 1.0 * cex1, las = 1,
621-
main = method, xlab = "PC1", ylab = "PC2"
684+
col = col1, pch = 20, cex = cex1, las = 1,
685+
main = method,
686+
xlab = paste0("PC1 (", round(pos1.varexp[[method]][1],2), "%)"),
687+
ylab = paste0("PC2 (", round(pos1.varexp[[method]][2],2), "%)")
622688
)
623689
}
624690

@@ -669,7 +735,7 @@ upload_module_normalization_server <- function(
669735
"Outliers markedly deviate from the vast majority of samples. Outliers could be caused by technical factors and negatively affect data analysis. Here, outliers are identified and marked for removal should you wish so."
670736

671737
missing.infotext <-
672-
"Missing values (MVs) reduce the completeness of biological data and hinder preprocessing steps. MVs (i.e., NA), more often populate proteomics and metabolomics data. Here, MVs are identified and their patterns in your data is shown."
738+
"Missing values (MVs) reduce the completeness of biological data and hinder preprocessing steps. MVs (i.e., NA), more often populate proteomics and metabolomics data. Here, MVs are identified and their patterns in your data is shown. PCA is also optionally performed on data imputed with all methods to aid comparison."
673739

674740
normalization.infotext <-
675741
"Normalization enables to standardize the data and improve their consistency, comparability and reproducibility. Boxplots of raw (unnormalized) and normalized data are shown. Normalization method can be selected on the left, under “Normalization”."
@@ -678,12 +744,10 @@ upload_module_normalization_server <- function(
678744
"Batch effects (BEs) are due to technical, experimental factors that introduce unwanted variation into the measurements. Here, BEs are detected and BEs correction is shown. BE correction methods can be selected on the left, under “Batch-effects correction”."
679745

680746
missing.options <- tagList(
681-
shiny::radioButtons(ns("missing_plottype"),
682-
"Plot type:",
683-
c("heatmap", "ratio plot", "missingness per sample"),
684-
selected = "heatmap",
685-
inline = TRUE
686-
),
747+
shiny::radioButtons(ns("missing_plottype"), "Plot type:",
748+
c("heatmap", "ratio plot", "missingness per sample",
749+
"missingness across features", "PCA of imputed data"),
750+
selected = "heatmap", inline = TRUE),
687751
)
688752

689753
norm.options <- tagList(

0 commit comments

Comments
 (0)