File: ladderize.R

package info (click to toggle)
r-cran-ape 5.8-1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,676 kB
  • sloc: ansic: 7,676; cpp: 116; sh: 17; makefile: 2
file content (63 lines) | stat: -rw-r--r-- 1,763 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
## ladderize.R (2023-02-09)

##   Ladderize a Tree

## Copyright 2007-2023 Emmanuel Paradis, 2022 Klaus Schliep

## This file is part of the R-package `ape'.
## See the file ../COPYING for licensing issues.

ladderize <- function(phy, right = TRUE)
{
    desc_fun <- function(x) {
        parent <- x[, 1]
        children <- x[, 2]
        res <- vector("list", max(x))
        for (i in seq_along(parent))
            res[[parent[i]]] <- c(res[[parent[i]]], children[i])
        res
    }

    if (!is.null(phy$edge.length)) {
        el <- numeric(max(phy$edge))
        el[phy$edge[, 2]] <- phy$edge.length
    }

    nb.tip <- length(phy$tip.label)
    nb.node <- phy$Nnode
    nb.edge <- dim(phy$edge)[1]

    phy <- reorder(phy, "postorder")
    N <- .C(node_depth, as.integer(nb.tip),
            as.integer(phy$edge[, 1]), as.integer(phy$edge[, 2]),
            as.integer(nb.edge), double(nb.tip + nb.node), 1L)[[5]]

    ii <- order(x <- phy$edge[, 1], y <- N[phy$edge[, 2]], decreasing = right)
    desc <- desc_fun(phy$edge[ii, ])

    tmp <- integer(nb.node)
    new_anc <- integer(nb.node)
    new_anc[1] <- tmp[1] <- nb.tip + 1L
    k <- nb.node
    pos <- 1L

    while (pos > 0L && k > 0) {
        current <- tmp[pos]
        new_anc[k] <- current
        k <- k - 1L
        dc <- desc[[current]]
        ind <- dc > nb.tip
        if (any(ind)) {
            l <- sum(ind)
            tmp[pos -1L + seq_len(l)] <-  dc[ind]
            pos <- pos + l - 1L
        } else {
            pos <- pos - 1L
        }
    }
    edge <- cbind(rep(new_anc, lengths(desc[new_anc])), unlist(desc[new_anc]))
    phy$edge <- edge
    if (!is.null(phy$edge.length)) phy$edge.length <- el[edge[, 2L]]
    attr(phy, "order") <- "postorder"
    reorder(phy)
}