R: 距离,聚类,建树

R有自己的计算样本距离(dist)和聚类(hclust)的方法/函数,各自包含多种算法据数据特征选择。另外在生态学vegan包vegdist函数也可计算距离,包含多种生态常用距离算法。hclust聚类后的对象可直接plot出图。ape包as.phylo结合write.tree可将聚类文件写成nwk文件。

1 输入数据

library(tidyverse)  # data manipulation
library(cluster)    # clustering algorithms
library(factoextra) # clustering visualization
library(dendextend) # for comparing two dendrograms

set.seed(1995)  
# 随机种子
data=matrix(abs(round(rnorm(200, mean=0.5, sd=0.25), 2)), 20, 10)  
# 随机正整数,20行,20列
colnames(data)=paste("Species", 1:10, sep=".")  
# 列名-细菌
rownames(data)=paste("Sample", 1:20, sep=".")

注意:一行为一个样本

2 dist hclust plot

2.1 dist 计算样本距离

R dist 文档:
https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/dist
可选算法:
"euclidean", "maximum", "manhattan", "canberra", "binary" or "minkowski"

dist = dist(data, method = "euclidean")

2.2 hclust 聚类样本

R hclust 文档:
https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/hclust
可选算法:
"ward.D", "ward.D2", "single", "complete", "average" (= UPGMA), "mcquitty" (= WPGMA), "median" (= WPGMC) or "centroid" (= UPGMC).

hclust_dist = hclust(dist, method = "complete")

3.3 plot 聚类结果

plot(hclust_dist)
plot(hclust_dist, hang = -1)
rect.hclust(hclust_dist, k = 4, border = 1:4)

hang 末端对齐
k 切割
border 颜色

3.4 分组散点图:fviz_cluster

library("factoextra")
sub = cutree(hclust_dist, k=4)
fviz_cluster(list(data = data, cluster = sub))

3 vegdist hclust plot

library("vegan")
vegdist = vegdist(data, method = "bray")
hclust_vegdist = hclust(vegdist, method = "complete")
plot(hclust_vegdist)

4 hcut - 切树法一

https://rpkgs.datanovia.com/factoextra/reference/hcut.html

计算距离,聚类,切割一步完成

res <- hcut(data, k = 4, stand = TRUE,
            hc_metric = "euclidean",
            hc_func = "hclust",
            hc_method = "complete")

stand: 是否进行数据标准化 scale()
k: 生成多少个cluster
hc_metric: 距离算法
hc_func:聚类函数
hc_method:距离算法

结果

fviz_dend(res, rect = TRUE)

聚类评估算法-轮廓系数:Silhouette Coefficient
si接近1,则说明样本i聚类合理;
si接近-1,则说明样本i更应该分类到另外的簇;
si 近似为0,则说明样本i在两个簇的边界上。

fviz_silhouette(res)
fviz_cluster(res)

5 cut - 切树法二

https://stackoverflow.com/questions/41992119/cut-a-dendrogram

dend <- as.dendrogram(hclust(dist(data)))
depth.cutoff <- 1

plot(dend, horiz =  F)
abline(h=depth.cutoff, col="red", lty=2)

horiz: 水平树,或者垂直树
h: horizon 线
v: vertical 垂直线

cut(dend, h = depth.cutoff)
summary(cut(dend, h = depth.cutoff))
attr(cut(dend, h = depth.cutoff)$lower[[1]], "members")
attr(cut(dend, h = depth.cutoff)$lower[[2]], "members")

upper是cutoff上的cluster, lower是cutoff下的cluster.

打印cutoff以上的cluster (branch)

plot(cut(dend, h = depth.cutoff)$upper, horiz = F)

6 cutree - 切树法三

6.1 建树

vegdist = vegdist(data, method = "euclidean")  # distance
hclust_vegdist = hclust(vegdist, method = "complete")  # clust
plot(hclust_vegdist)  # 观察,确定cutoff,或者k
depth.cutoff = 1.2
plot(hclust_vegdist)
abline(h=depth.cutoff, col="red", lty=2)

