1. 函数源代码
该R包中最主要的函数是 hclust ,代码如下:
> fastcluster::hclust function (d, method = "complete", members = NULL) { if (method == "ward") { message("The \"ward\" method has been renamed to \"ward.D\"; note new \"ward.D2\"") method <- "ward.D" } METHODS <- c("single", "complete", "average", "mcquitty", "ward.D", "centroid", "median", "ward.D2") method <- pmatch(method, METHODS) if (is.na(method)) stop("Invalid clustering method.") if (method == -1) stop("Ambiguous clustering method.") dendrogram <- c(.Call(fastcluster, attr(d, "Size"), method, d, members), list(labels = attr(d, "Labels"), method = METHODS[method], call = match.call(), dist.method = attr(d, "method"))) class(dendrogram) <- "hclust" return(dendrogram) }
对比基础包 stats 中的函数 hclust :
> stats::hclust function (d, method = "complete", members = NULL) { METHODS <- c("ward.D", "single", "complete", "average", "mcquitty", "median", "centroid", "ward.D2") if (method == "ward") { message("The \"ward\" method has been renamed to \"ward.D\"; note new \"ward.D2\"") method <- "ward.D" } i.meth <- pmatch(method, METHODS) if (is.na(i.meth)) stop("invalid clustering method", paste("", method)) if (i.meth == -1) stop("ambiguous clustering method", paste("", method)) n <- as.integer(attr(d, "Size")) if (is.null(n)) stop("invalid dissimilarities") if (is.na(n) || n > 65536L) stop("size cannot be NA nor exceed 65536") if (n < 2) stop("must have n >= 2 objects to cluster") len <- as.integer(n * (n - 1)/2) if (length(d) != len) (if (length(d) < len) stop else warning)("dissimilarities of improper length") if (is.null(members)) members <- rep(1, n) else if (length(members) != n) stop("invalid length of members") storage.mode(d) <- "double" hcl <- .Fortran(C_hclust, n = n, len = len, method = as.integer(i.meth), ia = integer(n), ib = integer(n), crit = double(n), members = as.double(members), nn = integer(n), disnn = double(n), diss = d) hcass <- .Fortran(C_hcass2, n = n, ia = hcl$ia, ib = hcl$ib, order = integer(n), iia = integer(n), iib = integer(n)) structure(list(merge = cbind(hcass$iia[1L:(n - 1)], hcass$iib[1L:(n - 1)]), height = hcl$crit[1L:(n - 1)], order = hcass$order, labels = attr(d, "Labels"), method = METHODS[i.meth], call = match.call(), dist.method = attr(d, "method")), class = "hclust") }
二者的区别如下:
fastcluster::hclust 和 stats::hclust 函数都用于进行层次聚类,但它们在实现和性能上可能有差异。从 R 代码来看,它们在接口上非常相似,都需要一个距离矩阵 d 和一个指定方法 method 的参数。不过,这些函数在内部如何处理聚类过程可能有所不同。
fastcluster::hclust 是 fastcluster 包中的函数,这个包特别设计用于处理大数据集并优化性能。它提供了一个接口到 fastcluster 库,这是一个为速度优化的层次聚类算法的集合。如代码所示, fastcluster::hclust 使用 .Call 接口调用 C 语言级别的代码,这通常比 R 中的纯代码执行得更快。
stats::hclust 是 R 中 stats 包的一部分,提供了标准的层次聚类功能。代码显示它使用 .Fortran 调用 Fortran 代码来执行聚类。虽然 stats 包非常可靠并且在标准 R 安装中提供,但可能没有 fastcluster 包中的函数那么快,特别是在处理非常大的数据集时。
此外, fastcluster::hclust 在处理 "ward" 方法时,会发出警告信息指出 "ward" 方法已经更名为 "ward.D"(这里同时提到了一个新的 "ward.D2" 方法)。这表明 fastcluster 包在方法名称上可能更严格。其他方面,这两个函数的参数都很相似,例如 method , members 等。
总的来说,两者的主要区别可能在于执行速度,尤其是在大规模数据集上。 fastcluster 在算法上可能更加高效,因此对于大型数据集可能是更好的选择。对于较小的数据集,或者当性能考虑不是首要问题时, stats::hclust 或许已经足够。然而,这两个函数在 API 设计上是非常类似的,提供了相似的用户体验。在选择使用哪一个时,可能需要根据你的数据规模和性能需求来决定。
2. 代码
函数的使用代码如下
sampleTree = hclust(d = dist(datExpr), method = "average")
3. 结果解析
hclust 函数在 R 中用于层次聚类分析,其结果是一个 hclust 对象。这个对象包含进行聚类分析所需的所有信息,并能够以树状图(dendrogram)的形式展现。
下面是 hclust 结果对象的组成部分和它们各自的含义:
1. merge:一个矩阵,描述了在聚类过程中各个聚类是如何合并的。每一行代表一个合并的操作,如果值为负数,表示它指向单个初始观测点;如果为正数,表示它指向由 merge 矩阵之前行的合并结果形成的聚类。
2. height:一个向量,包含了在聚类树中每次合并发生时的“高度”。这个“高度”可以根据所选的相异度测量方法(比如,最大距离、平均距离、Ward's 方法等)而有所不同。
3. order:一个向量,表示了叶子节点在绘制树状图时的顺序,可以用来帮助在二维平面上更好地展示树状图。
4. labels:一个字符向量,包含了观测点的标签。在树状图中,每个叶子节点旁边通常会显示对应的标签。
5. method:表示用于聚类的方法,比如 "complete" 、 "average" 、 "single" 等。
6. call:一个R语言的调用对象,表示了 hclust 函数的原始调用方式。
7. dist.method:当使用 dist 函数计算相异度矩阵时使用的方法。
4. 聚类结果可视化
一个 hclust 对象通常通过 plot 函数来可视化,这会生成一棵树状图,反映了数据点是如何层次性地聚类在一起的。
例如:
# 计算距离矩阵 dist_matrix <- dist(mydata) # 进行层次聚类 hc <- hclust(dist_matrix) # 绘制树状图 plot(hc)
在上面的代码中, mydata 是原始数据集, dist_matrix 是计算出的距离矩阵。 hclust 函数使用这个距离矩阵执行层次聚类,并返回聚类结果 hc 。然后,我们可以通过 plot(hc) 来绘制树状图。
5. 聚类结果分组
cutree 函数有助于我们通过指定聚类数 k 来切割树状图,从而得到聚类的分组结果。也可以使用 cutreeStatic 函数对树状图进行切割。
cutree 函数和 cutreeStatic 函数的区别如下:
cutree 和 cutreeStatic 都是 R 语言中的函数,用于在层次聚类树(dendrogram)中切割分支,从而将数据分成不同的簇或者组。他们的功能是相似的,但有一些关键的区别:
1. cutree:
cutree 是 R 的基础统计包中的函数。这是一个普遍用于层次聚类分析的标准函数。它可以根据指定的簇的数量 k 或者指定的高度 h 来切割聚类树。当基于簇的数量来切割时, cutree 会尝试保持簇的数量尽可能接近你指定的 k 值。但是由于它没有内置的最小簇大小限制,因此可能会生成一些非常小的簇。
举个例子:
clusters <- cutree(hc, k = 5) # 或者 clusters <- cutree(hc, h = 1.25)
在这个例子中, hc 是之前通过 hclust 得到的层次聚类对象, k = 5 指示 cutree 函数将数据点分成5个簇。 h = 1.25 导致树状图在高度1.25处被切割,从而将观测点分配到不同的簇中。结果是,所有在高度1.25以下相连的点都会被划分为同一个簇,而高度在1.25以上的点会分属于不同的簇。
2. cutreeStatic:
cutreeStatic 是专门设计用于 WGCNA 包中的,它也执行恒定高度的切割,但使用了额外的条件限制生成的簇。
cutreeStatic 允许用户指定一个最小簇大小( minSize ),这有助于避免划分出太小的簇,这在基因表达数据分析中是有意义的,因为太小的模块可能在统计学上不够稳健。 cutreeStatic 返回的每个簇至少有 minSize 个成员,否则这些对象会被标记为0(未分配)。
使用 cutreeStatic 的例子:
# 假设 dendro 是通过 hclust 得到的层次聚类树状图 library(WGCNA) clusters <- cutreeStatic(dendro, cutHeight = 0.9, minSize = 50)
在 cutreeStatic 中, cutHeight 参数定义了树应该在何处高度上切割, minSize 参数则确保只有足够大的簇才被保留。相比之下, cutree 可以返回任意大小的簇。
总结来说, cutree 更适用于一般的层次聚类和簇的快速提取,而 cutreeStatic 提供了更多控制,特别是在需要避免过小的簇时,这在 WGCNA 的上下文中尤其有价值。
6. 分组结果解析
cutreeStatic 函数的输出是一个数值向量,它给出了层次聚类树状图上每个对象的簇标签。在这个向量中,具有相同数值的对象被归为同一个簇,而数值为0的对象表示未被分配到任何簇。这通常意味着树在指定的高度上被切割,然后剔除了那些成员数量少于 `minSize` 参数指定值的分支。
举例来说,如果你有一个包含100个对象的数据集,并执行了 cutreeStatic 函数,得到了如下类型的输出:
[1] 1 1 1 2 2 2 0 0 3 3 3 3 3 0 4 4 4 4 4 4 0 0 5 5 ...
在这个例子中,前三个对象(值为1)被归为第一个簇,接着的三个对象(值为2)形成第二个簇。值为0的对象没有被分配到任何簇,可能因为这些对象所属的原始分支在切割时没有足够的成员数满足 minSize 的要求。随后的五个对象(值为3)构成了第三个簇,如此类推。
cutreeStatic 函数会根据簇的大小来赋予簇编号,其中最大的簇会被标记为1,第二大的簇标记为2,以此类推。这样的编号方式有助于快速识别数据集中最大的几个簇,这在许多情况下很有用,尤其是在生物信息学和网络分析中,大的簇可能代表了更有生物学意义的模块。
需要注意的是, cutreeStatic 特别适用于 WGCNA 分析,因为在该框架中,研究者通常对较大的簇或模块更感兴趣,这些簇可能代表了具有共同生物学功能的基因集合。小簇可能是噪声或者不具有足够统计力的信号,因此在某些情况下被排除在外是合理的。