X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=R%2FrTrait.R;h=1b5852d102024a01a9a1a312643e82f57f9c0d76;hb=HEAD;hp=8cc48e17c9e45296c082b33ca33f29e01c3f3296;hpb=06c3113db74a7cfa54c15a6f18163cd9b2c1f6db;p=ape.git diff --git a/R/rTrait.R b/R/rTrait.R index 8cc48e1..1b5852d 100644 --- a/R/rTrait.R +++ b/R/rTrait.R @@ -1,8 +1,8 @@ -## rTrait.R (2010-05-06) +## rTrait.R (2012-02-09) ## Trait Evolution -## Copyright 2010 Emmanuel Paradis +## Copyright 2010-2012 Emmanuel Paradis ## This file is part of the R-package `ape'. ## See the file ../COPYING for licensing issues. @@ -10,7 +10,7 @@ rTraitDisc <- function(phy, model = "ER", k = if (is.matrix(model)) ncol(model) else 2, rate = 0.1, states = LETTERS[1:k], freq = rep(1/k, k), - ancestor = FALSE, root.value = 1) + ancestor = FALSE, root.value = 1, ...) { if (is.null(phy$edge.length)) stop("tree has no branch length") @@ -18,7 +18,7 @@ rTraitDisc <- stop("at least one branch length negative") if (is.character(model)) { - switch(model, "ER" = { + switch(toupper(model), "ER" = { if (length(rate) != 1) stop("`rate' must have one element") Q <- matrix(rate, k, k) @@ -56,7 +56,7 @@ rTraitDisc <- if (is.function(model)) { environment(model) <- environment() # to find 'k' - for (i in N:1) x[des[i]] <- model(x[anc[i]], el[i]) + for (i in N:1) x[des[i]] <- model(x[anc[i]], el[i], ...) } else { freq <- rep(freq, each = k) Q <- Q * freq @@ -64,7 +64,7 @@ rTraitDisc <- diag(Q) <- -rowSums(Q) for (i in N:1) { p <- matexpo(Q * el[i])[x[anc[i]], ] - x[des[i]] <- .Internal(sample(k, size = 1, FALSE, prob = p)) + x[des[i]] <- sample.int(k, size = 1, FALSE, prob = p) } } @@ -81,8 +81,8 @@ rTraitDisc <- } rTraitCont <- - function(phy, model = "BM", sigma = 0.1, alpha = 1, - theta = 0, ancestor = FALSE, root.value = 0) + function(phy, model = "BM", sigma = 0.1, alpha = 1, theta = 0, + ancestor = FALSE, root.value = 0, ...) { if (is.null(phy$edge.length)) stop("tree has no branch length") @@ -102,9 +102,9 @@ rTraitCont <- if (is.function(model)) { environment(model) <- environment() - for (i in N:1) x[des[i]] <- model(x[anc[i]], el[i]) + for (i in N:1) x[des[i]] <- model(x[anc[i]], el[i], ...) } else { - model <- pmatch(model, c("BM", "OU")) + model <- pmatch(toupper(model), c("BM", "OU")) if (length(sigma) == 1) sigma <- rep(sigma, N) else if (length(sigma) != N) stop("'sigma' must have one or Nedge(phy) elements") @@ -116,7 +116,10 @@ rTraitCont <- else if (length(theta) != N) stop("'theta' must have one or Nedge(phy) elements") } - .C("rTraitCont", as.integer(model), as.integer(N), as.integer(anc - 1L), as.integer(des - 1L), el, sigma, alpha, theta, x, DUP = FALSE, NAOK = TRUE, PACKAGE = "ape") + .C("rTraitCont", as.integer(model), as.integer(N), + as.integer(anc - 1L), as.integer(des - 1L), el, + as.double(sigma), as.double(alpha), as.double(theta), x, + DUP = FALSE, NAOK = TRUE, PACKAGE = "ape") } if (ancestor) { @@ -128,3 +131,44 @@ rTraitCont <- } x } + +rTraitMult <- + function(phy, model, p = 1, root.value = rep(0, p), ancestor = FALSE, + asFactor = NULL, trait.labels = paste("x", 1:p, sep = ""), ...) +{ + phy <- reorder(phy, "pruningwise") + n <- length(phy$tip.label) + m <- phy$Nnode + N <- dim(phy$edge)[1] + ROOT <- n + 1L + + x <- matrix(0, n + m, p) + x[ROOT, ] <- root.value + + anc <- phy$edge[, 1] + des <- phy$edge[, 2] + + el <- phy$edge.length + if (is.null(el)) el <- numeric(N) + + environment(model) <- environment() # to find 'p' + + for (i in N:1) x[des[i], ] <- model(x[anc[i], ], el[i], ...) + + if (ancestor) { + if (is.null(phy$node.label)) phy <- makeNodeLabel(phy) + rownames(x) <- c(phy$tip.label, phy$node.label) + } else { + x <- x[1:n, , drop = FALSE] + rownames(x) <- phy$tip.label + } + x <- as.data.frame(x) + names(x) <- trait.labels + if (!is.null(asFactor)) { + for (i in asFactor) { + y <- x[, i] + x[, i] <- factor(y, labels = LETTERS[1:length(unique(y))]) + } + } + x +}