├── .Rbuildignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── agglomeration.R ├── as_tibble.R ├── dplyr-joins.R ├── dplyr-verbs.R ├── import-phyloseq.R ├── merge_samples.R ├── merge_taxa_vec.R ├── phyloseq-constructors.R ├── plot-methods.R ├── printing.R ├── psmelt.R ├── transform-filter.R ├── utils-pipe.R ├── utils.R └── zzz.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── docs ├── 404.html ├── LICENSE-text.html ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── Rplot004.png │ ├── Rplot005.png │ ├── Rplot006.png │ ├── Rplot007.png │ ├── Rplot008.png │ ├── as_tibble-phyloseq.html │ ├── bad_flush_right.html │ ├── bad_or_unique.html │ ├── filter-phyloseq.html │ ├── filter_sample_data.html │ ├── filter_tax_table.html │ ├── filter_taxa.html │ ├── import_phyloseq_functions.html │ ├── index.html │ ├── join-phyloseq.html │ ├── merge_groups.html │ ├── merge_samples2.html │ ├── merge_taxa_vec-methods.html │ ├── merge_taxa_vec.html │ ├── merge_taxa_vec_pseudo.html │ ├── mutate-phyloseq.html │ ├── mutate_sample_data.html │ ├── mutate_tax_table.html │ ├── oneline.html │ ├── orient_taxa.html │ ├── pipe.html │ ├── plot_bar-1.png │ ├── plot_bar-2.png │ ├── plot_bar-3.png │ ├── plot_bar-4.png │ ├── plot_bar.html │ ├── plot_heatmap-1.png │ ├── plot_heatmap-2.png │ ├── plot_heatmap-3.png │ ├── plot_heatmap-4.png │ ├── plot_heatmap-5.png │ ├── plot_heatmap-6.png │ ├── plot_heatmap-7.png │ ├── plot_heatmap-8.png │ ├── plot_heatmap.html │ ├── plot_tree-1.png │ ├── plot_tree-2.png │ ├── plot_tree.html │ ├── ps_tibble.html │ ├── psmelt-1.png │ ├── psmelt.html │ ├── reexports.html │ ├── relocate-phyloseq.html │ ├── rename-phyloseq.html │ ├── sample_data_stable.html │ ├── select-phyloseq.html │ ├── select_taxa-methods.html │ ├── show-methods.html │ ├── tax_glom.html │ ├── tibble-constructors.html │ ├── tibble_print.html │ ├── tip_glom-1.png │ ├── tip_glom-2.png │ ├── tip_glom.html │ ├── transform_sample_counts.html │ ├── tree_glom-1.png │ ├── tree_glom.html │ └── unique_or_na.html └── sitemap.xml ├── man ├── as_tibble-phyloseq.Rd ├── bad_flush_right.Rd ├── bad_or_unique.Rd ├── filter-phyloseq.Rd ├── filter_taxa.Rd ├── import_phyloseq_functions.Rd ├── join-phyloseq.Rd ├── merge_groups.Rd ├── merge_samples2.Rd ├── merge_taxa_vec.Rd ├── merge_taxa_vec_pseudo.Rd ├── mutate-phyloseq.Rd ├── oneline.Rd ├── orient_taxa.Rd ├── pipe.Rd ├── plot_bar.Rd ├── plot_heatmap.Rd ├── plot_tree.Rd ├── psmelt.Rd ├── reexports.Rd ├── relocate-phyloseq.Rd ├── rename-phyloseq.Rd ├── sample_data_stable.Rd ├── select-phyloseq.Rd ├── select_taxa-methods.Rd ├── show-methods.Rd ├── tax_glom.Rd ├── tibble-constructors.Rd ├── tibble_print.Rd ├── tip_glom.Rd ├── transform_sample_counts.Rd ├── tree_glom.Rd └── unique_or_na.Rd └── tests ├── testthat.R └── testthat ├── test-as_tibble.R ├── test-constructors.R ├── test-dplyr-verbs.R ├── test-glom-functions.R ├── test-merge_samples.R ├── test-merge_taxa_vec.R ├── test-print.R ├── test-psmelt.R ├── test-transform-filter.R └── test-utils.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^README\.Rmd$ 2 | ^dev$ 3 | ^\.travis\.yml$ 4 | ^_pkgdown\.yml$ 5 | ^docs$ 6 | ^pkgdown$ 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: r 4 | cache: packages 5 | warnings_are_errors: true 6 | r: 7 | - bioc-release 8 | bioc_packages: 9 | - phyloseq 10 | r_packages: 11 | - covr 12 | after_success: 13 | - Rscript -e 'covr::codecov()' 14 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: speedyseq 2 | Title: Faster implementations of phyloseq functions 3 | Version: 0.5.3.9021 4 | Authors@R: 5 | person(given = "Michael", 6 | family = "McLaren", 7 | role = c("aut", "cre"), 8 | email = "m.mclaren42@gmail.com") 9 | Description: Faster implementations of phyloseq functions. 10 | URL: https://mikemc.github.io/speedyseq, https://github.com/mikemc/speedyseq 11 | BugReports: https://github.com/mikemc/speedyseq/issues 12 | License: AGPL-3 + file LICENSE 13 | Encoding: UTF-8 14 | LazyData: true 15 | Depends: 16 | phyloseq 17 | Imports: 18 | ape, 19 | Biostrings, 20 | castor, 21 | data.table, 22 | dplyr, 23 | ggplot2, 24 | magrittr, 25 | methods, 26 | purrr, 27 | rlang, 28 | tibble, 29 | tidyr, 30 | scales, 31 | stringr, 32 | vctrs (>= 0.3.0), 33 | vegan 34 | RoxygenNote: 7.3.1 35 | Suggests: 36 | cowplot, 37 | DECIPHER, 38 | forcats, 39 | ggtree, 40 | janitor, 41 | phangorn, 42 | testthat, 43 | withr 44 | Roxygen: list(markdown = TRUE) 45 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as_tibble,XStringSet) 4 | S3method(as_tibble,otu_table) 5 | S3method(as_tibble,phyloseq) 6 | S3method(as_tibble,sample_data) 7 | S3method(as_tibble,taxonomyTable) 8 | S3method(glimpse,sample_data) 9 | S3method(glimpse,taxonomyTable) 10 | S3method(print,otu_table) 11 | S3method(print,sample_data) 12 | S3method(print,taxonomyTable) 13 | S3method(unique_or_na,default) 14 | S3method(unique_or_na,factor) 15 | export("%>%") 16 | export(filter_sample_data) 17 | export(filter_tax_table) 18 | export(filter_taxa) 19 | export(filter_taxa2) 20 | export(inner_join_sample_data) 21 | export(inner_join_tax_table) 22 | export(left_join_sample_data) 23 | export(left_join_tax_table) 24 | export(merge_samples2) 25 | export(merge_taxa_vec) 26 | export(mutate_sample_data) 27 | export(mutate_tax_table) 28 | export(orient_taxa) 29 | export(plot_bar) 30 | export(plot_heatmap) 31 | export(plot_tree) 32 | export(psmelt) 33 | export(relocate_sample_data) 34 | export(relocate_tax_table) 35 | export(rename_sample_data) 36 | export(rename_tax_table) 37 | export(rename_with_sample_data) 38 | export(rename_with_tax_table) 39 | export(select_sample_data) 40 | export(select_tax_table) 41 | export(tax_glom) 42 | export(tip_glom) 43 | export(transform_sample_counts) 44 | export(transmute_sample_data) 45 | export(transmute_tax_table) 46 | export(tree_glom) 47 | export(unique_or_na) 48 | exportMethods(otu_table) 49 | exportMethods(sample_data) 50 | exportMethods(show) 51 | exportMethods(tax_table) 52 | import(phyloseq, except = c(psmelt, plot_bar, plot_tree, plot_heatmap, tax_glom, tip_glom, filter_taxa, transform_sample_counts)) 53 | importFrom(data.table,data.table) 54 | importFrom(data.table,setkey) 55 | importFrom(data.table,setkeyv) 56 | importFrom(ggplot2,aes) 57 | importFrom(ggplot2,aes_string) 58 | importFrom(ggplot2,element_blank) 59 | importFrom(ggplot2,element_text) 60 | importFrom(ggplot2,facet_grid) 61 | importFrom(ggplot2,geom_bar) 62 | importFrom(ggplot2,geom_point) 63 | importFrom(ggplot2,geom_raster) 64 | importFrom(ggplot2,geom_segment) 65 | importFrom(ggplot2,geom_text) 66 | importFrom(ggplot2,ggplot) 67 | importFrom(ggplot2,ggtitle) 68 | importFrom(ggplot2,scale_fill_gradient) 69 | importFrom(ggplot2,scale_size_continuous) 70 | importFrom(ggplot2,scale_x_continuous) 71 | importFrom(ggplot2,scale_x_discrete) 72 | importFrom(ggplot2,scale_y_discrete) 73 | importFrom(ggplot2,theme) 74 | importFrom(magrittr,"%>%") 75 | importFrom(scales,log_trans) 76 | importFrom(tibble,as_tibble) 77 | importFrom(tibble,glimpse) 78 | importFrom(vegan,scores) 79 | -------------------------------------------------------------------------------- /R/as_tibble.R: -------------------------------------------------------------------------------- 1 | #' @importFrom tibble as_tibble 2 | tibble::as_tibble 3 | 4 | #' Coerce phyloseq objects to tibble data frames 5 | #' 6 | #' These functions extend the `as_tibble()` function defined by the tibble 7 | #' package to work on phyloseq objects or phyloseq-component objects. 8 | #' 9 | #' Tibbles (tbl_df objects) do not support rownames; the taxa and sample names 10 | #' in the returned tibbles will always be stored in the first or second 11 | #' columns. The names ".otu", ".sample", ".abundance", and ".sequence" are 12 | #' special column names reserved for the otu/taxa names, sample names, 13 | #' abundances, and reference sequences. 14 | #' 15 | #' @param x A phyloseq object or component. 16 | #' @param pivot Whether to pivot the otu table to long format. 17 | #' @param tax Whether to include taxonomy data. 18 | #' @param ref Whether to include reference sequences. 19 | #' @param .name_repair Function to repair names in the case of conflicts. 20 | #' 21 | #' @return A tibble (tbl_df) 22 | #' 23 | #' @name as_tibble-phyloseq 24 | #' 25 | #' @examples 26 | #' library(tibble) # for as_tibble() and glimpse() 27 | #' 28 | #' data(GlobalPatterns) 29 | #' 30 | #' # Subset to 1/100 of the original taxa to speed operations 31 | #' ps <- GlobalPatterns %>% 32 | #' filter_tax_table(dplyr::row_number() %% 100 == 1) 33 | #' 34 | #' # On phyloseq objects, as_tibble is similar to psmelt() 35 | #' psmelt(ps) %>% glimpse 36 | #' as_tibble(ps) %>% glimpse 37 | #' 38 | #' # By default, the otu_table method provides a tibble in long-format like 39 | #' # psmelt and the phyloseq method 40 | #' otu_table(ps) %>% as_tibble %>% glimpse 41 | #' 42 | #' # Sample data and taxonomy tables produced by as_tibble can be converted 43 | #' # back into their respective phyloseq objects using speedyseq's tbl_df 44 | #' # constructors 45 | #' sample_data(ps) <- sample_data(ps) %>% 46 | #' as_tibble %>% 47 | #' dplyr::mutate(sample_sum = sample_sums(ps)) %>% 48 | #' sample_data 49 | #' sample_data(ps) %>% glimpse 50 | NULL 51 | 52 | #' @export 53 | #' @rdname as_tibble-phyloseq 54 | as_tibble.otu_table <- function(x, 55 | pivot = TRUE, 56 | .name_repair = base::make.unique) { 57 | mat <- x %>% as("matrix") 58 | if (pivot) { 59 | if (!taxa_are_rows(x)) 60 | mat <- t(mat) 61 | tb <- mat %>% 62 | tibble::as_tibble(rownames = ".otu") %>% 63 | tidyr::pivot_longer( 64 | cols = sample_names(x), 65 | names_to = ".sample", 66 | values_to = ".abundance" 67 | ) 68 | } else { 69 | rn <- ifelse(taxa_are_rows(x), ".otu", ".sample") 70 | tb <- mat %>% 71 | tibble::as_tibble(rownames = rn) %>% 72 | rlang::set_names(., 73 | vctrs::vec_as_names(names(.), repair = .name_repair) 74 | ) 75 | } 76 | tb 77 | } 78 | 79 | #' @export 80 | #' @rdname as_tibble-phyloseq 81 | as_tibble.sample_data <- function(x, .name_repair = base::make.unique) { 82 | x %>% 83 | as("data.frame") %>% 84 | tibble::as_tibble(rownames = ".sample") %>% 85 | rlang::set_names(., 86 | vctrs::vec_as_names(names(.), repair = .name_repair) 87 | ) 88 | } 89 | 90 | #' @export 91 | #' @rdname as_tibble-phyloseq 92 | as_tibble.taxonomyTable <- function(x, .name_repair = base::make.unique) { 93 | x %>% 94 | as("matrix") %>% 95 | tibble::as_tibble(rownames = ".otu") %>% 96 | rlang::set_names(., 97 | vctrs::vec_as_names(names(.), repair = .name_repair) 98 | ) 99 | } 100 | 101 | #' @export 102 | #' @rdname as_tibble-phyloseq 103 | as_tibble.XStringSet <- function(x) { 104 | x %>% 105 | as.character %>% 106 | tibble::enframe(".otu", ".sequence") 107 | } 108 | 109 | #' @export 110 | #' @rdname as_tibble-phyloseq 111 | as_tibble.phyloseq <- function(x, 112 | tax = TRUE, 113 | ref = FALSE, 114 | .name_repair = base::make.unique) { 115 | tb <- otu_table(x) %>% as_tibble(pivot = TRUE) 116 | # Add sample data if it exists 117 | sam <- access(x, "sam_data") 118 | if (!is.null(sam)) { 119 | tb <- tb %>% 120 | dplyr::left_join( 121 | sam %>% as_tibble(.name_repair = .name_repair), 122 | by = ".sample", 123 | suffix = c("", ".sam") 124 | ) 125 | } 126 | # Add tax_table if it exists and tax = TRUE 127 | tt <- access(x, "tax_table") 128 | if (tax & !is.null(tt)) { 129 | tb <- tb %>% 130 | dplyr::left_join( 131 | tt %>% as_tibble(.name_repair = .name_repair), 132 | by = ".otu", 133 | suffix = c("", ".tax") 134 | ) 135 | } 136 | # Add refseq if it exists and ref = TRUE 137 | rs <- access(x, "refseq") 138 | if (ref & !is.null(rs)) { 139 | tb <- tb %>% 140 | dplyr::left_join( 141 | rs %>% as_tibble, 142 | by = ".otu", 143 | suffix = c("", ".ref") 144 | ) 145 | } 146 | tb 147 | } 148 | -------------------------------------------------------------------------------- /R/dplyr-joins.R: -------------------------------------------------------------------------------- 1 | # vim: foldmethod=marker 2 | 3 | # Some of the documentation for these functions is modified from the 4 | # corresponding dplyr functions (https://github.com/tidyverse/dplyr), MIT 5 | # license RStudio and others. 6 | 7 | #' Mutating joins of the taxonomy table or sample data 8 | #' 9 | #' @description 10 | #' `r lifecycle::badge("experimental")` 11 | #' 12 | #' These functions are wrappers around dplyr joining operations (see 13 | #' `dplyr::mutate-joins`) whose first (`x`) argument is either the taxonomy 14 | #' table or sample data. 15 | #' 16 | #' @details 17 | #' When joining by taxonomy table, the .otu column name can be used to match 18 | #' taxa names. 19 | #' When joining by sample data, the .sample column name can be used to match 20 | #' sample names. 21 | #' 22 | #' @param x A `phyloseq`, `taxonomyTable`, or `sample_data` object 23 | #' @param ... Arguments passed to respective dplyr joining operation 24 | #' 25 | #' @return An object of the same type as `x`, with added columns 26 | #' 27 | #' @seealso 28 | #' [dplyr::left_join()] 29 | #' [dplyr::inner_join()] 30 | #' 31 | #' @name join-phyloseq 32 | #' 33 | #' @examples 34 | #' library(tibble) 35 | #' 36 | #' data(GlobalPatterns) 37 | #' 38 | #' GlobalPatterns %>% sample_variables 39 | #' ps1 <- GlobalPatterns %>% 40 | #' select_sample_data(!contains("Barcode")) 41 | #' y <- GlobalPatterns %>% 42 | #' sample_data %>% 43 | #' select_sample_data(contains("Barcode")) %>% 44 | #' as_tibble 45 | #' ps2 <- ps1 %>% left_join_sample_data(y, by = ".sample") 46 | #' ps2 %>% sample_variables 47 | NULL 48 | 49 | # left_join ----------------------------------------------------------------{{{ 50 | 51 | #' @rdname join-phyloseq 52 | #' @export 53 | setGeneric("left_join_tax_table", 54 | function(x, ...) standardGeneric("left_join_tax_table") 55 | ) 56 | 57 | #' @rdname join-phyloseq 58 | setMethod("left_join_tax_table", "phyloseq", 59 | function(x, ...) { 60 | tax_table(x) <- tax_table(x) %>% left_join_tax_table(...) 61 | x 62 | }) 63 | 64 | #' @rdname join-phyloseq 65 | setMethod("left_join_tax_table", "taxonomyTable", 66 | function(x, ...) { 67 | x %>% 68 | as_tibble %>% 69 | dplyr::left_join(...) %>% 70 | {suppressMessages(tax_table(.))} 71 | }) 72 | 73 | #' @rdname join-phyloseq 74 | #' @export 75 | setGeneric("left_join_sample_data", 76 | function(x, ...) standardGeneric("left_join_sample_data") 77 | ) 78 | 79 | #' @rdname join-phyloseq 80 | setMethod("left_join_sample_data", "phyloseq", 81 | function(x, ...) { 82 | sample_data(x) <- sample_data(x) %>% left_join_sample_data(...) 83 | x 84 | }) 85 | 86 | #' @rdname join-phyloseq 87 | setMethod("left_join_sample_data", "sample_data", 88 | function(x, ...) { 89 | x %>% 90 | as_tibble %>% 91 | dplyr::left_join(...) %>% 92 | {suppressMessages(sample_data(.))} 93 | }) 94 | 95 | # }}} 96 | 97 | # inner_join ---------------------------------------------------------------{{{ 98 | 99 | #' @rdname join-phyloseq 100 | #' @export 101 | setGeneric("inner_join_tax_table", 102 | function(x, ...) standardGeneric("inner_join_tax_table") 103 | ) 104 | 105 | #' @rdname join-phyloseq 106 | setMethod("inner_join_tax_table", "phyloseq", 107 | function(x, ...) { 108 | tax_table(x) <- tax_table(x) %>% inner_join_tax_table(...) 109 | x 110 | }) 111 | 112 | #' @rdname join-phyloseq 113 | setMethod("inner_join_tax_table", "taxonomyTable", 114 | function(x, ...) { 115 | x %>% 116 | as_tibble %>% 117 | dplyr::inner_join(...) %>% 118 | {suppressMessages(tax_table(.))} 119 | }) 120 | 121 | #' @rdname join-phyloseq 122 | #' @export 123 | setGeneric("inner_join_sample_data", 124 | function(x, ...) standardGeneric("inner_join_sample_data") 125 | ) 126 | 127 | #' @rdname join-phyloseq 128 | setMethod("inner_join_sample_data", "phyloseq", 129 | function(x, ...) { 130 | sample_data(x) <- sample_data(x) %>% inner_join_sample_data(...) 131 | x 132 | }) 133 | 134 | #' @rdname join-phyloseq 135 | setMethod("inner_join_sample_data", "sample_data", 136 | function(x, ...) { 137 | x %>% 138 | as_tibble %>% 139 | dplyr::inner_join(...) %>% 140 | {suppressMessages(sample_data(.))} 141 | }) 142 | 143 | # }}} 144 | -------------------------------------------------------------------------------- /R/import-phyloseq.R: -------------------------------------------------------------------------------- 1 | #' Import phyloseq functions 2 | #' 3 | #' Import all phyloseq functions for internal use, except those we are 4 | #' reimplementing. 5 | #' 6 | #' @name import_phyloseq_functions 7 | #' @rawNamespace import(phyloseq, except = c(psmelt, plot_bar, plot_tree, plot_heatmap, tax_glom, tip_glom, filter_taxa, transform_sample_counts)) 8 | NULL 9 | -------------------------------------------------------------------------------- /R/phyloseq-constructors.R: -------------------------------------------------------------------------------- 1 | #' Construct phyloseq objects from tibbles 2 | #' 3 | #' These methods extend phyloseq's constructor functions to construct phyloseq 4 | #' components from tibbles (objects with class "tbl_df"). 5 | #' 6 | #' Since tibbles cannot have row names, the sample or taxon identifiers must be 7 | #' contained in a regular column. Speedyseq currently always uses the first 8 | #' column for the identifiers that would normally be taken from the row names 9 | #' by phyloseq's built-in constructors. Thus the first column is assumed to 10 | #' contain the sample names for `sample_data()` and the OTU/taxa names for 11 | #' `tax_table()`; for `otu_table()`, the first column is assumed to contain the 12 | #' sample names if `taxa_are_rows = TRUE` and the taxa names if `taxa_are_rows 13 | #' = FALSE`, with the other identifier being taken from the remaining column 14 | #' names. 15 | #' 16 | #' @param object A tibble whose first column contains the sample or taxa ids 17 | #' @param taxa_are_rows Logical; `TRUE` if rows correspond to taxa and `FALSE` 18 | #' if rows correspond to samples 19 | #' 20 | #' @name tibble-constructors 21 | #' 22 | #' @seealso 23 | #' [`tibble::tbl_df`] 24 | #' [phyloseq::otu_table()] 25 | #' [phyloseq::sample_data()] 26 | #' [phyloseq::tax_table()] 27 | #' 28 | #' @examples 29 | #' \dontrun{ 30 | #' # Read a .csv file with readr, which creates an object of class `tbl_df` 31 | #' tbl <- readr::read_csv("path/to/otu_table.csv") 32 | #' # Inspect and check if taxa are rows and that the first column contains the 33 | #' # sample names or the taxa/OTU names 34 | #' head(tbl) 35 | #' # Create a phyloseq `otu_table` object 36 | #' otu <- otu_table(tbl, taxa_are_rows = FALSE) 37 | #' 38 | #' # Read a .csv file with readr, which creates an object of class `tbl_df` 39 | #' tbl <- readr::read_csv("path/to/sample_data.csv") 40 | #' # Inspect and check that the first column contains the sample names 41 | #' head(tbl) 42 | #' # Create a phyloseq `sample_data` object 43 | #' sam <- sample_data(tbl) 44 | #' } 45 | NULL 46 | 47 | #' @rdname tibble-constructors 48 | #' @export 49 | setMethod("otu_table", "tbl_df", function (object, taxa_are_rows) { 50 | if (taxa_are_rows) { 51 | message(paste0( 52 | "Assuming first column, `", names(object)[1], 53 | "`, contains the taxa names")) 54 | } else { 55 | message(paste0( 56 | "Assuming first column, `", names(object)[1], 57 | "`, contains the sample names")) 58 | } 59 | object %>% 60 | tibble::column_to_rownames(var = names(object)[1]) %>% 61 | as("matrix") %>% 62 | otu_table(taxa_are_rows) 63 | }) 64 | 65 | #' @rdname tibble-constructors 66 | #' @export 67 | setMethod("sample_data", "tbl_df", function(object) { 68 | message(paste0( 69 | "Assuming first column, `", names(object)[1], 70 | "`, contains the sample names")) 71 | object %>% 72 | tibble::column_to_rownames(var = names(object)[1]) %>% 73 | sample_data 74 | }) 75 | 76 | #' @rdname tibble-constructors 77 | #' @export 78 | setMethod("tax_table", "tbl_df", function (object) { 79 | message(paste0( 80 | "Assuming first column, `", names(object)[1], 81 | "`, contains the taxa names")) 82 | object %>% 83 | tibble::column_to_rownames(var = names(object)[1]) %>% 84 | as("matrix") %>% 85 | tax_table 86 | }) 87 | 88 | -------------------------------------------------------------------------------- /R/psmelt.R: -------------------------------------------------------------------------------- 1 | # Attribution: The documentation for `psmelt()` and the first 54 lines of the 2 | # function's code are from phyloseq, 3 | # https://github.com/joey711/phyloseq/blob/master/R/plot-methods.R 4 | 5 | #' Melt phyloseq data object into large data.frame 6 | #' 7 | #' The psmelt function is a specialized melt function for melting phyloseq 8 | #' objects (instances of the phyloseq class), usually for producing graphics 9 | #' with [ggplot2::ggplot2]. The naming conventions used in downstream phyloseq 10 | #' graphics functions have reserved the following variable names that should 11 | #' not be used as the names of [sample_variables()] or taxonomic 12 | #' [rank_names()]. These reserved names are `c("Sample", "Abundance", "OTU")`. 13 | #' Also, you should not have identical names for sample variables and taxonomic 14 | #' ranks. That is, the intersection of the output of the following two 15 | #' functions [sample_variables()], [rank_names()] should be an empty vector 16 | #' (e.g. `intersect(sample_variables(physeq), rank_names(physeq))`). All of 17 | #' these potential name collisions are checked-for and renamed automatically 18 | #' with a warning. However, if you (re)name your variables accordingly ahead of 19 | #' time, it will reduce confusion and eliminate the warnings. 20 | #' 21 | #' The `as` argument allows choosing between three classes for tabular data: 22 | #' 23 | #' - [data.frame-class] is chosen by "data.frame" or "df" 24 | #' - [data.table-class] is chosen by "data.table" or "dt" 25 | #' - [tbl_df-class] is chosen by "tbl_df", "tbl", or "tibble" 26 | #' 27 | #' The default is "data.frame" and can be overridden by setting the 28 | #' "speedyseq.psmelt_class" option. 29 | #' 30 | #' Note that "melted" phyloseq data is stored much less efficiently, and so RAM 31 | #' storage issues could arise with a smaller dataset (smaller number of 32 | #' samples/OTUs/variables) than one might otherwise expect. For common sizes 33 | #' of graphics-ready datasets, however, this should not be a problem. Because 34 | #' the number of OTU entries has a large effect on the RAM requirement, methods 35 | #' to reduce the number of separate OTU entries -- for instance by 36 | #' agglomerating OTUs based on phylogenetic distance using [tip_glom()] -- can 37 | #' help alleviate RAM usage problems. This function is made user-accessible for 38 | #' flexibility, but is also used extensively by plot functions in phyloseq. 39 | #' 40 | #' @param physeq An [otu_table-class] or [phyloseq-class]; most useful for 41 | #' phyloseq-class. 42 | #' @param as Class of the output table; see Details. 43 | #' 44 | #' @return A table of the specified class 45 | #' 46 | #' @seealso 47 | #' [plot_bar()] 48 | #' 49 | #' @export 50 | #' 51 | #' @examples 52 | #' data("GlobalPatterns") 53 | #' gp.ch = subset_taxa(GlobalPatterns, Phylum == "Chlamydiae") 54 | #' mdf = psmelt(gp.ch) 55 | #' nrow(mdf) 56 | #' ncol(mdf) 57 | #' colnames(mdf) 58 | #' head(rownames(mdf)) 59 | #' # Create a ggplot similar to 60 | #' library("ggplot2") 61 | #' p = ggplot(mdf, aes(x=SampleType, y=Abundance, fill=Genus)) 62 | #' p = p + geom_bar(color="black", stat="identity", position="stack") 63 | #' print(p) 64 | psmelt <- function(physeq, as = getOption("speedyseq.psmelt_class")) { 65 | stopifnot(as %in% c("data.frame", "df", "data.table", "dt", "tbl_df", "tbl", 66 | "tibble")) 67 | # Access covariate names from object, if present 68 | if(!inherits(physeq, "phyloseq")){ 69 | rankNames = NULL 70 | sampleVars = NULL 71 | } else { 72 | # Still might be NULL, but attempt access 73 | rankNames = rank_names(physeq, FALSE) 74 | sampleVars = sample_variables(physeq, FALSE) 75 | } 76 | # Define reserved names 77 | reservedVarnames = c("Sample", "Abundance", "OTU") 78 | # type-1a conflict: between sample_data 79 | # and reserved psmelt variable names 80 | type1aconflict = intersect(reservedVarnames, sampleVars) 81 | if(length(type1aconflict) > 0){ 82 | wh1a = which(sampleVars %in% type1aconflict) 83 | new1a = paste0("sample_", sampleVars[wh1a]) 84 | # First warn about the change 85 | warning("The sample variables: \n", 86 | paste(sampleVars[wh1a], collapse=", "), 87 | "\n have been renamed to: \n", 88 | paste0(new1a, collapse=", "), "\n", 89 | "to avoid conflicts with special phyloseq plot attribute names.") 90 | # Rename the sample variables. 91 | colnames(sample_data(physeq))[wh1a] <- new1a 92 | } 93 | # type-1b conflict: between tax_table 94 | # and reserved psmelt variable names 95 | type1bconflict = intersect(reservedVarnames, rankNames) 96 | if(length(type1bconflict) > 0){ 97 | wh1b = which(rankNames %in% type1bconflict) 98 | new1b = paste0("taxa_", rankNames[wh1b]) 99 | # First warn about the change 100 | warning("The rank names: \n", 101 | paste(rankNames[wh1b], collapse=", "), 102 | "\n have been renamed to: \n", 103 | paste0(new1b, collapse=", "), "\n", 104 | "to avoid conflicts with special phyloseq plot attribute names.") 105 | # Rename the conflicting taxonomic ranks 106 | colnames(tax_table(physeq))[wh1b] <- new1b 107 | } 108 | # type-2 conflict: internal between tax_table and sample_data 109 | type2conflict = intersect(sampleVars, rankNames) 110 | if(length(type2conflict) > 0){ 111 | wh2 = which(sampleVars %in% type2conflict) 112 | new2 = paste0("sample_", sampleVars[wh2]) 113 | # First warn about the change 114 | warning("The sample variables: \n", 115 | paste0(sampleVars[wh2], collapse=", "), 116 | "\n have been renamed to: \n", 117 | paste0(new2, collapse=", "), "\n", 118 | "to avoid conflicts with taxonomic rank names.") 119 | # Rename the sample variables 120 | colnames(sample_data(physeq))[wh2] <- new2 121 | } 122 | # Enforce OTU table orientation. Redundant-looking step 123 | # supports "naked" otu_table as `physeq` input. 124 | otutab = otu_table(physeq) 125 | if(!taxa_are_rows(otutab)){otutab <- t(otutab)} 126 | ## Speedyseq changes start here 127 | # Convert the otu table to a tibble in tall form (one sample-taxon obsevation 128 | # per row) 129 | dtb <- otutab %>% 130 | as("matrix") %>% 131 | data.table::as.data.table(keep.rownames = "OTU") %>% 132 | data.table::melt(id.vars = c("OTU"), variable.name = "Sample", 133 | value.name = "Abundance", variable.factor = FALSE) 134 | # Add the sample data if it exists 135 | if (!is.null(sampleVars)) { 136 | sam <- sample_data(physeq) %>% 137 | as("data.frame") %>% 138 | data.table::as.data.table(keep.rownames = "Sample") 139 | dtb <- dtb[sam, on = .(Sample = Sample)] 140 | } 141 | # Add the tax table if it exists 142 | if (!is.null(rankNames)) { 143 | tax <- tax_table(physeq) %>% 144 | as("matrix") %>% 145 | data.table::as.data.table(keep.rownames = "OTU") 146 | dtb <- dtb[tax, on = .(OTU = OTU)] 147 | } 148 | # Arrange by Abundance, then OTU names (to approx. phyloseq behavior) 149 | dtb <- dtb %>% 150 | data.table::setorder(-Abundance, OTU) 151 | # Return as requested class 152 | if (as %in% c("data.table", "dt")) { 153 | dtb 154 | } else if (as %in% c("data.frame", "df")) { 155 | dtb %>% as("data.frame") 156 | } else if (as %in% c("tbl_df", "tbl", "tibble")) { 157 | dtb <- dtb %>% tibble::as_tibble() 158 | attr(dtb, ".internal.selfref") <- NULL 159 | dtb 160 | } else { 161 | stop("Invalid output class specified by `as`.") 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /R/transform-filter.R: -------------------------------------------------------------------------------- 1 | # Function titles copied from phyloseq's documentation 2 | 3 | # Transform sample counts ----------------------------------------------------- 4 | 5 | #' Transform abundance data in an `otu_table`, sample-by-sample 6 | #' 7 | #' Version of [phyloseq::transform_sample_counts()] that allows a 8 | #' purrr-style anonymous function. 9 | #' 10 | #' This function simply calls [purrr::as_mapper()] on `fun` and passes the 11 | #' resulting function on to [phyloseq::transform_sample_counts()]. 12 | #' 13 | #' @param physeq [phyloseq-class()] or [ape::phylo()]. 14 | #' @param fun A function or formula that can be converted to a function by 15 | #' [purrr::as_mapper()] 16 | #' @param ... Additional arguments passed on to `fun` 17 | #' 18 | #' @seealso 19 | #' [phyloseq::transform_sample_counts()] 20 | #' [purrr::as_mapper()] 21 | #' 22 | #' @export 23 | #' @examples 24 | #' data(GlobalPatterns) 25 | #' # Filter low prevalence taxa, then convert to proportions 26 | #' gp.prop <- GlobalPatterns %>% 27 | #' filter_taxa2(~ sum(. > 0) > 5) %>% 28 | #' transform_sample_counts(~ . / sum(.)) 29 | transform_sample_counts <- function(physeq, fun, ...) { 30 | phyloseq::transform_sample_counts(physeq, purrr::as_mapper(fun), ...) 31 | } 32 | 33 | # Filter taxa ----------------------------------------------------------------- 34 | 35 | #' Filter taxa based on across-sample OTU abundance criteria 36 | #' 37 | #' Variations of [phyloseq::filter_taxa()] that allows a purrr-style anonymous 38 | #' function. 39 | #' 40 | #' `filter_taxa()` simply calls [purrr::as_mapper()] on `fun` and passes the 41 | #' resulting function on to [phyloseq::filter_taxa()]. `filter_taxa2()` also 42 | #' sets `prune = TRUE`, which is convenient when passing a phyloseq object in a 43 | #' pipe chain (see example). 44 | #' 45 | #' @param physeq [phyloseq-class()] or [ape::phylo()]. 46 | #' @param fun A function or formula that can be converted to a function by 47 | #' [purrr::as_mapper()] 48 | #' @param prune A logical. If `FALSE`, then this function returns a logical 49 | #' vector specifying the taxa that passed the filter; if `TRUE`, then this 50 | #' function returns the pruned phyloseq object. 51 | #' 52 | #' @export 53 | #' @seealso 54 | #' [phyloseq::filter_taxa()] 55 | #' [purrr::as_mapper()] 56 | #' 57 | #' @examples 58 | #' data(GlobalPatterns) 59 | #' # Filter low prevalence taxa and then convert to proportions 60 | #' gp.prop <- GlobalPatterns %>% 61 | #' filter_taxa2(~ sum(. > 0) > 5) %>% 62 | #' transform_sample_counts(~ . / sum(.)) 63 | filter_taxa <- function(physeq, fun, prune = FALSE) { 64 | phyloseq::filter_taxa(physeq, purrr::as_mapper(fun), prune = prune) 65 | } 66 | 67 | #' @export 68 | #' @describeIn filter_taxa Sets `prune = TRUE` 69 | filter_taxa2 <- function(physeq, fun) { 70 | phyloseq::filter_taxa(physeq, purrr::as_mapper(fun), prune = TRUE) 71 | } 72 | 73 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | # select_taxa ----------------------------------------------------------------- 2 | 3 | #' Select a subset of taxa in a specified order where possible 4 | #' 5 | #' Select (a subset of) taxa; if `x` allows taxa to be reordered, then taxa are 6 | #' given in the specified order. 7 | #' 8 | #' This is a simple selector function that is like `prune_taxa(taxa, x)` when 9 | #' `taxa` is a character vector but always gives the taxa in the order `taxa` 10 | #' if possible (that is, except for phy_tree's and phyloseq objects that 11 | #' contain phy_tree's). 12 | #' 13 | #' @param x A phyloseq object or phyloseq component object 14 | #' @param taxa Character vector of taxa to select, in requested order 15 | #' @param reorder Logical specifying whether to use the order in `taxa` (TRUE) 16 | #' or keep the order in `taxa_names(x)` (FALSE) 17 | #' @keywords internal 18 | #' @rdname select_taxa-methods 19 | setGeneric("select_taxa", 20 | function(x, taxa, reorder = TRUE) standardGeneric("select_taxa") 21 | ) 22 | 23 | #' @rdname select_taxa-methods 24 | setMethod("select_taxa", signature("sample_data", "character"), 25 | function(x, taxa) { 26 | stopifnot(!anyDuplicated(taxa)) 27 | x 28 | } 29 | ) 30 | 31 | #' @rdname select_taxa-methods 32 | setMethod("select_taxa", signature("otu_table", "character"), 33 | function(x, taxa, reorder = TRUE){ 34 | stopifnot(!anyDuplicated(taxa)) 35 | stopifnot(all(taxa %in% taxa_names(x))) 36 | if (!reorder) 37 | taxa <- intersect(taxa_names(x), taxa) 38 | if (taxa_are_rows(x)) { 39 | x[taxa, , drop=FALSE] 40 | } else { 41 | x[, taxa, drop=FALSE] 42 | } 43 | } 44 | ) 45 | 46 | #' @rdname select_taxa-methods 47 | setMethod("select_taxa", signature("taxonomyTable", "character"), 48 | function(x, taxa, reorder = TRUE) { 49 | stopifnot(!anyDuplicated(taxa)) 50 | stopifnot(all(taxa %in% taxa_names(x))) 51 | if (!reorder) 52 | taxa <- intersect(taxa_names(x), taxa) 53 | x[taxa, , drop=FALSE] 54 | } 55 | ) 56 | 57 | #' @rdname select_taxa-methods 58 | setMethod("select_taxa", signature("XStringSet", "character"), 59 | function(x, taxa, reorder = TRUE) { 60 | stopifnot(!anyDuplicated(taxa)) 61 | stopifnot(all(taxa %in% taxa_names(x))) 62 | if (!reorder) 63 | taxa <- intersect(taxa_names(x), taxa) 64 | x[taxa] 65 | } 66 | ) 67 | 68 | #' @rdname select_taxa-methods 69 | setMethod("select_taxa", signature("phylo", "character"), 70 | function(x, taxa) { 71 | # NOTE: `reorder` argument silently ignored if supplied 72 | stopifnot(!anyDuplicated(taxa)) 73 | stopifnot(all(taxa %in% taxa_names(x))) 74 | ape::keep.tip(x, taxa) 75 | } 76 | ) 77 | 78 | #' @rdname select_taxa-methods 79 | setMethod("select_taxa", signature("phyloseq", "character"), 80 | function(x, taxa, reorder = TRUE) { 81 | stopifnot(!anyDuplicated(taxa)) 82 | stopifnot(all(taxa %in% taxa_names(x))) 83 | if (!reorder) 84 | taxa <- intersect(taxa_names(x), taxa) 85 | otu_table(x) <- select_taxa(otu_table(x), taxa) 86 | phyloseq:::index_reorder(x, index_type = "taxa") 87 | } 88 | ) 89 | 90 | # orient_taxa ----------------------------------------------------------------- 91 | 92 | #' Orient a phyloseq object or otu table to have taxa as rows or as columns 93 | #' 94 | #' Puts the phyloseq or otu-table object `x` in the orientation (taxa as rows 95 | #' or as columns) specified by `as`. This is useful when passing the otu table 96 | #' on to functions that require the abundance matrix to have a specific 97 | #' orientation and are unaware of the `taxa_are_rows(x)` property. 98 | #' 99 | #' @param x A phyloseq or otu-table object 100 | #' @param as The matrix dimension that is desired for taxa. Must be 101 | #' "rows" for rows and "columns" or "cols" for columns. 102 | #' 103 | #' @export 104 | #' 105 | #' @examples 106 | #' data(soilrep) 107 | #' taxa_are_rows(soilrep) 108 | #' x <- soilrep %>% orient_taxa(as = "columns") 109 | #' taxa_are_rows(x) 110 | setGeneric("orient_taxa", 111 | function(x, as) standardGeneric("orient_taxa") 112 | ) 113 | 114 | orient_taxa_default <- function(x, as) { 115 | stopifnot(as %in% c("rows", "columns", "cols")) 116 | if (identical(as, "rows")) { 117 | if (!taxa_are_rows(x)) 118 | x <- t(x) 119 | } else { 120 | if (taxa_are_rows(x)) 121 | x <- t(x) 122 | } 123 | x 124 | } 125 | 126 | #' @rdname orient_taxa 127 | setMethod("orient_taxa", "otu_table", orient_taxa_default) 128 | 129 | #' @rdname orient_taxa 130 | setMethod("orient_taxa", "phyloseq", orient_taxa_default) 131 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | speedyseq_default_options <- list( 2 | speedyseq.psmelt_class = "data.frame" 3 | ) 4 | 5 | .onLoad <- function(libname, pkgname) { 6 | op <- options() 7 | toset <- !(names(speedyseq_default_options) %in% names(op)) 8 | if (any(toset)) 9 | options(speedyseq_default_options[toset]) 10 | invisible() 11 | } 12 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r setup, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | # speedyseq 16 | 17 | 18 | [![DOI](https://zenodo.org/badge/179732395.svg)](https://zenodo.org/badge/latestdoi/179732395) 19 | [![Travis build 20 | status](https://travis-ci.com/mikemc/speedyseq.svg?branch=main)](https://travis-ci.com/mikemc/speedyseq) 21 | [![Codecov test 22 | coverage](https://codecov.io/gh/mikemc/speedyseq/branch/main/graph/badge.svg)](https://codecov.io/gh/mikemc/speedyseq?branch=main) 23 | 24 | 25 | Speedyseq is an R package for microbiome data analysis that extends the popular [phyloseq](https://joey711.github.io/phyloseq/) package. Speedyseq began with the limited goal of providing faster versions of phyloseq's plotting and taxonomic merging functions, but now contains a growing number of enhancements to phyloseq which I have found useful. 26 | 27 | ## Installation 28 | 29 | Install the current development version with the remotes package, 30 | ```{r, eval = FALSE} 31 | # install.packages("remotes") 32 | remotes::install_github("mikemc/speedyseq") 33 | ``` 34 | 35 | ## Usage 36 | 37 | Method 1: Call speedyseq functions explicitly when you want to use speedyseq's version instead of phyloseq. This method ensures that you do not unintentionally call speedyseq's version of a phyloseq function. 38 | ```{r} 39 | library(phyloseq) 40 | data(GlobalPatterns) 41 | system.time( 42 | # Calls phyloseq's psmelt 43 | df1 <- psmelt(GlobalPatterns) # slow 44 | ) 45 | system.time( 46 | df2 <- speedyseq::psmelt(GlobalPatterns) # fast 47 | ) 48 | dplyr::all_equal(df1, df2, ignore_row_order = TRUE) 49 | detach(package:phyloseq) 50 | ``` 51 | 52 | Method 2: Load speedyseq, which will load phyloseq and all speedyseq functions and cause calls to the overlapping function names to go to speedyseq by default. 53 | ```{r} 54 | library(speedyseq) 55 | data(GlobalPatterns) 56 | system.time( 57 | ps1 <- phyloseq::tax_glom(GlobalPatterns, "Genus") # slow 58 | ) 59 | system.time( 60 | # Calls speedyseq's tax_glom 61 | ps2 <- tax_glom(GlobalPatterns, "Genus") # fast 62 | ) 63 | ``` 64 | Loading speedyseq will also load the [magrittr](https://magrittr.tidyverse.org/) pipe (`%>%`) to allow pipe chains with phyloseq objects, 65 | ```{r} 66 | gp.filt.prop <- GlobalPatterns %>% 67 | filter_taxa2(~ sum(. > 0) > 5) %>% 68 | transform_sample_counts(~ . / sum(.)) 69 | ``` 70 | 71 | ## Features 72 | 73 | ### Faster implementations of phyloseq functions 74 | 75 | * `psmelt()` and the plotting functions that use it: `plot_bar()`, `plot_heatmap()`, and `plot_tree()`. 76 | * The taxonomic merging functions `tax_glom()` and `tip_glom()`. Speedyseq's `tip_glom()` also has significantly lower memory usage. 77 | 78 | These functions should generally function as drop-in replacements for phyloseq's versions, with additional arguments allowing for modified behavior. Differences in row order (for `psmelt()`) and taxon order (for `tax_glom()`) can occur; see [Changelog](https://mikemc.github.io/speedyseq/news/index.html) for details. 79 | 80 | ### New taxonomic merging functions 81 | 82 | * A general-purpose merging function `merge_taxa_vec()` that provides a vectorized version of phyloseq's `merge_taxa()` function. 83 | * A function `tree_glom()` that performs direct phylogenetic merging of taxa. This function provides an alternative to the indirect phylogenetic merging done by `tip_glom()` that is much faster and arguably more intuitive. 84 | 85 | See the [Changelog](https://mikemc.github.io/speedyseq/news/index.html) for details and examples. 86 | 87 | ### Enhancements and additions to other phyloseq functions 88 | 89 | See the [online documentation](https://mikemc.github.io/speedyseq/reference/index.html) for an up-to-date list and usage information and the [Changelog](https://mikemc.github.io/speedyseq/news/index.html) for further information. 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # speedyseq 5 | 6 | 7 | 8 | [![DOI](https://zenodo.org/badge/179732395.svg)](https://zenodo.org/badge/latestdoi/179732395) 9 | [![Travis build 10 | status](https://travis-ci.com/mikemc/speedyseq.svg?branch=main)](https://travis-ci.com/mikemc/speedyseq) 11 | [![Codecov test 12 | coverage](https://codecov.io/gh/mikemc/speedyseq/branch/main/graph/badge.svg)](https://codecov.io/gh/mikemc/speedyseq?branch=main) 13 | 14 | 15 | Speedyseq is an R package for microbiome data analysis that extends the 16 | popular [phyloseq](https://joey711.github.io/phyloseq/) package. 17 | Speedyseq began with the limited goal of providing faster versions of 18 | phyloseq’s plotting and taxonomic merging functions, but now contains a 19 | growing number of enhancements to phyloseq which I have found useful. 20 | 21 | ## Installation 22 | 23 | Install the current development version with the remotes package, 24 | 25 | ``` r 26 | # install.packages("remotes") 27 | remotes::install_github("mikemc/speedyseq") 28 | ``` 29 | 30 | ## Usage 31 | 32 | Method 1: Call speedyseq functions explicitly when you want to use 33 | speedyseq’s version instead of phyloseq. This method ensures that you do 34 | not unintentionally call speedyseq’s version of a phyloseq function. 35 | 36 | ``` r 37 | library(phyloseq) 38 | data(GlobalPatterns) 39 | system.time( 40 | # Calls phyloseq's psmelt 41 | df1 <- psmelt(GlobalPatterns) # slow 42 | ) 43 | #> user system elapsed 44 | #> 6.320 0.063 6.390 45 | system.time( 46 | df2 <- speedyseq::psmelt(GlobalPatterns) # fast 47 | ) 48 | #> user system elapsed 49 | #> 0.344 0.004 0.245 50 | dplyr::all_equal(df1, df2, ignore_row_order = TRUE) 51 | #> [1] TRUE 52 | detach(package:phyloseq) 53 | ``` 54 | 55 | Method 2: Load speedyseq, which will load phyloseq and all speedyseq 56 | functions and cause calls to the overlapping function names to go to 57 | speedyseq by default. 58 | 59 | ``` r 60 | library(speedyseq) 61 | #> Loading required package: phyloseq 62 | #> 63 | #> Attaching package: 'speedyseq' 64 | #> The following objects are masked from 'package:phyloseq': 65 | #> 66 | #> filter_taxa, plot_bar, plot_heatmap, plot_tree, psmelt, tax_glom, tip_glom, 67 | #> transform_sample_counts 68 | data(GlobalPatterns) 69 | system.time( 70 | ps1 <- phyloseq::tax_glom(GlobalPatterns, "Genus") # slow 71 | ) 72 | #> user system elapsed 73 | #> 31.856 0.106 32.031 74 | system.time( 75 | # Calls speedyseq's tax_glom 76 | ps2 <- tax_glom(GlobalPatterns, "Genus") # fast 77 | ) 78 | #> user system elapsed 79 | #> 0.241 0.000 0.230 80 | ``` 81 | 82 | Loading speedyseq will also load the 83 | [magrittr](https://magrittr.tidyverse.org/) pipe (`%>%`) to allow pipe 84 | chains with phyloseq objects, 85 | 86 | ``` r 87 | gp.filt.prop <- GlobalPatterns %>% 88 | filter_taxa2(~ sum(. > 0) > 5) %>% 89 | transform_sample_counts(~ . / sum(.)) 90 | ``` 91 | 92 | ## Features 93 | 94 | ### Faster implementations of phyloseq functions 95 | 96 | - `psmelt()` and the plotting functions that use it: `plot_bar()`, 97 | `plot_heatmap()`, and `plot_tree()`. 98 | - The taxonomic merging functions `tax_glom()` and `tip_glom()`. 99 | Speedyseq’s `tip_glom()` also has significantly lower memory usage. 100 | 101 | These functions should generally function as drop-in replacements for 102 | phyloseq’s versions, with additional arguments allowing for modified 103 | behavior. Differences in row order (for `psmelt()`) and taxon order (for 104 | `tax_glom()`) can occur; see 105 | [Changelog](https://mikemc.github.io/speedyseq/news/index.html) for 106 | details. 107 | 108 | ### New taxonomic merging functions 109 | 110 | - A general-purpose merging function `merge_taxa_vec()` that provides 111 | a vectorized version of phyloseq’s `merge_taxa()` function. 112 | - A function `tree_glom()` that performs direct phylogenetic merging 113 | of taxa. This function provides an alternative to the indirect 114 | phylogenetic merging done by `tip_glom()` that is much faster and 115 | arguably more intuitive. 116 | 117 | See the [Changelog](https://mikemc.github.io/speedyseq/news/index.html) 118 | for details and examples. 119 | 120 | ### Enhancements and additions to other phyloseq functions 121 | 122 | See the [online 123 | documentation](https://mikemc.github.io/speedyseq/reference/index.html) 124 | for an up-to-date list and usage information and the 125 | [Changelog](https://mikemc.github.io/speedyseq/news/index.html) for 126 | further information. 127 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://mikemc.github.io/speedyseq 2 | reference: 3 | - title: "Merge samples or taxa" 4 | - contents: 5 | - merge_samples2 6 | - merge_taxa_vec 7 | - ends_with("glom") 8 | - title: "Transform or subset data" 9 | - contents: 10 | - select-phyloseq 11 | - relocate-phyloseq 12 | - rename-phyloseq 13 | - filter-phyloseq 14 | - mutate-phyloseq 15 | - join-phyloseq 16 | - starts_with("filter_taxa") 17 | - starts_with("transform") 18 | - orient_taxa 19 | - title: "Coercion" 20 | - contents: 21 | - psmelt 22 | - as_tibble-phyloseq 23 | - tibble-constructors 24 | - title: "Plotting" 25 | - contents: 26 | - starts_with("plot") 27 | - title: "Other" 28 | - contents: 29 | - unique_or_na 30 | - show,phyloseq-method 31 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page not found (404) • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 105 | 106 | 107 | 108 |
109 | 110 |
111 |
112 | 115 | 116 | Content not found. Please use links in the navbar. 117 | 118 |
119 | 120 | 125 | 126 |
127 | 128 | 129 | 130 | 140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 | 105 | 106 | 107 | 108 |
109 | 110 |
111 |
112 | 115 | 116 |
    117 |
  • 118 |

    Michael McLaren. Author, maintainer. 119 |

    120 |
  • 121 |
