Skip to content

Commit 800c6de

Browse files
committed
feat: handle empty variable in contrasts_yml by allowing report_grouping_variable.
1 parent 8c070ae commit 800c6de

File tree

5 files changed

+85
-16
lines changed

5 files changed

+85
-16
lines changed

assets/differentialabundance_report.Rmd

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -972,24 +972,54 @@ if (!is.null(params$functional_method)){
972972
cat("\n#### ", toupper(params$functional_method) ," {.tabset}\n")
973973
974974
if (params$functional_method == 'gsea') {
975+
976+
# Only keep contrasts that have both reference and target
977+
gsea_contrasts <- contrasts[
978+
!is.na(contrasts$reference) & contrasts$reference != "" &
979+
!is.na(contrasts$target) & contrasts$target != "",
980+
]
981+
982+
if (nrow(gsea_contrasts) == 0) {
983+
warning("No contrasts with reference and target defined. Skipping GSEA report section.")
984+
} else {
985+
975986
for (gmt_file in simpleSplit(params$gene_sets_files)) {
976-
gmt_name <- basename(tools::file_path_sans_ext(gmt_file))
977-
cat("\n##### ", gmt_name ," {.tabset}\n")
978-
979-
reference_gsea_tables <- paste0(differential_names, ".", gmt_name, '.gsea_report_for_', contrasts$reference, '.tsv')
980-
target_gsea_tables <- paste0(differential_names, ".", gmt_name, '.gsea_report_for_', contrasts$target, '.tsv')
981-
for (i in 1:nrow(contrasts)){
982-
cat("\n###### ", contrast_descriptions[i], "\n")
983-
target_gsea_results <- read_metadata(target_gsea_tables[i])[,c(-2,-3)]
984-
target_gsea_results <- round_dataframe_columns(target_gsea_results, digits=params$round_digits)
985-
print( htmltools::tagList(datatable(target_gsea_results, caption = paste0("\nTarget (", contrasts$target[i], ")\n"), rownames = FALSE) ))
986-
ref_gsea_results <- read_metadata(reference_gsea_tables[i])[,c(-2,-3)]
987-
ref_gsea_results <- round_dataframe_columns(ref_gsea_results, digits=params$round_digits)
988-
print( htmltools::tagList(datatable(ref_gsea_results, caption = paste0("\nReference (", contrasts$reference[i], ")\n"), rownames = FALSE) ))
987+
gmt_name <- basename(tools::file_path_sans_ext(gmt_file))
988+
cat("\n##### ", gmt_name ," {.tabset}\n")
989+
990+
reference_gsea_tables <- paste0(differential_names, ".", gmt_name, '.gsea_report_for_', gsea_contrasts$reference, '.tsv')
991+
target_gsea_tables <- paste0(differential_names, ".", gmt_name, '.gsea_report_for_', gsea_contrasts$target, '.tsv')
992+
993+
for (i in seq_len(nrow(gsea_contrasts))) {
994+
cat("\n###### ", contrast_descriptions[i], "\n")
995+
996+
if (file.exists(target_gsea_tables[i])) {
997+
target_gsea_results <- read_metadata(target_gsea_tables[i])[,c(-2,-3)]
998+
target_gsea_results <- round_dataframe_columns(target_gsea_results, digits=params$round_digits)
999+
print( htmltools::tagList(
1000+
datatable(target_gsea_results,
1001+
caption = paste0("\nTarget (", gsea_contrasts$target[i], ")\n"),
1002+
rownames = FALSE)
1003+
))
1004+
} else {
1005+
cat("\n*Target GSEA file missing: ", target_gsea_tables[i], "*\n")
1006+
}
1007+
1008+
if (file.exists(reference_gsea_tables[i])) {
1009+
ref_gsea_results <- read_metadata(reference_gsea_tables[i])[,c(-2,-3)]
1010+
ref_gsea_results <- round_dataframe_columns(ref_gsea_results, digits=params$round_digits)
1011+
print( htmltools::tagList(
1012+
datatable(ref_gsea_results,
1013+
caption = paste0("\nReference (", gsea_contrasts$reference[i], ")\n"),
1014+
rownames = FALSE)
1015+
))
1016+
} else {
1017+
cat("\n*Reference GSEA file missing: ", reference_gsea_tables[i], "*\n")
1018+
}
1019+
}
9891020
}
9901021
}
991-
992-
} else if (params$functional_method == 'gprofiler2') {
1022+
} else if (params$functional_method == 'gprofiler2') {
9931023
9941024
cat(paste0("\nThis section contains the results tables of the pathway analysis which was done with the R package gprofiler2. The differential fraction is the number of differential genes in a pathway divided by that pathway's size, i.e. the number of genes annotated for the pathway.",
9951025
ifelse(params$gprofiler2_significant, paste0(" Enrichment was only considered if significant, i.e. adjusted p-value <= ", params$gprofiler2_max_qval, "."), "Enrichment was also considered if not significant."), "\n"))

nextflow.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ params {
186186

187187
// Report options
188188
skip_reports = false
189+
report_grouping_variable = null
189190

190191
// Note: for shinyapps deployment, in addition to setting these values,
191192
// SHINYAPPS_TOKEN and SHINYAPPS_SECRET must be available to the

subworkflows/local/utils_nfcore_differentialabundance_pipeline/main.nf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,23 @@ def validateInputParameters(paramsets) {
206206
if (!(row.contrasts_yml || row.contrasts)) {
207207
error("Either '--contrasts' and '--contrasts_yml' must be set. Please specify one of these options to define contrasts.")
208208
}
209+
210+
if (row.contrasts_yml && !row.skip_reports && !row.report_grouping_variable) {
211+
log.warn """
212+
=======================================================================
213+
You are using a formula-based contrasts YAML file (--contrasts_yml)
214+
but have not provided --report_grouping_variable.
215+
216+
This can cause errors when rendering reports if no grouping variable
217+
is available in the contrasts table (the 'variable' column is empty).
218+
219+
Please specify a grouping variable to use in reports, e.g.:
220+
--report_grouping_variable 'treatment'
221+
222+
Or set --skip_reports if you do not need reporting.
223+
=======================================================================
224+
"""
225+
}
209226
}
210227
}
211228

tests/test_rnaseq_limma.nf.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ nextflow_pipeline {
7676
matrix = "https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/variancepartition_dream/counts.tsv"
7777
contrasts_yml = "https://github.com/nf-core/test-datasets/raw/differentialabundance/testdata/formula_contrasts/rnaseq_complex_contrast.yaml"
7878
exploratory_log2_assays = "raw"
79-
skip_reports = true
79+
report_grouping_variable = 'treatment'
8080
}
8181
}
8282

workflows/differentialabundance.nf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,27 @@ workflow DIFFERENTIALABUNDANCE {
789789
.groupTuple() // [ meta, [meta with contrast], [functional results] ]
790790
.map { [it[0], it.tail().tail().flatten()] } // [ meta, [functional results] ]
791791

792+
// If users provide a `report_grouping_variable` then update the contrasts file 'variable' column with that information
793+
if (params.report_grouping_variable) {
794+
ch_validated_contrast = ch_validated_contrast
795+
.splitCsv(header: true, sep: '\t')
796+
.map { meta, row ->
797+
def variable = row.variable?.trim()
798+
if (!variable || variable == 'NA') {
799+
row.variable = params.report_grouping_variable
800+
}
801+
[meta, row]
802+
}
803+
.groupTuple()
804+
.map { meta, rows ->
805+
def header = rows[0].keySet().join('\t')
806+
def lines = rows.collect { it.values().join('\t') }
807+
def content = ([header] + lines).join('\n')
808+
def outFile = file("${workflow.workDir}/${meta.id ?: meta.paramset_name}_contrast_variable_filled.tsv")
809+
outFile.text = content
810+
[meta, outFile]
811+
}
812+
}
792813
// Prepare input for report generation
793814
// Each paramset will generate one markdown report by gathering all the files created with the same paramset
794815

0 commit comments

Comments
 (0)