tests/testthat/test-AdditionTree.R

test_that("Addition tree is more parsimonious", {
  data("Lobo", package = "TreeTools")
  L10 <- Lobo.phy[1:10]
  seq10 <- names(L10)
  Score <- function (tr, k) TreeLength(tr, Lobo.phy, concavity = k)
  
  set.seed(1) # ensure consistent addition sequence
  eq <- AdditionTree(Lobo.phy)
  kx <- AdditionTree(L10, sequence = seq10, concavity = 10)
  pr <- AdditionTree(L10, sequence = 1:10, concavity = "pr")
  
  skip_if_not_installed("phangorn")
  # Previously used TreeTools::NJTree but since rewriting it's more parsimonious
  # than ape/phangorn.
  nj <- RootTree(ape::nj(phangorn::dist.hamming(Lobo.phy)), 1)
  nj10 <- TreeTools::KeepTip(nj, 1:10)
  
  expect_lt(TreeLength(eq, Lobo.phy), TreeLength(nj, Lobo.phy))
  expect_lt(Score(kx, 10), Score(nj10, 10))
  expect_lt(Score(pr, "pr"), Score(nj10, "pr"))
})

test_that(".ConstraintConstrains() succeeds", {
  expect_false(.ConstraintConstrains(NULL))
  
  # Single level
  expect_false(.ConstraintConstrains(
    structure(list(A = 1L, B = 2L, C = 2L, D = 2L), weight = 1L, nr = 1L,
              nc = 1L, index = 1L, levels = 0, allLevels = c("0", "?"),
              type = "USER", contrast = 
                structure(c(1, 1), dim = 2:1, dimnames = list(NULL, 0)),
              class = "phyDat")
  ))
  
  expect_false(.ConstraintConstrains(
    structure(list(A = 1L, B = 2L, C = 1L, D = 1L, E = 3L), weight = 1L, nr = 1L,
              nc = 2L, index = 1L, levels = 0:1,
              allLevels = c("0", "1", "?"), type = "USER",
              contrast = structure(c(1, 0, 1, 0, 1, 1), dim = 3:2,
                                   dimnames = list(NULL, 0:1)),
              class = "phyDat")
  ))
  expect_true(.ConstraintConstrains(structure(
    list(A = 1L, B = 2L, C = 1L, D = 1L, E = 3L, F = 2L), weight = 1L, nr = 1L,
    nc = 2L, index = 1L, levels = 0:1, allLevels = c("0", "1", "?"),
    type = "USER", contrast = structure(c(1, 0, 1, 0, 1, 1), dim = 3:2,
                                        dimnames = list(NULL, 0:1)),
    class = "phyDat")
  ))
  expect_false(.ConstraintConstrains(structure(
    list(A = 1L, B = 2L, C = 1L, D = 1L, E = 3L, F = 2L), weight = 1L, nr = 1L,
    nc = 2L, index = 1L,
    levels = 0:2, allLevels = c("0", "1", "2", "?"), type = "USER",
    contrast = structure(c(1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1),
                         dim = c(4, 3), dimnames = list(NULL, 0:2)),
    class = "phyDat")
  ))
  expect_true(.ConstraintConstrains(structure(
    list(A = 1L, B = 2L, C = 1L, D = 1L, E = 3L, F = 2L), weight = 1L, nr = 1L,
    nc = 2L, index = 1L, levels = 0:2, allLevels = c("0", "1", "2", "?"),
    type = "USER", contrast = structure(c(1, 0, 1, 1, 0, 1, 0, 1, 1),
                                        dim = c(3, 3), dimnames = list(NULL, 0:2)),
    class = "phyDat")
  ))
})

test_that("Addition tree obeys constraints", {
  dataset <- MatrixToPhyDat(matrix(
    c(0, 1, 1, 1, 0, 1,
      0, 1, 1, 0, 0, 1), ncol = 2,
    dimnames = list(letters[1:6], NULL)))
  constraint <- c(a = 0, b = 0, c = 0, d = 0, e = 1, f = 1)
  # as phyDat
  expect_true(as.Splits(c(F, F, F, F, T, T), letters[1:6]) %in%
              as.Splits(AdditionTree(dataset, constraint = 
                                       MatrixToPhyDat(constraint)),
                        letters[1:6]))
  # as non-phyDat
  expect_true(as.Splits(c(F, F, F, F, T, T), letters[1:6]) %in%
              as.Splits(AdditionTree(dataset, constraint = cbind(constraint)),
                        letters[1:6]))
  
  constraintTree <- TreeTools::BalancedTree(constraint)
  
  set.seed(0)
  unconstrained <- AdditionTree(dataset)
  
  CheckUnconstrained <- function(constraint) {
    set.seed(0)
    expect_equal(AdditionTree(dataset, constraint = constraint), unconstrained)
  }
  
  CheckUnconstrained(KeepTip(constraintTree, c("a", "b")))
  CheckUnconstrained(c(a = 0))
  CheckUnconstrained(KeepTip(constraintTree, "a"))
  CheckUnconstrained(c())
  CheckUnconstrained(KeepTip(constraintTree, character(0)))
  CheckUnconstrained(NULL)
  
  cdef <- letters[3:6]
  subtree <- TreeTools::KeepTip(
    AdditionTree(dataset, constraint = constraint[3:6], seq = letters[1:6]), 
    cdef)
  expect_equal(ape::read.tree(text = "(c, d, (e, f));"),
               TreeTools::UnrootTree(subtree))
})

test_that("AdditionTree() handles edge cases", {
  library("TreeTools", quietly = TRUE)
  dataset <- MatrixToPhyDat(matrix(
    c(0, 1, 1, 1, 0, 1,
      0, 1, 1, 0, 0, 1), ncol = 2,
    dimnames = list(letters[1:6], NULL)))
  expect_equal(PectinateTree(letters[1:3]), AdditionTree(dataset[1:3]))
  expect_equal(UnrootTree(PectinateTree(c("a", "d", "b", "c"))), 
               UnrootTree(AdditionTree(dataset[1:4], conc = "pr")))
  # All trees have equal score
  expect_equal(5, NTip(AdditionTree(dataset[-4])))
})

Try the TreeSearch package in your browser

Any scripts or data that you put into this service are public.

TreeSearch documentation built on April 11, 2025, 5:49 p.m.