| # File src/library/stats/R/cutree.R |
| # Part of the R package, https://www.R-project.org |
| # |
| # Copyright (C) 1995-2012 The R Core Team |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # A copy of the GNU General Public License is available at |
| # https://www.R-project.org/Licenses/ |
| |
| cutree <- function(tree, k=NULL, h=NULL) |
| { |
| if(is.null(n1 <- nrow(tree$merge)) || n1 < 1) |
| stop("invalid 'tree' ('merge' component)") |
| n <- n1 + 1 |
| if(is.null(k) && is.null(h)) |
| stop("either 'k' or 'h' must be specified") |
| if(is.null(k)) { |
| if(is.unsorted(tree$height)) |
| stop("the 'height' component of 'tree' is not sorted (increasingly)") |
| ## h |--> k |
| ## S+6 help(cutree) says k(h) = k(h+), but does k(h-) [continuity] |
| ## h < min() should give k = n; |
| k <- n+1L - apply(outer(c(tree$height,Inf), h, ">"), 2, which.max) |
| if(getOption("verbose")) message("cutree(): k(h) = ", k, domain = NA) |
| } |
| else { |
| k <- as.integer(k) |
| if(min(k) < 1 || max(k) > n) |
| stop(gettextf("elements of 'k' must be between 1 and %d", n), |
| domain = NA) |
| } |
| |
| ans <- .Call(C_cutree, tree$merge, k) |
| |
| if(length(k) == 1L) { |
| ans <- setNames(as.vector(ans), tree$labels) |
| } |
| else{ |
| colnames(ans) <- if(!is.null(h)) h else k |
| rownames(ans) <- tree$labels |
| } |
| return(ans) |
| } |