################################################################################
#' S4 class SummarizedPhyloseq
#'
#' A S4 Object for storing phyloseq data at all phylogenic levels
#'
#' This class inherit from the
#' \code{\link{phyloseq-class}}
#' from the phyloseq package. It contains three data classes:
#' \code{\link{otu_table-class}} ("otu_table" slot),
#' \code{\link{sample_data-class}} ("sample_data" slot), and
#' \code{\link{taxonomyTable-class}} ("tax_table" slot).
#' Besides the three slots inherit from phyloseq-class, the SummarizedPhyloseq
#' also has 7 more slots, "kingdom_table", "phylum_table", "class_table",
#' "order_table", "family_table", "genus_table", and "species_table", all in
#' the class of otu_table-class. This allows you to view the data in different
#' phylogenic levels.
#' \code{\link{summarizeFromPhyloseq}}
#' is the main constructor for this class, directly from a phyloseq object.
#' The phyloseq needs to have the otu_table, tax_table, and sample_data to
#' successfully construct this class.
#'
#' slots:
#' \describe{
#' \item{otu_table}{ a tabular object of the OTU table, class of otu_table-class}
#' \item{sam_data}{ a tabular object of the sample meta-data, class of sample_data.}
#' \item{tax_table}{ a tabular object of the taxonomy table, class of taxonomyTable.}
#' \item{kingdom_table}{ a tabular object of the summarized OTU table into the kingdom level, class of otu_table}
#' \item{phylum_table}{ a tabular object of the summarized OTU table into the phylum level, class of otu_table}
#' \item{class_table}{ a tabular object of the summarized OTU table into the class level, class of otu_table}
#' \item{order_table}{ a tabular object of the summarized OTU table into the order level, class of otu_table}
#' \item{family_table}{ a tabular object of the summarized OTU table into the family level, class of otu_table}
#' \item{genus_table}{ a tabular object of the summarized OTU table into the genus level, class of otu_table}
#' \item{species_table}{ a tabular object of the summarized OTU table into the species level, class of otu_table}
#' }
#'
#' @seealso
#' \code{\link{phyloseq-class}}
#' \code{\link{summarizeFromPhyloseq}}
#' \code{\link{SummarizedPhyloStats-class}}
#' \code{\link{SummarizedPhyloseq-accessors}}
#' \code{\link{SummarizedPhyloseq-assign}}
#'
#' @importClassesFrom phyloseq phyloseq
#' @name SummarizedPhyloseq-class
#' @aliases SummarizedPhyloseq-class
#' @exportClass SummarizedPhyloseq
#' @rdname SummarizedPhyloseq-class
#' @author Chenghao Zhu
setClass(
Class = "SummarizedPhyloseq",
representation = representation(
kingdom_table = "otu_tableOrNULL",
phylum_table = "otu_tableOrNULL",
class_table = "otu_tableOrNULL",
order_table = "otu_tableOrNULL",
family_table = "otu_tableOrNULL",
genus_table = "otu_tableOrNULL",
species_table = "otu_tableOrNULL"
),
contains = "phyloseq",
prototype = prototype(
kingdom_table = "NULL",
phylum_table = "NULL",
class_table = "NULL",
order_table = "NULL",
family_table = "NULL",
genus_table = "NULL",
species_table = "NULL"
)
)
################################################################################
#' summarizeFromPhyloseq
#'
#' Construct a
#' \code{\link{SummarizedPhyloseq-class}} object from a
#' \code{\link{phyloseq-class}} object
#'
#' This is the main constructor of the SummarizedPhyloseq class. It takes a
#' phyloseq object and calls the
#' \code{link{summarize_taxa}}() function for each phylogenic level and return
#' a SummarizedPhyloseq object.
#'
#' @usage summarizeFromPhyloseq(physeq, level = "all", keep_full_tax = FALSE)
#'
#' @param physeq An phyloseq object from the phyloseq package. It must contain
#' an otu_table slot, a sam_data slot, and a tax_table slot. The phy_tree slot
#' and refseq slots are not required.
#' @param level The taxonomy level to summarize. It can be one ore more from
#' Kingdom, Phylum, Class, Order, Family, Genus, and Species. If mutiple
#' phylogenic levels are specified, use a string vector. Default is "all" that
#' parses all levels. The slots that are not specified will be NULL.
#'
#' @return A SummarizedPhyloseq object
#'
#' @seealso \code{\link{SummarizedPhyloseq-class}}
#'
#' @author Chenghao Zhu
#' @import phyloseq
#' @importFrom magrittr %>%
#' @import dplyr
#' @import tibble
#' @export
#' @examples
#' library(phyloseq)
#' data(GlobalPatterns)
#' spy = summarizedFromPhyloseq(GlobalPatterns)
summarizeFromPhyloseq <- function(physeq, level = "all"){
all_levels = c("Kingdom", "Phylum", "Class", "Order",
"Family", "Genus", "Species")
if( length(level) == 1 & "all" %in% level) level = all_levels
summarizedPhyseq = lapply(level, function(lvl){
otu_table = summarize_taxa(physeq, level = lvl,
keep_full_tax = FALSE) %>%
column_to_rownames("taxonomy")
otu_table(otu_table, taxa_are_rows = TRUE)
})
names(summarizedPhyseq) = level
for(lvl in all_levels){
if(lvl %in% level){
assign(lvl, summarizedPhyseq[[lvl]])
}else{
assign(lvl, NULL)
}
}
new("SummarizedPhyloseq",
kingdom_table = Kingdom,
phylum_table = Phylum,
class_table = Class,
order_table = Order,
family_table = Family,
genus_table = Genus,
species_table = Species,
otu_table = physeq@otu_table,
tax_table = physeq@tax_table,
sam_data = physeq@sam_data,
phy_tree = physeq@phy_tree,
refseq = physeq@refseq)
}
################################################################################
## This validity method checks if the summarized slots have the same sample
## names as the sam_data
setValidity(
"SummarizedPhyloseq",
function(object){
sp_list = splat_phyloseq_objects(object)
otu_tables = c("kingdom_table", "phylum_table", "class_table",
"order_table", "family_table", "genus_table",
"species_table")
object_sample_names = sample_names(object@sam_data)
for(tbl in otu_tables){
table = sp_list[[tbl]]
if(!is.null(table)){
if((length(sample_names(table)) != length(object_sample_names)) |
all.equal(sample_names(table), object_sample_names) != T){
return(paste("in ", tbl, " sample names don't match"))
}
}
}
validObject(as(object, "phyloseq"))
}
)
################################################################################
### This function converts a phyloseq object to an unclassed list, with the
### name of each element being the name of each slot. It actually works for
### other classes not only phyloseq.
#' @keywords internal
splat_phyloseq_objects = function(object){
slot_names = slotNames(object)
slot_list = lapply(slot_names, function(slt){
eval(parse(text = paste0("object@", slt)))
})
names(slot_list) = slot_names
return(slot_list[!is.na(slot_list)])
}
################################################################################
# this funciton converts sample_data to a data.frame
#' @export
setMethod(
f = "as.data.frame",
signature = "sample_data",
definition = function(x){
as(x, "data.frame")
}
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.