R:我可以 'set' 我的树状图和使用 dendextend 的 for 循环吗?
R: Can I 'set' my dendrogram with a for loop using dendextend?
以 iris
数据集为例,我按以下方式使用 dendextend
进行 Pearson 聚类:
library(RColorBrewer)
library(dendextend)
data(iris)
newmat <- iris[,1:4]
rownames(newmat) <- paste(iris$Species, rownames(iris))
dmat <- 1 - cor(t(newmat), method="pearson")
dmat <- as.dist(dmat)
clust.obj <- hclust(dmat, method="complete")
dend.obj <- as.dendrogram(clust.obj)
numsamples <- length(rownames(newmat))
maxdist <- max(get_nodes_attr(dend.obj, "height"))
groups <- levels(iris$Species)
cols <- colorRampPalette(brewer.pal(length(groups), "Set1"))
myPal <- cols(length(groups))
vals1 <- grep(groups[1], labels(dend.obj), value=TRUE)
vals2 <- grep(groups[2], labels(dend.obj), value=TRUE)
vals3 <- grep(groups[3], labels(dend.obj), value=TRUE)
vals1B <- grepl(groups[1], labels(dend.obj))
vals2B <- grepl(groups[2], labels(dend.obj))
vals3B <- grepl(groups[3], labels(dend.obj))
dend.obj <- dend.obj %>%
set("leaves_pch", 19) %>%
set("leaves_cex", 1) %>%
set("branches_lty", 2) %>%
set("by_labels_branches_col", value = vals1, TF_values = c(myPal[1],Inf)) %>%
set("by_labels_branches_lwd", value = vals1, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals1, TF_values = c(1,Inf)) %>%
set("by_labels_branches_col", value = vals2, TF_values = c(myPal[2],Inf)) %>%
set("by_labels_branches_lwd", value = vals2, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals2, TF_values = c(1,Inf)) %>%
set("by_labels_branches_col", value = vals3, TF_values = c(myPal[3],Inf)) %>%
set("by_labels_branches_lwd", value = vals3, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals3, TF_values = c(1,Inf)) %>%
set("labels_colors", ifelse(vals1B, myPal[1], ifelse(vals2B, myPal[2], myPal[3]))) %>%
set("leaves_col", ifelse(vals1B, myPal[1], ifelse(vals2B, myPal[2], myPal[3])))
png(filename="test.png", height=1200, width=400)
mar.default <- c(5,4,4,2) + 0.1
par(mar = mar.default + c(0, 0, 0, 4))
plot(dend.obj, main="test cluster", xlab="Distance", horiz=TRUE, cex.main=1, cex.axis=1, cex.lab=1)
legend(maxdist, numsamples, groups, cex=1, pch=19, col=myPal)
dev.off()
它产生了这个簇,我发现它对颜色和所有东西都非常有用:
问题是现在我想把它封装成一个函数。 groups
的长度可以变化。所以我需要在 for
循环或其他内容中执行 dend.obj
的 set
部分。
类似于:
for (i in 1:length(groups)){
set("by_labels_branches_col", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(myPal[i],Inf)) %>%
set("by_labels_branches_lwd", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(2,Inf)) %>%
set("by_labels_branches_lty", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(1,Inf))
}
这显然是行不通的...其中的 ifelse
也是如此,这真的很棘手。
如有任何帮助,我们将不胜感激!我不知道如何解决这个问题。谢谢!
好吧,如果有人感兴趣,我最后所做的似乎工作正常,就是执行 for
循环并将命令存储在 execval
变量中,然后 运行 该变量具有:
eval(parse(text=execval))
以 iris
数据集为例,我按以下方式使用 dendextend
进行 Pearson 聚类:
library(RColorBrewer)
library(dendextend)
data(iris)
newmat <- iris[,1:4]
rownames(newmat) <- paste(iris$Species, rownames(iris))
dmat <- 1 - cor(t(newmat), method="pearson")
dmat <- as.dist(dmat)
clust.obj <- hclust(dmat, method="complete")
dend.obj <- as.dendrogram(clust.obj)
numsamples <- length(rownames(newmat))
maxdist <- max(get_nodes_attr(dend.obj, "height"))
groups <- levels(iris$Species)
cols <- colorRampPalette(brewer.pal(length(groups), "Set1"))
myPal <- cols(length(groups))
vals1 <- grep(groups[1], labels(dend.obj), value=TRUE)
vals2 <- grep(groups[2], labels(dend.obj), value=TRUE)
vals3 <- grep(groups[3], labels(dend.obj), value=TRUE)
vals1B <- grepl(groups[1], labels(dend.obj))
vals2B <- grepl(groups[2], labels(dend.obj))
vals3B <- grepl(groups[3], labels(dend.obj))
dend.obj <- dend.obj %>%
set("leaves_pch", 19) %>%
set("leaves_cex", 1) %>%
set("branches_lty", 2) %>%
set("by_labels_branches_col", value = vals1, TF_values = c(myPal[1],Inf)) %>%
set("by_labels_branches_lwd", value = vals1, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals1, TF_values = c(1,Inf)) %>%
set("by_labels_branches_col", value = vals2, TF_values = c(myPal[2],Inf)) %>%
set("by_labels_branches_lwd", value = vals2, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals2, TF_values = c(1,Inf)) %>%
set("by_labels_branches_col", value = vals3, TF_values = c(myPal[3],Inf)) %>%
set("by_labels_branches_lwd", value = vals3, TF_values = c(2,Inf)) %>%
set("by_labels_branches_lty", value = vals3, TF_values = c(1,Inf)) %>%
set("labels_colors", ifelse(vals1B, myPal[1], ifelse(vals2B, myPal[2], myPal[3]))) %>%
set("leaves_col", ifelse(vals1B, myPal[1], ifelse(vals2B, myPal[2], myPal[3])))
png(filename="test.png", height=1200, width=400)
mar.default <- c(5,4,4,2) + 0.1
par(mar = mar.default + c(0, 0, 0, 4))
plot(dend.obj, main="test cluster", xlab="Distance", horiz=TRUE, cex.main=1, cex.axis=1, cex.lab=1)
legend(maxdist, numsamples, groups, cex=1, pch=19, col=myPal)
dev.off()
它产生了这个簇,我发现它对颜色和所有东西都非常有用:
问题是现在我想把它封装成一个函数。 groups
的长度可以变化。所以我需要在 for
循环或其他内容中执行 dend.obj
的 set
部分。
类似于:
for (i in 1:length(groups)){
set("by_labels_branches_col", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(myPal[i],Inf)) %>%
set("by_labels_branches_lwd", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(2,Inf)) %>%
set("by_labels_branches_lty", value=grep(groups[i],labels(dend.obj),value=TRUE), TF_values=c(1,Inf))
}
这显然是行不通的...其中的 ifelse
也是如此,这真的很棘手。
如有任何帮助,我们将不胜感激!我不知道如何解决这个问题。谢谢!
好吧,如果有人感兴趣,我最后所做的似乎工作正常,就是执行 for
循环并将命令存储在 execval
变量中,然后 运行 该变量具有:
eval(parse(text=execval))