Nothing
#' @name clusterDendrogram
#' @title Accessing and manipulating the dendrograms
#' @rdname clusterDendrogram
#' @description These functions are for accessing and manipulating the
#' dendrograms stored in a \code{ClusterExperiment} object. We also document
#' the required format of these dendrograms here.
#' @param x a ClusterExperiment object
#' @section The Stored Dendrograms
#' @details Two dendrograms are stored in a \code{ClusterExperiment} object. One
#' is a dendrogram that describes the hierarchy between the clusters
#' (\code{@dendro_clusters}), and the other is a dendrogram that extends that
#' hierarchy to include the clusters (\code{@dendro_samples}). The clustering
#' that is used to make these hierarchies is saved in as well
#' (\code{@dendro_index})
#' @details The dendrograms stored in a \code{ClusterExperiment} object are
#' required to be a \code{\link[phylobase]{phylo4d-class}} from the package
#' \code{phylobase} (which uses the basic format of the S3 class
#' \code{\link[ape]{phylo}} in the \code{ape} package to store the edges;
#' \code{phylobase} makes it a S4 class with some useful helpers). This class
#' allows storage of a data.frame of information corresponding to information
#' on each node (see \code{\link[phylobase]{tdata}}).
#' @details Additional requirements are made of these dendrograms to be a valid
#' for the slots of the \code{ClusterExperiment} class, described below,
#' regarding the data that must be stored with it and the labels which can be
#' assigned. Possible dendrograms can be checked for validity with the
#' function \code{checkDendrogram}. The reason for the restrictions on the
#' labels is so as to not duplicate storage of the names, see below
#' descriptions for where to save user-defined names.
#' @section Cluster Hierarchy
#' @details \itemize{
#' \item{Labels}{The cluster dendrogram can only have labels
#' on the \emph{internal} nodes. Labels on the internal nodes of the cluster
#' dendrogram can be set by the user (the function \code{nodeLabels<-} is
#' defined to work on a \code{ClusterExperiment} object to make this easy).
#' The tips of the cluster dendrogram, corresponding to the clusters, cannot
#' have labels; users can set the labels (e.g. for plotting, etc) in the
#' \code{\link{clusterLegend}} slot using the function
#' \code{\link{renameClusters}}.}
#' \item{Data}{ The cluster hierarchy must have
#' data stored with it that has the following columns (additional ones are
#' allowed):
#' \itemize{
#' \item{NodeId}{The permanent node id for the node. Must
#' be of the format "NodeIdX" where "X" is a integer.}
#' \item{Position}{The
#' type of node, in terms of its position. The internal nodes should have the
#' values "cluster hierarchy node" while the tips should have "cluster
#' hierarchy tip".}
#' \item{ClusterIdDendro}{Only for tips of dendrogram, should
#' have the id that corresponds to its cluster in the clustering of the
#' @dendro_index. Of the form "ClusterIdX", where "X" is the internal cluster
#' id (see \code{\link{clusterLegend}}). Internal nodes should have NA
#' values.}
#' \item{ClusterIdMerge}{The id that corresponds to the cluster in
#' the clustering of the @merge_index, if it exists. Of the form "ClusterIdX",
#' where "X" is the internal cluster id (see \code{\link{clusterLegend}}} } }
#' }
#' @section Sample Hierarchy
#' @details \itemize{
#' \item{Labels}{The sample dendrogram is not allowed to have ANY labels. The
#' names for those nodes that correspond to the cluster hierarchy will be pulled
#' from the names in the cluster hierarchy for plotting, etc. and should be set
#' there (see above). Sample names for the tips of the tree will be pulled from
#' \code{colnames} of the object and should be set there. }
#' \item{Data}{
#' The cluster hierarchy must have data stored with it that has the following
#' columns (additional ones are allowed):
#' \itemize{
#' \item{NodeId}{For those nodes that correspond to a node in the cluster
#' hierarchy, should have its permanent node id in this column. Other nodes
#' should be NA.}
#' \item{Position}{The type of node, in terms of its position. The internal
#' nodes should have the values "cluster hierarchy node" while the tips should
#' have "cluster hierarchy tip".}
#' \item{SampleIndex}{Only for tips of dendrogram, the index of the sample at
#' that tip to the samples in the object.}
#' }
#' }
#' }
#' @section Helper Functions
#' @seealso \code{\link{makeDendrogram}},
#' \code{\link[phylobase]{phylo4d-class}}, \code{\link[ape]{phylo}}
#' @return \code{clusterDendrogram} returns the dendrogram describing the
#' clustering hierarchy.
#' @importMethodsFrom phylobase nodeLabels nodeLabels<- nTips nNodes
#' @export
#' @examples
#' data(rsecFluidigm)
#' # retrieve the dendrogram of the clusters:
#' head(clusterDendrogram(rsecFluidigm),5)
#' # retrieve the dendrogram of the samples:
#' head(sampleDendrogram(rsecFluidigm),5)
#' # Return # internal nodes from cluster hierarchy
#' nInternalNodes(rsecFluidigm)
#' # Return # tips from cluster hierarchy (i.e. # clusters)
#' nTips(rsecFluidigm)
#' # Return internal node ids
#' nodeIds(rsecFluidigm,type="internal")
#' # Labels assigned to internal nodes
#' nodeLabels(rsecFluidigm)
#' # Assign new labels to the internal nodes of the cluster hierarchy
#' l1<-paste("A", 1:nInternalNodes(rsecFluidigm),sep=":")
#' names(l1)<-nodeIds(rsecFluidigm,type="internal")
#' nodeLabels(rsecFluidigm)<-l1
#' nodeLabels(rsecFluidigm)
#' @aliases clusterDendrogram,ClusterExperiment-method
setMethod(
f = "clusterDendrogram",
signature = "ClusterExperiment",
definition = function(x) {
return(x@dendro_clusters)
}
)
#' @rdname clusterDendrogram
#' @return \code{sampleDendrogram} returns the dendrogram that expands the
#' cluster hierarchy to the samples.
#' @export
#' @aliases sampleDendrogram
setMethod(
f = "sampleDendrogram",
signature = "ClusterExperiment",
definition = function(x) {
return(x@dendro_samples)
}
)
#' @rdname clusterDendrogram
#' @return \code{nInternalNodes} returns the number of \emph{internal} nodes of
#' the cluster hierarchy.
#' @export
#' @aliases nInternalNodes
setMethod(
f = "nInternalNodes",
signature = "ClusterExperiment",
definition = function(x) {
return(length(phylobase::nodeLabels(x@dendro_clusters)))
}
)
#' @rdname clusterDendrogram
#' @return \code{nTips} returns the number of tips of the cluster hierarchy
#' (same as number of non-negative clusters in the dendrogram clustering)
#' @export
#' @aliases nTips
setMethod(
f = "nTips",
signature = "ClusterExperiment",
definition = function(x) {
return(phylobase::nTips(x@dendro_clusters))
}
)
#' @rdname clusterDendrogram
#' @return \code{nNodes} returns the number of total nodes of the cluster hierarchy
#' @export
#' @aliases nNodes
setMethod(
f = "nNodes",
signature = "ClusterExperiment",
definition = function(x) {
return(phylobase::nNodes(x@dendro_clusters))
}
)
#' @rdname clusterDendrogram
#' @return \code{nodeLabels<-} sets the node labels of the \emph{cluster}
#' dendrogram
#' @export
#' @details For setting the node labels of the cluster dendrogram via
#' \code{nodeLabels<-}, the replacement value has to have names that match the
#' internal ids of the cluster dendrogram (the \code{NodeId} column).
#' @aliases nodeLabels<-
#' @param value replacement value for \code{nodeLabels}. See details.
#' @param ... additional options passed to \code{nodeLabels<-} (ignored)
setMethod(
f = "nodeLabels<-",
signature = signature(x="ClusterExperiment", value="ANY"),
definition = function(x, ..., value) {
if(!is.null(names(value))){
#match them
m<-try(.matchToDendroData(inputValue=names(value),dendro=x@dendro_clusters,matchColumn="NodeId",returnColumn="NodeIndex"),silent=TRUE)
if(inherits(m,"try-error")) stop("names of replace vector do not match in internal node id:",m)
phylobase::labels(x@dendro_clusters)[m]<-value
ch<-.checkDendrogram(x)
if(!is.logical(ch)) stop(ch)
return(x)
}
else{stop("the replacement value needs to have names that match the internal node ids")}
}
)
#' @rdname clusterDendrogram
#' @return \code{checkClusterDendrogram} checks if a \code{phylo4d} objects are
#' valid for the cluster and sample dendrogram slots of the given
#' \code{ClusterExperiment} object. Returns \code{TRUE} if there are no
#' problems. Otherwise creates error.
#' @param dendroCluster a \code{phylo4d} to be check as for being cluster hierarchy
#' @param dendroSample a \code{phylo4d} to be check as for being cluster hierarchy
#' @inheritParams getClusterIndex
#' @export
#' @aliases checkDendrogram
setMethod(
f = "checkDendrogram",
signature = signature(x="ClusterExperiment",dendroCluster="phylo4d",dendroSample="phylo4d"),
definition = function(x,dendroCluster,dendroSample,whichCluster="dendro") {
whCl<-getSingleClusterIndex(x,whichCluster)
x@dendro_clusters<-dendroCluster
x@dendro_samples<-dendroSample
x@dendro_index<-whCl
ch<-.checkDendrogram(x)
if(!is.logical(ch)) stop(ch)
else return(TRUE)
}
)
#' @rdname clusterDendrogram
#' @return \code{nodeLabels} returns the node labels of the \emph{cluster}
#' dendrogram
#' @export
#' @aliases nodeLabels
setMethod(
f = "nodeLabels",
signature = signature(x="ClusterExperiment"),
definition = function(x) {
phylobase::nodeLabels(x@dendro_clusters)
}
)
#' @rdname clusterDendrogram
#' @return \code{nodeIds} returns the internal (permanent) node ids of the
#' \emph{cluster} dendrogram
#' @param type the type of node to return results from. One of "all",
#' "internal", and "tip".
#' @export
#' @aliases nodeIds
setMethod(
f = "nodeIds",
signature = signature(x="ClusterExperiment"),
definition = function(x,type=c("all","internal","tip")) {
phylobase::tdata(x@dendro_clusters,type=type)[,"NodeId"]
}
)
#' @rdname clusterDendrogram
#' @return \code{convertToDendrogram} returns the sample dendrogram converted to
#' a \code{\link[stats]{dendrogram}} class.
#' @seealso \code{\link[stats]{dendrogram}}
#' @export
#' @aliases convertToDendrogram
setMethod(
f="convertToDendrogram",
signature = "ClusterExperiment",
definition=function(x){
dendroId <- .setNodeLabels(x,labelType="id")$dendro_samples
return(.convertToDendrogram(dendroId,tipNames=colnames(x)))
})
#' @importFrom ape as.hclust.phylo
#' @importFrom stats as.dendrogram
.convertToDendrogram<-function(x,tipNames=NULL){
if(inherits(x,"dendrogram") )return(x)
if(inherits(x,"phylo4")){
x<-.convertToPhyClasses(x,"phylo")
}
if(inherits(x,"phylo")){
if(any(is.na(as.numeric(x$tip.label)))) stop("can only convert to dendrogram if sample indices are the tip.labels")
x<-try(ape::as.hclust.phylo(x),FALSE)
if(inherits(x, "try-error")) stop("coding error -- could not convert to hclust object. Reported error:",x)
#need to convert integers in $order and (negative) entries in $merge into the values of $labels
newOrder<-as.integer(as.numeric(x$labels))
if(!all(sort(newOrder)==seq_along(newOrder))) stop("could not convert hclust object because dendrogram does not have all consecutive sample indices as tip labels.")
m<-match(abs(x$merge[x$merge<0]),x$order)
newMerge<-x$merge
newMerge[x$merge<0]<-newOrder[m]
newMerge[x$merge<0]<-newMerge[x$merge<0]*sign(x$merge[x$merge<0])
newMerge<-matrix(as.integer(newMerge),ncol=2)
x$order<-newOrder
x$merge<-newMerge
if(is.null(tipNames)) x$labels<-NULL
else x$labels<-tipNames[x$order]
}
if(inherits(x,"hclust")){
x<-try(stats::as.dendrogram(x),FALSE)
if(inherits(x, "try-error")) stop("could not convert from hclust to dendrogram object. Reported error:",x)
if(!is.integer(unlist(x))) stop("coding error -- did not create integer valued dendrogram")
return(x)
}
else{ stop("input x is not of hclust, phylo4 or phylo class")}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.