diff --git a/DESCRIPTION b/DESCRIPTION index c05e9ec8..b2495948 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: TreeTools Title: Create, Modify and Analyse Phylogenetic Trees -Version: 2.1.0.9000 +Version: 2.1.0.9001 Authors@R: c( person("Martin R.", 'Smith', role = c("aut", "cre", "cph"), email = "martin.smith@durham.ac.uk", diff --git a/NAMESPACE b/NAMESPACE index 3372bf5d..f8ac08b4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -53,6 +53,7 @@ S3method(DropTip,Splits) S3method(DropTip,list) S3method(DropTip,multiPhylo) S3method(DropTip,phylo) +S3method(EdgeRatio,phylo) S3method(KeepTip,"NULL") S3method(KeepTip,Splits) S3method(KeepTip,list) @@ -298,6 +299,7 @@ export(DropTip) export(DropTipPhylo) export(EdgeAncestry) export(EdgeDistances) +export(EdgeRatio) export(EndSentence) export(ExtractTaxa) export(FirstMatchingSplit) diff --git a/NEWS.md b/NEWS.md index 803a0296..dc0d34b2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# TreeTools 2.1.0.9001 (2026-02-19) # + +- `EdgeRatio()` reports the ratio of external:internal edges. + # TreeTools 2.1.0.9000 (2026-02-16) # - `SplitInformation()` supports `Splits` and `phylo` objects. diff --git a/R/EdgeRatio.R b/R/EdgeRatio.R new file mode 100644 index 00000000..bb5edcce --- /dev/null +++ b/R/EdgeRatio.R @@ -0,0 +1,34 @@ +#' Ratio of external:internal edge length +#' +#' Reports the ratio of tree length associated with external edges (i.e. +#' edges whose child is a leaf) and internal edges. +#' Where tree length is dominated by internal edges, variation between tips +#' is dominantly controlled by phylogenetic history. +#' +#' @param x A tree of class \code{\link[ape:read.tree]{phylo}}. +#' @returns `EdgeRatio()` returns a numeric specifying the ratio of external +#' to internal edge length (> 1 means the length of a tree is predominantly +#' in external edges), with attributes `external`, `internal`, and `total` +#' specifying the total length associated with edges of that nature. +#' @template MRS +#' @export +EdgeRatio <- function(x) UseMethod("EdgeRatio") + +#' @rdname EdgeRatio +#' @export +EdgeRatio.phylo <- function(x) { + el <- x[["edge.length"]] + if (is.null(el)) { + warning("Edge lengths not specified") + return(NA_real_) + } + ed <- x[["edge"]] + nTip <- NTip(x) + external <- ed[, 2] <= nTip + exLen <- sum(el[external]) + inLen <- sum(el[!external]) + structure(exLen / inLen, + external = exLen, + internal = inLen, + total = sum(exLen, inLen)) +} diff --git a/man/EdgeRatio.Rd b/man/EdgeRatio.Rd new file mode 100644 index 00000000..6a2f2760 --- /dev/null +++ b/man/EdgeRatio.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/EdgeRatio.R +\name{EdgeRatio} +\alias{EdgeRatio} +\alias{EdgeRatio.phylo} +\title{Ratio of external:internal edge length} +\usage{ +EdgeRatio(x) + +\method{EdgeRatio}{phylo}(x) +} +\arguments{ +\item{x}{A tree of class \code{\link[ape:read.tree]{phylo}}.} +} +\value{ +\code{EdgeRatio()} returns a numeric specifying the ratio of external +to internal edge length (> 1 means the length of a tree is predominantly +in external edges), with attributes \code{external}, \code{internal}, and \code{total} +specifying the total length associated with edges of that nature. +} +\description{ +Reports the ratio of tree length associated with external edges (i.e. +edges whose child is a leaf) and internal edges. +Where tree length is dominated by internal edges, variation between tips +is dominantly controlled by phylogenetic history. +} +\author{ +\href{https://orcid.org/0000-0001-5660-1727}{Martin R. Smith} +(\href{mailto:martin.smith@durham.ac.uk}{martin.smith@durham.ac.uk}) +} diff --git a/tests/testthat/test-EdgeRatio.R b/tests/testthat/test-EdgeRatio.R new file mode 100644 index 00000000..95bec1f6 --- /dev/null +++ b/tests/testthat/test-EdgeRatio.R @@ -0,0 +1,9 @@ +test_that("EdgeRatio() works", { + expect_warning(expect_equal(EdgeRatio(BalancedTree(5)), NA_real_), + "[Ee]dge lengths not spec") + + ex2 <- BalancedTree(4) + ex2[["edge.length"]] <- c(1, 2, 2, 1, 2, 2) + expect_equal(EdgeRatio(ex2), + structure(8/2, external = 8, internal = 2, total = 10)) +})