diff --git a/NAMESPACE b/NAMESPACE index 3cc68d95..624bee7d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand +export(LCBD_pq) export(SRS_curve_pq) export(accu_plot) export(accu_samp_threshold) @@ -42,6 +43,7 @@ export(lulu_phyloseq) export(lulu_pq) export(merge_krona) export(multi_biplot_pq) +export(multipatt_pq) export(multiplot) export(multitax_bar_pq) export(otu_circle) @@ -49,6 +51,7 @@ export(perc) export(phyloseq_to_edgeR) export(physeq_graph_test) export(physeq_heat_tree) +export(plot_LCBD_pq) export(plot_deseq2_phyloseq) export(plot_deseq2_pq) export(plot_edgeR_phyloseq) @@ -75,6 +78,7 @@ export(summary_plot_phyloseq) export(summary_plot_pq) export(tax_bar_pq) export(tax_datatable) +export(tbl_sum_samdata) export(track_wkflow) export(track_wkflow_samples) export(treemap_pq) diff --git a/NEWS.md b/NEWS.md index 89d541c4..a150d2d3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # MiscMetabar 0.51 (in development) -- Add function `LCBD_pq()` and `plot_LCBD_pq()` to compute, test and plot local contributions to beta diversity (LCBD) of samples +- Add function `LCBD_pq()` and `plot_LCBD_pq()` to compute, test and plot local contributions to beta diversity (LCBD) of samples +- Add function `tbl_sum_samdata()` to summarize information from sample data in a table # MiscMetabar 0.5 diff --git a/R/beta_div_test.R b/R/beta_div_test.R index 4a53d649..3861ea29 100644 --- a/R/beta_div_test.R +++ b/R/beta_div_test.R @@ -355,24 +355,40 @@ plot_LCBD_pq <- function(physeq, } +#' @title Test and plot multipatt result +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A wrapper for the [indicspecies::multipatt()] function in the case of `physeq` +#' object. +#' @inheritParams clean_pq +#' @param fact (required) Name of the factor in `physeq@sam_data` used to plot +#' different lines +#' @param p_adjust_method (chr, default "BH"): the method used to adjust p-value +#' @param pval (int, default 0.05): the value to determine the significance of +#' LCBD +#' @param control see `?indicspecies::multipatt()` +#' @param ... Others arguments passed on to [indicspecies::multipatt()] function +#' +#' @return A ggplot object +#' @export #' @examples #' multipatt_pq(subset_samples(data_fungi, !is.na(Time)), fact="Time") #' multipatt_pq(subset_samples(data_fungi, !is.na(Time)), fact="Time", #' max.order = 1, control = how(nperm=9999)) +#' @author Adrien Taudière multipatt_pq <- function(physeq, fact, p_adjust_method = "BH", pval = 0.05, control = how(nperm = 999), -max.order = 3, ...){ res <- - multipatt(as.matrix(physeq@otu_table), + indicspecies::multipatt(as.matrix(physeq@otu_table), physeq@sam_data[[fact]], control = control, - max.order = max.order, ...) res_df <- res$sign diff --git a/R/plot_functions.R b/R/plot_functions.R index 3edc4ce2..9fcb7d4a 100644 --- a/R/plot_functions.R +++ b/R/plot_functions.R @@ -1251,7 +1251,7 @@ hill_pq <- colnames(otu_hill) <- c("Hill_0", "Hill_1", "Hill_2") df_hill <- data.frame(otu_hill, physeq@sam_data) - df_hill[, c(1:3)] <- apply(df_hill[, c(1:3)], 2, as.numeric) + df_hill[, 1:3] <- apply(df_hill[, 1:3], 2, as.numeric) p_var <- hill_tuckey_pq(physeq, variable, correction_for_sample_size = correction_for_sample_size) @@ -1654,7 +1654,7 @@ rotl_pq <- function(physeq, #' @inheritParams clean_pq #' @param taxonomic_level (default: NULL): a vector of selected #' taxonomic level using -#' their column numbers (e.g. taxonomic_level = c(1:7)) +#' their column numbers (e.g. taxonomic_level = 1:7) #' @param ... Arguments passed on to \code{\link[metacoder]{heat_tree}} #' #' @return A plot diff --git a/R/table_functions.R b/R/table_functions.R index 82798095..022de634 100644 --- a/R/table_functions.R +++ b/R/table_functions.R @@ -5,7 +5,7 @@ #' @inheritParams clean_pq #' @param abundance (default: TRUE) Does the number of sequences is print #' @param taxonomic_level (default: NULL) a vector of selected taxonomic -#' level using their column numbers (e.g. taxonomic_level = c(1:7)) +#' level using their column numbers (e.g. taxonomic_level = 1:7) #' @param modality (default: NULL) A sample modality to split #' OTU abundancy by level of the modality #' @param ... Other argument for the datatable function @@ -229,7 +229,7 @@ compare_pairs_pq <- function(physeq = NULL, } res_df_t <- t(as_tibble(res, .name_repair = "minimal")) - colnames(res_df_t) <- paste0("V", seq_along(ncol(res_df_t)) + colnames(res_df_t) <- paste0("V", seq_along(ncol(res_df_t))) res_df <- as_tibble(res_df_t) # res_df <- as_tibble(t(as_tibble(res, .name_repair = "universal")), .name_repair = "universal") diff --git a/README.Rmd b/README.Rmd index 5ca66d67..8f3a8dc6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -24,7 +24,7 @@ knitr::opts_chunk$set( ) ``` -# MiscMetabar +# MiscMetabar MiscMetabar website See the pkdown site [here](https://adrientaudiere.github.io/MiscMetabar/). diff --git a/default.nix b/default.nix new file mode 100644 index 00000000..09febf1f --- /dev/null +++ b/default.nix @@ -0,0 +1,73 @@ +# This file was generated by the {rix} R package v0.4.1 on 2023-11-21 +# with following call: +# >rix(r_ver = "976fa3369d722e76f37c77493d99829540d43845", +# > r_pkgs = c("quarto", +# > "dplyr", +# > "DT", +# > "flexdashboard", +# > "forcats", +# > "formattable", +# > "ggplot2", +# > "ggVennDiagram", +# > "grid", +# > "gridExtra", +# > "here", +# > "knitr", +# > "networkD3", +# > "optparse", +# > "plotly", +# > "qs", +# > "quarto", +# > "rmarkdown", +# > "stringr", +# > "targets", +# > "this.path", +# > "treemap", +# > "vegan", +# > "viridis", +# > "visNetwork"), +# > system_pkgs = "quarto", +# > tex_pkgs = c("amsmath", +# > "framed", +# > "fvextra", +# > "environ", +# > "fontawesome5", +# > "orcidlink", +# > "pdfcol", +# > "tcolorbox", +# > "tikzfill"), +# > ide = "rstudio", +# > project_path = ".", +# > overwrite = TRUE, +# > print = TRUE, +# > shell_hook = "") +# It uses nixpkgs' revision 976fa3369d722e76f37c77493d99829540d43845 for reproducibility purposes +# which will install R version 4.3.1 +# Report any issues to https://github.com/b-rodrigues/rix +let + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/976fa3369d722e76f37c77493d99829540d43845.tar.gz") {}; + rpkgs = builtins.attrValues { + inherit (pkgs.rPackages) quarto dplyr DT flexdashboard forcats formattable ggplot2 ggVennDiagram grid gridExtra here knitr networkD3 optparse plotly qs quarto rmarkdown stringr targets this_path treemap vegan viridis visNetwork; +}; + tex = (pkgs.texlive.combine { + inherit (pkgs.texlive) scheme-small amsmath framed fvextra environ fontawesome5 orcidlink pdfcol tcolorbox tikzfill; +}); + system_packages = builtins.attrValues { + inherit (pkgs) R glibcLocalesUtf8 quarto; +}; + rstudio_pkgs = pkgs.rstudioWrapper.override { + packages = [ rpkgs ]; +}; + in + pkgs.mkShell { + LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocalesUtf8}/lib/locale/locale-archive" else ""; + LANG = "en_US.UTF-8"; + LC_ALL = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + + buildInputs = [ rpkgs tex system_packages rstudio_pkgs ]; + + } diff --git a/man/LCBD_pq.Rd b/man/LCBD_pq.Rd new file mode 100644 index 00000000..d5fc8d5c --- /dev/null +++ b/man/LCBD_pq.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/beta_div_test.R +\name{LCBD_pq} +\alias{LCBD_pq} +\title{Compute and test local contributions to beta diversity (LCBD) of samples} +\usage{ +LCBD_pq(physeq, p_adjust_method = "BH", ...) +} +\arguments{ +\item{physeq}{(required): a \code{\link{phyloseq-class}} object obtained +using the \code{phyloseq} package.} + +\item{p_adjust_method}{(chr, default "BH"): the method used to adjust p-value} + +\item{...}{Others arguments passed on to \code{\link[adespatial:beta.div]{adespatial::beta.div()}} function} +} +\value{ +An object of class \code{beta.div} see \code{\link[adespatial:beta.div]{adespatial::beta.div()}} function +for more information +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A wrapper for the \code{\link[adespatial:beta.div]{adespatial::beta.div()}} function in the case of \code{physeq} +object. +} +\examples{ +LCBD_pq(data_fungi, nperm=100) +LCBD_pq(data_fungi, nperm=100, method = "jaccard") +} +\seealso{ +\link{plot_LCBD_pq}, \code{\link[adespatial:beta.div]{adespatial::beta.div()}} +} diff --git a/man/MiscMetabar-package.Rd b/man/MiscMetabar-package.Rd index d0e0e8ea..f3538d9c 100644 --- a/man/MiscMetabar-package.Rd +++ b/man/MiscMetabar-package.Rd @@ -9,6 +9,8 @@ Functions to help analyze and visualize metabarcoding data. Mainly based on the phyloseq and dada2 packages. +\if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} + Functions to help analyze and visualize metabarcoding data. Mainly build on the top of phyloseq, dada2 and targets R packages. } \seealso{ diff --git a/man/figures/logo.png b/man/figures/logo.png new file mode 100644 index 00000000..c8f4a3a7 Binary files /dev/null and b/man/figures/logo.png differ diff --git a/man/heat_tree_pq.Rd b/man/heat_tree_pq.Rd index abee6e21..f70bafb3 100644 --- a/man/heat_tree_pq.Rd +++ b/man/heat_tree_pq.Rd @@ -12,7 +12,7 @@ using the \code{phyloseq} package.} \item{taxonomic_level}{(default: NULL): a vector of selected taxonomic level using -their column numbers (e.g. taxonomic_level = c(1:7))} +their column numbers (e.g. taxonomic_level = 1:7)} \item{...}{Arguments passed on to \code{\link[metacoder]{heat_tree}}} } diff --git a/man/multipatt_pq.Rd b/man/multipatt_pq.Rd new file mode 100644 index 00000000..1f8b3306 --- /dev/null +++ b/man/multipatt_pq.Rd @@ -0,0 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/beta_div_test.R +\name{multipatt_pq} +\alias{multipatt_pq} +\title{Test and plot multipatt result} +\usage{ +multipatt_pq( + physeq, + fact, + p_adjust_method = "BH", + pval = 0.05, + control = how(nperm = 999), + ... +) +} +\arguments{ +\item{physeq}{(required): a \code{\link{phyloseq-class}} object obtained +using the \code{phyloseq} package.} + +\item{fact}{(required) Name of the factor in \code{physeq@sam_data} used to plot +different lines} + +\item{p_adjust_method}{(chr, default "BH"): the method used to adjust p-value} + +\item{pval}{(int, default 0.05): the value to determine the significance of +LCBD} + +\item{control}{see \code{?indicspecies::multipatt()}} + +\item{...}{Others arguments passed on to \code{\link[indicspecies:multipatt]{indicspecies::multipatt()}} function} +} +\value{ +A ggplot object +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A wrapper for the \code{\link[indicspecies:multipatt]{indicspecies::multipatt()}} function in the case of \code{physeq} +object. +} +\examples{ +multipatt_pq(subset_samples(data_fungi, !is.na(Time)), fact="Time") +multipatt_pq(subset_samples(data_fungi, !is.na(Time)), fact="Time", + max.order = 1, control = how(nperm=9999)) +} +\author{ +Adrien Taudière +} diff --git a/man/plot_LCBD_pq.Rd b/man/plot_LCBD_pq.Rd new file mode 100644 index 00000000..738f81a1 --- /dev/null +++ b/man/plot_LCBD_pq.Rd @@ -0,0 +1,58 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/beta_div_test.R +\name{plot_LCBD_pq} +\alias{plot_LCBD_pq} +\title{Plot and test local contributions to beta diversity (LCBD) of samples} +\usage{ +plot_LCBD_pq( + physeq, + p_adjust_method = "BH", + pval = 0.05, + sam_variables = NULL, + only_plot_significant = TRUE, + ... +) +} +\arguments{ +\item{physeq}{(required): a \code{\link{phyloseq-class}} object obtained +using the \code{phyloseq} package.} + +\item{p_adjust_method}{(chr, default "BH"): the method used to adjust p-value} + +\item{pval}{(int, default 0.05): the value to determine the significance of +LCBD} + +\item{sam_variables}{A vector of variables names present in the \code{sam_data} +slot to plot alongside the LCBD value} + +\item{only_plot_significant}{(logical, default TRUE) Do we plot all LCBD +values or only the significant ones} + +\item{...}{Others arguments passed on to \code{\link[adespatial:beta.div]{adespatial::beta.div()}} function} +} +\value{ +A ggplot object build with the package patchwork +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A wrapper for the \code{\link[adespatial:beta.div]{adespatial::beta.div()}} function in the case of \code{physeq} +object. +} +\examples{ +plot_LCBD_pq(data_fungi, nperm=100, only_plot_significant = FALSE, pval = 0.2) +plot_LCBD_pq(data_fungi, nperm=100, only_plot_significant = TRUE, pval = 0.2) +plot_LCBD_pq(data_fungi, nperm=100, only_plot_significant = FALSE, + sam_variables=c("Time", "Height")) +plot_LCBD_pq(data_fungi, nperm=100, only_plot_significant = TRUE, pval = 0.2, + sam_variables=c("Time", "Height", "Tree_name")) & + theme(legend.key.size = unit(0.4, 'cm'), + legend.text = element_text(size=10), + axis.title.x = element_text(size=6)) +} +\seealso{ +\link{LCBD_pq}, \code{\link[adespatial:beta.div]{adespatial::beta.div()}} +} +\author{ +Adrien Taudière +} diff --git a/man/sankey_pq.Rd b/man/sankey_pq.Rd index f8c8baf3..03119423 100644 --- a/man/sankey_pq.Rd +++ b/man/sankey_pq.Rd @@ -7,7 +7,7 @@ sankey_pq( physeq = NULL, fact = NULL, - taxa = c(1:4), + taxa = 1:4, add_nb_seq = FALSE, min_prop_tax = 0, tax2remove = NULL, @@ -57,8 +57,8 @@ of \code{fact} data("GlobalPatterns") GP <- subset_taxa(GlobalPatterns, GlobalPatterns@tax_table[, 1] == "Archaea") sankey_pq(GP, fact = "SampleType") -sankey_pq(GP, taxa = c(1:4), min_prop_tax = 0.01) -sankey_pq(GP, taxa = c(1:4), min_prop_tax = 0.01, add_nb_seq = TRUE) +sankey_pq(GP, taxa = 1:4, min_prop_tax = 0.01) +sankey_pq(GP, taxa = 1:4, min_prop_tax = 0.01, add_nb_seq = TRUE) } \seealso{ \code{\link[networkD3]{sankeyNetwork}} diff --git a/man/tax_datatable.Rd b/man/tax_datatable.Rd index 2307ce74..19561118 100644 --- a/man/tax_datatable.Rd +++ b/man/tax_datatable.Rd @@ -19,7 +19,7 @@ using the \code{phyloseq} package.} \item{abundance}{(default: TRUE) Does the number of sequences is print} \item{taxonomic_level}{(default: NULL) a vector of selected taxonomic -level using their column numbers (e.g. taxonomic_level = c(1:7))} +level using their column numbers (e.g. taxonomic_level = 1:7)} \item{modality}{(default: NULL) A sample modality to split OTU abundancy by level of the modality} diff --git a/man/tbl_sum_samdata.Rd b/man/tbl_sum_samdata.Rd new file mode 100644 index 00000000..55ec7ca1 --- /dev/null +++ b/man/tbl_sum_samdata.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dada_phyloseq.R +\name{tbl_sum_samdata} +\alias{tbl_sum_samdata} +\title{Summarize information from sample data in a table} +\usage{ +tbl_sum_samdata(physeq, remove_col_unique_value = TRUE, ...) +} +\arguments{ +\item{physeq}{(required): a \code{\link{phyloseq-class}} object obtained +using the \code{phyloseq} package.} + +\item{remove_col_unique_value}{(logical, default TRUE) Do we remove informative +columns (categorical column with one value per samples), e.g. samples names ?} + +\item{...}{Others arguments pass on to \code{\link[tbl_summary:tbl_summary]{tbl_summary::tbl_summary()}}.} +} +\value{ +a physeq object with a larger slot tax_table +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A wrapper for the \link[tbl_summary:tbl_summary(...)]{tbl_summary::tbl_summary(...)} function in the case of \code{physeq} +object. +} +\examples{ +tbl_sum_samdata(data_fungi) + +tbl_sum_samdata(data_fungi, include = c("Time", "Height"), + type= list(Time ~ "continuous2", Height ~ "categorical"), + statistic = list(Time ~ c("{median} ({p25}, {p75})", "{min}, {max}"))) + +tbl_sum_samdata (enterotype) +tbl_sum_samdata (enterotype, include = !contains("SampleId")) +} +\author{ +Adrien Taudière +} diff --git a/pkgdown/favicon/apple-touch-icon-120x120.png b/pkgdown/favicon/apple-touch-icon-120x120.png new file mode 100644 index 00000000..97992763 Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-120x120.png differ diff --git a/pkgdown/favicon/apple-touch-icon-152x152.png b/pkgdown/favicon/apple-touch-icon-152x152.png new file mode 100644 index 00000000..1e7c8899 Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-152x152.png differ diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png new file mode 100644 index 00000000..d55e0716 Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-180x180.png differ diff --git a/pkgdown/favicon/apple-touch-icon-60x60.png b/pkgdown/favicon/apple-touch-icon-60x60.png new file mode 100644 index 00000000..69e6db1d Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-60x60.png differ diff --git a/pkgdown/favicon/apple-touch-icon-76x76.png b/pkgdown/favicon/apple-touch-icon-76x76.png new file mode 100644 index 00000000..1d5cdecc Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-76x76.png differ diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png new file mode 100644 index 00000000..4ac21e60 Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon.png differ diff --git a/pkgdown/favicon/favicon-16x16.png b/pkgdown/favicon/favicon-16x16.png new file mode 100644 index 00000000..12e5faa4 Binary files /dev/null and b/pkgdown/favicon/favicon-16x16.png differ diff --git a/pkgdown/favicon/favicon-32x32.png b/pkgdown/favicon/favicon-32x32.png new file mode 100644 index 00000000..cf61c1fd Binary files /dev/null and b/pkgdown/favicon/favicon-32x32.png differ diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico new file mode 100644 index 00000000..87be5bf5 Binary files /dev/null and b/pkgdown/favicon/favicon.ico differ diff --git a/tests/testthat/test_figures_beta_div.R b/tests/testthat/test_figures_beta_div.R index f102316f..a9dfb993 100644 --- a/tests/testthat/test_figures_beta_div.R +++ b/tests/testthat/test_figures_beta_div.R @@ -280,6 +280,6 @@ test_that("upset_test_pq works with data_fungi dataset", { ), "data.frame" ) - expect_error(upset_test_pq(data_fungi, "Height", var_to_test = c("GUILDDDS"))) + expect_error(upset_test_pq(data_fungi, "Height", var_to_test = "GUILDDDS")) expect_error(upset_test_pq(data_fungi)) }) diff --git a/tests/testthat/test_figures_taxo.R b/tests/testthat/test_figures_taxo.R index 0ee22e0b..097b4c13 100644 --- a/tests/testthat/test_figures_taxo.R +++ b/tests/testthat/test_figures_taxo.R @@ -32,7 +32,7 @@ test_that("heat_tree_pq works with data_fungi dataset", { expect_silent(suppressMessages(ht <- heat_tree_pq(data_basidio))) expect_s3_class(ht, "ggplot") expect_s3_class( - heat_tree_pq(data_basidio, taxonomic_level = c(1:4)), + heat_tree_pq(data_basidio, taxonomic_level = 1:4), "ggplot" ) }) diff --git a/tests/testthat/test_table_functions.R b/tests/testthat/test_table_functions.R index 7d947dc1..3f6b281c 100644 --- a/tests/testthat/test_table_functions.R +++ b/tests/testthat/test_table_functions.R @@ -3,7 +3,7 @@ data(data_fungi) test_that("tax_datatable function works fine with data_fungi dataset", { expect_silent(taxdt <- tax_datatable(data_fungi)) expect_s3_class(taxdt, "datatables") - expect_silent(taxdt <- tax_datatable(data_fungi, taxonomic_level = c(1:2))) + expect_silent(taxdt <- tax_datatable(data_fungi, taxonomic_level = 1:2)) expect_s3_class(taxdt, "datatables") expect_no_warning(taxdt <- suppressWarnings(tax_datatable(data_fungi, modality = data_fungi@sam_data$Height))) expect_s3_class(taxdt, "datatables") diff --git a/vignettes/beta-div.Rmd b/vignettes/beta-div.Rmd index 7b398030..760768b1 100644 --- a/vignettes/beta-div.Rmd +++ b/vignettes/beta-div.Rmd @@ -85,7 +85,7 @@ ggvenn_pq(data_fungi, fact = "Height", taxonomic_rank = "Genus", min_nb_seq = 10 ## Upset plot -Venn diagramm can quickly become complex to read when the number of modality increase. One graphical solution is upset plot. MiscMetabar propose a solution based on the package [ComplexUpset](https://krassowski.github.io/complex-upset/). +Venn diagram can quickly become complex to read when the number of modalities increase. One graphical solution is upset plot. MiscMetabar propose a solution based on the package [ComplexUpset](https://krassowski.github.io/complex-upset/). ```{r} upset_pq(data_fungi, fact = "Height") ```