6.1 切树

cutree(hclust_vegdist, h = depth.cutoff)

6.3 结果整理

clusters = data.frame(cutree(hclust_vegdist, h = depth.cutoff))
colnames(clusters) = c("clusters")
clusters$samples = rownames(clusters)
clusters = data.frame(clusters[order(clusters$clusters, decreasing=F),])

6.4 核实对应关系

6.5 hub样本

fviz_cluster展示聚类后的样本分布

sub = cutree(hclust_dist, k=5)
fviz_cluster(list(data = data, cluster = sub))

获取其中一个cluster的hub sample

# 1 距离矩阵转成表格
df_dist = data.frame(as.matrix(vegdist))
# 2 整理 cluster1数据
target = clusters[clusters$clusters=="1",]$samples
target_dist = df_dist[c(target), c(target)] 
dist_sum = apply(target_dist, 1, FUN=sum)
target_dist_sum = data.frame(samples = rownames(target_dist),
                             dist_sum = dist_sum)
target_dist_sum_sort = target_dist_sum[order(target_dist_sum$dist_sum, decreasing=F),]

7 比较树,比较距离或聚类算法

library(dendextend) # for comparing two dendrograms

hc1 <- hclust(vegdist(data, method = "bray"), method = "complete")
hc2 <- hclust(vegdist(data, method = "bray"), method = "average")

tanglegram(as.dendrogram(hc1), as.dendrogram(hc2))
dend1 = as.dendrogram(hc1)
dend2 = as.dendrogram(hc2)

dend_list <- dendlist(dend1, dend2)

tanglegram(dend1, dend2,
  highlight_distinct_edges = FALSE, # Turn-off dashed lines
  common_subtrees_color_lines = FALSE, # Turn-off line colors
  common_subtrees_color_branches = TRUE, # Color common branches 
  main = paste("entanglement =", round(entanglement(dend_list), 2))
  )

8 选择合适的聚类数

Elbow Method

fviz_nbclust(data, FUN = hcut, method = "wss")


Average Silhouette Method

fviz_nbclust(data, FUN = hcut, method = "silhouette")


Gap Statistic Method

library(cluster)
gap_stat <- clusGap(data, FUN = hcut, nstart = 25, K.max = 10, B = 50)
fviz_gap_stat(gap_stat)

9 kmeans聚类

kmeans: K-Means Clustering

set.seed(123)
# Data preparation
data("iris")
head(iris)
# Remove species column (5) and scale the data
iris.scaled <- scale(iris[, -5])

# K-means clustering
km.res <- kmeans(iris.scaled, 3, nstart = 10)

# Visualize kmeans clustering
# use repel = TRUE to avoid overplotting
fviz_cluster(km.res, iris[, -5], ellipse.type = "norm")
# Change the color palette and theme
fviz_cluster(km.res, iris[, -5],
   palette = "Set2", ggtheme = theme_minimal())

tree转nwk,plot树形

library(ape)
tree = as.phylo(hclust_vegdist)
plot(tree, type="fan")

可选树形:
“phylogram”, “cladogram”, “fan”, “unrooted”, “radial”

write.tree为nwk

write.tree(phy=tree, file="tree.nwk") 
# 保存为nwk

更多:
R语言:UPGMA聚类分析和树状图
R:层次聚类分析-dist、hclust、heatmap等
R语言鸢尾花iris数据集的层次聚类分析
cmdscale: Classical (Metric) Multidimensional Scaling
cmdscale 经典度量多为测量,也称PCOA,主坐标分析
Cluster with distance threshold in R
Hierarchical Clustering in R: Step-by-Step Example
Hierarchical Clustering in R
Hierarchical Cluster Analysis
推荐:树比较,最佳cluster数计算

你可能感兴趣的:(R: 距离,聚类,建树)