122 | 123 |
124 | 125 |
126 | 127 | 128 | 129 | 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent; 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.14.0.2 2 | pkgdown: 1.6.1 3 | pkgdown_sha: ~ 4 | articles: {} 5 | last_built: 2021-06-25T11:20Z 6 | urls: 7 | reference: https://mikemc.github.io/speedyseq/reference 8 | article: https://mikemc.github.io/speedyseq/articles 9 | 10 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /docs/reference/Rplot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot004.png -------------------------------------------------------------------------------- /docs/reference/Rplot005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot005.png -------------------------------------------------------------------------------- /docs/reference/Rplot006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot006.png -------------------------------------------------------------------------------- /docs/reference/Rplot007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot007.png -------------------------------------------------------------------------------- /docs/reference/Rplot008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/Rplot008.png -------------------------------------------------------------------------------- /docs/reference/bad_flush_right.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Replace all values with NA upon seeing a bad value — bad_flush_right • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 118 | 119 |
    120 |

    Helper for merge_taxa_vec()

    121 |
    122 | 123 |
    bad_flush_right(x, bad = "BAD", na_bad = FALSE, k = length(x))
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 |
    x

    a vector

    bad

    the string representing a bad value

    na_bad

    whether NAs should also be treated as bad

    k

    the index to which values are flushed

    145 | 146 | 147 |
    148 | 153 |
    154 | 155 | 156 |
    157 | 160 | 161 |
    162 |

    Site built with pkgdown 1.6.1.

    163 |
    164 | 165 |
    166 |
    167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /docs/reference/bad_or_unique.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Reduce a vector x to its unique value or the value of bad — bad_or_unique • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 118 | 119 |
    120 |

    Helper for merge_taxa_vec()

    121 |
    122 | 123 |
    bad_or_unique(x, bad = "BAD")
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
    x

    a vector

    bad

    the string representing a bad value

    137 | 138 | 139 |
    140 | 145 |
    146 | 147 | 148 |
    149 | 152 | 153 |
    154 |

    Site built with pkgdown 1.6.1.

    155 |
    156 | 157 |
    158 |
    159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /docs/reference/filter_sample_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Subset samples using values in the sample data — filter_sample_data • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 107 | 108 | 109 | 110 |
    111 | 112 |
    113 |
    114 | 119 | 120 |
    121 |

    This function is a wrapper around dplyr::filter() that provides a 122 | convenient way to subset samples using the sample_data(x).

    123 |
    124 | 125 |
    filter_sample_data(x, ...)
    126 | 
    127 | # S4 method for phyloseq
    128 | filter_sample_data(x, ...)
    129 | 
    130 | # S4 method for sample_data
    131 | filter_sample_data(x, ...)
    132 | 133 |

    Arguments

    134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 |
    x

    A phyloseq or sample_data object

    ...

    Expressions passed to dplyr::filter()

    145 | 146 | 147 |
    148 | 153 |
    154 | 155 | 156 |
    157 | 160 | 161 |
    162 |

    Site built with pkgdown 1.6.1.

    163 |
    164 | 165 |
    166 |
    167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /docs/reference/import_phyloseq_functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Import phyloseq functions — import_phyloseq_functions • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 107 | 108 | 109 | 110 |
    111 | 112 |
    113 |
    114 | 119 | 120 |
    121 |

    Import all phyloseq functions for internal use, except those we are 122 | reimplementing.

    123 |
    124 | 125 | 126 | 127 | 128 |
    129 | 134 |
    135 | 136 | 137 |
    138 | 141 | 142 |
    143 |

    Site built with pkgdown 1.6.1.

    144 |
    145 | 146 |
    147 |
    148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /docs/reference/merge_groups.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Merge groups of elements within a vector by a function — merge_groups • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
    65 |
    66 | 108 | 109 | 110 | 111 |
    112 | 113 |
    114 |
    115 | 120 | 121 |
    122 |

    Internal function used in merge_samples2() to merge variables. Note, owing 123 | to the use of split(), the merged elements in the new vector will be 124 | reordered according to group.

    125 |
    126 | 127 |
    merge_groups(x, group, f = unique_or_na)
    128 | 129 |

    Arguments

    130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 144 | 145 |
    x

    A vector whose elements will be merged.

    group

    A vector such that as.factor(group) defines the grouping.

    f

    A function that, when applied to a subvector of x, returns a single 143 | value. Can also be a formula as interpretted by purrr::as_mapper().

    146 | 147 | 148 |
    149 | 154 |
    155 | 156 | 157 |
    158 | 161 | 162 |
    163 |

    Site built with pkgdown 1.6.1.

    164 |
    165 | 166 |
    167 |
    168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /docs/reference/merge_taxa_vec_pseudo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pseudo-merge taxa in groups — merge_taxa_vec_pseudo • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 118 | 119 |
    120 |

    Returns x pruned to the first taxon of each group defined in group.

    121 |
    122 | 123 |
    merge_taxa_vec_pseudo(x, group, reorder = FALSE)
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 137 |
    x

    a phyloseq component-class object

    group

    a vector with one element for each taxon in x that defines 135 | the new groups

    138 | 139 | 140 |
    141 | 146 |
    147 | 148 | 149 |
    150 | 153 | 154 |
    155 |

    Site built with pkgdown 1.6.1.

    156 |
    157 | 158 |
    159 |
    160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/reference/oneline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | One-line summaries of phyloseq components — oneline • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 118 | 119 |
    120 |

    One-line summaries of phyloseq components

    121 |
    122 | 123 |
    oneline(x)
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 |
    x

    A phyloseq component object

    133 | 134 | 135 |
    136 | 141 |
    142 | 143 | 144 |
    145 | 148 | 149 |
    150 |

    Site built with pkgdown 1.6.1.

    151 |
    152 | 153 |
    154 |
    155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /docs/reference/pipe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pipe operator — %>% • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 118 | 119 |
    120 |

    See magrittr::%>% for details.

    121 |
    122 | 123 |
    lhs %>% rhs
    124 | 125 | 126 | 127 |
    128 | 133 |
    134 | 135 | 136 |
    137 | 140 | 141 |
    142 |

    Site built with pkgdown 1.6.1.

    143 |
    144 | 145 |
    146 |
    147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /docs/reference/plot_bar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_bar-1.png -------------------------------------------------------------------------------- /docs/reference/plot_bar-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_bar-2.png -------------------------------------------------------------------------------- /docs/reference/plot_bar-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_bar-3.png -------------------------------------------------------------------------------- /docs/reference/plot_bar-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_bar-4.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-1.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-2.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-3.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-4.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-5.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-6.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-7.png -------------------------------------------------------------------------------- /docs/reference/plot_heatmap-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_heatmap-8.png -------------------------------------------------------------------------------- /docs/reference/plot_tree-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_tree-1.png -------------------------------------------------------------------------------- /docs/reference/plot_tree-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/plot_tree-2.png -------------------------------------------------------------------------------- /docs/reference/psmelt-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/psmelt-1.png -------------------------------------------------------------------------------- /docs/reference/reexports.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Objects exported from other packages — reexports • speedyseq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
    68 |
    69 | 111 | 112 | 113 | 114 |
    115 | 116 |
    117 |
    118 | 123 | 124 |
    125 |

    These objects are imported from other packages. Follow the links 126 | below to see their documentation.

    127 |
    128 |
    tibble

    as_tibble

    129 | 130 |
    131 |
    132 | 133 | 134 | 135 | 136 |
    137 | 142 |
    143 | 144 | 145 |
    146 | 149 | 150 |
    151 |

    Site built with pkgdown 1.6.1.

    152 |
    153 | 154 |
    155 |
    156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/tip_glom-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/tip_glom-1.png -------------------------------------------------------------------------------- /docs/reference/tip_glom-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/tip_glom-2.png -------------------------------------------------------------------------------- /docs/reference/tree_glom-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikemc/speedyseq/0057652ff7a4244ccef2b786dca58d901ec2fc62/docs/reference/tree_glom-1.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://mikemc.github.io/speedyseq/index.html 5 | 6 | 7 | https://mikemc.github.io/speedyseq/reference/as_tibble-phyloseq.html 8 | 9 | 10 | https://mikemc.github.io/speedyseq/reference/bad_flush_right.html 11 | 12 | 13 | https://mikemc.github.io/speedyseq/reference/bad_or_unique.html 14 | 15 | 16 | https://mikemc.github.io/speedyseq/reference/filter-phyloseq.html 17 | 18 | 19 | https://mikemc.github.io/speedyseq/reference/filter_taxa.html 20 | 21 | 22 | https://mikemc.github.io/speedyseq/reference/import_phyloseq_functions.html 23 | 24 | 25 | https://mikemc.github.io/speedyseq/reference/join-phyloseq.html 26 | 27 | 28 | https://mikemc.github.io/speedyseq/reference/merge_groups.html 29 | 30 | 31 | https://mikemc.github.io/speedyseq/reference/merge_samples2.html 32 | 33 | 34 | https://mikemc.github.io/speedyseq/reference/merge_taxa_vec.html 35 | 36 | 37 | https://mikemc.github.io/speedyseq/reference/merge_taxa_vec_pseudo.html 38 | 39 | 40 | https://mikemc.github.io/speedyseq/reference/mutate-phyloseq.html 41 | 42 | 43 | https://mikemc.github.io/speedyseq/reference/oneline.html 44 | 45 | 46 | https://mikemc.github.io/speedyseq/reference/orient_taxa.html 47 | 48 | 49 | https://mikemc.github.io/speedyseq/reference/pipe.html 50 | 51 | 52 | https://mikemc.github.io/speedyseq/reference/plot_bar.html 53 | 54 | 55 | https://mikemc.github.io/speedyseq/reference/plot_heatmap.html 56 | 57 | 58 | https://mikemc.github.io/speedyseq/reference/plot_tree.html 59 | 60 | 61 | https://mikemc.github.io/speedyseq/reference/psmelt.html 62 | 63 | 64 | https://mikemc.github.io/speedyseq/reference/reexports.html 65 | 66 | 67 | https://mikemc.github.io/speedyseq/reference/relocate-phyloseq.html 68 | 69 | 70 | https://mikemc.github.io/speedyseq/reference/rename-phyloseq.html 71 | 72 | 73 | https://mikemc.github.io/speedyseq/reference/sample_data_stable.html 74 | 75 | 76 | https://mikemc.github.io/speedyseq/reference/select-phyloseq.html 77 | 78 | 79 | https://mikemc.github.io/speedyseq/reference/select_taxa-methods.html 80 | 81 | 82 | https://mikemc.github.io/speedyseq/reference/show-methods.html 83 | 84 | 85 | https://mikemc.github.io/speedyseq/reference/tax_glom.html 86 | 87 | 88 | https://mikemc.github.io/speedyseq/reference/tibble-constructors.html 89 | 90 | 91 | https://mikemc.github.io/speedyseq/reference/tibble_print.html 92 | 93 | 94 | https://mikemc.github.io/speedyseq/reference/tip_glom.html 95 | 96 | 97 | https://mikemc.github.io/speedyseq/reference/transform_sample_counts.html 98 | 99 | 100 | https://mikemc.github.io/speedyseq/reference/tree_glom.html 101 | 102 | 103 | https://mikemc.github.io/speedyseq/reference/unique_or_na.html 104 | 105 | 106 | -------------------------------------------------------------------------------- /man/as_tibble-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_tibble.R 3 | \name{as_tibble-phyloseq} 4 | \alias{as_tibble-phyloseq} 5 | \alias{as_tibble.otu_table} 6 | \alias{as_tibble.sample_data} 7 | \alias{as_tibble.taxonomyTable} 8 | \alias{as_tibble.XStringSet} 9 | \alias{as_tibble.phyloseq} 10 | \title{Coerce phyloseq objects to tibble data frames} 11 | \usage{ 12 | \method{as_tibble}{otu_table}(x, pivot = TRUE, .name_repair = base::make.unique) 13 | 14 | \method{as_tibble}{sample_data}(x, .name_repair = base::make.unique) 15 | 16 | \method{as_tibble}{taxonomyTable}(x, .name_repair = base::make.unique) 17 | 18 | \method{as_tibble}{XStringSet}(x) 19 | 20 | \method{as_tibble}{phyloseq}(x, tax = TRUE, ref = FALSE, .name_repair = base::make.unique) 21 | } 22 | \arguments{ 23 | \item{x}{A phyloseq object or component.} 24 | 25 | \item{pivot}{Whether to pivot the otu table to long format.} 26 | 27 | \item{.name_repair}{Function to repair names in the case of conflicts.} 28 | 29 | \item{tax}{Whether to include taxonomy data.} 30 | 31 | \item{ref}{Whether to include reference sequences.} 32 | } 33 | \value{ 34 | A tibble (tbl_df) 35 | } 36 | \description{ 37 | These functions extend the \code{as_tibble()} function defined by the tibble 38 | package to work on phyloseq objects or phyloseq-component objects. 39 | } 40 | \details{ 41 | Tibbles (tbl_df objects) do not support rownames; the taxa and sample names 42 | in the returned tibbles will always be stored in the first or second 43 | columns. The names ".otu", ".sample", ".abundance", and ".sequence" are 44 | special column names reserved for the otu/taxa names, sample names, 45 | abundances, and reference sequences. 46 | } 47 | \examples{ 48 | library(tibble) # for as_tibble() and glimpse() 49 | 50 | data(GlobalPatterns) 51 | 52 | # Subset to 1/100 of the original taxa to speed operations 53 | ps <- GlobalPatterns \%>\% 54 | filter_tax_table(dplyr::row_number() \%\% 100 == 1) 55 | 56 | # On phyloseq objects, as_tibble is similar to psmelt() 57 | psmelt(ps) \%>\% glimpse 58 | as_tibble(ps) \%>\% glimpse 59 | 60 | # By default, the otu_table method provides a tibble in long-format like 61 | # psmelt and the phyloseq method 62 | otu_table(ps) \%>\% as_tibble \%>\% glimpse 63 | 64 | # Sample data and taxonomy tables produced by as_tibble can be converted 65 | # back into their respective phyloseq objects using speedyseq's tbl_df 66 | # constructors 67 | sample_data(ps) <- sample_data(ps) \%>\% 68 | as_tibble \%>\% 69 | dplyr::mutate(sample_sum = sample_sums(ps)) \%>\% 70 | sample_data 71 | sample_data(ps) \%>\% glimpse 72 | } 73 | -------------------------------------------------------------------------------- /man/bad_flush_right.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_taxa_vec.R 3 | \name{bad_flush_right} 4 | \alias{bad_flush_right} 5 | \title{Replace all values with NA upon seeing a bad value} 6 | \usage{ 7 | bad_flush_right(x, bad = "BAD", na_bad = FALSE, k = length(x)) 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | 12 | \item{bad}{the string representing a bad value} 13 | 14 | \item{na_bad}{whether NAs should also be treated as bad} 15 | 16 | \item{k}{the index to which values are flushed} 17 | } 18 | \description{ 19 | Helper for \code{merge_taxa_vec()} 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/bad_or_unique.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_taxa_vec.R 3 | \name{bad_or_unique} 4 | \alias{bad_or_unique} 5 | \title{Reduce a vector x to its unique value or the value of \code{bad}} 6 | \usage{ 7 | bad_or_unique(x, bad = "BAD") 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | 12 | \item{bad}{the string representing a bad value} 13 | } 14 | \description{ 15 | Helper for \code{merge_taxa_vec()} 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/filter-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-verbs.R 3 | \name{filter-phyloseq} 4 | \alias{filter-phyloseq} 5 | \alias{filter_tax_table} 6 | \alias{filter_tax_table,phyloseq-method} 7 | \alias{filter_tax_table,taxonomyTable-method} 8 | \alias{filter_sample_data} 9 | \alias{filter_sample_data,phyloseq-method} 10 | \alias{filter_sample_data,sample_data-method} 11 | \title{Subset rows in the taxonomy table or sample data using column values} 12 | \usage{ 13 | filter_tax_table(x, ...) 14 | 15 | \S4method{filter_tax_table}{phyloseq}(x, ...) 16 | 17 | \S4method{filter_tax_table}{taxonomyTable}(x, ...) 18 | 19 | filter_sample_data(x, ...) 20 | 21 | \S4method{filter_sample_data}{phyloseq}(x, ...) 22 | 23 | \S4method{filter_sample_data}{sample_data}(x, ...) 24 | } 25 | \arguments{ 26 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 27 | 28 | \item{...}{Expressions passed to \code{dplyr::filter()}} 29 | } 30 | \description{ 31 | These functions are wrappers around \code{dplyr::filter()} that make it possible 32 | to subset rows (corresponding to taxa or samples) using column values in the 33 | taxonomy table or sample data. 34 | } 35 | \examples{ 36 | data(GlobalPatterns) 37 | 38 | ps <- GlobalPatterns \%>\% 39 | filter_tax_table(Kingdom == "Bacteria") \%>\% 40 | filter_sample_data(SampleType \%in\% c("Feces", "Soil")) 41 | } 42 | -------------------------------------------------------------------------------- /man/filter_taxa.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/transform-filter.R 3 | \name{filter_taxa} 4 | \alias{filter_taxa} 5 | \alias{filter_taxa2} 6 | \title{Filter taxa based on across-sample OTU abundance criteria} 7 | \usage{ 8 | filter_taxa(physeq, fun, prune = FALSE) 9 | 10 | filter_taxa2(physeq, fun) 11 | } 12 | \arguments{ 13 | \item{physeq}{\code{\link[=phyloseq-class]{phyloseq-class()}} or \code{\link[ape:read.tree]{ape::phylo()}}.} 14 | 15 | \item{fun}{A function or formula that can be converted to a function by 16 | \code{\link[purrr:as_mapper]{purrr::as_mapper()}}} 17 | 18 | \item{prune}{A logical. If \code{FALSE}, then this function returns a logical 19 | vector specifying the taxa that passed the filter; if \code{TRUE}, then this 20 | function returns the pruned phyloseq object.} 21 | } 22 | \description{ 23 | Variations of \code{\link[phyloseq:filter_taxa]{phyloseq::filter_taxa()}} that allows a purrr-style anonymous 24 | function. 25 | } 26 | \details{ 27 | \code{filter_taxa()} simply calls \code{\link[purrr:as_mapper]{purrr::as_mapper()}} on \code{fun} and passes the 28 | resulting function on to \code{\link[phyloseq:filter_taxa]{phyloseq::filter_taxa()}}. \code{filter_taxa2()} also 29 | sets \code{prune = TRUE}, which is convenient when passing a phyloseq object in a 30 | pipe chain (see example). 31 | } 32 | \section{Functions}{ 33 | \itemize{ 34 | \item \code{filter_taxa2()}: Sets \code{prune = TRUE} 35 | 36 | }} 37 | \examples{ 38 | data(GlobalPatterns) 39 | # Filter low prevalence taxa and then convert to proportions 40 | gp.prop <- GlobalPatterns \%>\% 41 | filter_taxa2(~ sum(. > 0) > 5) \%>\% 42 | transform_sample_counts(~ . / sum(.)) 43 | } 44 | \seealso{ 45 | \code{\link[phyloseq:filter_taxa]{phyloseq::filter_taxa()}} 46 | \code{\link[purrr:as_mapper]{purrr::as_mapper()}} 47 | } 48 | -------------------------------------------------------------------------------- /man/import_phyloseq_functions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/import-phyloseq.R 3 | \name{import_phyloseq_functions} 4 | \alias{import_phyloseq_functions} 5 | \title{Import phyloseq functions} 6 | \description{ 7 | Import all phyloseq functions for internal use, except those we are 8 | reimplementing. 9 | } 10 | -------------------------------------------------------------------------------- /man/join-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-joins.R 3 | \name{join-phyloseq} 4 | \alias{join-phyloseq} 5 | \alias{left_join_tax_table} 6 | \alias{left_join_tax_table,phyloseq-method} 7 | \alias{left_join_tax_table,taxonomyTable-method} 8 | \alias{left_join_sample_data} 9 | \alias{left_join_sample_data,phyloseq-method} 10 | \alias{left_join_sample_data,sample_data-method} 11 | \alias{inner_join_tax_table} 12 | \alias{inner_join_tax_table,phyloseq-method} 13 | \alias{inner_join_tax_table,taxonomyTable-method} 14 | \alias{inner_join_sample_data} 15 | \alias{inner_join_sample_data,phyloseq-method} 16 | \alias{inner_join_sample_data,sample_data-method} 17 | \title{Mutating joins of the taxonomy table or sample data} 18 | \usage{ 19 | left_join_tax_table(x, ...) 20 | 21 | \S4method{left_join_tax_table}{phyloseq}(x, ...) 22 | 23 | \S4method{left_join_tax_table}{taxonomyTable}(x, ...) 24 | 25 | left_join_sample_data(x, ...) 26 | 27 | \S4method{left_join_sample_data}{phyloseq}(x, ...) 28 | 29 | \S4method{left_join_sample_data}{sample_data}(x, ...) 30 | 31 | inner_join_tax_table(x, ...) 32 | 33 | \S4method{inner_join_tax_table}{phyloseq}(x, ...) 34 | 35 | \S4method{inner_join_tax_table}{taxonomyTable}(x, ...) 36 | 37 | inner_join_sample_data(x, ...) 38 | 39 | \S4method{inner_join_sample_data}{phyloseq}(x, ...) 40 | 41 | \S4method{inner_join_sample_data}{sample_data}(x, ...) 42 | } 43 | \arguments{ 44 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 45 | 46 | \item{...}{Arguments passed to respective dplyr joining operation} 47 | } 48 | \value{ 49 | An object of the same type as \code{x}, with added columns 50 | } 51 | \description{ 52 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 53 | 54 | These functions are wrappers around dplyr joining operations (see 55 | \code{dplyr::mutate-joins}) whose first (\code{x}) argument is either the taxonomy 56 | table or sample data. 57 | } 58 | \details{ 59 | When joining by taxonomy table, the .otu column name can be used to match 60 | taxa names. 61 | When joining by sample data, the .sample column name can be used to match 62 | sample names. 63 | } 64 | \examples{ 65 | library(tibble) 66 | 67 | data(GlobalPatterns) 68 | 69 | GlobalPatterns \%>\% sample_variables 70 | ps1 <- GlobalPatterns \%>\% 71 | select_sample_data(!contains("Barcode")) 72 | y <- GlobalPatterns \%>\% 73 | sample_data \%>\% 74 | select_sample_data(contains("Barcode")) \%>\% 75 | as_tibble 76 | ps2 <- ps1 \%>\% left_join_sample_data(y, by = ".sample") 77 | ps2 \%>\% sample_variables 78 | } 79 | \seealso{ 80 | \code{\link[dplyr:mutate-joins]{dplyr::left_join()}} 81 | \code{\link[dplyr:mutate-joins]{dplyr::inner_join()}} 82 | } 83 | -------------------------------------------------------------------------------- /man/merge_groups.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_samples.R 3 | \name{merge_groups} 4 | \alias{merge_groups} 5 | \title{Merge groups of elements within a vector by a function} 6 | \usage{ 7 | merge_groups(x, group, f = unique_or_na) 8 | } 9 | \arguments{ 10 | \item{x}{A vector whose elements will be merged.} 11 | 12 | \item{group}{A vector such that \code{as.factor(group)} defines the grouping.} 13 | 14 | \item{f}{A function that, when applied to a subvector of x, returns a single 15 | value. Can also be a formula as interpretted by \code{purrr::as_mapper()}.} 16 | } 17 | \description{ 18 | Internal function used in \code{merge_samples2()} to merge variables. Note, owing 19 | to the use of \code{split()}, the merged elements in the new vector will be 20 | reordered according to \code{group}. 21 | } 22 | \keyword{internal} 23 | -------------------------------------------------------------------------------- /man/merge_samples2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_samples.R 3 | \name{merge_samples2} 4 | \alias{merge_samples2} 5 | \alias{merge_samples2,phyloseq-method} 6 | \alias{merge_samples2,otu_table-method} 7 | \alias{merge_samples2,sample_data-method} 8 | \title{Merge samples by a sample variable or factor} 9 | \usage{ 10 | merge_samples2(x, group, fun_otu = sum, funs = list(), reorder = FALSE) 11 | 12 | \S4method{merge_samples2}{phyloseq}(x, group, fun_otu = sum, funs = list(), reorder = FALSE) 13 | 14 | \S4method{merge_samples2}{otu_table}(x, group, fun_otu = sum, reorder = FALSE) 15 | 16 | \S4method{merge_samples2}{sample_data}(x, group, funs = list(), reorder = FALSE) 17 | } 18 | \arguments{ 19 | \item{x}{A \code{phyloseq}, \code{otu_table}, or \code{sample_data} object} 20 | 21 | \item{group}{A sample variable or a vector of length \code{nsamples(x)} defining 22 | the sample grouping. A vector must be supplied if x is an otu_table} 23 | 24 | \item{fun_otu}{Function for combining abundances in the otu table; default 25 | is \code{sum}. Can be a formula to be converted to a function by 26 | \code{\link[purrr:as_mapper]{purrr::as_mapper()}}} 27 | 28 | \item{funs}{Named list of merge functions for sample variables; default is 29 | \code{unique_or_na}} 30 | 31 | \item{reorder}{Logical specifying whether to reorder the new (merged) 32 | samples by name} 33 | } 34 | \description{ 35 | This function provides an alternative to \code{phyloseq::merge_samples()} that 36 | better handles sample variables of different types, especially categorical 37 | sample variables. It combines the samples in \code{x} defined by the sample 38 | variable or factor \code{group} by summing the abundances in \code{otu_table(x)} and 39 | combines sample variables by the summary functions in \code{funs}. The default 40 | summary function, \code{unique_or_na()}, collapses the values within a group to a 41 | single unique value if it exists and otherwise returns NA. The new (merged) 42 | samples are named by the values in \code{group}. 43 | } 44 | \examples{ 45 | data(enterotype) 46 | 47 | # Merge samples with the same project and clinical status 48 | ps <- enterotype 49 | sample_data(ps) <- sample_data(ps) \%>\% 50 | transform(Project.ClinicalStatus = Project:ClinicalStatus) 51 | sample_data(ps) \%>\% head 52 | ps0 <- merge_samples2(ps, "Project.ClinicalStatus", 53 | fun_otu = mean, 54 | funs = list(Age = mean) 55 | ) 56 | sample_data(ps0) \%>\% head 57 | } 58 | -------------------------------------------------------------------------------- /man/merge_taxa_vec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_taxa_vec.R 3 | \name{merge_taxa_vec} 4 | \alias{merge_taxa_vec} 5 | \alias{merge_taxa_vec,phyloseq-method} 6 | \alias{merge_taxa_vec,otu_table-method} 7 | \alias{merge_taxa_vec,taxonomyTable-method} 8 | \alias{merge_taxa_vec,phylo-method} 9 | \alias{merge_taxa_vec,XStringSet-method} 10 | \title{Merge taxa in groups (vectorized version)} 11 | \usage{ 12 | merge_taxa_vec(x, group, reorder = FALSE, tax_adjust = 1L) 13 | 14 | \S4method{merge_taxa_vec}{phyloseq}(x, group, reorder = FALSE, tax_adjust = 1L) 15 | 16 | \S4method{merge_taxa_vec}{otu_table}(x, group, reorder = FALSE) 17 | 18 | \S4method{merge_taxa_vec}{taxonomyTable}(x, group, reorder = FALSE, tax_adjust = 1L) 19 | 20 | \S4method{merge_taxa_vec}{phylo}(x, group) 21 | 22 | \S4method{merge_taxa_vec}{XStringSet}(x, group, reorder = FALSE) 23 | } 24 | \arguments{ 25 | \item{x}{A phyloseq object or component object} 26 | 27 | \item{group}{A vector with one element for each taxon in \code{physeq} that 28 | defines the new groups. see \code{base::rowsum()}.} 29 | 30 | \item{reorder}{Logical specifying whether to reorder the taxa by their 31 | \code{group} values. Ignored if \code{x} has (or is) a phylogenetic tree.} 32 | 33 | \item{tax_adjust}{0: no adjustment; 1: phyloseq-compatible adjustment; 2: 34 | conservative adjustment} 35 | } 36 | \description{ 37 | Merge taxa in \code{x} into a smaller set of taxa defined by the vector \code{group}. 38 | Taxa whose value in \code{group} is NA will be dropped. New taxa will be named 39 | according to the most abundant taxon in each group (\code{phyloseq} and 40 | \code{otu_table} objects) or the first taxon in each group (all other phyloseq 41 | component objects). 42 | } 43 | \details{ 44 | If \code{x} is a phyloseq object with a phylogenetic tree, then the new taxa will 45 | be ordered as they are in the tree. Otherwise, the taxa order can be 46 | controlled by the \code{reorder} argument, which behaves like the \code{reorder} 47 | argument in \code{\link[base:rowsum]{base::rowsum()}}. \code{reorder = FALSE} will keep taxa in 48 | the original order determined by when the member of each group first appears 49 | in \code{taxa_names(x)}; \code{reorder = TRUE} will order new taxa according to their 50 | corresponding value in \code{group}. 51 | 52 | The \code{tax_adjust} argument controls the handling of taxonomic disagreements 53 | within groups. Setting \code{tax_adjust == 0} causes no adjustment; the taxonomy 54 | of the new group is set to the archetype taxon (see below). Otherwise, 55 | disagreements within a group at a given rank cause the values at lower ranks 56 | to be set to \code{NA}. If \code{tax_adjust == 1} (the default), then a rank where all 57 | taxa in the group are already NA is not counted as a disagreement, and lower 58 | ranks may be kept if the taxa agree. This corresponds to the original 59 | phyloseq behavior. If \code{tax_adjust == 2}, then these NAs are treated as a 60 | disagreement; all ranks are set to NA after the first disagreement or NA. 61 | } 62 | \examples{ 63 | \dontrun{ 64 | # Create 97\% OTUs from a phyloseq object with reference sequences 65 | # Assume ps is a phyloseq object with refseq slot 66 | dna <- refseq(ps) 67 | nproc <- 1 # Increase to use multiple processors 68 | aln <- DECIPHER::AlignSeqs(dna, processors = nproc) 69 | d <- DECIPHER::DistanceMatrix(aln, processors = nproc) 70 | clusters <- DECIPHER::IdClusters( 71 | d, 72 | method = "complete", 73 | cutoff = 0.03, 74 | processors = nproc 75 | ) 76 | ps0 <- merge_taxa_vec( 77 | ps, 78 | group = clusters$cluster, 79 | ) 80 | } 81 | } 82 | \seealso{ 83 | Merging functions that use this function: \code{\link[=tax_glom]{tax_glom()}}, \code{\link[=tip_glom]{tip_glom()}}, 84 | \code{\link[=tree_glom]{tree_glom()}} 85 | 86 | \code{\link[base:rowsum]{base::rowsum()}} 87 | 88 | \code{\link[phyloseq:merge_taxa-methods]{phyloseq::merge_taxa()}} 89 | } 90 | -------------------------------------------------------------------------------- /man/merge_taxa_vec_pseudo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_taxa_vec.R 3 | \name{merge_taxa_vec_pseudo} 4 | \alias{merge_taxa_vec_pseudo} 5 | \title{Pseudo-merge taxa in groups} 6 | \usage{ 7 | merge_taxa_vec_pseudo(x, group, reorder = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{a phyloseq component-class object} 11 | 12 | \item{group}{a vector with one element for each taxon in \code{x} that defines 13 | the new groups} 14 | } 15 | \description{ 16 | Returns \code{x} pruned to the first taxon of each group defined in \code{group}. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/mutate-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-verbs.R 3 | \name{mutate-phyloseq} 4 | \alias{mutate-phyloseq} 5 | \alias{mutate_tax_table} 6 | \alias{mutate_tax_table,taxonomyTable-method} 7 | \alias{mutate_tax_table,phyloseq-method} 8 | \alias{transmute_tax_table} 9 | \alias{transmute_tax_table,taxonomyTable-method} 10 | \alias{transmute_tax_table,phyloseq-method} 11 | \alias{mutate_sample_data} 12 | \alias{mutate_sample_data,sample_data-method} 13 | \alias{mutate_sample_data,phyloseq-method} 14 | \alias{transmute_sample_data} 15 | \alias{transmute_sample_data,sample_data-method} 16 | \alias{transmute_sample_data,phyloseq-method} 17 | \title{Create, modify, and delete columns in the taxonomy table or sample data} 18 | \usage{ 19 | mutate_tax_table(x, ...) 20 | 21 | \S4method{mutate_tax_table}{taxonomyTable}(x, ...) 22 | 23 | \S4method{mutate_tax_table}{phyloseq}(x, ...) 24 | 25 | transmute_tax_table(x, ...) 26 | 27 | \S4method{transmute_tax_table}{taxonomyTable}(x, ...) 28 | 29 | \S4method{transmute_tax_table}{phyloseq}(x, ...) 30 | 31 | mutate_sample_data(x, ...) 32 | 33 | \S4method{mutate_sample_data}{sample_data}(x, ...) 34 | 35 | \S4method{mutate_sample_data}{phyloseq}(x, ...) 36 | 37 | transmute_sample_data(x, ...) 38 | 39 | \S4method{transmute_sample_data}{sample_data}(x, ...) 40 | 41 | \S4method{transmute_sample_data}{phyloseq}(x, ...) 42 | } 43 | \arguments{ 44 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 45 | 46 | \item{...}{Expressions passed to \code{dplyr::mutate()} or \code{dplyr::transmute()}} 47 | } 48 | \description{ 49 | These functions are wrappers around \code{dplyr::mutate()} and 50 | \code{dplyr::transmute()} that provide convenient ways to modify \code{tax_table(x)} 51 | and \code{sample_data(x)} as well as the sample and taxa names. 52 | } 53 | \details{ 54 | When modifying the taxonomy table, the \code{.otu} column name can be used to set 55 | new taxa names. 56 | When modifying the sample data, the \code{.sample} column name can be used to set 57 | new taxa names. 58 | 59 | The experimental arguments to \code{dplyr::mutate()} of \code{.keep}, \code{.before}, and 60 | \code{.after} are not currently supported and may result in errors or unexpected 61 | behavior. 62 | } 63 | \examples{ 64 | data(GlobalPatterns) 65 | 66 | ps <- GlobalPatterns \%>\% 67 | transmute_sample_data(SampleType, sample_sum = sample_sums(.)) \%>\% 68 | filter_sample_data(SampleType \%in\% c("Feces", "Skin", "Tongue")) \%>\% 69 | filter_tax_table(Kingdom == "Bacteria") \%>\% 70 | tax_glom("Phylum") \%>\% 71 | transmute_tax_table(Kingdom, Phylum, .otu = Phylum) 72 | sample_data(ps) 73 | tax_table(ps) 74 | } 75 | -------------------------------------------------------------------------------- /man/oneline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/printing.R 3 | \name{oneline} 4 | \alias{oneline} 5 | \title{One-line summaries of phyloseq components} 6 | \usage{ 7 | oneline(x) 8 | } 9 | \arguments{ 10 | \item{x}{A phyloseq component object} 11 | } 12 | \description{ 13 | One-line summaries of phyloseq components 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/orient_taxa.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{orient_taxa} 4 | \alias{orient_taxa} 5 | \alias{orient_taxa,otu_table-method} 6 | \alias{orient_taxa,phyloseq-method} 7 | \title{Orient a phyloseq object or otu table to have taxa as rows or as columns} 8 | \usage{ 9 | orient_taxa(x, as) 10 | 11 | \S4method{orient_taxa}{otu_table}(x, as) 12 | 13 | \S4method{orient_taxa}{phyloseq}(x, as) 14 | } 15 | \arguments{ 16 | \item{x}{A phyloseq or otu-table object} 17 | 18 | \item{as}{The matrix dimension that is desired for taxa. Must be 19 | "rows" for rows and "columns" or "cols" for columns.} 20 | } 21 | \description{ 22 | Puts the phyloseq or otu-table object \code{x} in the orientation (taxa as rows 23 | or as columns) specified by \code{as}. This is useful when passing the otu table 24 | on to functions that require the abundance matrix to have a specific 25 | orientation and are unaware of the \code{taxa_are_rows(x)} property. 26 | } 27 | \examples{ 28 | data(soilrep) 29 | taxa_are_rows(soilrep) 30 | x <- soilrep \%>\% orient_taxa(as = "columns") 31 | taxa_are_rows(x) 32 | } 33 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/plot_bar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot-methods.R 3 | \name{plot_bar} 4 | \alias{plot_bar} 5 | \title{A flexible, informative barplot phyloseq data} 6 | \usage{ 7 | plot_bar(physeq, x="Sample", y="Abundance", fill=NULL, 8 | title=NULL, facet_grid=NULL) 9 | } 10 | \arguments{ 11 | \item{physeq}{(Required). An \code{\link{otu_table-class}} or 12 | \code{\link{phyloseq-class}}.} 13 | 14 | \item{x}{(Optional). Optional, but recommended, especially if your data 15 | is comprised of many samples. A character string. 16 | The variable in the melted-data that should be mapped to the x-axis. 17 | See \code{\link{psmelt}}, \code{\link{melt}}, 18 | and \code{\link{ggplot}} for more details.} 19 | 20 | \item{y}{(Optional). A character string. 21 | The variable in the melted-data that should be mapped to the y-axis. 22 | Typically this will be \code{"Abundance"}, in order to 23 | quantitatively display the abundance values for each OTU/group. 24 | However, alternative variables could be used instead, 25 | producing a very different, though possibly still informative, plot. 26 | See \code{\link{psmelt}}, \code{\link{melt}}, 27 | and \code{\link{ggplot}} for more details.} 28 | 29 | \item{fill}{(Optional). A character string. Indicates which sample variable 30 | should be used to map to the fill color of the bars. 31 | The default is \code{NULL}, resulting in a gray fill for all bar segments.} 32 | 33 | \item{title}{(Optional). Default \code{NULL}. Character string. 34 | The main title for the graphic.} 35 | 36 | \item{facet_grid}{(Optional). A formula object. 37 | It should describe the faceting you want in exactly the same way as for 38 | \code{\link[ggplot2]{facet_grid}}, 39 | and is ulitmately provided to \code{\link{ggplot}}2 graphics. 40 | The default is: \code{NULL}, resulting in no faceting.} 41 | } 42 | \value{ 43 | A \code{\link[ggplot2]{ggplot}}2 graphic object -- rendered in the 44 | graphical device as the default 45 | \code{\link[base]{print}}/\code{\link[methods]{show}} method. 46 | } 47 | \description{ 48 | There are many useful examples of phyloseq barplot graphics in the 49 | \href{http://joey711.github.io/phyloseq/plot_bar-examples}{phyloseq online 50 | tutorials}. This function wraps \code{ggplot2} plotting, and returns a 51 | \code{ggplot2} graphic object that can be saved or further modified with 52 | additional layers, options, etc. The main purpose of this function is to 53 | quickly and easily create informative summary graphics of the differences in 54 | taxa abundance between samples in an experiment. 55 | } 56 | \examples{ 57 | data("GlobalPatterns") 58 | gp.ch = subset_taxa(GlobalPatterns, Phylum == "Chlamydiae") 59 | plot_bar(gp.ch) 60 | plot_bar(gp.ch, fill="Genus") 61 | plot_bar(gp.ch, x="SampleType", fill="Genus") 62 | plot_bar(gp.ch, "SampleType", fill="Genus", facet_grid=~Family) 63 | # See additional examples in the plot_bar online tutorial. Link above. 64 | } 65 | \seealso{ 66 | \href{http://joey711.github.io/phyloseq/plot_bar-examples}{phyloseq online 67 | tutorials}. 68 | 69 | \code{\link{psmelt}} 70 | 71 | \code{\link{ggplot}} 72 | 73 | \code{\link{qplot}} 74 | } 75 | -------------------------------------------------------------------------------- /man/psmelt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psmelt.R 3 | \name{psmelt} 4 | \alias{psmelt} 5 | \title{Melt phyloseq data object into large data.frame} 6 | \usage{ 7 | psmelt(physeq, as = getOption("speedyseq.psmelt_class")) 8 | } 9 | \arguments{ 10 | \item{physeq}{An \linkS4class{otu_table} or \linkS4class{phyloseq}; most useful for 11 | phyloseq-class.} 12 | 13 | \item{as}{Class of the output table; see Details.} 14 | } 15 | \value{ 16 | A table of the specified class 17 | } 18 | \description{ 19 | The psmelt function is a specialized melt function for melting phyloseq 20 | objects (instances of the phyloseq class), usually for producing graphics 21 | with \link[ggplot2:ggplot2-package]{ggplot2::ggplot2}. The naming conventions used in downstream phyloseq 22 | graphics functions have reserved the following variable names that should 23 | not be used as the names of \code{\link[=sample_variables]{sample_variables()}} or taxonomic 24 | \code{\link[=rank_names]{rank_names()}}. These reserved names are \code{c("Sample", "Abundance", "OTU")}. 25 | Also, you should not have identical names for sample variables and taxonomic 26 | ranks. That is, the intersection of the output of the following two 27 | functions \code{\link[=sample_variables]{sample_variables()}}, \code{\link[=rank_names]{rank_names()}} should be an empty vector 28 | (e.g. \code{intersect(sample_variables(physeq), rank_names(physeq))}). All of 29 | these potential name collisions are checked-for and renamed automatically 30 | with a warning. However, if you (re)name your variables accordingly ahead of 31 | time, it will reduce confusion and eliminate the warnings. 32 | } 33 | \details{ 34 | The \code{as} argument allows choosing between three classes for tabular data: 35 | \itemize{ 36 | \item \linkS4class{data.frame} is chosen by "data.frame" or "df" 37 | \item \linkS4class{data.table} is chosen by "data.table" or "dt" 38 | \item \linkS4class{tbl_df} is chosen by "tbl_df", "tbl", or "tibble" 39 | } 40 | 41 | The default is "data.frame" and can be overridden by setting the 42 | "speedyseq.psmelt_class" option. 43 | 44 | Note that "melted" phyloseq data is stored much less efficiently, and so RAM 45 | storage issues could arise with a smaller dataset (smaller number of 46 | samples/OTUs/variables) than one might otherwise expect. For common sizes 47 | of graphics-ready datasets, however, this should not be a problem. Because 48 | the number of OTU entries has a large effect on the RAM requirement, methods 49 | to reduce the number of separate OTU entries -- for instance by 50 | agglomerating OTUs based on phylogenetic distance using \code{\link[=tip_glom]{tip_glom()}} -- can 51 | help alleviate RAM usage problems. This function is made user-accessible for 52 | flexibility, but is also used extensively by plot functions in phyloseq. 53 | } 54 | \examples{ 55 | data("GlobalPatterns") 56 | gp.ch = subset_taxa(GlobalPatterns, Phylum == "Chlamydiae") 57 | mdf = psmelt(gp.ch) 58 | nrow(mdf) 59 | ncol(mdf) 60 | colnames(mdf) 61 | head(rownames(mdf)) 62 | # Create a ggplot similar to 63 | library("ggplot2") 64 | p = ggplot(mdf, aes(x=SampleType, y=Abundance, fill=Genus)) 65 | p = p + geom_bar(color="black", stat="identity", position="stack") 66 | print(p) 67 | } 68 | \seealso{ 69 | \code{\link[=plot_bar]{plot_bar()}} 70 | } 71 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_tibble.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{as_tibble} 7 | \title{Objects exported from other packages} 8 | \keyword{internal} 9 | \description{ 10 | These objects are imported from other packages. Follow the links 11 | below to see their documentation. 12 | 13 | \describe{ 14 | \item{tibble}{\code{\link[tibble]{as_tibble}}} 15 | }} 16 | 17 | -------------------------------------------------------------------------------- /man/relocate-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-verbs.R 3 | \name{relocate-phyloseq} 4 | \alias{relocate-phyloseq} 5 | \alias{relocate_tax_table} 6 | \alias{relocate_tax_table,taxonomyTable-method} 7 | \alias{relocate_tax_table,phyloseq-method} 8 | \alias{relocate_sample_data} 9 | \alias{relocate_sample_data,sample_data-method} 10 | \alias{relocate_sample_data,phyloseq-method} 11 | \title{Change column order in the taxonomy table or sample data} 12 | \usage{ 13 | relocate_tax_table(x, ...) 14 | 15 | \S4method{relocate_tax_table}{taxonomyTable}(x, ...) 16 | 17 | \S4method{relocate_tax_table}{phyloseq}(x, ...) 18 | 19 | relocate_sample_data(x, ...) 20 | 21 | \S4method{relocate_sample_data}{sample_data}(x, ...) 22 | 23 | \S4method{relocate_sample_data}{phyloseq}(x, ...) 24 | } 25 | \arguments{ 26 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 27 | 28 | \item{...}{Expressions and arguments passed to \code{dplyr::relocate()}} 29 | } 30 | \description{ 31 | These functions are wrappers around \code{dplyr::relocate()} that provide 32 | convenient ways to modify \code{tax_table(x)} and \code{sample_data(x)}. 33 | } 34 | \details{ 35 | The special column names '.otu' and '.sample' should not be used; see 36 | \code{mutate-phyloseq} for the ability to change taxa and sample names using 37 | these names. 38 | } 39 | \examples{ 40 | data(GlobalPatterns) 41 | 42 | GlobalPatterns \%>\% sample_variables 43 | ps <- GlobalPatterns \%>\% 44 | relocate_sample_data(SampleType, .after = X.SampleID) 45 | ps \%>\% sample_variables 46 | } 47 | -------------------------------------------------------------------------------- /man/rename-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-verbs.R 3 | \name{rename-phyloseq} 4 | \alias{rename-phyloseq} 5 | \alias{rename_tax_table} 6 | \alias{rename_tax_table,taxonomyTable-method} 7 | \alias{rename_tax_table,phyloseq-method} 8 | \alias{rename_with_tax_table} 9 | \alias{rename_with_tax_table,taxonomyTable-method} 10 | \alias{rename_with_tax_table,phyloseq-method} 11 | \alias{rename_sample_data} 12 | \alias{rename_sample_data,sample_data-method} 13 | \alias{rename_sample_data,phyloseq-method} 14 | \alias{rename_with_sample_data} 15 | \alias{rename_with_sample_data,sample_data-method} 16 | \alias{rename_with_sample_data,phyloseq-method} 17 | \title{Rename columns in the taxonomy table or sample data} 18 | \usage{ 19 | rename_tax_table(x, ...) 20 | 21 | \S4method{rename_tax_table}{taxonomyTable}(x, ...) 22 | 23 | \S4method{rename_tax_table}{phyloseq}(x, ...) 24 | 25 | rename_with_tax_table(x, ...) 26 | 27 | \S4method{rename_with_tax_table}{taxonomyTable}(x, ...) 28 | 29 | \S4method{rename_with_tax_table}{phyloseq}(x, ...) 30 | 31 | rename_sample_data(x, ...) 32 | 33 | \S4method{rename_sample_data}{sample_data}(x, ...) 34 | 35 | \S4method{rename_sample_data}{phyloseq}(x, ...) 36 | 37 | rename_with_sample_data(x, ...) 38 | 39 | \S4method{rename_with_sample_data}{sample_data}(x, ...) 40 | 41 | \S4method{rename_with_sample_data}{phyloseq}(x, ...) 42 | } 43 | \arguments{ 44 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 45 | 46 | \item{...}{Renaming expressions passed to \code{dplyr::rename()} or arguments 47 | passed to \code{dplyr::rename_with()}} 48 | } 49 | \description{ 50 | \code{rename_tax_table()} and \code{rename_with_tax_table()} provide the functionality 51 | of \code{dplyr::rename()} and \code{dplyr::rename_with()} to phyloseq taxonomy tables; 52 | \code{rename_sample_data()} and \code{rename_with_sample_data()} provide this 53 | functionality to phyloseq sample data. 54 | } 55 | \examples{ 56 | data(GlobalPatterns) 57 | 58 | GlobalPatterns \%>\% rank_names 59 | 60 | ps1 <- GlobalPatterns \%>\% 61 | rename_tax_table(Domain = Kingdom) \%>\% 62 | rename_with_tax_table(stringr::str_to_lower) 63 | ps1 \%>\% rank_names 64 | 65 | GlobalPatterns \%>\% sample_variables 66 | ps2 <- GlobalPatterns \%>\% 67 | rename_with_sample_data(janitor::make_clean_names) \%>\% 68 | rename_sample_data(sample_id = x_sample_id) 69 | ps2 \%>\% sample_variables 70 | } 71 | -------------------------------------------------------------------------------- /man/sample_data_stable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_samples.R 3 | \name{sample_data_stable} 4 | \alias{sample_data_stable} 5 | \title{Create sample data without adjusting row/sample names} 6 | \usage{ 7 | sample_data_stable(object) 8 | } 9 | \arguments{ 10 | \item{object}{A "data.frame"-class object} 11 | } 12 | \description{ 13 | \code{phyloseq::sample_data()} will change the sample names from the row names if 14 | they are \code{as.character(1:nrow(object))}. This function instead keeps the 15 | names as is. 16 | } 17 | \examples{ 18 | x <- data.frame(var1 = letters[1:3], var2 = 7:9) 19 | rownames(x) 20 | sample_data(x) 21 | speedyseq:::sample_data_stable(x) 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /man/select-phyloseq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dplyr-verbs.R 3 | \name{select-phyloseq} 4 | \alias{select-phyloseq} 5 | \alias{select_tax_table} 6 | \alias{select_tax_table,taxonomyTable-method} 7 | \alias{select_tax_table,phyloseq-method} 8 | \alias{select_sample_data} 9 | \alias{select_sample_data,sample_data-method} 10 | \alias{select_sample_data,phyloseq-method} 11 | \title{Subset columns in the taxonomy table or sample data using their names and types} 12 | \usage{ 13 | select_tax_table(x, ...) 14 | 15 | \S4method{select_tax_table}{taxonomyTable}(x, ...) 16 | 17 | \S4method{select_tax_table}{phyloseq}(x, ...) 18 | 19 | select_sample_data(x, ...) 20 | 21 | \S4method{select_sample_data}{sample_data}(x, ...) 22 | 23 | \S4method{select_sample_data}{phyloseq}(x, ...) 24 | } 25 | \arguments{ 26 | \item{x}{A \code{phyloseq}, \code{taxonomyTable}, or \code{sample_data} object} 27 | 28 | \item{...}{Expressions passed to \code{dplyr::select()}} 29 | } 30 | \description{ 31 | These functions are wrappers around \code{dplyr::select()} that provide 32 | convenient ways to modify \code{tax_table(x)} and \code{sample_data(x)}. 33 | See \code{dplyr::select()} for supported syntax and helpers. 34 | } 35 | \details{ 36 | The special column names '.otu' and '.sample' should not be used; see 37 | \code{mutate-phyloseq} for the ability to change taxa and sample names using 38 | these names. 39 | } 40 | \examples{ 41 | data(GlobalPatterns) 42 | 43 | GlobalPatterns \%>\% rank_names 44 | GlobalPatterns \%>\% sample_variables 45 | ps <- GlobalPatterns \%>\% 46 | select_tax_table(Phylum, Genus:Species) \%>\% 47 | select_sample_data(!dplyr::contains("Barcode")) 48 | ps \%>\% rank_names 49 | ps \%>\% sample_variables 50 | } 51 | -------------------------------------------------------------------------------- /man/select_taxa-methods.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{select_taxa} 4 | \alias{select_taxa} 5 | \alias{select_taxa,sample_data,character-method} 6 | \alias{select_taxa,otu_table,character-method} 7 | \alias{select_taxa,taxonomyTable,character-method} 8 | \alias{select_taxa,XStringSet,character-method} 9 | \alias{select_taxa,phylo,character-method} 10 | \alias{select_taxa,phyloseq,character-method} 11 | \title{Select a subset of taxa in a specified order where possible} 12 | \usage{ 13 | select_taxa(x, taxa, reorder = TRUE) 14 | 15 | \S4method{select_taxa}{sample_data,character}(x, taxa) 16 | 17 | \S4method{select_taxa}{otu_table,character}(x, taxa, reorder = TRUE) 18 | 19 | \S4method{select_taxa}{taxonomyTable,character}(x, taxa, reorder = TRUE) 20 | 21 | \S4method{select_taxa}{XStringSet,character}(x, taxa, reorder = TRUE) 22 | 23 | \S4method{select_taxa}{phylo,character}(x, taxa) 24 | 25 | \S4method{select_taxa}{phyloseq,character}(x, taxa, reorder = TRUE) 26 | } 27 | \arguments{ 28 | \item{x}{A phyloseq object or phyloseq component object} 29 | 30 | \item{taxa}{Character vector of taxa to select, in requested order} 31 | 32 | \item{reorder}{Logical specifying whether to use the order in \code{taxa} (TRUE) 33 | or keep the order in \code{taxa_names(x)} (FALSE)} 34 | } 35 | \description{ 36 | Select (a subset of) taxa; if \code{x} allows taxa to be reordered, then taxa are 37 | given in the specified order. 38 | } 39 | \details{ 40 | This is a simple selector function that is like \code{prune_taxa(taxa, x)} when 41 | \code{taxa} is a character vector but always gives the taxa in the order \code{taxa} 42 | if possible (that is, except for phy_tree's and phyloseq objects that 43 | contain phy_tree's). 44 | } 45 | \keyword{internal} 46 | -------------------------------------------------------------------------------- /man/show-methods.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/printing.R 3 | \name{show,phyloseq-method} 4 | \alias{show,phyloseq-method} 5 | \alias{show,taxonomyTable-method} 6 | \alias{show,sample_data-method} 7 | \alias{show,otu_table-method} 8 | \title{Methods for \code{show()} for phyloseq objects.} 9 | \usage{ 10 | \S4method{show}{phyloseq}(object) 11 | 12 | \S4method{show}{taxonomyTable}(object) 13 | 14 | \S4method{show}{sample_data}(object) 15 | 16 | \S4method{show}{otu_table}(object) 17 | } 18 | \arguments{ 19 | \item{object}{Any R object} 20 | } 21 | \description{ 22 | See \code{\link[methods]{show}}. Speedyseq provides \code{show()} methods that 23 | overwrite phyloseq's methods for the classes defined in phyloseq. 24 | } 25 | \examples{ 26 | data(GlobalPatterns) 27 | show(GlobalPatterns) 28 | GlobalPatterns 29 | } 30 | \seealso{ 31 | \code{\link[methods]{show}} 32 | } 33 | -------------------------------------------------------------------------------- /man/tax_glom.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/agglomeration.R 3 | \name{tax_glom} 4 | \alias{tax_glom} 5 | \title{Agglomerate taxa using taxonomy.} 6 | \usage{ 7 | tax_glom( 8 | physeq, 9 | taxrank = rank_names(physeq)[1], 10 | NArm = TRUE, 11 | bad_empty = c(NA, "", " ", "\\t"), 12 | reorder = FALSE 13 | ) 14 | } 15 | \arguments{ 16 | \item{physeq}{(Required). \code{\link[=phyloseq-class]{phyloseq-class()}} or \code{\link[=tax_table]{tax_table()}}.} 17 | 18 | \item{taxrank}{A character string specifying the taxonomic level that you 19 | want to agglomerate over. Should be among the results of 20 | \code{rank_names(physeq)}. The default value is \code{rank_names(physeq)[1]}, which 21 | may agglomerate too broadly for a given experiment. You are strongly 22 | encouraged to try different values for this argument.} 23 | 24 | \item{NArm}{(Optional). Logical, length equal to one. Default is \code{TRUE}. 25 | CAUTION. The decision to prune (or not) taxa for which you lack categorical 26 | data could have a large effect on downstream analysis. You may want to 27 | re-compute your analysis under both conditions, or at least think carefully 28 | about what the effect might be and the reasons explaining the absence of 29 | information for certain taxa. In the case of taxonomy, it is often a result 30 | of imprecision in taxonomic designation based on short phylogenetic 31 | sequences and a patchy system of nomenclature. If this seems to be an issue 32 | for your analysis, think about also trying the nomenclature-agnostic 33 | \code{\link[=tip_glom]{tip_glom()}} method if you have a phylogenetic tree available.} 34 | 35 | \item{bad_empty}{(Optional). Character vector. Default: \code{c(NA, "", " ", "\\t")}. Defines the bad/empty values that should be ignored and/or 36 | considered unknown. They will be removed from the internal agglomeration 37 | vector derived from the argument to \code{tax}, and therefore agglomeration will 38 | not combine taxa according to the presence of these values in \code{tax}. 39 | Furthermore, the corresponding taxa can be optionally pruned from the output 40 | if \code{NArm} is set to \code{TRUE}.} 41 | 42 | \item{reorder}{Logical specifying whether to reorder the taxa by taxonomy 43 | strings or keep initial order. Ignored if \code{physeq} has a phylogenetic tree.} 44 | } 45 | \value{ 46 | A taxonomically-agglomerated, optionally-pruned, object with class 47 | matching the class of \code{physeq}. 48 | } 49 | \description{ 50 | This method merges species that have the same taxonomy at a certain 51 | taxonomic rank. Its approach is analogous to \code{\link[=tip_glom]{tip_glom()}}, but 52 | uses categorical data instead of a tree. In principal, other categorical 53 | data known for all taxa could also be used in place of taxonomy, but for the 54 | moment, this must be stored in the \code{taxonomyTable} of the data. Also, 55 | columns/ranks to the right of the rank chosen to use for agglomeration will 56 | be replaced with \code{NA}, because they should be meaningless following 57 | agglomeration. 58 | } 59 | \details{ 60 | This is the speedyseq reimplementation of \code{phyloseq::tax_glom()}. It should 61 | produce results that are identical to phyloseq up to taxon order. 62 | 63 | If \code{x} is a phyloseq object with a phylogenetic tree, then the new taxa will 64 | be ordered as they are in the tree. Otherwise, the taxa order can be 65 | controlled by the \code{reorder} argument, which behaves like the \code{reorder} 66 | argument in \code{\link[base:rowsum]{base::rowsum()}}. \code{reorder = FALSE} will keep taxa in 67 | the original order determined by when the member of each group first appears 68 | in \code{taxa_names(x)}; \code{reorder = TRUE} will order new taxa alphabetically 69 | according to taxonomy (string of concatenated rank values). 70 | 71 | Acknowledgements: Documentation and general strategy derived from 72 | \code{phyloseq::tax_glom()}. 73 | } 74 | \examples{ 75 | data(GlobalPatterns) 76 | # print the available taxonomic ranks 77 | colnames(tax_table(GlobalPatterns)) 78 | # agglomerate at the Family taxonomic rank 79 | (x1 <- tax_glom(GlobalPatterns, taxrank="Family")) 80 | # How many taxa before/after agglomeration? 81 | ntaxa(GlobalPatterns); ntaxa(x1) 82 | } 83 | \seealso{ 84 | \code{\link[phyloseq:tax_glom]{phyloseq::tax_glom()}} 85 | 86 | \code{\link[=tip_glom]{tip_glom()}} 87 | 88 | \code{\link[=prune_taxa]{prune_taxa()}} 89 | 90 | \code{\link[=merge_taxa_vec]{merge_taxa_vec()}} 91 | } 92 | -------------------------------------------------------------------------------- /man/tibble-constructors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/phyloseq-constructors.R 3 | \name{tibble-constructors} 4 | \alias{tibble-constructors} 5 | \alias{otu_table,tbl_df-method} 6 | \alias{sample_data,tbl_df-method} 7 | \alias{tax_table,tbl_df-method} 8 | \title{Construct phyloseq objects from tibbles} 9 | \usage{ 10 | \S4method{otu_table}{tbl_df}(object, taxa_are_rows) 11 | 12 | \S4method{sample_data}{tbl_df}(object) 13 | 14 | \S4method{tax_table}{tbl_df}(object) 15 | } 16 | \arguments{ 17 | \item{object}{A tibble whose first column contains the sample or taxa ids} 18 | 19 | \item{taxa_are_rows}{Logical; \code{TRUE} if rows correspond to taxa and \code{FALSE} 20 | if rows correspond to samples} 21 | } 22 | \description{ 23 | These methods extend phyloseq's constructor functions to construct phyloseq 24 | components from tibbles (objects with class "tbl_df"). 25 | } 26 | \details{ 27 | Since tibbles cannot have row names, the sample or taxon identifiers must be 28 | contained in a regular column. Speedyseq currently always uses the first 29 | column for the identifiers that would normally be taken from the row names 30 | by phyloseq's built-in constructors. Thus the first column is assumed to 31 | contain the sample names for \code{sample_data()} and the OTU/taxa names for 32 | \code{tax_table()}; for \code{otu_table()}, the first column is assumed to contain the 33 | sample names if \code{taxa_are_rows = TRUE} and the taxa names if \code{taxa_are_rows = FALSE}, with the other identifier being taken from the remaining column 34 | names. 35 | } 36 | \examples{ 37 | \dontrun{ 38 | # Read a .csv file with readr, which creates an object of class `tbl_df` 39 | tbl <- readr::read_csv("path/to/otu_table.csv") 40 | # Inspect and check if taxa are rows and that the first column contains the 41 | # sample names or the taxa/OTU names 42 | head(tbl) 43 | # Create a phyloseq `otu_table` object 44 | otu <- otu_table(tbl, taxa_are_rows = FALSE) 45 | 46 | # Read a .csv file with readr, which creates an object of class `tbl_df` 47 | tbl <- readr::read_csv("path/to/sample_data.csv") 48 | # Inspect and check that the first column contains the sample names 49 | head(tbl) 50 | # Create a phyloseq `sample_data` object 51 | sam <- sample_data(tbl) 52 | } 53 | } 54 | \seealso{ 55 | \code{\link[tibble:tbl_df-class]{tibble::tbl_df}} 56 | \code{\link[phyloseq:otu_table-methods]{phyloseq::otu_table()}} 57 | \code{\link[phyloseq:sample_data-methods]{phyloseq::sample_data()}} 58 | \code{\link[phyloseq:tax_table-methods]{phyloseq::tax_table()}} 59 | } 60 | -------------------------------------------------------------------------------- /man/tibble_print.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/printing.R 3 | \name{tibble_print} 4 | \alias{tibble_print} 5 | \title{Print a 2-d data.frame or matrix like a tibble} 6 | \usage{ 7 | tibble_print( 8 | x, 9 | n = NULL, 10 | width = NULL, 11 | n_extra = NULL, 12 | types = TRUE, 13 | rows = "rows", 14 | cols = "variables" 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{A data frame or matrix} 19 | 20 | \item{n}{Number of rows to print} 21 | 22 | \item{width}{Display width} 23 | 24 | \item{n_extra}{Number of extra columns after width to summarize after main 25 | display} 26 | 27 | \item{types}{Whether to print the second row with the variable types} 28 | 29 | \item{rows}{What rows are called in the end summary} 30 | 31 | \item{cols}{What columns are called in the end summary} 32 | } 33 | \description{ 34 | Print a 2-d data.frame or matrix like a tibble 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /man/tip_glom.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/agglomeration.R 3 | \name{tip_glom} 4 | \alias{tip_glom} 5 | \title{Agglomerate taxa using phylogeny-derived distances.} 6 | \usage{ 7 | tip_glom(physeq, h = 0.2, hcfun = cluster::agnes, tax_adjust = 1L, ...) 8 | } 9 | \arguments{ 10 | \item{physeq}{(Required). A \code{\link[=phyloseq-class]{phyloseq-class()}}, containing a phylogenetic 11 | tree. Alternatively, a phylogenetic tree \code{\link[ape:read.tree]{ape::phylo()}} will also work.} 12 | 13 | \item{h}{(Optional). Numeric scalar of the height where the tree should be 14 | cut. This refers to the tree resulting from hierarchical clustering of the 15 | distance matrix, not the original phylogenetic tree. Default value is \code{0.2}.} 16 | 17 | \item{hcfun}{(Optional). A function. The (agglomerative, hierarchical) 18 | clustering function to use. The default is \code{\link[cluster:agnes]{cluster::agnes()}} for phyloseq 19 | compatiblity.} 20 | 21 | \item{tax_adjust}{0: no adjustment; 1: phyloseq-compatible adjustment; 2: 22 | conservative adjustment (see \code{\link[=merge_taxa_vec]{merge_taxa_vec()}} for details)} 23 | 24 | \item{...}{(Optional). Additional named arguments to pass to \code{hcfun}.} 25 | } 26 | \value{ 27 | An instance of the \code{\link[=phyloseq-class]{phyloseq-class()}}. Or alternatively, a 28 | \code{\link[=phylo]{phylo()}} object if the \code{physeq} argument was just a tree. In the 29 | expected-use case, the number of OTUs will be fewer (see \code{\link[=ntaxa]{ntaxa()}}), after 30 | merging OTUs that are related enough to be called the same OTU. 31 | } 32 | \description{ 33 | All tips of the tree separated by a phylogenetic cophenetic distance smaller 34 | than \code{h} will be agglomerated into one taxon. 35 | } 36 | \details{ 37 | Can be used to create a non-trivial OTU Table, if a phylogenetic tree is 38 | available. 39 | 40 | By default, simple "greedy" single-linkage clustering is used. It is 41 | possible to specify different clustering approaches by setting \code{hcfun} and 42 | its parameters in \code{...}. In particular, complete-linkage clustering appears 43 | to be used more commonly for OTU clustering applications. 44 | 45 | The merged taxon is named according to the "archetype" defined as the the 46 | most abundant taxon (having the largest value of \code{taxa_sums(physeq)}. The 47 | tree and refseq objects are pruned to the archetype taxa. 48 | 49 | Speedyseq note: \code{\link[stats:hclust]{stats::hclust()}} is faster than the default \code{hcfun}; set 50 | \code{method = "average"} to get equivalent clustering. 51 | 52 | Acknowledgements: Documentation and general strategy derived from 53 | \code{phyloseq::tip_glom()}. 54 | } 55 | \examples{ 56 | data("esophagus") 57 | esophagus <- prune_taxa(taxa_names(esophagus)[1:25], esophagus) 58 | plot_tree(esophagus, label.tips="taxa_names", size="abundance", 59 | title="Before tip_glom()") 60 | plot_tree(tip_glom(esophagus, h=0.2), label.tips="taxa_names", 61 | size="abundance", title="After tip_glom()") 62 | 63 | # *speedyseq only:* Demonstration of different `tax_adjust` behaviors 64 | data(GlobalPatterns) 65 | 66 | set.seed(20190421) 67 | ps <- prune_taxa(sample(taxa_names(GlobalPatterns), 2e2), GlobalPatterns) 68 | 69 | ps1 <- tip_glom(ps, 0.1, tax_adjust = 1) 70 | ps2 <- tip_glom(ps, 0.1, tax_adjust = 2) 71 | tax_table(ps1)[c(108, 136, 45),] 72 | tax_table(ps2)[c(108, 136, 45),] 73 | } 74 | \seealso{ 75 | \code{\link[phyloseq:tip_glom]{phyloseq::tip_glom()}} 76 | 77 | \code{\link[=tree_glom]{tree_glom()}} for direct phylogenetic merging 78 | 79 | \code{\link[=merge_taxa_vec]{merge_taxa_vec()}} 80 | 81 | \code{\link[cluster:agnes]{cluster::agnes()}} 82 | 83 | \code{\link[stats:hclust]{stats::hclust()}} 84 | 85 | \code{\link[castor:get_all_pairwise_distances]{castor::get_all_pairwise_distances()}} 86 | 87 | \code{\link[ape:read.tree]{ape::phylo()}} 88 | } 89 | -------------------------------------------------------------------------------- /man/transform_sample_counts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/transform-filter.R 3 | \name{transform_sample_counts} 4 | \alias{transform_sample_counts} 5 | \title{Transform abundance data in an \code{otu_table}, sample-by-sample} 6 | \usage{ 7 | transform_sample_counts(physeq, fun, ...) 8 | } 9 | \arguments{ 10 | \item{physeq}{\code{\link[=phyloseq-class]{phyloseq-class()}} or \code{\link[ape:read.tree]{ape::phylo()}}.} 11 | 12 | \item{fun}{A function or formula that can be converted to a function by 13 | \code{\link[purrr:as_mapper]{purrr::as_mapper()}}} 14 | 15 | \item{...}{Additional arguments passed on to \code{fun}} 16 | } 17 | \description{ 18 | Version of \code{\link[phyloseq:transformcounts]{phyloseq::transform_sample_counts()}} that allows a 19 | purrr-style anonymous function. 20 | } 21 | \details{ 22 | This function simply calls \code{\link[purrr:as_mapper]{purrr::as_mapper()}} on \code{fun} and passes the 23 | resulting function on to \code{\link[phyloseq:transformcounts]{phyloseq::transform_sample_counts()}}. 24 | } 25 | \examples{ 26 | data(GlobalPatterns) 27 | # Filter low prevalence taxa, then convert to proportions 28 | gp.prop <- GlobalPatterns \%>\% 29 | filter_taxa2(~ sum(. > 0) > 5) \%>\% 30 | transform_sample_counts(~ . / sum(.)) 31 | } 32 | \seealso{ 33 | \code{\link[phyloseq:transformcounts]{phyloseq::transform_sample_counts()}} 34 | \code{\link[purrr:as_mapper]{purrr::as_mapper()}} 35 | } 36 | -------------------------------------------------------------------------------- /man/tree_glom.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/agglomeration.R 3 | \name{tree_glom} 4 | \alias{tree_glom} 5 | \title{Agglomerate taxa at a given phylogenetic resolution.} 6 | \usage{ 7 | tree_glom(physeq, resolution, criterion = "max_tip_depth", tax_adjust = 1L) 8 | } 9 | \arguments{ 10 | \item{physeq}{\code{\link[=phyloseq-class]{phyloseq-class()}} or \code{\link[ape:read.tree]{ape::phylo()}}.} 11 | 12 | \item{resolution}{Phylogenetic resolution at which to merge taxa.} 13 | 14 | \item{criterion}{Criterion for determining whether to collapse taxa. See 15 | \code{\link[castor:collapse_tree_at_resolution]{castor::collapse_tree_at_resolution()}} for details.} 16 | 17 | \item{tax_adjust}{0: no adjustment; 1: phyloseq-compatible adjustment; 2: 18 | conservative adjustment (see \code{\link[=merge_taxa_vec]{merge_taxa_vec()}} for details)} 19 | } 20 | \value{ 21 | A \code{physeq} object with new taxa reflecting the phylogenetically 22 | merged groups. 23 | } 24 | \description{ 25 | This function merges taxa that are sufficiently closely related in the tree 26 | in \code{phy_tree(physeq)}. It is similar to \code{tip_glom()}, except that it uses 27 | the tree directly, rather than as the basis for hierarchical clustering. 28 | } 29 | \details{ 30 | This function uses \code{\link[castor:collapse_tree_at_resolution]{castor::collapse_tree_at_resolution()}} from 31 | the castor package to determine the groups of taxa to be collapsed; see this 32 | function for details about the \code{resolution} and \code{criterion} parameters. 33 | 34 | New taxa are named according to the most abundant taxon of each group. The 35 | tree, reference sequences, and (by default) the taxonomy table reflect these 36 | "archetype" taxa. 37 | } 38 | \examples{ 39 | data(GlobalPatterns) 40 | ps1 <- subset_taxa(GlobalPatterns, Phylum == "Chlamydiae") 41 | ntaxa(ps1) 42 | ps2 <- tree_glom(ps1, 0.05) 43 | ntaxa(ps2) 44 | 45 | suppressPackageStartupMessages(library(dplyr)) 46 | suppressPackageStartupMessages(library(ggtree)) 47 | suppressPackageStartupMessages(library(cowplot)) 48 | 49 | plot1 <- phy_tree(ps1) \%>\% 50 | ggtree + 51 | geom_tiplab() + 52 | geom_label(aes(x = branch, label = round(branch.length, 4))) 53 | plot2 <- phy_tree(ps2) \%>\% 54 | ggtree + 55 | geom_tiplab() + 56 | geom_label(aes(x = branch, label = round(branch.length, 4))) 57 | plot_grid(plot1, plot2) 58 | } 59 | \seealso{ 60 | \code{\link[castor:collapse_tree_at_resolution]{castor::collapse_tree_at_resolution()}} for more information about the 61 | \code{resolution} and \code{criterion} parameters. 62 | 63 | \code{\link[=merge_taxa_vec]{merge_taxa_vec()}} for more about \code{tax_adjust} and general merging behavior 64 | 65 | \code{\link[=tip_glom]{tip_glom()}} for indirect phylogenetic merging 66 | 67 | \code{\link[=tax_glom]{tax_glom()}} for merging using taxonomy 68 | } 69 | -------------------------------------------------------------------------------- /man/unique_or_na.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_samples.R 3 | \name{unique_or_na} 4 | \alias{unique_or_na} 5 | \title{Get the unique value in x or NA if none} 6 | \usage{ 7 | unique_or_na(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector} 11 | } 12 | \description{ 13 | If \code{unique(x)} is a single value, return it; otherwise, return an NA of the 14 | same type as \code{x}. If \code{x} is a factor, then the levels and ordered status 15 | will be kept in either case. If \code{x} is a non-atomic vector (i.e. a list), 16 | then the logical \code{NA} will be used. 17 | } 18 | \examples{ 19 | f <- factor(c("a", "a", "b", "c"), ordered = TRUE) 20 | unique_or_na(f) 21 | unique_or_na(f[1:2]) 22 | 23 | x <- c("a", "b", "a") 24 | unique_or_na(x[c(1, 3)]) 25 | unique_or_na(x) 26 | unique_or_na(x) \%>\% typeof 27 | } 28 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(speedyseq) 3 | 4 | test_check("speedyseq") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-as_tibble.R: -------------------------------------------------------------------------------- 1 | # devtools::test_active_file(here::here("tests", "testthat", "test-as_tibble.R")) 2 | 3 | data(GlobalPatterns) 4 | ps <- prune_taxa( 5 | ape::extract.clade(phy_tree(GlobalPatterns), "0.589.38") %>% .$tip.label, 6 | GlobalPatterns 7 | ) 8 | # add reference sequences 9 | rs <- split( 10 | sample(c("A", "C", "G", "T"), 2 * ntaxa(ps), replace = TRUE), 11 | rep(seq(ntaxa(ps)), each = 2) 12 | ) %>% 13 | purrr::map_chr(paste, collapse = "") %>% 14 | rlang::set_names(taxa_names(ps)) %>% 15 | Biostrings::DNAStringSet() 16 | ps <- merge_phyloseq(ps, rs) 17 | rm(rs) 18 | 19 | test_that("as_tibble and psmelt agree up to row order", { 20 | x <- ps %>% as_tibble %>% 21 | dplyr::rename(OTU = .otu, Sample = .sample, Abundance = .abundance) 22 | y <- ps %>% psmelt 23 | expect_true(dplyr::all_equal(x, y, ignore_row_order = TRUE)) 24 | }) 25 | 26 | test_that("as_tibble returns expected columns", { 27 | x <- ps %>% sample_data %>% as_tibble 28 | expect_identical(names(x), c(".sample", sample_variables(ps))) 29 | x <- ps %>% otu_table %>% as_tibble 30 | expect_identical(names(x), c(".otu", ".sample", ".abundance")) 31 | x <- ps %>% otu_table %>% as_tibble(pivot = FALSE) 32 | expect_identical(names(x), c(".otu", sample_names(ps))) 33 | x <- ps %>% as_tibble(ref = TRUE) 34 | expect_identical(names(x), 35 | c(".otu", ".sample", ".abundance", sample_variables(ps), rank_names(ps), 36 | ".sequence") 37 | ) 38 | }) 39 | 40 | test_that("as_tibble works after tibble is loaded", { 41 | library(tibble) 42 | x <- ps %>% sample_data %>% as_tibble 43 | expect_identical(names(x), c(".sample", sample_variables(ps))) 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test-constructors.R: -------------------------------------------------------------------------------- 1 | # run just this file: 2 | # devtools::test_file(here::here("tests", "testthat", "test-constructors.R")) 3 | 4 | data(GlobalPatterns) 5 | 6 | test_that("results from tibble constructors match starting objects", { 7 | tax <- tax_table(GlobalPatterns) %>% 8 | as("matrix") %>% 9 | tibble::as_tibble(rownames = "taxon") %>% 10 | tax_table 11 | expect_identical(tax, tax_table(GlobalPatterns)) 12 | 13 | sam <- sample_data(GlobalPatterns) %>% 14 | as("data.frame") %>% 15 | tibble::as_tibble(rownames = "sample") %>% 16 | sample_data 17 | expect_identical(sam, sample_data(GlobalPatterns)) 18 | 19 | otu1 <- otu_table(GlobalPatterns) %>% 20 | as("matrix") %>% 21 | tibble::as_tibble(rownames = "taxon") %>% 22 | otu_table(taxa_are_rows = TRUE) 23 | expect_identical(otu1, otu_table(GlobalPatterns)) 24 | 25 | otu2 <- otu_table(GlobalPatterns) %>% 26 | t %>% 27 | as("matrix") %>% 28 | tibble::as_tibble(rownames = "taxon") %>% 29 | otu_table(taxa_are_rows = FALSE) 30 | expect_identical(otu2, otu_table(GlobalPatterns) %>% t) 31 | }) 32 | -------------------------------------------------------------------------------- /tests/testthat/test-dplyr-verbs.R: -------------------------------------------------------------------------------- 1 | # run just this file: 2 | # devtools::test_active_file(here::here("tests", "testthat", "test-dplyr-verbs.R")) 3 | 4 | data(GlobalPatterns) 5 | ps <- GlobalPatterns %>% prune_taxa(head(taxa_names(.), 10), .) 6 | 7 | test_that("mutate and filter tax table", { 8 | ps1 <- ps %>% 9 | mutate_tax_table( 10 | .otu = stringr::str_c(Kingdom, .otu), 11 | across(Class, ~stringr::str_c("c__", .)) 12 | ) %>% 13 | filter_tax_table(stringr::str_detect(Class, "^c__Th")) 14 | tax1 <- ps %>% 15 | tax_table %>% 16 | mutate_tax_table( 17 | .otu = stringr::str_c(Kingdom, .otu), 18 | across(Class, ~stringr::str_c("c__", .)) 19 | ) %>% 20 | filter_tax_table(stringr::str_detect(Class, "^c__Th")) 21 | expect_identical(ntaxa(ps1), 3L) 22 | expect_identical(tax_table(ps1), tax1) 23 | }) 24 | 25 | test_that("mutate and filter sample data", { 26 | ps1 <- ps %>% 27 | mutate_sample_data( 28 | .sample = stringr::str_c(SampleType, .sample), 29 | new_var = dplyr::row_number() 30 | ) %>% 31 | filter_sample_data(SampleType %in% c("Feces", "Soil")) 32 | sam1 <- ps %>% 33 | sample_data %>% 34 | mutate_sample_data( 35 | .sample = stringr::str_c(SampleType, .sample), 36 | new_var = dplyr::row_number() 37 | ) %>% 38 | filter_sample_data(SampleType %in% c("Feces", "Soil")) 39 | expect_identical(nsamples(ps1), 7L) 40 | expect_identical(sample_data(ps1), sam1) 41 | }) 42 | 43 | test_that("can rename columns in taxonomy table and sample data", { 44 | ps1 <- GlobalPatterns %>% 45 | rename_tax_table(Domain = Kingdom) %>% 46 | rename_with_tax_table(stringr::str_to_lower) %>% 47 | rename_with_sample_data(janitor::make_clean_names) %>% 48 | rename_sample_data(sample_id = x_sample_id) 49 | 50 | nms <- rank_names(GlobalPatterns) %>% stringr::str_to_lower() 51 | nms[1] <- "domain" 52 | expect_identical(ps1 %>% rank_names, nms) 53 | 54 | nms <- sample_variables(GlobalPatterns) %>% janitor::make_clean_names() 55 | nms[1] <- "sample_id" 56 | expect_identical(ps1 %>% sample_variables, nms) 57 | }) 58 | 59 | test_that("can select and relocate columns in taxonomy table and sample data", { 60 | ps1 <- GlobalPatterns %>% 61 | select_tax_table(Phylum, Genus:Species) %>% 62 | select_sample_data(-dplyr::contains("Barcode")) 63 | expect_identical(c("Phylum", "Genus", "Species"), rank_names(ps1)) 64 | nms <- GlobalPatterns %>% sample_variables %>% 65 | stringr::str_subset("Barcode", negate = TRUE) 66 | expect_identical(nms, sample_variables(ps1)) 67 | ps2 <- ps1 %>% 68 | relocate_sample_data(SampleType) %>% 69 | relocate_tax_table(Phylum, .after = dplyr::last_col()) 70 | expect_identical(sample_variables(ps2), 71 | c("SampleType", setdiff(sample_variables(ps1), "SampleType")) 72 | ) 73 | expect_identical(rank_names(ps2), 74 | c(setdiff(rank_names(ps1), "Phylum"), "Phylum") 75 | ) 76 | }) 77 | 78 | test_that("can join on sample data", { 79 | data(GlobalPatterns) 80 | 81 | ps1 <- GlobalPatterns %>% 82 | select_sample_data(!contains("Barcode")) 83 | y <- GlobalPatterns %>% 84 | sample_data %>% 85 | select_sample_data(contains("Barcode")) %>% 86 | as_tibble 87 | ps2 <- ps1 %>% left_join_sample_data(y, by = ".sample") 88 | 89 | z <- GlobalPatterns %>% 90 | relocate_sample_data(contains("Barcode"), .after = dplyr::last_col()) %>% 91 | sample_data 92 | 93 | expect_identical(ps2 %>% sample_data, z) 94 | }) 95 | -------------------------------------------------------------------------------- /tests/testthat/test-merge_samples.R: -------------------------------------------------------------------------------- 1 | # run just this file: 2 | # devtools::test_active_file(here::here("tests", "testthat", "test-merge_samples.R")) 3 | 4 | # helpers --------------------------------------------------------------------- 5 | 6 | test_that("unique_or_na() returns expected results", { 7 | ## Atomic vectors 8 | # Characters 9 | expect_identical(unique_or_na(NA_character_), NA_character_) 10 | expect_identical(unique_or_na("a"), "a") 11 | expect_identical(unique_or_na(c("a", "b")), NA_character_) 12 | expect_identical(unique_or_na(c("a", NA_character_)), NA_character_) 13 | # Integers 14 | expect_identical(unique_or_na(NA_integer_), NA_integer_) 15 | expect_identical(unique_or_na(1L), 1L) 16 | expect_identical(unique_or_na(c(1L, 2L)), NA_integer_) 17 | expect_identical(unique_or_na(c(1L, NA_integer_)), NA_integer_) 18 | # Doubles 19 | expect_identical(unique_or_na(NA_real_), NA_real_) 20 | expect_identical(unique_or_na(1), 1) 21 | expect_identical(unique_or_na(c(1, 2)), NA_real_) 22 | expect_identical(unique_or_na(c(1, NA_real_)), NA_real_) 23 | # Booleans 24 | expect_identical(unique_or_na(NA), NA) 25 | expect_identical(unique_or_na(TRUE), TRUE) 26 | expect_identical(unique_or_na(c(TRUE, FALSE)), NA) 27 | expect_identical(unique_or_na(c(TRUE, NA)), NA) 28 | # Factors 29 | expect_identical( 30 | unique_or_na(factor(letters[1:4], levels = letters[4:1])), 31 | factor(NA, levels = letters[4:1]) 32 | ) 33 | expect_identical( 34 | unique_or_na(factor(c("a", "a"), levels = letters[4:1])), 35 | factor("a", levels = letters[4:1]) 36 | ) 37 | expect_identical( 38 | unique_or_na(factor(c("a", "a"), levels = letters[4:1], 39 | labels = paste("letter", letters[4:1]))), 40 | factor("a", levels = letters[4:1], labels = paste("letter", letters[4:1])) 41 | ) 42 | expect_identical( 43 | unique_or_na(factor(letters[1:4], levels = letters[4:1], ordered = TRUE)), 44 | factor(NA, levels = letters[4:1], ordered = TRUE) 45 | ) 46 | ## Lists 47 | expect_identical(unique_or_na(list(1,2)), NA) 48 | expect_identical(unique_or_na(list(1,1)), 1) 49 | }) 50 | 51 | test_that("`sample_data_stable()` maintains names", { 52 | x <- data.frame(var1 = letters[1:3], var2 = 7:9) 53 | expect_identical(sample_data_stable(x) %>% sample_names, as.character(1:3)) 54 | rownames(x) <- c("3", "two", "1") 55 | expect_identical(sample_data_stable(x) %>% sample_names, c("3", "two", "1")) 56 | }) 57 | 58 | # merge_samples2 -------------------------------------------------------------- 59 | 60 | test_that("Test `merge_samples2()` on the `enterotype` dataset", { 61 | data(enterotype) 62 | ps <- enterotype %>% prune_taxa(head(taxa_names(.), 10), .) 63 | sample_data(ps) <- sample_data(ps) %>% 64 | transform(Project.ClinicalStatus = Project:ClinicalStatus) 65 | # Will get a warning since `group` has NAs 66 | expect_warning( 67 | ps0 <- merge_samples2(ps, "Project.ClinicalStatus", 68 | funs = list(Age = mean)) 69 | ) 70 | # Types of the sample vars should be unchanged 71 | purrr::walk2(sample_data(ps), sample_data(ps0), 72 | ~expect_equal(typeof(.x), typeof(.y)) 73 | ) 74 | # Check OTU table, including that order is kept 75 | grp <- sample_data(ps)$Project.ClinicalStatus 76 | expect_warning( 77 | x <- rowsum(t(otu_table(ps)), grp, reorder = FALSE) %>% 78 | {.[!is.na(rownames(.)),]} %>% t 79 | ) 80 | expect_identical(otu_table(ps0) %>% as("matrix"), x) 81 | # Result should be identical if computed with taxa as cols 82 | expect_warning( 83 | ps1 <- merge_samples2(ps %>% t, "Project.ClinicalStatus", 84 | funs = list(Age = mean)) %>% t 85 | ) 86 | expect_identical(ps0, ps1) 87 | # Remaining components should be the same as original 88 | expect_identical(tax_table(ps0), tax_table(ps)) 89 | # Should also work on columns that are numbers, or factors whose levels are 90 | # numbers, even if the values are of the form 1:n. (Issue #52) 91 | expect_warning(ps2 <- merge_samples2(ps, "Enterotype")) 92 | sample_data(ps)$Enterotype <- sample_data(ps)$Enterotype %>% as.integer 93 | expect_warning(ps3 <- merge_samples2(ps, "Enterotype")) 94 | sample_data(ps3)$Enterotype <- sample_data(ps3)$Enterotype %>% as.factor 95 | expect_identical(ps2, ps3) 96 | # Test with alternate abundance-merging function 97 | expect_warning( 98 | ps0 <- merge_samples2(ps, "Project.ClinicalStatus", 99 | fun_otu = mean, 100 | funs = list(Age = mean) 101 | ) 102 | ) 103 | }) 104 | 105 | test_that("Test that group names are preserved", { 106 | # For Issue #52 107 | sam <- tibble::tibble(sample_id = letters[1:3], group_var = 1:3) %>% 108 | sample_data 109 | x <- merge_samples2(sam, "group_var") 110 | expect_identical(sample_names(x), as.character(sam$group_var)) 111 | }) 112 | -------------------------------------------------------------------------------- /tests/testthat/test-print.R: -------------------------------------------------------------------------------- 1 | data(GlobalPatterns) 2 | 3 | test_that("print(x) returns x without error", { 4 | # Note, ape's print.phylo method does not return anything 5 | slts <- setdiff(slotNames(GlobalPatterns), "phy_tree") 6 | for (s in slts) { 7 | x <- slot(GlobalPatterns, s) 8 | y <- slot(GlobalPatterns, s) %>% print 9 | expect_identical(x, y) 10 | } 11 | # Test when only 1 column to ensure no "drop" bugs 12 | x <- tibble::tibble(sample = letters[1:3], var = 1:3) %>% sample_data 13 | expect_identical(x, print(x)) 14 | }) 15 | -------------------------------------------------------------------------------- /tests/testthat/test-psmelt.R: -------------------------------------------------------------------------------- 1 | # devtools::test_file(here::here("tests", "testthat", "test-psmelt.R")) 2 | 3 | # Test on a subset of GlobalPatterns 4 | data(GlobalPatterns) 5 | set.seed(20190421) 6 | ps <- GlobalPatterns %>% 7 | {prune_taxa(sample(taxa_names(.), 40), .)} %>% 8 | tax_glom("Genus") 9 | 10 | test_that("psmelt() functionally matches phyloseq::psmelt()", { 11 | # In this example, phyloseq::psmelt() drops the "Species" column from the 12 | # tax_table (which is full of NAs). But speedyseq::psmelt() does not 13 | # discard columns even if they contain no non-missing data. Other 14 | # differences: phyloseq's output has rownames (which seem not meaningful); 15 | # speedyseq's output does not; both data frames are sorted by Abundance, 16 | # but the row order differs in cases where Abundance and OTU names differ. 17 | options(stringsAsFactors = FALSE) 18 | tb1 <- phyloseq::psmelt(ps) 19 | tb2 <- psmelt(ps) 20 | expect_is(tb2$Kingdom, "character") 21 | expect_true(dplyr::all_equal(tb1, dplyr::select(tb2, -Species), 22 | ignore_col_order = FALSE, ignore_row_order = TRUE)) 23 | expect_equal(tb1$Abundance, tb2$Abundance) 24 | expect_identical(tb1$OTU, tb2$OTU) 25 | }) 26 | 27 | test_that("psmelt() provides the requested class", { 28 | dt <- psmelt(ps, as = "data.table") 29 | df <- psmelt(ps, as = "data.frame") 30 | tb <- psmelt(ps, as = "tibble") 31 | expect_is(dt, "data.table") 32 | expect_is(df, "data.frame") 33 | expect_is(tb, "tbl_df") 34 | expect_identical(df, dt %>% as("data.frame")) 35 | expect_identical(tb, df %>% tibble::as_tibble()) 36 | # The dt -> tibble direct conversion has the ".internal.selfref" attribute 37 | expect_equivalent(tb, dt %>% tibble::as_tibble()) 38 | # By default, gets `as` from "speedyseq.psmelt_class" option 39 | dt <- withr::with_options( 40 | list(speedyseq.psmelt_class = "data.table"), 41 | psmelt(ps) 42 | ) 43 | expect_is(dt, "data.table") 44 | }) 45 | 46 | # Test code taken from phyloseq ----------------------------------------------- 47 | # https://github.com/joey711/phyloseq/blob/master/tests/testthat/test-plot.R 48 | 49 | test_that("psmelt properly protects against various name collisions", { 50 | data("GlobalPatterns") 51 | gp.ch = subset_taxa(GlobalPatterns, Phylum == "Chlamydiae") 52 | ps1 = NULL 53 | gp1 = gp.ch 54 | # type-1a conflict, Abundance 55 | sample_data(gp1)$Abundance <- paste0("Sa-", 1:nsamples(gp1)) 56 | expect_warning(ps1 <- psmelt(gp1)) 57 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 58 | expect_equal(dim(ps1), c(546L, 18L)) 59 | expect_true("sample_Abundance" %in% colnames(ps1)) 60 | # A different type-1a conflict, OTU 61 | ps1 = NULL 62 | gp1 = gp.ch 63 | sample_data(gp1)$OTU <- paste0("Sa-", 1:nsamples(gp1)) 64 | expect_warning(ps1 <- psmelt(gp1)) 65 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 66 | expect_equal(dim(ps1), c(546L, 18L)) 67 | expect_true("sample_OTU" %in% colnames(ps1)) 68 | # A different type-1a conflict, Sample 69 | ps1 = NULL 70 | gp1 = gp.ch 71 | sample_data(gp1)$Sample <- paste0("Sa-", 1:nsamples(gp1)) 72 | expect_warning(ps1 <- psmelt(gp1)) 73 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 74 | expect_equal(dim(ps1), c(546L, 18L)) 75 | expect_true("sample_Sample" %in% colnames(ps1)) 76 | # type-1b conflict. rank_names conflict with special variables 77 | ps1 = NULL 78 | gp1 = gp.ch 79 | tax_table(gp1) <- cbind(tax_table(gp1), Sample=paste0("ta", taxa_names(gp1))) 80 | expect_warning(ps1 <- psmelt(gp1)) 81 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 82 | expect_equal(dim(ps1), c(546L, 18L)) 83 | expect_true("taxa_Sample" %in% colnames(ps1)) 84 | # type-2 conflict. Variable collision between rank_names and sample_data 85 | ps1 = NULL 86 | gp1 = gp.ch 87 | tax_table(gp1) <- cbind(tax_table(gp1), Primer=paste0("ta", taxa_names(gp1))) 88 | expect_warning(ps1 <- psmelt(gp1)) 89 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 90 | expect_equal(dim(ps1), c(546L, 18L)) 91 | expect_true("sample_Primer" %in% colnames(ps1)) 92 | # All conflict types at once. 93 | ps1 = NULL 94 | gp1 = gp.ch 95 | sample_data(gp1)$Abundance <- paste0("Sa-", 1:nsamples(gp1)) 96 | sample_data(gp1)$OTU <- paste0("Sa-", 1:nsamples(gp1)) 97 | sample_data(gp1)$Sample <- paste0("Sa-", 1:nsamples(gp1)) 98 | tax_table(gp1) <- cbind(tax_table(gp1), Sample=paste0("ta", taxa_names(gp1))) 99 | tax_table(gp1) <- cbind(tax_table(gp1), Primer=paste0("ta", taxa_names(gp1))) 100 | expect_warning(ps1 <- psmelt(gp1)) 101 | expect_equal(colnames(ps1)[1:3], c("OTU", "Sample", "Abundance")) 102 | expect_equal(dim(ps1), c(546L, 22L)) 103 | newvars = c("sample_OTU", "sample_Sample", "sample_Abundance", 104 | "sample_Primer", "taxa_Sample") 105 | expect_true(all(newvars %in% colnames(ps1))) 106 | }) 107 | 108 | test_that("psmelt correctly handles phyloseq data with NULL components, and OTU tables", { 109 | data("GlobalPatterns") 110 | GP = prune_taxa(names(sort(taxa_sums(GlobalPatterns), TRUE)[1:50]), 111 | GlobalPatterns) 112 | # The objects with NULL components 113 | GPS = phyloseq(otu_table(GP), sample_data(GP), phy_tree(GP)) 114 | GPT = phyloseq(otu_table(GP), tax_table(GP), phy_tree(GP)) 115 | GPTr = phyloseq(otu_table(GP), phy_tree(GP)) 116 | GPN = otu_table(GP) 117 | # Try psmelt directly. Should be no errors or warnings. 118 | expect_is((testT <- psmelt(GPT)), "data.frame") 119 | expect_is((testS <- psmelt(GPS)), "data.frame") 120 | expect_is((testTr <- psmelt(GPTr)), "data.frame") 121 | expect_is((testN <- psmelt(GPN)), "data.frame") 122 | # Test values of the results. 123 | expect_is(testT$Abundance, "numeric") 124 | expect_is(testT$OTU, "character") 125 | expect_is(testT$Sample, "character") 126 | expect_equivalent( 127 | colnames(testT), 128 | c("OTU", "Sample", "Abundance", "Kingdom", "Phylum", "Class", "Order", 129 | "Family", "Genus", "Species") 130 | ) 131 | expect_equivalent( 132 | colnames(testS), 133 | # NOTE: phyloseq instead expects c("Sample", "OTU", ... for this case 134 | c("OTU", "Sample", 135 | "Abundance", "X.SampleID", "Primer", "Final_Barcode", 136 | "Barcode_truncated_plus_T", "Barcode_full_length", "SampleType", 137 | "Description") 138 | ) 139 | # Try psmelt via plot function that relies on it 140 | expect_is(pS <- plot_tree(GPS, color="SampleType"), "ggplot") 141 | expect_is(pT <- plot_tree(GPT, shape="Kingdom"), "ggplot") 142 | expect_is(pTr <- plot_tree(GPTr), "ggplot") 143 | expect_is(pN <- plot_bar(GPN), "ggplot") 144 | # Note, these calls produce graphical output 145 | expect_is((prPS <- print(pS)), "gg") 146 | expect_is((prPT <- print(pT)), "gg") 147 | expect_is((prPTr <- print(pTr)), "gg") 148 | expect_is((prPN <- print(pN)), "gg") 149 | }) 150 | 151 | test_that("psmelt doesn't break when the number of taxa is 1", { 152 | data(GlobalPatterns) 153 | # tree removal warning when prune to 1 OTU. 154 | expect_warning(GP1 <- prune_taxa(taxa_names(GlobalPatterns)[1], GlobalPatterns)) 155 | expect_equal(ntaxa(GP1), 1) 156 | df <- psmelt(GP1) 157 | expect_is(df, 'data.frame') 158 | reqnames = c("OTU", "Sample", "Abundance", "SampleType", "Kingdom", "Phylum") 159 | expect_true(all(reqnames %in% names(df))) 160 | expect_equivalent(sum(df$Abundance, na.rm = TRUE), taxa_sums(GP1)) 161 | }) 162 | -------------------------------------------------------------------------------- /tests/testthat/test-transform-filter.R: -------------------------------------------------------------------------------- 1 | # run just this file: 2 | # devtools::test_file(here::here("tests", "testthat", "test-transform-filter.R")) 3 | data(GlobalPatterns) 4 | 5 | test_that("transform and filter functions agree with phyloseq", { 6 | gp1 <- filter_taxa2(GlobalPatterns, ~ sum(. > 0) > 5) 7 | gp2 <- phyloseq::filter_taxa(GlobalPatterns, function(x) sum(x > 0) > 5, 8 | prune = TRUE) 9 | expect_identical(gp1, gp2) 10 | 11 | gp3 <- transform_sample_counts(gp1, ~ . / sum(.)) 12 | gp4 <- phyloseq::transform_sample_counts(gp1, function(x) x / sum(x)) 13 | expect_identical(gp3, gp4) 14 | }) 15 | -------------------------------------------------------------------------------- /tests/testthat/test-utils.R: -------------------------------------------------------------------------------- 1 | # run just this file: 2 | # devtools::test_file(here::here("tests", "testthat", "test-utils.R")) 3 | 4 | # select_taxa ----------------------------------------------------------------- 5 | 6 | # Get a phyloseq object with all slots filled for testing 7 | data(GlobalPatterns) 8 | ps <- prune_taxa( 9 | ape::extract.clade(phy_tree(GlobalPatterns), "0.589.38") %>% .$tip.label, 10 | GlobalPatterns 11 | ) 12 | # add reference sequences 13 | rs <- phy_tree(ps) %>% 14 | phangorn::simSeq(10) %>% 15 | purrr::map(factor, levels = as.character(1:4)) %>% 16 | purrr::map(forcats::fct_recode, A = "1", C = "2", G = "3", T = "4") %>% 17 | purrr::map(as.character) %>% 18 | purrr::map_chr(paste, collapse = "") %>% 19 | Biostrings::DNAStringSet() 20 | ps <- merge_phyloseq(ps, rs) 21 | rm(rs) 22 | # Taxa to select, in order different from original 23 | taxa <- taxa_names(ps)[c(5,1,9,2,6,3)] 24 | current_order <- taxa_names(ps) %>% intersect(taxa) 25 | 26 | test_that("select_taxa() gives taxa in requested order unless `x` is or contains a tree", { 27 | expect_equal(current_order, ps %>% select_taxa(taxa) %>% taxa_names) 28 | expect_equal(current_order, ps %>% phy_tree %>% select_taxa(taxa) %>% taxa_names) 29 | expect_equal(taxa, ps %>% refseq %>% select_taxa(taxa) %>% taxa_names) 30 | expect_equal(taxa, ps %>% otu_table %>% select_taxa(taxa) %>% taxa_names) 31 | expect_equal(taxa, ps %>% tax_table %>% select_taxa(taxa) %>% taxa_names) 32 | expect_equal(current_order, 33 | ps %>% refseq %>% select_taxa(taxa, reorder = FALSE) %>% taxa_names) 34 | expect_equal(current_order, 35 | ps %>% otu_table %>% select_taxa(taxa, reorder = FALSE) %>% taxa_names) 36 | expect_equal(current_order, 37 | ps %>% tax_table %>% select_taxa(taxa, reorder = FALSE) %>% taxa_names) 38 | 39 | ps1 <- ps 40 | ps1@phy_tree <- NULL 41 | expect_equal(taxa, ps1 %>% select_taxa(taxa) %>% taxa_names) 42 | expect_equal(current_order, 43 | ps1 %>% select_taxa(taxa, reorder = FALSE) %>% taxa_names) 44 | ps1@refseq <- NULL 45 | expect_equal(taxa, ps1 %>% select_taxa(taxa) %>% taxa_names) 46 | ps1@tax_table <- NULL 47 | expect_equal(taxa, ps1 %>% select_taxa(taxa) %>% taxa_names) 48 | }) 49 | 50 | test_that("select_taxa() agrees with prune_taxa() when accounting for order", { 51 | expect_equal( 52 | ps %>% select_taxa(taxa) %>% otu_table, 53 | ps %>% prune_taxa(taxa, .) %>% otu_table 54 | ) 55 | expect_equal( 56 | ps %>% sample_data %>% select_taxa(taxa), 57 | ps %>% sample_data %>% prune_taxa(taxa, .) 58 | ) 59 | expect_equal( 60 | ps %>% phy_tree %>% select_taxa(taxa), 61 | ps %>% phy_tree %>% prune_taxa(taxa, .) 62 | ) 63 | expect_equal( 64 | ps %>% refseq %>% select_taxa(taxa, reorder = FALSE), 65 | ps %>% refseq %>% prune_taxa(taxa, .) 66 | ) 67 | expect_equal( 68 | ps %>% otu_table %>% select_taxa(taxa, reorder = TRUE), 69 | ps %>% otu_table %>% prune_taxa(taxa, .) 70 | ) 71 | expect_equal( 72 | ps %>% tax_table %>% select_taxa(taxa, reorder = TRUE), 73 | ps %>% tax_table %>% prune_taxa(taxa, .) 74 | ) 75 | }) 76 | 77 | test_that("select_taxa() returns sample data unchanged", { 78 | expect_equal(ps %>% sample_data %>% select_taxa(taxa), sample_data(ps)) 79 | }) 80 | 81 | test_that("select_taxa() throws an error on duplicates or taxa not in x", { 82 | expect_error(ps %>% select_taxa(c(taxa, taxa[1])), 83 | "is not TRUE" 84 | ) 85 | expect_error(ps %>% sample_data %>% select_taxa(c(taxa, taxa[1])), 86 | "is not TRUE" 87 | ) 88 | expect_error(ps %>% otu_table %>% select_taxa(c(taxa, taxa[1])), 89 | "is not TRUE" 90 | ) 91 | expect_error(ps %>% phy_tree %>% select_taxa(c(taxa, taxa[1])), 92 | "is not TRUE" 93 | ) 94 | expect_error(ps %>% tax_table %>% select_taxa(c(taxa, taxa[1])), 95 | "is not TRUE" 96 | ) 97 | expect_error(ps %>% refseq %>% select_taxa(c(taxa, taxa[1])), 98 | "is not TRUE" 99 | ) 100 | expect_error(ps %>% select_taxa(c(taxa, "asdf")), 101 | "is not TRUE" 102 | ) 103 | expect_error(ps %>% otu_table %>% select_taxa(c(taxa, "asdf")), 104 | "is not TRUE" 105 | ) 106 | expect_error(ps %>% phy_tree %>% select_taxa(c(taxa, "asdf")), 107 | "is not TRUE" 108 | ) 109 | expect_error(ps %>% tax_table %>% select_taxa(c(taxa, "asdf")), 110 | "is not TRUE" 111 | ) 112 | expect_error(ps %>% refseq %>% select_taxa(c(taxa, "asdf")), 113 | "is not TRUE" 114 | ) 115 | }) 116 | 117 | # orient_taxa ----------------------------------------------------------------- 118 | # 119 | test_that("orient_taxa() produces expected output on phyloseq and otu-table objects", { 120 | otu <- otu_table(ps) 121 | ps_t <- t(ps) 122 | expect_identical(ps %>% orient_taxa("rows"), ps) 123 | expect_identical(ps %>% orient_taxa("columns"), ps %>% t) 124 | expect_identical(ps_t %>% orient_taxa("rows"), ps) 125 | expect_identical(ps_t %>% orient_taxa("columns"), ps_t) 126 | expect_identical(otu %>% orient_taxa("rows"), otu) 127 | expect_identical(otu %>% orient_taxa("columns"), otu %>% t) 128 | }) 129 | --------------------------------------------------------------------------------