是否有一种简单的方法可以计算h
中产生给定最小尺寸分组的cut
的最低值?
在这个例子中,如果我想要每个至少有十个成员的集群,我应该使用h = 3.80
:
# using iris data simply for reproducible example
data(iris)
d <- data.frame(scale(iris[,1:4]))
hc <- hclust(dist(d))
plot(hc)
cut(as.dendrogram(hc), h=3.79) # produces 5 groups; group 4 has 7 members
cut(as.dendrogram(hc), h=3.80) # produces 4 groups; no group has <10 members
由于分割的高度在hc$height
中给出,我可以使用hc$height + 0.00001
创建一组候选值,然后在每个值中循环切割。但是,我不知道如何从members
类解析群集大小dendrogram
。例如,cut(as.dendrogram(hc), h=3.80)$lower[[1]]$members
会根据需要返回NULL
,而不是66。
请注意,这是一个比Cutting dendrogram into n trees with minimum cluster size in R使用包dynamicTreeCut
更简单的问题;这里我没有指定树的数量,只是最小的簇大小。 TYVM。
答案 0 :(得分:3)
感谢@Vlo和@lukeA,我能够实现一个循环。但是,我只是将其作为起点发布,并且肯定会向更优雅的解决方案开放。
unnest <- function(x) { # from Vlo's answer
if(is.null(names(x))) x
else c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest)))
}
cuts <- hc$height + 1e-9
min_size <- 10
smallest <- 0
i <- 0
while(smallest < min_size & i <= length(cuts)){
h_i <- cuts[i <- i+1]
if(i > length(cuts)){
warning("Couldn't find a cluster big enough.")
}
else smallest <-
Reduce(min,
lapply(X = unnest(cut(as.dendrogram(hc), h=h_i)$lower),
FUN = attr, which = "members") ) # from lukeA's comment
}
h_i # returns desired output: [1] 3.79211
答案 1 :(得分:2)
此功能在dendextend包中提供heights_per_k.dendrogram
函数(在加载dendextendRcpp函数时也具有更快的C ++实现)。
## Not run:
hc <- hclust(dist(USArrests[1:4,]), "ave")
dend <- as.dendrogram(hc)
heights_per_k.dendrogram(dend)
## 1 2 3 4
##86.47086 68.84745 45.98871 28.36531
作为旁注,dendextend包有一个cutree.dendrogram
S3方法用于树状图(与hclust对象的cutree非常相似)。
答案 2 :(得分:1)
这不能回答这个问题,但如果您决定循环使用members
,则可能对h
提取有用。
窃取并修改here
中的某些代码# Unnest the list/dendogram structure
unnest <- function(x) {
if(is.null(names(x))) {
x
}
else {
c(list(all=unname(unlist(x))), do.call(c, lapply(x, unnest)))
}
}
# Extract the `members` attribute from each dendogram
lapply(X = unnest(cut(as.dendrogram(hc), h=3.8)), FUN = attr, which = "members")
输出:
# Please don't ask me why there are 2 dendograms stored
# in the `$upper` list while `print` displays one
$upper1
[1] 2
$upper2
[1] 2
$lower1
[1] 66
$lower2
[1] 11
$lower3
[1] 24
$lower4
[1] 49