Skip to content

Commit 79603fc

Browse files
authored
Merge pull request #462 from atrigila/limma_formula
2 parents 883ee29 + 3e92fc3 commit 79603fc

File tree

25 files changed

+1184
-446
lines changed

25 files changed

+1184
-446
lines changed

assets/differentialabundance_report.Rmd

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ if (is.null(differential_file_suffix)) {
367367
differential_file_suffix <- paste0(".", params$differential_method, ".results.tsv")
368368
}
369369
differential_files <- lapply(contrasts$id, function(d){
370-
file.path(params$input_dir, paste0(gsub(' |;', '_', d), '_', params$study_name, differential_file_suffix))
370+
file.path(params$input_dir, paste0(gsub(' |;', '_', d), differential_file_suffix))
371371
})
372372
differential_names <- paste0(contrasts$id, '_', params$study_name)
373373
@@ -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"))

docs/usage.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ contrasts:
200200
The necessary fields in order are:
201201

202202
- `formula` - A string representation of the model formula. It is used to build the design matrix.
203-
- `make_contrasts_str` - An explicit literal contrast string (e.g., "treatmenthND6 - treatmentmCherry") that is passed directly to [`limma::makeContrasts()`](https://rdrr.io/bioc/limma/man/makeContrasts.html) in `VARIANCEPARTITION_DREAM`. The parameter names must be syntactically valid variable names in R (see [`make.names`](https://stat.ethz.ch/R-manual/R-devel/library/base/html/make.names.html)). This field provides full control for complex designs. Requires `formula`.
203+
- `make_contrasts_str` - An explicit literal contrast string (e.g., "treatmenthND6 - treatmentmCherry") that is passed directly to [`limma::makeContrasts()`](https://rdrr.io/bioc/limma/man/makeContrasts.html) in `VARIANCEPARTITION_DREAM` and `LIMMA_DIFFERENTIAL`. The parameter names must be syntactically valid variable names in R (see [`make.names`](https://stat.ethz.ch/R-manual/R-devel/library/base/html/make.names.html)). This field provides full control for complex designs. Requires `formula`.
204204

205205
> [!WARNING]
206-
> Formula-based contrasts are currently only supported by `VARIANCEPARTITION_DREAM`. They **do not work** with tools like `DESEQ2` or base `LIMMA` implementations yet.
206+
> Formula-based contrasts are currently only supported by `VARIANCEPARTITION_DREAM` and `LIMMA_DIFFERENTIAL`. They **do not work** with tools like `DESEQ2` yet.
207207

208208
> [!NOTE]
209209
>
@@ -215,6 +215,7 @@ The necessary fields in order are:
215215
> - Then, `make_contrasts_str: "conditiontreated"` selects that coefficient for testing.
216216
>
217217
> This gives full control over the contrast definition but requires understanding of the model matrix.
218+
> Some downstream applications (e.g. `GSEA_GSEA`, `SHINYNGS_APP`) do not support formula-based contrasts as they require a `meta.variable`.
218219

219220
Beyond the basic one-factor comparison, the YAML contrasts format supports advanced experimental designs through the use of interaction terms and custom contrast strings. These are particularly useful in multifactorial experiments where the effect of one variable may depend on the level of another (e.g. genotype × treatment). To model an interaction between genotype and treatment, use a formula like `~ genotype * treatment`, which expands the yaml to:
220221

@@ -465,6 +466,8 @@ process {
465466

466467
You will not get the final reporting outcomes of the workflow, but you will get the differential tables produced by DESeq2 or Limma, and the results of any gene seta analysis you have enabled.
467468

469+
We have also added a dedicated pipeline parameter, `--skip_reports` that allows you to skip only the RMarkdown notebook and bundled report while leaving other reporting processes active. The `RMARKDOWNNOTEBOOK` process assumes that every grouping variable you pass to it (from the contrasts file’s variable column or PCA-derived informative_variables) exists as a valid, named column in your sample metadata. If you know your metadata or contrasts might be incomplete or non-standard (such as using formula-based yaml files), the you can use this flag to skip these steps.
470+
468471
#### Restricting samples considered by DESeq2 or Limma
469472

470473
By default, the DESeq2 or Limma differential modules model all samples at once, rather than just the samples involved in the contrast. This is usually the correct thing to do, but when there are are large numbers of samples involved in each contrast it may be unnecessary, and things can be sped up significantly by setting `--differential_subset_to_contrast_samples`. This will remove any samples not relevant to the contrast before the main differential analysis routines are called.

modules.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
},
7373
"limma/differential": {
7474
"branch": "master",
75-
"git_sha": "6ac0725bddb061e6f8eb3e22d20129f901021d9a",
75+
"git_sha": "41d1a6ad16756e12a424e508cbe3a1b3b8639946",
7676
"installed_by": ["abundance_differential_filter"]
7777
},
7878
"propr/grea": {
@@ -82,7 +82,7 @@
8282
},
8383
"propr/propd": {
8484
"branch": "master",
85-
"git_sha": "25c228dd132d91596e87b636b0e03fd48d4c951a",
85+
"git_sha": "ce6e8e8bc0c00d284733d7c48ddc794873f60ffe",
8686
"installed_by": ["abundance_differential_filter"]
8787
},
8888
"proteus/readproteingroups": {
@@ -136,12 +136,12 @@
136136
"nf-core": {
137137
"abundance_differential_filter": {
138138
"branch": "master",
139-
"git_sha": "6ac0725bddb061e6f8eb3e22d20129f901021d9a",
139+
"git_sha": "4006954b7bfbbc61c7d5fb009319ed536d2ffca4",
140140
"installed_by": ["subworkflows"]
141141
},
142142
"differential_functional_enrichment": {
143143
"branch": "master",
144-
"git_sha": "6ac0725bddb061e6f8eb3e22d20129f901021d9a",
144+
"git_sha": "4006954b7bfbbc61c7d5fb009319ed536d2ffca4",
145145
"installed_by": ["subworkflows"]
146146
},
147147
"utils_nextflow_pipeline": {

modules/nf-core/limma/differential/main.nf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/nf-core/limma/differential/meta.yml

Lines changed: 9 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)