Provides one-command and method-specific workflows for
phylogenetic signal in continuous, binary, and categorical traits. Compiled
tree-pruning algorithms implement Blomberg's K and Pagel's lambda without
constructing a dense phylogenetic covariance matrix in production.
Fritz and Purvis D retains separate random and Brownian null models, while
categorical Delta combines discrete ancestral-state likelihoods with MCMC
and permutation diagnostics. The package also provides reusable prepared
trees, explicit tree/data matching, trait-wise missing-value handling,
conservative tree diagnostics, bounded simulation memory, and structured
timing and Monte Carlo uncertainty metadata. Clade scans describe local
and overall signal in continuous, binary and multistate traits, with
optional model-reference tests of signal dispersion or deviation. Methods
follow Blomberg, Garland and Ives (2003)
Fast phylogenetic signal analysis for continuous, binary and multistate traits in R. Use fast_signal() to select K, lambda, D or Delta, and fast_hetero() to compare clade-level signal and map patterns of phylogenetic conservatism. C++ kernels, batch input and reusable tree contexts support large trees and repeated analyses.
With optimized C++ kernels, fastphylosig is up to 23,591 times faster than standard implementations such as phytools and caper (lambda on a 2,000-species tree, compared with phytools), and is particularly suited to large phylogenetic trees with more than 10,000 tips.
Website · 中文指南 · fast_hetero case study
Current release: 0.3.5. This patch corrects ARD full-tree ancestral probabilities and ER/ARD ACE rate standard errors. See the patch notes and reanalysis guidance for affected outputs.
Requires R ≥ 4.1.0 and a C++ toolchain, such as Rtools matching your R version on Windows. OpenMP is optional. The release passed CI on Linux, Windows and macOS, including a build without OpenMP.
# Install dependencies on first use
install.packages(c("ape", "Rcpp", "RcppArmadillo"))
install.packages(
"https://github.com/yinwen-ecology/fastphylosig/releases/download/v0.3.5/fastphylosig_0.3.5.tar.gz",
repos = NULL, type = "source"
)
library(fastphylosig)
# Alternatively, install the fixed release tag
# install.packages("remotes")
# remotes::install_github("yinwen-ecology/[email protected]")
Provide a phylo tree and named trait data, then select the method explicitly:
set.seed(1)
tree <- ape::rtree(30)
trait <- setNames(stats::rnorm(30), tree$tip.label)
fit <- fast_signal(tree, data = trait, method = "K", progress = FALSE)
summary(fit)
fast_signal() checks the tree, matches species and handles missing values per trait before running the selected method.
| Method | Selector | Traits | Estimates and tests |
|---|---|---|---|
| Blomberg's K | "K" |
Continuous | K; optional tip-randomization test |
| Pagel's lambda | "lambda" |
Continuous | ML estimate; optional likelihood-ratio test against lambda = 0 |
| Fritz–Purvis D | "D" |
Binary | D; random-association and Brownian-threshold null tests |
| Delta | "Delta" |
Multistate categorical | Delta, MCMC diagnostics; optional tip-randomization test |
Inspect results with print(), summary() or as.data.frame(). Plotting requires the corresponding saved simulations or likelihood profile, as shown below.
For explicit preparation and reusable tree calculations:
checked <- check_tree(tree, signal = "K") # Read-only inspection
tree_ready <- resolve_tree(tree, signal = "K") # Edge order and node numbering
matched <- match_tree_data(tree_ready, data = trait)
ctx <- prepare_tree(matched$tree)
| Function | Main controls |
|---|---|
fast_k() |
Custom permutations, block processing and null retention |
fast_lambda() |
Likelihood profiles and approximate confidence intervals |
fast_d() |
Random/Brownian state inputs and null retention |
fast_delta() |
Multivariate traits; ER/ARD models, MCMC chain length and sampling controls (mcmc_sim, thin, burn), and convergence diagnostics |
fast_ace() |
Discrete ancestral-state ML estimates and rate standard errors |
fit_k <- fast_k(ctx, x = matched$data, test = TRUE, nsim = 999,
return_sim = TRUE, progress = FALSE)
fit_lambda <- fast_lambda(ctx, trait, test = TRUE,
lambda_profile = TRUE, progress = FALSE)
binary <- setNames(as.integer(trait > stats::median(trait)), names(trait))
fit_d <- fast_d(ctx, binary, nsim = 999,
return_sim = TRUE, keep_null = TRUE, progress = FALSE)
# Delta: for multivariate, discrete traits
categorical <- setNames(rep(c("a", "b", "c"), length.out = length(trait)),
names(trait))
fit_delta <- fast_delta(ctx, categorical, test = TRUE, nsim = 99,
mcmc_sim = 10000, thin = 10, burn = 100,
return_sim = TRUE, progress = FALSE)
fast_delta() defaults to ARD; the clade example below explicitly selects ER. Choose models and simulation budgets for the study design. The 99 permutations above are a quick demonstration.
For repeated analyses, pass multiple traits as a matrix/data frame and reuse ctx. Prepared contexts support saveRDS()/readRDS(); prepare them again after changing the source tree.

