R将树状图切割成最小尺寸的组

R将树状图切割成最小尺寸的组,r,dendrogram,hclust,R,Dendrogram,Hclust,在cut中,是否有一种简单的方法来计算产生给定最小大小分组的h的最小值 在这个例子中,如果我想要每个集群至少有十个成员,我应该选择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

cut
中,是否有一种简单的方法来计算产生给定最小大小分组的
h
的最小值

在这个例子中,如果我想要每个集群至少有十个成员,我应该选择
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
#使用虹膜数据只是为了重现示例
数据(iris)

d这并不能回答问题,但如果您决定在
h
中循环,则可能有助于
成员的提取

从中窃取和修改某些代码


感谢@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

<代码> unNest

此特性可在包中使用<>代码> HeistSyPryk .DrrRoGub//Cuff>函数(加载函数时,它也具有更快的C++实现)。

##未运行:

hc作为旁注:成员是属性-
attr(切割(如树状图(hc),h=3.80)$lower[[1],“成员”)
产生66。感谢您的回答(以及创建Dendestend包,+1)。我已经回滚了您的标记编辑,因为我的问题本身不是[Dendestend]问题,虽然这可能很方便,但[Dendestend]并不是唯一的解决方案。你好@C8H10N4O2。我很高兴你喜欢Dendestend:)(有机会投V票吗。至于删除标签,我看到了你链接到的元数据。在我看来,因为Dendestend是一个用来回答这些问题的包——我更希望当人们看到Dendestend标签时,他们会找到这个解决方案。i、 e:既然这是你的问题,那显然是你的决定。
# 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
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
## 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