On 2,000-species trees, observed median reference/fastphylosig runtime ratios were 135–151× for K, 20,697–23,591× for lambda and 218–224× for D. Tree/data preparation is excluded; each scenario has 10 matched pairs. Gains depend on the workload, and small-tree K can be slower than phytools.
Delta returned-call ratios were 23.9–33.6×, with numerical warnings in 112/120 reference calls and one fast fit reaching an optimizer limit. These timings do not establish equal accuracy or convergence. See benchmark settings, raw records and diagnostics.
fast_hetero() selects maximal disjoint crowns within size bounds, or accepts explicit internal nodes. It reports local estimates, sample sizes, missingness, categorical state composition and coverage, with optional whole-tree signal and reference tests of clade dispersion.
This separate 256-species example provides several crowns within the requested 50–100-tip range:
set.seed(2)
tree_h <- ape::stree(256, type = "balanced")
tree_h$edge.length <- rep(1, nrow(tree_h$edge))
trait_h <- ape::rTraitCont(tree_h)
binary_h <- ape::rTraitDisc(tree_h, model = "ER", k = 2, rate = 0.15)
categorical_h <- ape::rTraitDisc(tree_h, model = "ER", k = 3, rate = 0.15)
h <- fast_hetero(
tree_h, trait_h, method = "K", min_tips = 50, max_tips = 100,
test = TRUE, nsim = 999, overall_test = TRUE, progress = FALSE
)
h$clades # Local estimates, sample sizes and diagnostics
h$heterogeneity # Dispersion and reference test
h$overall # Whole-tree estimate and ordinary signal test
h$selection$coverage
nodes <- h$selection$nodes # Reuse the same crowns across methods
plot(h, tree = tree_h, node_labels = TRUE)
plot(h, tree = tree_h, type = "fan")
hl <- fast_hetero(tree_h, trait_h, method = "lambda", nodes = nodes,
min_tips = 50, test = TRUE, nsim = 999,
overall_test = TRUE, progress = FALSE)
hd <- fast_hetero(tree_h, binary_h, method = "D", nodes = nodes,
min_tips = 50, test = FALSE, d_nsim = 1000,
overall_test = TRUE, progress = FALSE)
hdelta <- fast_hetero(tree_h, categorical_h, method = "Delta", nodes = nodes,
min_tips = 50, test = FALSE, overall = TRUE,
delta_control = list(model = "ER"), progress = FALSE)
hdelta$clades[, c("node", "estimate", "n_states", "log_ratio_overall")]
hdelta$clades$state_counts
plot(hdelta, tree = tree_h)
nodes for prespecified biological groups, or size bounds for an automatic scan. Inspect coverage, sample sizes and crown ages. Explicit nodes override automatic size selection; min_tips still applies after NA removal.overall = TRUE adds the whole-tree estimate; overall_test = TRUE adds its ordinary signal test; clade_test = TRUE adds ordinary tests for each crown. These are separate from the heterogeneity reference enabled by test = TRUE. overall_nsim/clade_nsim control K/Delta ordinary tests; D uses d_nsim.show_summary = FALSE hides them. Plotting does not rerun tests. Select trait = "column_name" for a multi-trait result.| Method | Dispersion summary | Heterogeneity reference and current use |
|---|---|---|
| K | SD(log K) |
BM reference; P_BM and its common alias P_heterogeneity. Shaded envelopes are BM reference ranges. |
| lambda | SD(lambda) |
Approximate common-local-crown Gaussian reference, using pooled REML by default. Interpret alongside crown age and cut scale. |
| D | SD(D) |
Local/overall description recommended; shared symmetric ER inference conditional on crown state counts remains experimental (test = TRUE). |
| Delta | SD(log Delta), local/overall log ratios and RMS |
Local/overall description and diagnostics recommended; heterogeneity tests remain experimental research interfaces. |
Local differences describe conservatism patterns at the analysed scale. Ordinary signal P values and heterogeneity P values answer different questions; one significant and one nonsignificant signal P value do not establish a clade difference.
Heterogeneity tests require at least two non-overlapping crowns. Nested nodes support descriptive scans with test = FALSE. Single-state D/Delta crowns remain unavailable rather than being assigned zero. Retain failures and fit/MCMC diagnostics with the estimates.
The worked case study includes downloadable data, results and R code. See the fast_hetero workflow and method notes (Chinese) for additional detail.
resolve_tree() normalizes edge order and node numbering; root/outgroup choice remains with the user.se = NULL).| K permutation null (example) | Lambda likelihood profile (example) |
|---|---|
![]() |
![]() |
plot_signal(fit_k)
plot_signal(fit_lambda)
plot_signal(fit_d)
plot_signal(fit_delta)
K and Delta plots use saved randomization distributions; D overlays both null distributions; lambda displays its likelihood profile and approximate interval. For null plots, set test = TRUE, return_sim = TRUE; D also requires keep_null = TRUE. Lambda uses lambda_profile = TRUE.
mean(beta / alpha). Inspect ESS_Delta, split_Rhat_Delta, MCSE_Delta and available rank diagnostics, plus successful permutations and MCSE_P when testing. Defaults are ARD, mcmc_sim = 10000, thin = 10, burn = 100, test = FALSE.test = FALSE. Results include MCSE_P_random and MCSE_P_Brownian. In fast_hetero(), d_nsim controls this standardization and nsim controls optional heterogeneity simulation.progress = FALSE silences progress/matching messages while retaining statistical warnings and timing metadata.ncores. Fix seeds, controls, explicit simulation inputs (if supplied) and ncores. Changing Delta worker count can change random-stream allocation.options(fastphylosig.ace_threads = 1L) forces serial evaluation; 0L restores automatic selection. This setting does not reallocate random streams.