├── .covrignore ├── tests ├── testthat.R └── testthat │ ├── test-spt.R │ ├── test-conversion.R │ ├── test-r8s.R │ ├── test-treeqza.R │ ├── test-merge-tree.R │ ├── test-phyloxml.R │ ├── test-jtree.R │ ├── test-utilities.R │ ├── test-parser.R │ ├── test-as-phylo.R │ ├── test-jplace.R │ ├── test-treedata-accessor.R │ └── test-beast.R ├── man ├── figures │ └── logo.png ├── read.iqtree.Rd ├── is.ggtree.Rd ├── get.tree.Rd ├── merge_tree.Rd ├── read.mega_tabular.Rd ├── read.phylip.tree.Rd ├── treetime.Rd ├── print.treedataList.Rd ├── read-jtree.Rd ├── raxml2nwk.Rd ├── get.treetext-methods.Rd ├── read.r8s.Rd ├── read.jplace.Rd ├── getNodeNum.Rd ├── rescale_tree.Rd ├── read.nhx.Rd ├── read.phylip.Rd ├── write-jtree.Rd ├── read.codeml_mlc.Rd ├── read.newick.Rd ├── label_branch_paml.Rd ├── read.phylip.seq.Rd ├── read.raxml.Rd ├── get-placements.Rd ├── read.hyphy.seq.Rd ├── mask.Rd ├── write.jplace.Rd ├── as.treedata.Rd ├── read.nextstrain.json.Rd ├── read.fasta.Rd ├── read.phyloxml.Rd ├── read.paml_rst.Rd ├── read.astral.Rd ├── read.codeml.Rd ├── read.mcmctree.Rd ├── read.hyphy.Rd ├── rename_taxa.Rd ├── jplace-class.Rd ├── write.beast.Rd ├── read.treeqza.Rd ├── spt-methods.Rd ├── write.beast.newick.Rd ├── beast-parser.Rd ├── treeio-package.Rd ├── find.hclust.Rd └── reexports.Rd ├── inst ├── extdata │ ├── qiime2treeqza │ │ ├── iqt-tree.qza │ │ ├── fasttree-tree.qza │ │ ├── raxml-cat-tree.qza │ │ └── raxml-cat-bootstrap-tree.qza │ ├── sample.nwk │ ├── MEGA7 │ │ ├── mtCDNA_timetree.nwk │ │ ├── mtCDNA_timetree_tabular.txt │ │ └── mtCDNA_timetree.nex │ ├── NHX │ │ ├── ADH.nhx │ │ ├── phyldog.nhx │ │ └── notung.nhx │ ├── pa.nwk │ ├── HYPHY │ │ └── labelledtree.tree │ ├── pa_subs.csv │ ├── sample.jplace │ ├── phyloxml │ │ └── test_x2.xml │ ├── r8s │ │ └── H3.tree │ ├── RAxML │ │ ├── RAxML_bestTree.H3 │ │ ├── RAxML_bipartitions.H3 │ │ └── RAxML_bipartitionsBranchLabels.H3 │ ├── ref35extend.jplace │ └── MCMCTree │ │ └── mcmctree_output.tree └── CITATION ├── R ├── treeio-package.R ├── zzz.R ├── print.R ├── raxml2nwk.R ├── ape.R ├── treetime.R ├── iqtree.R ├── newick.R ├── AllGenerics.R ├── r8s.R ├── codeml_mlc.R ├── AllClasses.R ├── paml_rst.R ├── RAxML.R ├── mega.R ├── ASTRAL.R ├── codeml.R ├── rename.R ├── treeqza.R ├── reexport.R ├── rescale_tree.R ├── reroot-utilities.R ├── mask.R ├── write-jplace.R ├── MCMCTree.R ├── jtree.R ├── phylip.R ├── tree-utilities.R ├── merge_tree.R ├── nextstrain.json.R ├── sequence-utilities.R ├── phangorn.R ├── nhx.R ├── method-spt.R ├── utilities.R ├── hyphy.R ├── jplace.R └── phyloxml.R ├── .gitignore ├── .svnignore ├── .Rbuildignore ├── treeio.Rproj ├── .travis.yml ├── vignettes └── treeio.Rmd ├── .github ├── issue_template.md ├── pull_request_template.md └── CONTRIBUTING.md ├── appveyor.yml ├── CONTRIBUTORS.md ├── CONDUCT.md ├── Makefile ├── DESCRIPTION ├── README.Rmd ├── README.md └── NAMESPACE /.covrignore: -------------------------------------------------------------------------------- 1 | R/defunct.R 2 | *defunct.R 3 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(treeio) 3 | 4 | test_check("treeio") 5 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuLab-SMU/treeio/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /inst/extdata/qiime2treeqza/iqt-tree.qza: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuLab-SMU/treeio/HEAD/inst/extdata/qiime2treeqza/iqt-tree.qza -------------------------------------------------------------------------------- /R/treeio-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | ## usethis namespace: start 5 | ## usethis namespace: end 6 | NULL 7 | -------------------------------------------------------------------------------- /inst/extdata/sample.nwk: -------------------------------------------------------------------------------- 1 | (((((((A:4,B:4):6,C:5):8,D:6):3,E:21):10,((F:4,G:12):14,H:8):13):13,((I:5,J:2):30,(K:11,L:11):2):17):4,M:56); 2 | -------------------------------------------------------------------------------- /inst/extdata/qiime2treeqza/fasttree-tree.qza: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuLab-SMU/treeio/HEAD/inst/extdata/qiime2treeqza/fasttree-tree.qza -------------------------------------------------------------------------------- /inst/extdata/qiime2treeqza/raxml-cat-tree.qza: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuLab-SMU/treeio/HEAD/inst/extdata/qiime2treeqza/raxml-cat-tree.qza -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | *~ 5 | .DS_Store 6 | .svn 7 | mkdocs/mysoftware 8 | __pycache__ 9 | *.Rcheck 10 | *.html 11 | -------------------------------------------------------------------------------- /inst/extdata/qiime2treeqza/raxml-cat-bootstrap-tree.qza: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuLab-SMU/treeio/HEAD/inst/extdata/qiime2treeqza/raxml-cat-bootstrap-tree.qza -------------------------------------------------------------------------------- /.svnignore: -------------------------------------------------------------------------------- 1 | .git 2 | .Rhistory 3 | R/.Rhistory 4 | TODO.md 5 | appveyor.yml 6 | .travis.yml 7 | docs 8 | mkdocs 9 | .gitignore 10 | .gitmodules 11 | 12 | .github 13 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | globalVariables(".") 2 | 3 | 4 | ##' @importFrom yulab.utils yulab_msg 5 | .onAttach <- function(libname, pkgname) { 6 | options(check.tbl_tree.verbose=FALSE) 7 | packageStartupMessage(yulab_msg(pkgname)) 8 | } 9 | 10 | -------------------------------------------------------------------------------- /inst/extdata/MEGA7/mtCDNA_timetree.nwk: -------------------------------------------------------------------------------- 1 | ((((('chimpanzee':0.0776604,'bonobo':0.0776604):0.1329255,'homo sapiens':0.2105858):0.0717020,'gorilla':0.2822878):0.3117878,('orangutan':0.1152518,'sumatran':0.1152518):0.4788239):0.2123335,'gibbon':0.8064092); -------------------------------------------------------------------------------- /tests/testthat/test-spt.R: -------------------------------------------------------------------------------- 1 | context("shortest path tree") 2 | 3 | test_that("spt for igraph",{ 4 | set.seed(123) 5 | g <- igraph::sample_gnp(100, 3/100) 6 | tr <- spt(g, 6, igraph::V(g)) 7 | expect_true(inherits(tr, 'phylo')) 8 | }) 9 | 10 | -------------------------------------------------------------------------------- /tests/testthat/test-conversion.R: -------------------------------------------------------------------------------- 1 | context('converting tree object') 2 | 3 | phy <- rtree(30) 4 | p <- ggtree::ggtree(phy) 5 | 6 | test_that('tree object conversion', { 7 | expect_true(is(as.phylo(p), "phylo")) 8 | expect_true(is(as.treedata(p), "treedata")) 9 | }) 10 | 11 | 12 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | Makefile 4 | .gitignore 5 | .svnignore 6 | .travis.yml 7 | appveyor.yml 8 | mkdocs 9 | docs 10 | README.Rmd 11 | .github 12 | treeio_sticker.R 13 | site_src 14 | CONTRIBUTORS.md 15 | .covrignore 16 | ^CONDUCT\.md$ 17 | ^codemeta\.json$ 18 | TODO.md 19 | -------------------------------------------------------------------------------- /tests/testthat/test-r8s.R: -------------------------------------------------------------------------------- 1 | context("r8s") 2 | 3 | file <- system.file("extdata/r8s", "H3_r8s_output.log", package="treeio") 4 | r8s <- read.r8s(file) 5 | 6 | test_that("parsing r8s log file", { 7 | expect_true(all(c("TREE", "RATO", "PHYLO") %in% names(r8s))) 8 | expect_true(is(r8s, "multiPhylo")) 9 | }) 10 | -------------------------------------------------------------------------------- /inst/extdata/NHX/ADH.nhx: -------------------------------------------------------------------------------- 1 | (((ADH2:0.1[&&NHX:S=human], ADH1:0.11[&&NHX:S=human]):0.05[&&NHX:S=primates:D=Y:B=100], ADHY:0.1[&&NHX:S=nematode],ADHX:0.12[&&NHX:S=insect]):0.1[&&NHX:S=metazoa:D=N], (ADH4:0.09[&&NHX:S=yeast],ADH3:0.13[&&NHX:S=yeast], ADH2:0.12[&&NHX:S=yeast],ADH1:0.11[&&NHX:S=yeast]):0.1 [&&NHX:S=Fungi])[&&NHX:D=N]; 2 | -------------------------------------------------------------------------------- /tests/testthat/test-treeqza.R: -------------------------------------------------------------------------------- 1 | context("tree qza file (output of qiime2 phylogenetic inference) input") 2 | 3 | library(treeio) 4 | qzafile <- system.file("extdata/qiime2treeqza", "fasttree-tree.qza", package="treeio") 5 | 6 | tr <- read.treeqza(qzafile) 7 | 8 | test_that("read.treeqza should work for tree qza file",{ 9 | expect_true(is(tr, "phylo")) 10 | }) 11 | -------------------------------------------------------------------------------- /inst/extdata/pa.nwk: -------------------------------------------------------------------------------- 1 | (K:0.02616475,N:0.02027479,(D:0.02728771,(L:0.00165844,(J:0.00429993,(G:0.0157221,((C:0.00907281,(E:0.01033061,O:0.01603792)s:0.00253498)t:0.00514923,(H:0.00684454,(I:0.00471735,(B:0.01055936,(A:0.00374791,(F:0.00228087,M:0.00294252)n:0.00889342)o:0.00259775)p:0.00095993)q:0.00649159)r:0.00030615)u:0.00766986)v:0.01518124)w:0.00494841)x:0.01981392)y:0.07612933)z; 2 | -------------------------------------------------------------------------------- /R/print.R: -------------------------------------------------------------------------------- 1 | ##' print information of a list of treedata objects 2 | ##' 3 | ##' 4 | ##' @title print 5 | ##' @param x a list of treedata objects 6 | ##' @param ... no used 7 | ##' @return message 8 | ##' @method print treedataList 9 | ##' @export 10 | print.treedataList <- function(x, ...) { 11 | msg <- paste(length(x), "phylogenetic trees") 12 | cat(msg, "\n") 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /man/read.iqtree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/iqtree.R 3 | \name{read.iqtree} 4 | \alias{read.iqtree} 5 | \title{read.iqtree} 6 | \usage{ 7 | read.iqtree(file) 8 | } 9 | \arguments{ 10 | \item{file}{IQ-TREE Newick text} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | parse IQ-TREE output 17 | } 18 | \author{ 19 | Guangchuang Yu 20 | } 21 | -------------------------------------------------------------------------------- /man/is.ggtree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tree-utilities.R 3 | \name{is.ggtree} 4 | \alias{is.ggtree} 5 | \title{is.ggtree} 6 | \usage{ 7 | is.ggtree(x) 8 | } 9 | \arguments{ 10 | \item{x}{object} 11 | } 12 | \value{ 13 | TRUE or FALSE 14 | } 15 | \description{ 16 | test whether input object is produced by ggtree function 17 | } 18 | \author{ 19 | Guangchuang Yu 20 | } 21 | -------------------------------------------------------------------------------- /inst/extdata/HYPHY/labelledtree.tree: -------------------------------------------------------------------------------- 1 | (((((K:0.0245151,N:0.019108)Node5:0.0719836,D:0.0258507)Node4:0.0185486,L:0.00160607)Node3:0.00490454,J:0.00421135)Node2:0.0145442,G:0.0145687,((C:0.00886983,(E:0.0100596,O:0.0151697)Node15:0.00245533)Node13:0.00507224,(H:0.00666253,(I:0.00466618,(B:0.0102692,(A:0.00371759,(F:0.00224482,M:0.00291844)Node26:0.0086479)Node24:0.00258943)Node22:0.000928848)Node20:0.0063651)Node18:0.000322412)Node12:0.00749778); -------------------------------------------------------------------------------- /man/get.tree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/method-as-phylo.R 3 | \name{get.tree} 4 | \alias{get.tree} 5 | \title{get.tree} 6 | \usage{ 7 | get.tree(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{tree object} 11 | 12 | \item{...}{additional parameters} 13 | } 14 | \value{ 15 | phylo object 16 | } 17 | \description{ 18 | access phylo slot 19 | } 20 | \author{ 21 | Guangchuang Yu 22 | } 23 | -------------------------------------------------------------------------------- /man/merge_tree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_tree.R 3 | \name{merge_tree} 4 | \alias{merge_tree} 5 | \title{merge_tree} 6 | \usage{ 7 | merge_tree(obj1, obj2) 8 | } 9 | \arguments{ 10 | \item{obj1}{tree object 1} 11 | 12 | \item{obj2}{tree object 2} 13 | } 14 | \value{ 15 | tree object 16 | } 17 | \description{ 18 | merge two tree object 19 | } 20 | \author{ 21 | Guangchuang Yu 22 | } 23 | -------------------------------------------------------------------------------- /man/read.mega_tabular.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mega.R 3 | \name{read.mega_tabular} 4 | \alias{read.mega_tabular} 5 | \title{read.mega_tabular} 6 | \usage{ 7 | read.mega_tabular(file) 8 | } 9 | \arguments{ 10 | \item{file}{MEGA tabular file} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | parse tabular output of MEGA 17 | } 18 | \author{ 19 | Guangchuang Yu 20 | } 21 | -------------------------------------------------------------------------------- /man/read.phylip.tree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/phylip.R 3 | \name{read.phylip.tree} 4 | \alias{read.phylip.tree} 5 | \title{read.phylip.tree} 6 | \usage{ 7 | read.phylip.tree(file) 8 | } 9 | \arguments{ 10 | \item{file}{phylip file} 11 | } 12 | \value{ 13 | phylo or multiPhylo object 14 | } 15 | \description{ 16 | parse tree from phylip file 17 | } 18 | \author{ 19 | Guangchuang Yu 20 | } 21 | -------------------------------------------------------------------------------- /man/treetime.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/treetime.R 3 | \name{read.treetime} 4 | \alias{read.treetime} 5 | \alias{read.timetree} 6 | \title{read.timetree} 7 | \usage{ 8 | read.treetime(file) 9 | 10 | read.timetree(file) 11 | } 12 | \arguments{ 13 | \item{file}{the output tree file of timetree} 14 | } 15 | \value{ 16 | treedata object 17 | } 18 | \description{ 19 | read timetree output 20 | } 21 | -------------------------------------------------------------------------------- /man/print.treedataList.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{print.treedataList} 4 | \alias{print.treedataList} 5 | \title{print} 6 | \usage{ 7 | \method{print}{treedataList}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a list of treedata objects} 11 | 12 | \item{...}{no used} 13 | } 14 | \value{ 15 | message 16 | } 17 | \description{ 18 | print information of a list of treedata objects 19 | } 20 | -------------------------------------------------------------------------------- /man/read-jtree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/jtree.R 3 | \name{read.jtree} 4 | \alias{read.jtree} 5 | \title{read.jtree} 6 | \usage{ 7 | read.jtree(file) 8 | } 9 | \arguments{ 10 | \item{file}{tree file} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | Import tree data from jtree file, which is JSON-based text and probably output by write.jtree 17 | } 18 | \author{ 19 | Guangchuang Yu 20 | } 21 | -------------------------------------------------------------------------------- /man/raxml2nwk.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/raxml2nwk.R 3 | \name{raxml2nwk} 4 | \alias{raxml2nwk} 5 | \title{raxml2nwk} 6 | \usage{ 7 | raxml2nwk(infile, outfile = "raxml.tree") 8 | } 9 | \arguments{ 10 | \item{infile}{input file} 11 | 12 | \item{outfile}{output file} 13 | } 14 | \value{ 15 | newick file 16 | } 17 | \description{ 18 | convert raxml bootstrap tree to newick format 19 | } 20 | \author{ 21 | Guangchuang Yu 22 | } 23 | -------------------------------------------------------------------------------- /treeio.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 4 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/get.treetext-methods.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/AllGenerics.R 3 | \docType{methods} 4 | \name{get.treetext} 5 | \alias{get.treetext} 6 | \title{get.treetext method} 7 | \usage{ 8 | get.treetext(object, ...) 9 | } 10 | \arguments{ 11 | \item{object}{treedata object} 12 | 13 | \item{...}{additional parameter} 14 | } 15 | \value{ 16 | phylo object 17 | } 18 | \description{ 19 | access tree text (newick text) from tree object 20 | } 21 | -------------------------------------------------------------------------------- /man/read.r8s.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/r8s.R 3 | \name{read.r8s} 4 | \alias{read.r8s} 5 | \title{read.r8s} 6 | \usage{ 7 | read.r8s(file) 8 | } 9 | \arguments{ 10 | \item{file}{r8s output log file} 11 | } 12 | \value{ 13 | multiPhylo object 14 | } 15 | \description{ 16 | parse output from r8s 17 | } 18 | \examples{ 19 | read.r8s(system.file("extdata/r8s", "H3_r8s_output.log", package="treeio")) 20 | } 21 | \author{ 22 | Guangchuang Yu 23 | } 24 | -------------------------------------------------------------------------------- /man/read.jplace.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/jplace.R 3 | \name{read.jplace} 4 | \alias{read.jplace} 5 | \title{read.jplace} 6 | \usage{ 7 | read.jplace(file) 8 | } 9 | \arguments{ 10 | \item{file}{jplace file} 11 | } 12 | \value{ 13 | \code{jplace} instance 14 | } 15 | \description{ 16 | read jplace file 17 | } 18 | \examples{ 19 | jp <- system.file("extdata", "sample.jplace", package="treeio") 20 | read.jplace(jp) 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/getNodeNum.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tree-utilities.R 3 | \name{getNodeNum} 4 | \alias{getNodeNum} 5 | \alias{Nnode2} 6 | \title{getNodeNum} 7 | \usage{ 8 | getNodeNum(tree) 9 | 10 | Nnode2(tree) 11 | } 12 | \arguments{ 13 | \item{tree}{tree object} 14 | } 15 | \value{ 16 | number 17 | } 18 | \description{ 19 | calculate total number of nodes 20 | } 21 | \examples{ 22 | getNodeNum(rtree(30)) 23 | Nnode2(rtree(30)) 24 | } 25 | \author{ 26 | Guangchuang Yu 27 | } 28 | -------------------------------------------------------------------------------- /man/rescale_tree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rescale_tree.R 3 | \name{rescale_tree} 4 | \alias{rescale_tree} 5 | \title{rescale_tree} 6 | \usage{ 7 | rescale_tree(tree_object, branch.length) 8 | } 9 | \arguments{ 10 | \item{tree_object}{tree object} 11 | 12 | \item{branch.length}{numerical features (e.g. dN/dS)} 13 | } 14 | \value{ 15 | update tree object 16 | } 17 | \description{ 18 | rescale branch length of tree object 19 | } 20 | \author{ 21 | Guangchuang Yu 22 | } 23 | -------------------------------------------------------------------------------- /man/read.nhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nhx.R 3 | \name{read.nhx} 4 | \alias{read.nhx} 5 | \title{read.nhx} 6 | \usage{ 7 | read.nhx(file) 8 | } 9 | \arguments{ 10 | \item{file}{nhx file} 11 | } 12 | \value{ 13 | nhx object 14 | } 15 | \description{ 16 | read nhx tree file 17 | } 18 | \examples{ 19 | nhxfile <- system.file("extdata/NHX", "ADH.nhx", package="treeio") 20 | read.nhx(nhxfile) 21 | } 22 | \author{ 23 | Guangchuang Yu \url{https://guangchuangyu.github.io} 24 | } 25 | -------------------------------------------------------------------------------- /man/read.phylip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/phylip.R 3 | \name{read.phylip} 4 | \alias{read.phylip} 5 | \title{read.phylip} 6 | \usage{ 7 | read.phylip(file) 8 | } 9 | \arguments{ 10 | \item{file}{phylip file} 11 | } 12 | \value{ 13 | an instance of 'phylip' 14 | } 15 | \description{ 16 | parsing phylip tree format 17 | } 18 | \examples{ 19 | phyfile <- system.file("extdata", "sample.phy", package="treeio") 20 | read.phylip(phyfile) 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /R/raxml2nwk.R: -------------------------------------------------------------------------------- 1 | ##' convert raxml bootstrap tree to newick format 2 | ##' 3 | ##' 4 | ##' @title raxml2nwk 5 | ##' @param infile input file 6 | ##' @param outfile output file 7 | ##' @return newick file 8 | ##' @export 9 | ##' @importFrom ape write.tree 10 | ##' @author Guangchuang Yu 11 | raxml2nwk <- function(infile, outfile="raxml.tree") { 12 | raxml <- read.raxml(infile) 13 | nlabel <- raxml@data[[2]] 14 | nlabel[is.na(nlabel)] <- "" 15 | raxml@phylo$node.label <- nlabel 16 | write.tree(raxml@phylo, file=outfile) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /man/write-jtree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/jtree.R 3 | \name{write.jtree} 4 | \alias{write.jtree} 5 | \title{write.jtree} 6 | \usage{ 7 | write.jtree(treedata, file = "") 8 | } 9 | \arguments{ 10 | \item{treedata}{\code{treedata} object} 11 | 12 | \item{file}{output file. If file = "", print the output content on screen} 13 | } 14 | \value{ 15 | output file or file content on screen 16 | } 17 | \description{ 18 | Export \code{treedata} object to json tree file 19 | } 20 | \author{ 21 | Guangchuang Yu 22 | } 23 | -------------------------------------------------------------------------------- /man/read.codeml_mlc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/codeml_mlc.R 3 | \name{read.codeml_mlc} 4 | \alias{read.codeml_mlc} 5 | \title{read.codeml_mlc} 6 | \usage{ 7 | read.codeml_mlc(mlcfile) 8 | } 9 | \arguments{ 10 | \item{mlcfile}{mlc file} 11 | } 12 | \value{ 13 | A \code{codeml_mlc} object 14 | } 15 | \description{ 16 | read mlc file of codeml output 17 | } 18 | \examples{ 19 | mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 20 | read.codeml_mlc(mlcfile) 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/read.newick.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/newick.R 3 | \name{read.newick} 4 | \alias{read.newick} 5 | \title{read.newick} 6 | \usage{ 7 | read.newick(file, node.label = "label", ...) 8 | } 9 | \arguments{ 10 | \item{file}{newick file} 11 | 12 | \item{node.label}{parse node label as 'label' or 'support' value} 13 | 14 | \item{...}{additional parameter, passed to 'read.tree'} 15 | } 16 | \value{ 17 | phylo or treedata object 18 | } 19 | \description{ 20 | read newick tree 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/label_branch_paml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tree-utilities.R 3 | \name{label_branch_paml} 4 | \alias{label_branch_paml} 5 | \title{label_branch_paml} 6 | \usage{ 7 | label_branch_paml(tree, node, label) 8 | } 9 | \arguments{ 10 | \item{tree}{phylo object} 11 | 12 | \item{node}{node number} 13 | 14 | \item{label}{label of branch, e.g. #1} 15 | } 16 | \value{ 17 | updated phylo object 18 | } 19 | \description{ 20 | label branch for PAML to infer selection pressure using branch model 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/read.phylip.seq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/phylip.R 3 | \name{read.phylip.seq} 4 | \alias{read.phylip.seq} 5 | \title{read.phylip.seq} 6 | \usage{ 7 | read.phylip.seq(file) 8 | } 9 | \arguments{ 10 | \item{file}{phylip file, currently only sequential format is supported} 11 | } 12 | \value{ 13 | DNAbin object 14 | } 15 | \description{ 16 | read aligned sequences from phylip format 17 | } 18 | \references{ 19 | \url{http://evolution.genetics.washington.edu/phylip/doc/sequence.html} 20 | } 21 | \author{ 22 | Guangchuang Yu 23 | } 24 | -------------------------------------------------------------------------------- /man/read.raxml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RAxML.R 3 | \name{read.raxml} 4 | \alias{read.raxml} 5 | \title{read.raxml} 6 | \usage{ 7 | read.raxml(file) 8 | } 9 | \arguments{ 10 | \item{file}{RAxML bootstrapping analysis output} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | parse RAxML bootstrapping analysis output 17 | } 18 | \examples{ 19 | raxml_file <- system.file("extdata/RAxML", "RAxML_bipartitionsBranchLabels.H3", package="treeio") 20 | read.raxml(raxml_file) 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/get-placements.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/AllGenerics.R, R/jplace.R 3 | \name{get.placements} 4 | \alias{get.placements} 5 | \alias{get.placements.jplace} 6 | \title{get.placements} 7 | \usage{ 8 | get.placements(tree, ...) 9 | 10 | \method{get.placements}{jplace}(tree, by = "best", ...) 11 | } 12 | \arguments{ 13 | \item{tree}{tree object} 14 | 15 | \item{...}{additional parameters} 16 | 17 | \item{by}{one of 'best' and 'all'} 18 | } 19 | \value{ 20 | placement tibble 21 | } 22 | \description{ 23 | access placement information 24 | } 25 | -------------------------------------------------------------------------------- /man/read.hyphy.seq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hyphy.R 3 | \name{read.hyphy.seq} 4 | \alias{read.hyphy.seq} 5 | \title{read.hyphy.seq} 6 | \usage{ 7 | read.hyphy.seq(file) 8 | } 9 | \arguments{ 10 | \item{file}{output of hyphy ancestral sequence inference; nexus format} 11 | } 12 | \value{ 13 | DNAbin object 14 | } 15 | \description{ 16 | parse sequences from hyphy output 17 | } 18 | \examples{ 19 | ancseq <- system.file("extdata/HYPHY", "ancseq.nex", package="treeio") 20 | read.hyphy.seq(ancseq) 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/mask.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mask.R 3 | \name{mask} 4 | \alias{mask} 5 | \title{mask} 6 | \usage{ 7 | mask(tree_object, field, site, mask_site = FALSE) 8 | } 9 | \arguments{ 10 | \item{tree_object}{tree object} 11 | 12 | \item{field}{selected field} 13 | 14 | \item{site}{site} 15 | 16 | \item{mask_site}{if TRUE, site will be masked. 17 | if FALSE, selected site will not be masked, while other sites will be masked.} 18 | } 19 | \value{ 20 | updated tree object 21 | } 22 | \description{ 23 | site mask 24 | } 25 | \author{ 26 | Guangchuang Yu 27 | } 28 | -------------------------------------------------------------------------------- /man/write.jplace.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/write-jplace.R 3 | \name{write.jplace} 4 | \alias{write.jplace} 5 | \title{write.jplace} 6 | \usage{ 7 | write.jplace(x, outfile) 8 | } 9 | \arguments{ 10 | \item{x}{a jplace object.} 11 | 12 | \item{outfile}{the output file name} 13 | } 14 | \description{ 15 | Export \code{jplace} object to jplace file. 16 | } 17 | \examples{ 18 | jp <- system.file("extdata", "sample.jplace", package="treeio") 19 | tr1 <- read.jplace(jp) 20 | outfile <- tempfile() 21 | write.jplace(tr1, outfile) 22 | tr2 <- read.jplace(outfile) 23 | tr2 24 | } 25 | -------------------------------------------------------------------------------- /man/as.treedata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/method-as-treedata.R 3 | \name{as.treedata.phylo} 4 | \alias{as.treedata.phylo} 5 | \title{as.treedata} 6 | \usage{ 7 | \method{as.treedata}{phylo}(tree, boot = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{tree}{input tree, a \code{phylo} object} 11 | 12 | \item{boot}{optional, can be bootstrap value from ape::boot.phylo} 13 | 14 | \item{...}{additional parameters} 15 | } 16 | \description{ 17 | convert phylo to treedata 18 | } 19 | \details{ 20 | converting phylo object to treedata object 21 | } 22 | \author{ 23 | Guangchuang Yu 24 | } 25 | -------------------------------------------------------------------------------- /man/read.nextstrain.json.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nextstrain.json.R 3 | \name{read.nextstrain.json} 4 | \alias{read.nextstrain.json} 5 | \title{read.nextstrain.json} 6 | \usage{ 7 | read.nextstrain.json(x) 8 | } 9 | \arguments{ 10 | \item{x}{the json tree file of auspice from nextstrain.} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | read.nextstrain.json 17 | } 18 | \examples{ 19 | file1 <- system.file("extdata/nextstrain.json", "minimal_v2.json", package="treeio") 20 | tr <- read.nextstrain.json(file1) 21 | tr 22 | } 23 | \author{ 24 | Shuangbin Xu 25 | } 26 | -------------------------------------------------------------------------------- /man/read.fasta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sequence-utilities.R 3 | \name{read.fasta} 4 | \alias{read.fasta} 5 | \title{read.fasta} 6 | \usage{ 7 | read.fasta(fasta, type = "auto") 8 | } 9 | \arguments{ 10 | \item{fasta}{fasta file} 11 | 12 | \item{type}{sequence type of the input file, one of 'NT' or 'AA'. 13 | Default is 'auto' and guess the sequence type automatically} 14 | } 15 | \value{ 16 | DNAbin or AAbin object 17 | } 18 | \description{ 19 | read FASTA file 20 | } 21 | \details{ 22 | This function supports both DNA or AA sequences 23 | } 24 | \author{ 25 | Guangchuang Yu 26 | } 27 | -------------------------------------------------------------------------------- /R/ape.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom ape read.tree 2 | ##' @export 3 | ape::read.tree 4 | 5 | ##' @importFrom ape read.nexus 6 | ##' @export 7 | ape::read.nexus 8 | 9 | 10 | ##' @importFrom ape rtree 11 | ##' @export 12 | ape::rtree 13 | 14 | ##' @importFrom ape write.tree 15 | ##' @export 16 | ape::write.tree 17 | 18 | ##' @importFrom ape write.nexus 19 | ##' @export 20 | ape::write.nexus 21 | 22 | ##' @importFrom ape Nnode 23 | ##' @export 24 | ape::Nnode 25 | 26 | ##' @importFrom ape Ntip 27 | ##' @export 28 | ape::Ntip 29 | 30 | ##' @importFrom ape is.rooted 31 | ##' @export 32 | ape::is.rooted 33 | 34 | ##' @importFrom ape root 35 | ##' @export 36 | ape::root 37 | 38 | -------------------------------------------------------------------------------- /man/read.phyloxml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/phyloxml.R 3 | \name{read.phyloxml} 4 | \alias{read.phyloxml} 5 | \title{read.phyloxml} 6 | \usage{ 7 | read.phyloxml(file) 8 | } 9 | \arguments{ 10 | \item{file}{phyloxml file} 11 | } 12 | \value{ 13 | treedata class or treedataList class 14 | } 15 | \description{ 16 | read.phyloxml 17 | } 18 | \examples{ 19 | xmlfile1 <- system.file("extdata/phyloxml", "test_x2.xml", package="treeio") 20 | px1 <- read.phyloxml(xmlfile1) 21 | px1 22 | xmlfile2 <- system.file("extdata/phyloxml", "phyloxml_examples.xml", package="treeio") 23 | px2 <- read.phyloxml(xmlfile2) 24 | px2 25 | } 26 | -------------------------------------------------------------------------------- /tests/testthat/test-merge-tree.R: -------------------------------------------------------------------------------- 1 | context("merge_tree") 2 | 3 | beast_file <- system.file("examples/MCC_FluA_H3.tree", package="ggtree") 4 | rst_file <- system.file("examples/rst", package="ggtree") 5 | mlc_file <- system.file("examples/mlc", package="ggtree") 6 | beast_tree <- read.beast(beast_file) 7 | codeml_tree <- read.codeml(rst_file, mlc_file) 8 | 9 | merged_tree <- merge_tree(beast_tree, codeml_tree) 10 | 11 | 12 | test_that('merging tree objects', { 13 | expect_true(is(merged_tree, "treedata")) 14 | expect_true(all(get.fields(codeml_tree) %in% get.fields(merged_tree))) 15 | expect_true(all(get.fields(beast_tree) %in% get.fields(merged_tree))) 16 | }) 17 | -------------------------------------------------------------------------------- /man/read.paml_rst.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/paml_rst.R 3 | \name{read.paml_rst} 4 | \alias{read.paml_rst} 5 | \title{read.paml_rst} 6 | \usage{ 7 | read.paml_rst(rstfile, type = "Joint") 8 | } 9 | \arguments{ 10 | \item{rstfile}{rst file} 11 | 12 | \item{type}{one of 'Marginal' or 'Joint'} 13 | } 14 | \value{ 15 | A \code{treedata} object 16 | } 17 | \description{ 18 | read rst file from paml (both baseml and codeml) output 19 | } 20 | \examples{ 21 | rstfile <- system.file("extdata/PAML_Baseml", "rst", package="treeio") 22 | read.paml_rst(rstfile) 23 | } 24 | \author{ 25 | Guangchuang Yu \url{https://guangchuangyu.github.io} 26 | } 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | ## reference: http://docs.travis-ci.com/user/languages/r/ 2 | 3 | language: r 4 | r: 5 | - bioc-devel 6 | 7 | cache: packages 8 | bioc_required: true 9 | 10 | os: 11 | - linux 12 | 13 | r_packages: 14 | - covr 15 | - ape 16 | - tidyr 17 | - tidytree 18 | - ggtree 19 | - testthat 20 | - prettydoc 21 | - knitr 22 | 23 | env: 24 | global: 25 | - _R_CHECK_FORCE_SUGGESTS_=False 26 | - R_LIBS="http://cran.rstudio.com" 27 | 28 | 29 | after_failure: 30 | - ./travis-tool.sh dump_logs 31 | 32 | after_success: 33 | - Rscript -e 'library(covr); codecov()' 34 | 35 | notifications: 36 | email: 37 | on_success: change 38 | on_failure: change 39 | 40 | -------------------------------------------------------------------------------- /R/treetime.R: -------------------------------------------------------------------------------- 1 | ##' read timetree output 2 | ##' 3 | ##' @rdname treetime 4 | ##' @title read.timetree 5 | ##' @param file the output tree file of timetree 6 | ##' @return treedata object 7 | ##' @export 8 | read.treetime <- function(file) { 9 | con <- readLines(file) 10 | con <- sub("(\\[)\\\\\\[(.*)\\\\\\](\\])", "\\1\\2\\3", con) 11 | 12 | f <- tempfile() 13 | writeLines(con, f) 14 | x <- read.beast(f) 15 | x@file <- file 16 | return(x) 17 | } 18 | 19 | ##' @rdname treetime 20 | read.timetree <- function(file) { 21 | message("Please use `read.treetime() instead. The `read.timetree()` function may be removed in future version.\n") 22 | read.treetime(file) 23 | } 24 | 25 | -------------------------------------------------------------------------------- /man/read.astral.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ASTRAL.R 3 | \name{read.astral} 4 | \alias{read.astral} 5 | \title{read.astral} 6 | \usage{ 7 | read.astral(file) 8 | } 9 | \arguments{ 10 | \item{file}{ASTRAL Newick file} 11 | } 12 | \value{ 13 | treedata object 14 | } 15 | \description{ 16 | parse ASTRAL output newick text 17 | } 18 | \examples{ 19 | tt <- paste0( 20 | "((species1,(species2,species3)'[pp1=0.75;pp2=0.24;pp3=0.01]':", 21 | "1.2003685744180805)'[pp1=0.98;pp2=0.02;pp3=0]':0.9679599282730038,", 22 | "((species4,species5)'[pp1=0.88;pp2=0.11;pp3=0.01]':1.2454851536484994))" 23 | ) 24 | read.astral(textConnection(tt)) 25 | } 26 | \author{ 27 | Guangchuang Yu 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/test-phyloxml.R: -------------------------------------------------------------------------------- 1 | context("phyloxml input") 2 | 3 | library(treeio) 4 | xmlfile1 <- system.file("extdata/phyloxml", "test_x2.xml", package="treeio") 5 | xmlfile2 <- system.file("extdata/phyloxml", "phyloxml_examples.xml", package="treeio") 6 | tx1 <- read.phyloxml(xmlfile1) 7 | tx2 <- read.phyloxml(xmlfile2) 8 | 9 | test_that("read.phyloxml should work for phyloxml",{ 10 | expect_true(is(tx1, "treedata")) 11 | expect_true(is(tx2, "treedataList")) 12 | expect_equal(length(tx2), 13) 13 | }) 14 | 15 | dat <- list(A=list(a=12, b=c(B=1, "t"))) 16 | res1 <- extract_another(dat) 17 | res2 <- list(A=c(a=12,B=1,b="t")) 18 | 19 | test_that("checking extract_another",{ 20 | expect_equal(res1, res2) 21 | }) 22 | 23 | 24 | -------------------------------------------------------------------------------- /R/iqtree.R: -------------------------------------------------------------------------------- 1 | ##' parse IQ-TREE output 2 | ##' 3 | ##' 4 | ##' @title read.iqtree 5 | ##' @param file IQ-TREE Newick text 6 | ##' @return treedata object 7 | ##' @export 8 | ##' @author Guangchuang Yu 9 | read.iqtree <- function(file) { 10 | treetext <- readLines(file, warn = FALSE) 11 | phylo <- read.tree(text = treetext) 12 | nlabel <- phylo$node.label 13 | sh <- sub("/.*", "", nlabel) %>% as.numeric 14 | uf <- sub(".*/", "", nlabel) %>% as.numeric 15 | 16 | d <- tibble(node = Ntip(phylo) + 1:phylo$Nnode, 17 | SH_aLRT = sh, 18 | UFboot = uf) 19 | 20 | new("treedata", 21 | file = filename(file), 22 | treetext = treetext, 23 | phylo = phylo, 24 | data = d 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /vignettes/treeio.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "treeio: Base Classes and Functions for Phylogenetic Tree Input and Output" 3 | author: "Guangchuang Yu\\ 4 | 5 | School of Basic Medical Sciences, Southern Medical University" 6 | date: "`r Sys.Date()`" 7 | output: 8 | prettydoc::html_pretty: 9 | toc: true 10 | theme: cayman 11 | highlight: github 12 | pdf_document: 13 | toc: true 14 | vignette: > 15 | %\VignetteIndexEntry{treeio} 16 | %\VignetteEngine{knitr::rmarkdown} 17 | %\usepackage[utf8]{inputenc} 18 | --- 19 | 20 | ```{r style, echo=FALSE, results="asis", message=FALSE} 21 | knitr::opts_chunk$set(tidy = FALSE, 22 | message = FALSE) 23 | ``` 24 | 25 | 26 | 27 | 28 | Please go to for the full vignette. 29 | 30 | -------------------------------------------------------------------------------- /man/read.codeml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/codeml.R 3 | \name{read.codeml} 4 | \alias{read.codeml} 5 | \title{read.codeml} 6 | \usage{ 7 | read.codeml(rstfile, mlcfile, tree = "mlc", type = "Joint") 8 | } 9 | \arguments{ 10 | \item{rstfile}{rst file} 11 | 12 | \item{mlcfile}{mlc file} 13 | 14 | \item{tree}{one of 'mlc' or 'rst'} 15 | 16 | \item{type}{one of 'Marginal' or 'Joint'} 17 | } 18 | \value{ 19 | A \code{treedata} object 20 | } 21 | \description{ 22 | read baseml output 23 | } 24 | \examples{ 25 | rstfile <- system.file("extdata/PAML_Codeml", "rst", package="treeio") 26 | mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 27 | read.codeml(rstfile, mlcfile) 28 | } 29 | \author{ 30 | Guangchuang Yu 31 | } 32 | -------------------------------------------------------------------------------- /man/read.mcmctree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/MCMCTree.R 3 | \name{read.mcmctree} 4 | \alias{read.mcmctree} 5 | \title{read.mcmctree} 6 | \usage{ 7 | read.mcmctree(file, force.ultrametric = FALSE) 8 | } 9 | \arguments{ 10 | \item{file}{the output tree file of MCMCTree} 11 | 12 | \item{force.ultrametric}{logical whether convert the tree 13 | to be ultrametric, if it is not ultrametric, default is FALSE. 14 | When the tree is ultrametric, branch times will be calculated 15 | automatically.} 16 | } 17 | \value{ 18 | treedata object 19 | } 20 | \description{ 21 | read MCMCTree output Tree 22 | } 23 | \examples{ 24 | file <- system.file("extdata/MCMCTree", "mcmctree_output.tree", package="treeio") 25 | tr <- read.mcmctree(file) 26 | tr 27 | } 28 | -------------------------------------------------------------------------------- /tests/testthat/test-jtree.R: -------------------------------------------------------------------------------- 1 | context("jtree input and output") 2 | 3 | rstfile <- system.file("extdata/PAML_Codeml", "rst", package="treeio") 4 | mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 5 | ml <- read.codeml(rstfile, mlcfile) 6 | 7 | jtree_file <- tempfile() 8 | jtree_text <- write.jtree(ml, jtree_file) 9 | 10 | js <- jsonlite::fromJSON(jtree_file) 11 | 12 | tree <- read.jtree(jtree_file) 13 | 14 | test_that("write.jtree output a json file", { 15 | expect_gt(file.info(jtree_file)$size, 0) 16 | expect_true(is(js, "list")) 17 | expect_true(all(c("tree", "data") %in% names(js))) 18 | expect_true(all(c("edge_num", "dN", "dS") %in% names(js$data))) 19 | expect_true(treeio:::is.tree(tree)) 20 | expect_true(treeio:::has.slot(tree, "data")) 21 | }) 22 | -------------------------------------------------------------------------------- /R/newick.R: -------------------------------------------------------------------------------- 1 | ##' read newick tree 2 | ##' 3 | ##' 4 | ##' @title read.newick 5 | ##' @param file newick file 6 | ##' @param node.label parse node label as 'label' or 'support' value 7 | ##' @param ... additional parameter, passed to 'read.tree' 8 | ##' @return phylo or treedata object 9 | ##' @export 10 | ##' @author Guangchuang Yu 11 | read.newick <- function(file, node.label = "label", ...) { 12 | node.label <- match.arg(node.label, c("support", "label")) 13 | tree <- read.tree(file, ...) 14 | if (node.label == "label") 15 | return(tree) 16 | 17 | df <- tibble(node = nodeIds(tree), 18 | support = as.numeric(tree$node.label)) 19 | 20 | tree$node.label <- NULL 21 | new("treedata", 22 | phylo = tree, 23 | data = df) 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /inst/extdata/pa_subs.csv: -------------------------------------------------------------------------------- 1 | "label","subs","gc" 2 | "A","R262K/K603R",0.444 3 | "B","R262K",0.442 4 | "C","N272S/I354T",0.439 5 | "D","K104R/F105L/E382D/F480S/I596T",0.449 6 | "E","T208S/V379I/K609R",0.443 7 | "F","S277P/L549I",0.444 8 | "G","E2V/A36S/G99R/E101Q/K113Q/E141D/K142N/H297Y/M485I",0.443 9 | "H","I38V/E258D/T570I",0.443 10 | "I","",0.443 11 | "J","G99R",0.447 12 | "K","V387I/I407V/V432I",0.441 13 | "L","",0.441 14 | "M","A20T",0.441 15 | "N","H535Y",0.443 16 | "O","N96H/N115S/N321I/S364G",0.44 17 | "n","V100A",0.444 18 | "o","D394N",0.446 19 | "p","K356R",0.445 20 | "q","",0.445 21 | "r","",0.445 22 | "s","",0.442 23 | "t","L336M",0.442 24 | "u","I423V/G684E",0.445 25 | "v","A37S/A337T/S388N",0.446 26 | "w","",0.448 27 | "x","I61T/V63I/K262R/D272N/S405C/S409N/I554V/M607L",0.446 28 | "y","D101E/V323I/R391K/S400P/K716R",0.449 29 | -------------------------------------------------------------------------------- /man/read.hyphy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hyphy.R 3 | \name{read.hyphy} 4 | \alias{read.hyphy} 5 | \title{read.hyphy} 6 | \usage{ 7 | read.hyphy(nwk, ancseq, tip.fasfile = NULL) 8 | } 9 | \arguments{ 10 | \item{nwk}{tree file in nwk format, one of hyphy output} 11 | 12 | \item{ancseq}{ancestral sequence file in nexus format, 13 | one of hyphy output} 14 | 15 | \item{tip.fasfile}{tip sequence file} 16 | } 17 | \value{ 18 | A hyphy object 19 | } 20 | \description{ 21 | read HYPHY output 22 | } 23 | \examples{ 24 | nwk <- system.file("extdata/HYPHY", "labelledtree.tree", package="treeio") 25 | ancseq <- system.file("extdata/HYPHY", "ancseq.nex", package="treeio") 26 | read.hyphy(nwk, ancseq) 27 | } 28 | \author{ 29 | Guangchuang Yu \url{https://guangchuangyu.github.io} 30 | } 31 | -------------------------------------------------------------------------------- /man/rename_taxa.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rename.R 3 | \name{rename_taxa} 4 | \alias{rename_taxa} 5 | \title{rename_taxa} 6 | \usage{ 7 | rename_taxa(tree, data, key = 1, value = 2) 8 | } 9 | \arguments{ 10 | \item{tree}{tree object, either treedata or phylo} 11 | 12 | \item{data}{data frame} 13 | 14 | \item{key}{column in data that match tip label (use 1st column by default)} 15 | 16 | \item{value}{column in data for rename tip label (use 2nd column by default)} 17 | } 18 | \value{ 19 | tree object 20 | } 21 | \description{ 22 | rename tip label of phylogenetic tree 23 | } 24 | \examples{ 25 | tree <- rtree(3) 26 | d <- data.frame(old = paste0('t', 1:3), new = LETTERS[1:3]) 27 | rename_taxa(tree, d) 28 | rename_taxa(tree, d, old, new) 29 | } 30 | \author{ 31 | Guangchuang Yu 32 | } 33 | -------------------------------------------------------------------------------- /R/AllGenerics.R: -------------------------------------------------------------------------------- 1 | 2 | ##' access placement information 3 | ##' 4 | ##' 5 | ##' @title get.placements 6 | ##' @param tree tree object 7 | ##' @param ... additional parameters 8 | ##' @return placement tibble 9 | ##' @rdname get-placements 10 | ##' @export 11 | get.placements <- function(tree, ...) { 12 | UseMethod("get.placements") 13 | } 14 | 15 | 16 | ##' access tree text (newick text) from tree object 17 | ##' 18 | ##' 19 | ##' @docType methods 20 | ##' @name get.treetext 21 | ##' @rdname get.treetext-methods 22 | ##' @title get.treetext method 23 | ##' @param object treedata object 24 | ##' @param ... additional parameter 25 | ##' @return phylo object 26 | ##' @importFrom methods setGeneric 27 | ##' @export 28 | setGeneric( 29 | name = "get.treetext", 30 | def = function(object, ...) 31 | standardGeneric("get.treetext") 32 | ) 33 | -------------------------------------------------------------------------------- /R/r8s.R: -------------------------------------------------------------------------------- 1 | ##' parse output from r8s 2 | ##' 3 | ##' 4 | ##' @title read.r8s 5 | ##' @param file r8s output log file 6 | ##' @return multiPhylo object 7 | ##' @export 8 | ##' @examples 9 | ##' read.r8s(system.file("extdata/r8s", "H3_r8s_output.log", package="treeio")) 10 | ##' @author Guangchuang Yu 11 | read.r8s <- function(file) { 12 | r8s <- readLines(file) 13 | label_idx <- grep("\\[\\w+\\sDESCRIPTION\\sof\\stree\\s.*\\]", r8s) 14 | tree_idx <- grep("^tree\\s.*\\s=\\s", r8s) 15 | if (length(label_idx) != length(tree_idx)) { 16 | stop("fail to parse the file...") 17 | } 18 | 19 | tree_text <- gsub("^tree\\s.*\\s=\\s", "", r8s[tree_idx]) 20 | trees <- read.tree(text=tree_text) 21 | 22 | label <- gsub("^\\[(\\w+)\\s.*", "\\1", r8s[label_idx]) 23 | names(trees) <- label 24 | 25 | return(trees) 26 | } 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /inst/extdata/sample.jplace: -------------------------------------------------------------------------------- 1 | { 2 | "tree": "(((((((A:4{1},B:4{2}):6{3},C:5{4}):8{5},D:6{6}):3{7},E:21{8}):10{9},((F:4{10},G:12{11}):14{12},H:8{13}):13{14}):13{15},((I:5{16},J:2{17}):30{18},(K:11{19},L:11{20}):2{21}):17{22}):4{23},M:56{24});", 3 | "placements": [ 4 | {"p":[24, -61371.300778, 0.333344, 0.000003, 0.003887], "n":["AA"]}, 5 | {"p":[[1, -61312.210786, 0.333335, 0.000001, 0.000003],[2, -61322.210823, 0.333322, 0.000003, 0.000003],[24, -61352.210823, 0.333322, 0.000961, 0.000003]], "n":["BB"]}, 6 | {"p":[[8, -61312.229128, 0.200011, 0.000001, 0.000003],[9, -61322.229179, 0.200000, 0.000003, 0.000003],[10, -61342.229223, 0.199992, 0.000003, 0.000003]], "n":["CC"]} 7 | ], 8 | "metadata": {"info": "sample file, without any meaning"}, 9 | "version" : 2, 10 | "fields": ["edge_num", "likelihood", "like_weight_ratio", "distal_length", 11 | "pendant_length" 12 | ] 13 | } 14 | 15 | -------------------------------------------------------------------------------- /tests/testthat/test-utilities.R: -------------------------------------------------------------------------------- 1 | context("utilities") 2 | 3 | library(treeio) 4 | 5 | set.seed(42) 6 | tree <- ape::rtree(10) 7 | oldtree <- tree 8 | nodeID <- 1:Nnode(tree) + Ntip(tree) 9 | tree$tip.label <- paste0("'", tree$tip.label, '"') 10 | tree$node.label <- paste0("'", nodeID, '"') 11 | newtree <- treeio:::remove_quote_in_tree_label(tree) 12 | 13 | test_that("remove quote in tree label", { 14 | expect_equal(oldtree$tip.label, newtree$tip.label) 15 | expect_equal(newtree$node.label, as.character(nodeID)) 16 | }) 17 | 18 | phyfile <- system.file("extdata", "sample.phy", package="treeio") 19 | info <- treeio:::getPhyInfo(phyfile) 20 | 21 | test_that("tiny utilities", { 22 | expect_false(treeio:::is.tree(data.frame())) 23 | expect_false(treeio:::has.slot(data.frame(), "data")) 24 | expect_equal(info$num, 15) 25 | expect_equal(info$width, 2148) 26 | }) 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/testthat/test-parser.R: -------------------------------------------------------------------------------- 1 | context("parse tree") 2 | 3 | phyfile <- system.file("extdata", "sample.phy", package="treeio") 4 | ptree1 <- read.phylip(phyfile) 5 | ptree2 <- read.phylip.tree(phyfile) 6 | 7 | 8 | 9 | raxml_file <- system.file("extdata/RAxML", 10 | "RAxML_bipartitionsBranchLabels.H3", 11 | package="treeio") 12 | 13 | raxml <- read.raxml(raxml_file) 14 | 15 | nwk_file <- tempfile() 16 | raxml2nwk(raxml_file, nwk_file) 17 | 18 | test_that("parsing trees", { 19 | expect_true(is(raxml, "treedata")) 20 | expect_true(is(ptree1, "treedata")) 21 | expect_true(is(ptree2, "phylo")) 22 | expect_true('bootstrap' %in% names(raxml@data)) 23 | expect_equal(length(ptree1@tip_seq), Ntip(ptree1)) 24 | expect_true(all.equal(read.newick(nwk_file), read.tree(nwk_file))) 25 | expect_true('support' %in% names(read.newick(nwk_file, "support")@data)) 26 | }) 27 | -------------------------------------------------------------------------------- /man/jplace-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/AllClasses.R 3 | \docType{class} 4 | \name{jplace-class} 5 | \alias{jplace-class} 6 | \title{Class "jplace" 7 | This class stores phylogenetic placements} 8 | \description{ 9 | Class "jplace" 10 | This class stores phylogenetic placements 11 | } 12 | \section{Slots}{ 13 | 14 | \describe{ 15 | \item{\code{phylo}}{phylo object for tree structure} 16 | 17 | \item{\code{treetext}}{newick tree string} 18 | 19 | \item{\code{data}}{associated data} 20 | 21 | \item{\code{extraInfo}}{extra information, reserve for merge_tree} 22 | 23 | \item{\code{file}}{tree file} 24 | 25 | \item{\code{placements}}{reserve for jplace file to store placement information} 26 | 27 | \item{\code{info}}{extra information, e.g. metadata, software version etc.} 28 | }} 29 | 30 | \author{ 31 | Guangchuang Yu \url{https://guangchuangyu.github.io} 32 | } 33 | \keyword{classes} 34 | -------------------------------------------------------------------------------- /man/write.beast.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/write-beast.R 3 | \name{write.beast} 4 | \alias{write.beast} 5 | \title{write.beast} 6 | \usage{ 7 | write.beast(treedata, file = "", translate = TRUE, tree.name = NULL) 8 | } 9 | \arguments{ 10 | \item{treedata}{\code{treedata} object, list of \code{treedata}, \code{phylo}, or list of \code{phylo}} 11 | 12 | \item{file}{output file. If file = "", print the output content on screen} 13 | 14 | \item{translate}{whether to translate taxa labels} 15 | 16 | \item{tree.name}{names of the trees, NULL to use existing tree names} 17 | } 18 | \value{ 19 | output file or file content on screen 20 | } 21 | \description{ 22 | Export \code{treedata} object to BEAST NEXUS file. This function was adopted and modified from ape::write.nexus 23 | } 24 | \examples{ 25 | nhxfile <- system.file("extdata/NHX", "phyldog.nhx", package="treeio") 26 | nhx <- read.nhx(nhxfile) 27 | write.beast(nhx) 28 | } 29 | \author{ 30 | Guangchuang Yu 31 | } 32 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Prerequisites 2 | 3 | + [ ] Have you read [Feedback](https://guangchuangyu.github.io/software/treeio/#feedback) and follow the [guide](https://guangchuangyu.github.io/2016/07/how-to-bug-author/)? 4 | * [ ] make sure your are using the latest release version 5 | * [ ] read the [documents](https://guangchuangyu.github.io/software/treeio/documentation/) 6 | * [ ] google your quesion/issue 7 | 8 | ### Describe you issue 9 | 10 | * [ ] Make a reproducible example (*e.g.* [1](https://gist.github.com/talonsensei/e1fad082657054207f249ec98f0920eb)) 11 | * [ ] your code should contain comments to describe the problem (*e.g.* what expected and actually happened?) 12 | 13 | 14 | ### Ask in right place 15 | 16 | * [ ] for bugs or feature requests, post here (github issue) 17 | * [ ] for questions, please post to [google group](https://groups.google.com/forum/#!forum/bioc-ggtree) 18 | 19 | 20 |
Session Info 21 | 22 | ```r 23 | 24 | ``` 25 |
26 | 27 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ## Description 8 | 9 | 10 | ## Related Issue 11 | 14 | 15 | ## Example 16 | 18 | 19 | 21 | 22 | -------------------------------------------------------------------------------- /R/codeml_mlc.R: -------------------------------------------------------------------------------- 1 | ##' read mlc file of codeml output 2 | ##' 3 | ##' 4 | ##' @title read.codeml_mlc 5 | ##' @param mlcfile mlc file 6 | ##' @return A \code{codeml_mlc} object 7 | ##' @importFrom dplyr select 8 | ##' @export 9 | ##' @author Guangchuang Yu 10 | ##' @examples 11 | ##' mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 12 | ##' read.codeml_mlc(mlcfile) 13 | read.codeml_mlc <- function(mlcfile) { 14 | ## tip_seq <- read.tip_seq_mlc(mlcfile) 15 | dNdS <- read.dnds_mlc(mlcfile) 16 | if (is.null(dNdS)) { 17 | message("no dNdS information found...") 18 | dNdS <- matrix(NA) 19 | fields <- "" 20 | } else { 21 | fields <- colnames(dNdS)[-c(1,2)] 22 | } 23 | 24 | res <- new("treedata", 25 | treetext = read.treetext_paml_mlc(mlcfile), 26 | phylo = read.phylo_paml_mlc(mlcfile), 27 | file = filename(mlcfile)) 28 | if (!is.null(dNdS)) { 29 | res@data <- as_tibble(dNdS) %>% select(-"parent") 30 | } 31 | return(res) 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /R/AllClasses.R: -------------------------------------------------------------------------------- 1 | ##' Class "jplace" 2 | ##' This class stores phylogenetic placements 3 | ##' 4 | ##' 5 | ##' @name jplace-class 6 | ##' @docType class 7 | ##' @slot phylo phylo object for tree structure 8 | ##' @slot treetext newick tree string 9 | ##' @slot data associated data 10 | ##' @slot extraInfo extra information, reserve for merge_tree 11 | ##' @slot file tree file 12 | ##' @slot placements reserve for jplace file to store placement information 13 | ##' @slot info extra information, e.g. metadata, software version etc. 14 | ##' @importClassesFrom tidytree treedata 15 | ##' @exportClass jplace 16 | ##' @author Guangchuang Yu \url{https://guangchuangyu.github.io} 17 | ##' @keywords classes 18 | setClass("jplace", 19 | representation = representation( 20 | placements = "tbl_df" 21 | ), 22 | prototype = prototype( 23 | placements = tibble::tibble() 24 | ), 25 | contains = "treedata" 26 | ) 27 | 28 | 29 | ##' @importFrom tidytree treedata 30 | ##' @export 31 | tidytree::treedata 32 | 33 | -------------------------------------------------------------------------------- /tests/testthat/test-as-phylo.R: -------------------------------------------------------------------------------- 1 | context("as.phylo") 2 | 3 | ## library(ggtree) 4 | 5 | ## in tree 1.3.4 and ggtree 1.11.4, converting tree to data.frame is deprecated. 6 | ## new treeio and ggtree supports tbl_tree object 7 | 8 | ## test_that("as.phylo for tbl_tree and ggtree", { 9 | ## p <- ggtree(rtree(30)) 10 | ## x <- as.phylo(p) ## as.phylo.ggtree -> as.phylo.data.frame 11 | ## msg <- capture.output(ape::checkValidPhylo(x)) 12 | ## expect_false(any(grepl("FATAL", msg))) 13 | ## }) 14 | 15 | test_that("as.phylo for tree igraph",{ 16 | tr <- rtree(10) 17 | g <- ape::as.igraph.phylo(tr) 18 | tr2 <- as.phylo(g) 19 | expect_true(is(tr2, 'phylo')) 20 | expect_true(all(tr$tip.label %in% tr2$tip.label)) 21 | expect_equal(tr$Nnode, tr2$Nnode) 22 | }) 23 | 24 | test_that("as.phylo for tree igraph with weights",{ 25 | set.seed(123) 26 | g <- igraph::sample_gnp(18, .3) %>% 27 | igraph::mst() %>% 28 | igraph::set_edge_attr(name='weight', value=abs(rnorm(length(igraph::E(.))))) 29 | tr <- as.phylo(g, branch.length = weight) 30 | expect_true(is(tr, 'phylo')) 31 | 32 | } 33 | ) 34 | -------------------------------------------------------------------------------- /R/paml_rst.R: -------------------------------------------------------------------------------- 1 | 2 | ##' read rst file from paml (both baseml and codeml) output 3 | ##' 4 | ##' 5 | ##' @title read.paml_rst 6 | ##' @param rstfile rst file 7 | ##' @param type one of 'Marginal' or 'Joint' 8 | ##' @return A \code{treedata} object 9 | ##' @export 10 | ##' @author Guangchuang Yu \url{https://guangchuangyu.github.io} 11 | ##' @examples 12 | ##' rstfile <- system.file("extdata/PAML_Baseml", "rst", package="treeio") 13 | ##' read.paml_rst(rstfile) 14 | read.paml_rst <- function(rstfile, type = "Joint") { 15 | phylo <- read.phylo_paml_rst(rstfile) 16 | seqs <- read.ancseq_paml_rst(rstfile, by = type) 17 | seq_type <- get_seqtype(seqs[1]) 18 | seqs <- string2DNAbin(seqs) 19 | 20 | tip_seq <- seqs[labels(seqs) %in% phylo$tip.label] 21 | anc_seq <- seqs[!labels(seqs) %in% phylo$tip.label] 22 | 23 | 24 | res <- new("treedata", 25 | treetext = read.treetext_paml_rst(rstfile), 26 | phylo = phylo, 27 | seq_type = seq_type, 28 | anc_seq = anc_seq, 29 | tip_seq = tip_seq, 30 | file = filename(rstfile), 31 | info = list(type = type) 32 | ) 33 | 34 | set_substitution(res) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - R_VERSION: devel 4 | R_ARCH: x64 5 | USE_RTOOLS: true 6 | _R_CHECK_FORCE_SUGGESTS_: false 7 | 8 | # DO NOT CHANGE the "init" and "install" sections below 9 | 10 | # Download script file from GitHub 11 | init: 12 | ps: | 13 | $ErrorActionPreference = "Stop" 14 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 15 | Import-Module '..\appveyor-tool.ps1' 16 | 17 | install: 18 | ps: Bootstrap 19 | 20 | # Adapt as necessary starting from here 21 | 22 | build_script: 23 | - travis-tool.sh install_bioc Biostrings 24 | - travis-tool.sh install_deps 25 | 26 | test_script: 27 | - travis-tool.sh run_tests 28 | 29 | on_failure: 30 | - 7z a failure.zip *.Rcheck\* 31 | - appveyor PushArtifact failure.zip 32 | 33 | artifacts: 34 | - path: '*.Rcheck\**\*.log' 35 | name: Logs 36 | 37 | - path: '*.Rcheck\**\*.out' 38 | name: Logs 39 | 40 | - path: '*.Rcheck\**\*.fail' 41 | name: Logs 42 | 43 | - path: '*.Rcheck\**\*.Rout' 44 | name: Logs 45 | 46 | - path: '\*_*.tar.gz' 47 | name: Linux Package 48 | 49 | - path: '\*_*.zip' 50 | name: Windows Package 51 | -------------------------------------------------------------------------------- /man/read.treeqza.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/treeqza.R 3 | \name{read.treeqza} 4 | \alias{read.treeqza} 5 | \title{read.treeqza} 6 | \usage{ 7 | read.treeqza(treeqza, node.label = "label", ...) 8 | } 9 | \arguments{ 10 | \item{treeqza}{the qiime2 output file contained tree file.} 11 | 12 | \item{node.label}{parse node label as 'label' or 'support' value.} 13 | 14 | \item{...}{additional parameter, passed to 'read.tree'.} 15 | } 16 | \value{ 17 | phylo tree object or treedata object when node.label was parsed 'support'. 18 | } 19 | \description{ 20 | read.treeqza 21 | } 22 | \examples{ 23 | qzafile1 <- system.file("extdata/qiime2treeqza", "fasttree-tree.qza", package="treeio") 24 | qzafile2 <- system.file("extdata/qiime2treeqza", "iqt-tree.qza", package="treeio") 25 | qzafile3 <- system.file("extdata/qiime2treeqza", "raxml-cat-tree.qza", package="treeio") 26 | tr1 <- read.treeqza(qzafile1) 27 | tr1 28 | tr2 <- read.treeqza(qzafile2) 29 | tr2 30 | tr3 <- read.treeqza(qzafile3) 31 | tr3 32 | # parse node label as 'support' value. 33 | qzafile4 <- system.file("extdata/qiime2treeqza", "raxml-cat-bootstrap-tree.qza", package="treeio") 34 | tr4 <- read.treeqza(qzafile4, node.label="support") 35 | tr4 36 | } 37 | -------------------------------------------------------------------------------- /man/spt-methods.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/method-spt.R 3 | \name{spt} 4 | \alias{spt} 5 | \title{spt method} 6 | \usage{ 7 | spt(x, from, to, weights = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a igraph object} 11 | 12 | \item{from}{a specific node of network.} 13 | 14 | \item{to}{other nodes of the network, length of it must 15 | be larger than 2.} 16 | 17 | \item{weights}{a numeric vector giving edge weights or a character. 18 | If this is \code{NULL} and the graph has a \code{weight} edge attribute, 19 | then the attribute is used. If this is \code{NA} then no weights 20 | are used even if the graph has a \code{weight} attribute. If this is a 21 | character, the graph has the edge attribute which is numeric, then it 22 | will be used, default is \code{NULL}.} 23 | 24 | \item{...}{additional parameters} 25 | } 26 | \value{ 27 | phylo object 28 | } 29 | \description{ 30 | spt method 31 | } 32 | \examples{ 33 | library(igraph) 34 | set.seed(123) 35 | g <- igraph::sample_gnp(100, .1) \%>\% 36 | set_edge_attr(name='weight', value=abs(rnorm(E(.),3))) 37 | tr1 <- spt(g, from = 6, to=V(g), weights = 'weight') 38 | tr1 39 | tr2 <- spt(g, from = 6, to = V(g), weights = NA) 40 | tr2 41 | } 42 | -------------------------------------------------------------------------------- /R/RAxML.R: -------------------------------------------------------------------------------- 1 | ##' parse RAxML bootstrapping analysis output 2 | ##' 3 | ##' 4 | ##' @title read.raxml 5 | ##' @param file RAxML bootstrapping analysis output 6 | ##' @return treedata object 7 | ##' @export 8 | ##' @examples 9 | ##' raxml_file <- system.file("extdata/RAxML", "RAxML_bipartitionsBranchLabels.H3", package="treeio") 10 | ##' read.raxml(raxml_file) 11 | ##' @author Guangchuang Yu 12 | read.raxml <- function(file) { 13 | tree.text <- readLines(file, warn=FALSE) 14 | tree_text <- gsub('(:[0-9\\.eE+\\-]+)\\[(\\d+)\\]', '\\@\\2\\1', tree.text) 15 | phylo <- read.tree(text=tree_text) 16 | if(any(grepl('@', phylo$node.label))) { 17 | bootstrap <- suppressWarnings( 18 | as.numeric(gsub("[^@]*@(\\d+)", "\\1", phylo$node.label)) 19 | ) 20 | phylo$node.label <- gsub("@\\d+", "", phylo$node.label) 21 | } 22 | 23 | if (all(phylo$node.label == "")) { 24 | phylo$node.label <- NULL 25 | } 26 | 27 | bootstrap <- tibble(node = Ntip(phylo) + 1:phylo$Nnode, 28 | bootstrap = bootstrap) 29 | 30 | new("treedata", 31 | file = filename(file), 32 | treetext = tree.text, 33 | phylo = phylo, 34 | data = bootstrap 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /man/write.beast.newick.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/write-beast.R 3 | \name{write.beast.newick} 4 | \alias{write.beast.newick} 5 | \title{write.beast.newick} 6 | \usage{ 7 | write.beast.newick( 8 | treedata, 9 | file = "", 10 | append = FALSE, 11 | digits = 10, 12 | tree.prefix = "" 13 | ) 14 | } 15 | \arguments{ 16 | \item{treedata}{\code{treedata} object} 17 | 18 | \item{file}{output file. If file = "", print the output content on screen} 19 | 20 | \item{append}{logical. Only used if the argument 'file' is the name of file 21 | (and not a connection or "|cmd"). If 'TRUE' output will be appended to 22 | 'file'; otherwise, it will overwrite the contents of file.} 23 | 24 | \item{digits}{integer, the indicating the number of decimal places, default is 10.} 25 | 26 | \item{tree.prefix, }{character the tree prefix, default is "".} 27 | } 28 | \value{ 29 | output file or file content on screen 30 | } 31 | \description{ 32 | Export \code{treedata} object to BEAST Newick file. This is useful for making BEAST starting trees with metadata 33 | } 34 | \examples{ 35 | nhxfile <- system.file("extdata/NHX", "phyldog.nhx", package="treeio") 36 | nhx <- read.nhx(nhxfile) 37 | write.beast.newick(nhx) 38 | } 39 | \author{ 40 | Guangchuang Yu 41 | } 42 | -------------------------------------------------------------------------------- /R/mega.R: -------------------------------------------------------------------------------- 1 | ##' parse tabular output of MEGA 2 | ##' 3 | ##' 4 | ##' @title read.mega_tabular 5 | ##' @param file MEGA tabular file 6 | ##' @return treedata object 7 | ##' @export 8 | ##' @author Guangchuang Yu 9 | read.mega_tabular <- function(file) { 10 | ## output of MEGA 7 has "datafile=X", while output of MEGA X may not 11 | skip <- ifelse(grepl("datafile=", 12 | suppressMessages(scan(file, n = 1, what = character()))), 13 | 1, 0) 14 | check_installed('vroom', 'for `read.mega_tabular()`.') 15 | d <- suppressMessages(vroom::vroom(file, skip = skip)) 16 | d1 <- d[,c('NodeId','Des1')] %>% dplyr::rename(child=.data$Des1) 17 | d2 <- d[,c('NodeId','Des2')] %>% dplyr::rename(child=.data$Des2) 18 | dd <- dplyr::bind_rows(d1, d2) %>% dplyr::filter(child != '-') 19 | 20 | d <- dplyr::mutate(d, label = as.character(.data$NodeId)) 21 | 22 | obj <- as.phylo(dd) %>% as_tibble %>% 23 | dplyr::full_join(d, by='label') %>% 24 | dplyr::mutate(label=sub("^-$", "", .data$NodeLabel)) %>% 25 | dplyr::select(-c('NodeLabel', 'NodeId', 'Des1', 'Des2')) %>% 26 | as.treedata 27 | 28 | obj@file <- filename(file) 29 | return(obj) 30 | } 31 | 32 | ##' @rdname beast-parser 33 | ##' @export 34 | read.mega <- read.beast 35 | -------------------------------------------------------------------------------- /R/ASTRAL.R: -------------------------------------------------------------------------------- 1 | ##' parse ASTRAL output newick text 2 | ##' 3 | ##' 4 | ##' @title read.astral 5 | ##' @param file ASTRAL Newick file 6 | ##' @return treedata object 7 | ##' @export 8 | ##' @author Guangchuang Yu 9 | ##' @examples 10 | ##' tt <- paste0( 11 | ##' "((species1,(species2,species3)'[pp1=0.75;pp2=0.24;pp3=0.01]':", 12 | ##' "1.2003685744180805)'[pp1=0.98;pp2=0.02;pp3=0]':0.9679599282730038,", 13 | ##' "((species4,species5)'[pp1=0.88;pp2=0.11;pp3=0.01]':1.2454851536484994))" 14 | ##' ) 15 | ##' read.astral(textConnection(tt)) 16 | read.astral <- function(file) { 17 | treetext <- readLines(file, warn=FALSE) 18 | treetext <- gsub(";", "$", treetext) %>% 19 | gsub("'\\[", "@", .) %>% 20 | gsub("]'", "@", .) 21 | 22 | if (substring(treetext, nchar(treetext), nchar(treetext)) != ';') 23 | treetext <- paste0(treetext, ";") 24 | 25 | phylo <- read.tree(text = treetext) 26 | stats <- phylo$node.label %>% 27 | gsub("^@|@$", "", .) %>% 28 | gsub("\\$", ":", .) %>% 29 | get_nhx_feature 30 | 31 | stats <- convert_to_numeric(dat=stats) %>% as_tibble() 32 | 33 | stats$node <- Ntip(phylo) + 1:phylo$Nnode 34 | 35 | phylo$node.label <- NULL 36 | 37 | new("treedata", 38 | file = filename(file), 39 | phylo = phylo, 40 | data = stats 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /man/beast-parser.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beast.R, R/mega.R 3 | \name{read.beast} 4 | \alias{read.beast} 5 | \alias{read.mrbayes} 6 | \alias{read.beast.newick} 7 | \alias{read.mega} 8 | \title{read.beast} 9 | \usage{ 10 | read.beast(file, threads = 1, verbose = FALSE) 11 | 12 | read.mrbayes(file, threads = 1, verbose = FALSE) 13 | 14 | read.beast.newick(file, threads = 1, verbose = FALSE) 15 | 16 | read.mega(file, threads = 1, verbose = FALSE) 17 | } 18 | \arguments{ 19 | \item{file}{newick file} 20 | 21 | \item{threads}{number of threads for multithreading (default: 1)} 22 | 23 | \item{verbose}{set TRUE to log progress (default: FALSE)} 24 | } 25 | \value{ 26 | treedata object 27 | 28 | treedata object 29 | } 30 | \description{ 31 | read beast/mrbayes/mega Nexus output 32 | 33 | read beast/mrbayes/mega newick file format 34 | } 35 | \examples{ 36 | file <- system.file("extdata/BEAST", "beast_mcc.tree", package="treeio") 37 | read.beast(file) 38 | file <- system.file("extdata/MrBayes", "Gq_nxs.tre", package="treeio") 39 | read.mrbayes(file) 40 | tr <- read.beast.newick( 41 | textConnection( 42 | '(a[&rate=1]:2,(b[&rate=1.1]:1,c[&rate=0.9]:1)[&rate=1]:1);' 43 | ) 44 | ) 45 | } 46 | \author{ 47 | Guangchuang Yu \url{https://guangchuangyu.github.io} 48 | 49 | Bradley R Jones 50 | } 51 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | [Bradley Jones](https://github.com/brj1) 2 | ------------- 3 | + beast1 tree support 4 | - 5 | 6 | [Casey Dunn](https://github.com/caseywdunn) 7 | ---------- 8 | + `drop.tip` method 9 | - 10 | - 11 | - 12 | + add tip number in NHX annotation data 13 | - 14 | + use `textConnection` to pass string to the `file` parameter. 15 | - 16 | 17 | [Shuangbin Xu](https://github.com/xiangpin) 18 | ---------- 19 | + parse phyloxml file 20 | - 21 | - 22 | + parse `n` and `nm` in jplace when they coexists 23 | - 24 | + jplace version 1 support 25 | - 26 | 27 | [Tyler Bradley](https://github.com/tbradley1013) 28 | ------------ 29 | + `tree_subset` methods for `phylo` and `treedata` objects 30 | - 31 | 32 | 33 | [Konstantinos Geles](https://github.com/ConYel) 34 | ------------ 35 | + prototype of `as.treedata` method for `pvclust` object 36 | 37 | 38 | -------------------------------------------------------------------------------- /R/codeml.R: -------------------------------------------------------------------------------- 1 | ##' read baseml output 2 | ##' 3 | ##' 4 | ##' @title read.codeml 5 | ##' @param rstfile rst file 6 | ##' @param mlcfile mlc file 7 | ##' @param tree one of 'mlc' or 'rst' 8 | ##' @param type one of 'Marginal' or 'Joint' 9 | ##' @return A \code{treedata} object 10 | ##' @export 11 | ##' @author Guangchuang Yu 12 | ##' @examples 13 | ##' rstfile <- system.file("extdata/PAML_Codeml", "rst", package="treeio") 14 | ##' mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 15 | ##' read.codeml(rstfile, mlcfile) 16 | read.codeml <- function(rstfile, mlcfile, tree = "mlc", type = "Joint") { 17 | tree <- match.arg(tree, c("mlc", "rst")) 18 | 19 | rst <- read.paml_rst(rstfile, type=type) 20 | mlc <- read.codeml_mlc(mlcfile) 21 | 22 | res <- rst 23 | res@file <- c(res@file, mlc@file) 24 | if (tree == 'mlc') { 25 | res@phylo <- as.phylo(mlc) 26 | res@treetext <- mlc@treetext 27 | } 28 | 29 | if (nrow(res@data) == 0) { 30 | res@data <- mlc@data 31 | } else { 32 | res@data <- full_join(res@data, mlc@data, by = 'node') 33 | } 34 | 35 | if (nrow(res@extraInfo) == 0) { 36 | res@extraInfo <- mlc@extraInfo 37 | } else { 38 | res@extraInfo <- full_join(res@extraInfo, mlc@extraInfo, by = "node") 39 | } 40 | 41 | res@info <- c(res@info, mlc@info) 42 | return(res) 43 | } 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /R/rename.R: -------------------------------------------------------------------------------- 1 | ##' rename tip label of phylogenetic tree 2 | ##' 3 | ##' 4 | ##' @title rename_taxa 5 | ##' @param tree tree object, either treedata or phylo 6 | ##' @param data data frame 7 | ##' @param key column in data that match tip label (use 1st column by default) 8 | ##' @param value column in data for rename tip label (use 2nd column by default) 9 | ##' @importFrom rlang enexpr 10 | ##' @importFrom rlang quo_name 11 | ##' @export 12 | ##' @return tree object 13 | ##' @examples 14 | ##' tree <- rtree(3) 15 | ##' d <- data.frame(old = paste0('t', 1:3), new = LETTERS[1:3]) 16 | ##' rename_taxa(tree, d) 17 | ##' rename_taxa(tree, d, old, new) 18 | ##' @author Guangchuang Yu 19 | rename_taxa <- function(tree, data, key = 1, value = 2) { 20 | phylo <- as.phylo(tree) 21 | 22 | key_var <- enexpr(key) 23 | value_var <- enexpr(value) 24 | 25 | if (!is.numeric(key_var)) 26 | key_var <- quo_name(key_var) 27 | if (!is.numeric(value_var)) 28 | value_var <- quo_name(value_var) 29 | 30 | idx <- match(phylo$tip.label, as.character(data[[key_var]])) 31 | if (anyNA(idx)) { 32 | stop("taxa name not match, please check your input...") 33 | } 34 | phylo$tip.label <- as.character(data[[value_var]][idx]) 35 | 36 | if (!is(tree, "phylo")) { 37 | tree@phylo <- phylo 38 | } else { 39 | return(phylo) 40 | } 41 | return(tree) 42 | } 43 | 44 | -------------------------------------------------------------------------------- /inst/extdata/NHX/phyldog.nhx: -------------------------------------------------------------------------------- 1 | (((Prayidae_D27SS7@2825365:0.0682841[&&NHX:Ev=S:S=58:ND=0],(Kephyes_ovata@2606431:0.0193941[&&NHX:Ev=S:S=69:ND=1],Chuniphyes_multidentata@1277217:0.0121378[&&NHX:Ev=S:S=70:ND=2]):0.0217782[&&NHX:Ev=S:S=60:ND=3]):0.0607598[&&NHX:Ev=S:S=36:ND=4],((Apolemia_sp_@1353964:0.11832[&&NHX:Ev=S:S=31:ND=9],(((Bargmannia_amoena@263997:0.0144549[&&NHX:Ev=S:S=37:ND=10],Bargmannia_elongata@946788:0.0149723[&&NHX:Ev=S:S=38:ND=11]):0.0925388[&&NHX:Ev=S:S=33:ND=12],Physonect_sp_@2066767:0.077429[&&NHX:Ev=S:S=61:ND=13]):0.0274637[&&NHX:Ev=S:S=24:ND=14],(Stephalia_dilata@2960089:0.0761163[&&NHX:Ev=S:S=52:ND=15],((Frillagalma_vityazi@1155031:0.0906068[&&NHX:Ev=S:S=53:ND=16],Resomia_ornicephala@3111757:1e-06[&&NHX:Ev=S:S=54:ND=17]):1e-06[&&NHX:Ev=S:S=45:ND=18],((Lychnagalma_utricularia@2253871:0.120851[&&NHX:Ev=S:S=65:ND=19],Nanomia_bijuga@717864:0.133939[&&NHX:Ev=S:S=71:ND=20]):1e-06[&&NHX:Ev=S:S=56:ND=21],Cordagalma_sp_@1525873:0.0693814[&&NHX:Ev=S:S=64:ND=22]):1e-06[&&NHX:Ev=S:S=46:ND=23]):0.0333823[&&NHX:Ev=S:S=40:ND=24]):1e-06[&&NHX:Ev=S:S=35:ND=25]):0.0431861[&&NHX:Ev=D:S=24:ND=26]):1e-06[&&NHX:Ev=S:S=19:ND=27],Rhizophysa_filiformis@3073669:0.22283[&&NHX:Ev=S:S=26:ND=28]):0.0292362[&&NHX:Ev=S:S=17:ND=29]):0.185603[&&NHX:Ev=D:S=17:ND=8],(Hydra_magnipapillata@52244:0.0621782[&&NHX:Ev=S:S=16:ND=5],Ectopleura_larynx@3556167:0.332505[&&NHX:Ev=S:S=15:ND=6]):0.185603[&&NHX:Ev=S:S=12:ND=7])[&&NHX:Ev=S:S=9:ND=30]; 2 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /tests/testthat/test-jplace.R: -------------------------------------------------------------------------------- 1 | context("jplace input") 2 | 3 | library(treeio) 4 | file1 <- system.file("extdata", "ref35extend.jplace", package="treeio") 5 | file2 <- system.file("extdata", "upwelling.jplace", package="treeio") 6 | jp1 <- read.jplace(file1) 7 | jp2 <- read.jplace(file2) 8 | 9 | test_that("read.jplace should work for old version jplace",{ 10 | expect_true(is(jp1, "jplace")) 11 | expect_true(is(jp2, "jplace")) 12 | }) 13 | 14 | library(jsonlite) 15 | js1 <- fromJSON(file1) 16 | js2 <- fromJSON(file2) 17 | numplace <- function(p_field, n_field){ 18 | p_nrow <- ifelse(is.null(nrow(p_field)), 1, nrow(p_field)) 19 | n_nrow <- ifelse(is.matrix(n_field), nrow(n_field), length(n_field)) 20 | return (p_nrow * n_nrow) 21 | } 22 | 23 | nrowplace1 <- sum(unlist(mapply(numplace, js1$placements$p, js1$placements$n, SIMPLIFY=FALSE))) 24 | js2_names <- mapply(treeio:::mergenm,js2$placements$n, js2$placements$nm, SIMPLIFY=FALSE) 25 | nrowplace2 <- sum(unlist(mapply(numplace, js2$placements$p, js2_names, SIMPLIFY=FALSE))) 26 | 27 | test_that("check the nrow of placements.",{ 28 | jt1 <- treeio:::jplace_treetext_to_phylo(js1$tree) 29 | jt2 <- treeio:::jplace_treetext_to_phylo(js2$tree) 30 | expect_true(is(jt1, "phylo")) 31 | expect_true(is(jt2, "phylo")) 32 | jplacement1 <- treeio:::extract.placement(js1, jt1) 33 | jplacement2 <- treeio:::extract.placement(js2, jt2) 34 | expect_equal(nrow(jplacement1), nrowplace1) 35 | expect_equal(nrow(jplacement2), nrowplace2) 36 | }) 37 | -------------------------------------------------------------------------------- /tests/testthat/test-treedata-accessor.R: -------------------------------------------------------------------------------- 1 | context("accessor") 2 | 3 | library(treeio) 4 | library(tidytree) 5 | 6 | jp <- system.file("extdata", "sample.jplace", package="treeio") 7 | x <- read.jplace(jp) 8 | pp <- get.placements(x) 9 | 10 | test_that("access placements slot for jplace object", { 11 | expect_true(is(x, "jplace")) 12 | expect_equal(nrow(pp), 3) 13 | expect_equal(ncol(pp), 7) 14 | expect_true('likelihood' %in% names(pp)) 15 | }) 16 | 17 | mlcfile <- system.file("extdata/PAML_Codeml", "mlc", package="treeio") 18 | mlc <- read.codeml_mlc(mlcfile) 19 | 20 | tree <- read.tree(text = tidytree::get.treetext(mlc)) 21 | 22 | test_that("access treetext slot for treedata object", { 23 | expect_true(ape::all.equal.phylo(mlc@phylo, tree, use.tip.label=FALSE)) 24 | }) 25 | 26 | test_that("is.rooted method for treedata object", { 27 | expect_equal(is.rooted(mlc), ape::is.rooted(as.phylo(mlc))) 28 | }) 29 | 30 | test_that("convert edgeNum to nodeNum", { 31 | expect_true(is.numeric(treeio:::edgeNum2nodeNum(x, 3))) 32 | expect_true(is.na(treeio:::edgeNum2nodeNum(x, 100))) 33 | }) 34 | 35 | p <- ggtree::ggtree(mlc) 36 | 37 | test_that("access phylo slot", { 38 | expect_true(is(get.tree(mlc), "phylo")) 39 | expect_true(is(as.phylo(p), "phylo")) 40 | expect_true(is.ggtree(p)) 41 | }) 42 | 43 | phy <- rtree(30) 44 | nn <- treeio:::getNodeName(phy) 45 | test_that("access node name", { 46 | expect_equal(nn[1:Ntip(phy)], phy$tip.label) 47 | expect_equal(nn[1:Nnode(phy) + Ntip(phy)], 48 | as.character(1:Nnode(phy) + Ntip(phy))) 49 | expect_equal(treeio:::tipIds(phy), 1:Ntip(phy)) 50 | }) 51 | 52 | 53 | -------------------------------------------------------------------------------- /R/treeqza.R: -------------------------------------------------------------------------------- 1 | #' @title read.treeqza 2 | #' @param treeqza the qiime2 output file contained tree file. 3 | #' @param node.label parse node label as 'label' or 'support' value. 4 | #' @param ... additional parameter, passed to 'read.tree'. 5 | #' @return phylo tree object or treedata object when node.label was parsed 'support'. 6 | #' @export 7 | #' @examples 8 | #' qzafile1 <- system.file("extdata/qiime2treeqza", "fasttree-tree.qza", package="treeio") 9 | #' qzafile2 <- system.file("extdata/qiime2treeqza", "iqt-tree.qza", package="treeio") 10 | #' qzafile3 <- system.file("extdata/qiime2treeqza", "raxml-cat-tree.qza", package="treeio") 11 | #' tr1 <- read.treeqza(qzafile1) 12 | #' tr1 13 | #' tr2 <- read.treeqza(qzafile2) 14 | #' tr2 15 | #' tr3 <- read.treeqza(qzafile3) 16 | #' tr3 17 | #' # parse node label as 'support' value. 18 | #' qzafile4 <- system.file("extdata/qiime2treeqza", "raxml-cat-bootstrap-tree.qza", package="treeio") 19 | #' tr4 <- read.treeqza(qzafile4, node.label="support") 20 | #' tr4 21 | read.treeqza <- function(treeqza, node.label = "label", ...){ 22 | tmpdir <- tempdir() 23 | unzipfiles <- utils::unzip(treeqza, exdir=tmpdir) 24 | metadafile <- unzipfiles[grep("metadata.yaml", unzipfiles)[1]] 25 | check_installed('yaml', 'for `read.treeqza()`.') 26 | metaflag <- yaml::read_yaml(metadafile) 27 | formatflag <- metaflag$format 28 | if (formatflag!="NewickDirectoryFormat"){ 29 | stop("Please check whether treeqza file contained tree file!") 30 | }else{ 31 | datafile <- unzipfiles[grep("data/tree.nwk", unzipfiles)] 32 | x <- read.newick(datafile, node.label=node.label, ...) 33 | return (x) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/treeio-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/treeio-package.R 3 | \docType{package} 4 | \name{treeio-package} 5 | \alias{treeio} 6 | \alias{treeio-package} 7 | \title{treeio: Base Classes and Functions for Phylogenetic Tree Input and Output} 8 | \description{ 9 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} 10 | 11 | 'treeio' is an R package to make it easier to import and store phylogenetic tree with associated data; and to link external data from different sources to phylogeny. It also supports exporting phylogenetic tree with heterogeneous associated data to a single tree file and can be served as a platform for merging tree with associated data and converting file formats. 12 | } 13 | \seealso{ 14 | Useful links: 15 | \itemize{ 16 | \item \url{https://yulab-smu.top/contribution-tree-data/} 17 | \item Report bugs at \url{https://github.com/YuLab-SMU/treeio/issues} 18 | } 19 | 20 | } 21 | \author{ 22 | \strong{Maintainer}: Guangchuang Yu \email{guangchuangyu@gmail.com} (\href{https://orcid.org/0000-0002-6485-8781}{ORCID}) 23 | 24 | Other contributors: 25 | \itemize{ 26 | \item Tommy Tsan-Yuk Lam \email{tylam.tommy@gmail.com} [contributor, thesis advisor] 27 | \item Shuangbin Xu \email{xshuangbin@163.com} (\href{https://orcid.org/0000-0003-3513-5362}{ORCID}) [contributor] 28 | \item Bradley Jones \email{brj1@sfu.ca} [contributor] 29 | \item Casey Dunn \email{casey_dunn@brown.edu} [contributor] 30 | \item Tyler Bradley \email{tcb85@drexel.edu} [contributor] 31 | \item Konstantinos Geles \email{konstantinos.geles@studenti.unicz.it} [contributor] 32 | } 33 | 34 | } 35 | \keyword{internal} 36 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING # 2 | 3 | ### Bugs? 4 | 5 | * Submit an issue on the [Issues page](https://github.com/GuangchuangYu/treeio/issues) 6 | 7 | ### Issues and Pull Requests 8 | 9 | If you are considering a pull request, you may want to open an issue first to discuss with the maintainer(s). 10 | 11 | ### Code contributions 12 | 13 | * Fork this repo to your GitHub account 14 | * Clone your version on your account down to your machine from your account, e.g,. `git clone https://github.com//{repo}.git` 15 | * Make sure to track progress upstream (i.e., on our version of `treeio` at `GuangchuangYu/treeio`) by doing `git remote add upstream https://github.com/GuangchuangYu/treeio.git`. Before making changes make sure to pull changes in from upstream by doing either `git fetch upstream` then merge later or `git pull upstream` to fetch and merge in one step 16 | * Make your changes (bonus points for making changes on a new feature branch - see for how to contribute by branching, making changes, then submitting a pull request) 17 | * Push up to your account 18 | * Submit a pull request to home base (likely master branch, but check to make sure) at `GuangchuangYu/treeio` 19 | 20 | ### Discussion forum 21 | 22 | Check out our [discussion forum](https://discuss.ropensci.org) if you think your issue requires a longer form discussion. 23 | 24 | ### Prefer to Email? 25 | 26 | Email the person listed as maintainer in the `DESCRIPTION` file of this repo. 27 | 28 | Though note that private discussions over email don't help others - of course email is totally warranted if it's a sensitive problem of any kind. 29 | 30 | ### Thanks for contributing! 31 | -------------------------------------------------------------------------------- /R/reexport.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom magrittr %>% 2 | ##' @export 3 | magrittr::`%>%` 4 | 5 | ##' @importFrom magrittr %<>% 6 | ##' @export 7 | magrittr::`%<>%` 8 | 9 | ##' @import tidytree 10 | NULL 11 | 12 | ##' @importFrom tidytree get.fields 13 | ##' @export 14 | tidytree::get.fields 15 | 16 | ##' @importFrom tidytree get.data 17 | ##' @export 18 | tidytree::get.data 19 | 20 | ##' @importFrom tidytree as.treedata 21 | ##' @export 22 | tidytree::as.treedata 23 | 24 | ##' @importFrom tidytree ancestor 25 | ##' @export 26 | tidytree::ancestor 27 | 28 | ##' @importFrom tidytree parent 29 | ##' @export 30 | tidytree::parent 31 | 32 | ##' @importFrom tidytree child 33 | ##' @export 34 | tidytree::child 35 | 36 | ##' @importFrom tidytree offspring 37 | ##' @export 38 | tidytree::offspring 39 | 40 | ##' @importFrom tidytree rootnode 41 | ##' @export 42 | tidytree::rootnode 43 | 44 | ##' @importFrom tidytree nodeid 45 | ##' @export 46 | tidytree::nodeid 47 | 48 | ##' @importFrom tidytree nodelab 49 | ##' @export 50 | tidytree::nodelab 51 | 52 | ##' @importFrom tidytree MRCA 53 | ##' @export 54 | tidytree::MRCA 55 | 56 | 57 | ##' @importFrom dplyr full_join 58 | ##' @export 59 | dplyr::full_join 60 | 61 | 62 | ##' @importFrom dplyr inner_join 63 | ##' @export 64 | dplyr::inner_join 65 | 66 | ##' @importFrom tibble as_tibble 67 | ##' @export 68 | tibble::as_tibble 69 | 70 | ##' @importFrom tibble tibble 71 | ##' @export 72 | tibble::tibble 73 | 74 | ##' @importFrom tidytree as.phylo 75 | ##' @export 76 | tidytree::as.phylo 77 | 78 | ##' @importFrom rlang .data 79 | ##' @export 80 | rlang::.data 81 | 82 | ##' @importFrom tidytree drop.tip 83 | ##' @export 84 | tidytree::drop.tip 85 | 86 | ##' @importFrom tidytree isTip 87 | ##' @export 88 | tidytree::isTip 89 | -------------------------------------------------------------------------------- /R/rescale_tree.R: -------------------------------------------------------------------------------- 1 | 2 | ##' @importFrom tidytree get_tree_data 3 | set_branch_length <- function(tree_object, branch.length) { 4 | if (branch.length == "branch.length") { 5 | return(tree_object) 6 | } else if (branch.length == "none") { 7 | tree_object@phylo$edge.length <- NULL 8 | return(tree_object) 9 | } 10 | 11 | if (is(tree_object, "phylo")) { 12 | return(tree_object) 13 | } 14 | 15 | tree_anno <- get_tree_data(tree_object) 16 | tree_anno$node <- as.integer(tree_anno$node) 17 | 18 | phylo <- as.phylo(tree_object) 19 | 20 | cn <- colnames(tree_anno) 21 | cn <- cn[!cn %in% c('node', 'parent')] 22 | 23 | length <- match.arg(branch.length, cn) 24 | 25 | if (all(is.na(as.numeric(tree_anno[[length]])))) { 26 | stop("branch.length should be numerical attributes...") 27 | } 28 | 29 | edge <- phylo$edge 30 | colnames(edge) <- c("parent", "node") 31 | edge <- as_tibble(edge) 32 | 33 | dd <- full_join(edge, tree_anno, by = "node") 34 | 35 | dd <- dd[match(edge[['node']], dd[['node']]),] 36 | len <- unlist(dd[[length]]) 37 | len <- as.numeric(len) 38 | len[is.na(len)] <- 0 39 | 40 | phylo$edge.length <- len 41 | 42 | tree_object@phylo <- phylo 43 | return(tree_object) 44 | } 45 | 46 | 47 | ##' rescale branch length of tree object 48 | ##' 49 | ##' 50 | ##' @title rescale_tree 51 | ##' @param tree_object tree object 52 | ##' @param branch.length numerical features (e.g. dN/dS) 53 | ##' @return update tree object 54 | ##' @export 55 | ##' @author Guangchuang Yu 56 | rescale_tree <- function(tree_object, branch.length) { 57 | tree_object <- set_branch_length(tree_object, branch.length) 58 | return(tree_object) 59 | } 60 | 61 | -------------------------------------------------------------------------------- /inst/extdata/MEGA7/mtCDNA_timetree_tabular.txt: -------------------------------------------------------------------------------- 1 | datafile=mtCDNA.meg 2 | NodeLabel NodeId Des1 Des2 RelTime CI_Lower CI_Upper Rate Data Coverage 3 | homo sapiens 1 - - - - - 1.148398 - 4 | chimpanzee 2 - - - - - 0.821388 - 5 | bonobo 3 - - - - - 0.808047 - 6 | gorilla 4 - - - - - 0.949742 - 7 | orangutan 5 - - - - - 1.348223 - 8 | sumatran 6 - - - - - 0.834008 - 9 | gibbon 7 - - - - - 1.008138 - 10 | - 8 2 3 0.077660 0.045061 0.110260 0.814690 100.00% 11 | - 9 8 1 0.210586 0.138713 0.282458 0.967258 100.00% 12 | demoLabel2 10 9 4 0.282288 0.200617 0.363958 0.958460 100.00% 13 | - 11 5 6 0.115252 0.076326 0.154178 1.060391 100.00% 14 | - 12 10 11 0.594076 0.439042 0.749109 1.008138 100.00% 15 | - 13 12 7 0.806409 - - 1.008138 100.00% 16 | -------------------------------------------------------------------------------- /R/reroot-utilities.R: -------------------------------------------------------------------------------- 1 | build_new_labels <- function(tree){ 2 | node2label_old <- tree %>% as_tibble() %>% dplyr::select(c("node", "label")) 3 | if (inherits(tree, "treedata")){ 4 | tree <- tree@phylo 5 | } 6 | tree$tip.label <- paste0("t", seq_len(Ntip(tree))) 7 | tree$node.label <- paste0("n", seq_len(Nnode(tree))) 8 | node2label_new <- tree %>% as_tibble() %>% dplyr::select(c("node", "label")) 9 | old_and_new <- node2label_old %>% 10 | dplyr::inner_join(node2label_new, by="node") %>% 11 | dplyr::rename(old="label.x", new="label.y") 12 | return (list(tree=tree, node2old_new_lab=old_and_new)) 13 | } 14 | 15 | build_new_tree <- function(tree, node2old_new_lab){ 16 | # replace new label with old label 17 | treeda <- tree %>% as_tibble() 18 | treeda1 <- treeda %>% 19 | dplyr::filter(.data$label %in% node2old_new_lab$new) 20 | treeda2 <- treeda %>% 21 | dplyr::filter(!(.data$label %in% node2old_new_lab$new)) 22 | # original label 23 | treeda1$label <- node2old_new_lab[match(treeda1$label, node2old_new_lab$new), "old"] %>% 24 | unlist(use.names=FALSE) 25 | treeda <- rbind(treeda1, treeda2) 26 | tree <- treeda[order(treeda$node),] %>% as.phylo() 27 | return (tree) 28 | } 29 | 30 | old_new_node_mapping <- function(oldtree, newtree){ 31 | treelab1 <- oldtree %>% 32 | as_tibble() %>% 33 | dplyr::select(c("node", "label")) 34 | treelab2 <- newtree %>% 35 | as_tibble() %>% 36 | dplyr::select(c("node", "label")) 37 | node_map <- dplyr::inner_join(treelab1, treelab2, by="label") %>% 38 | dplyr::select(c("node.x", "node.y")) %>% 39 | dplyr::rename(c(old="node.x", new="node.y")) 40 | return(node_map) 41 | } 42 | -------------------------------------------------------------------------------- /man/find.hclust.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/method-spt.R 3 | \name{find.hclust} 4 | \alias{find.hclust} 5 | \title{find the hierarchical cluster analysis among the nodes of graph 6 | based on the length of all the shortest paths in the graph.} 7 | \usage{ 8 | find.hclust( 9 | x, 10 | graph.mst = FALSE, 11 | weights = NULL, 12 | hclust.method = "average", 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{a igraph object} 18 | 19 | \item{graph.mst}{logical whether obtain the minimum spanning tree first 20 | then find.hclust, default is FALSE.} 21 | 22 | \item{weights}{a numeric vector giving edge weights or a character. 23 | If this is \code{NULL} and the graph has a \code{weight} edge attribute, 24 | then the attribute is used. If this is \code{NA} then no weights 25 | are used even if the graph has a \code{weight} attribute. If this is a 26 | character, the graph has the edge attribute which is numeric, then it 27 | will be used, default is \code{NULL}.} 28 | 29 | \item{hclust.method}{the agglomeration method to be used, This should be (an 30 | unambiguous abbreviation of) one of \code{"ward.D"}, \code{"ward.D2"}, 31 | \code{"single"}, \code{"complete"}, \code{"average"} (= UPGMA), \code{"mcquitty"} 32 | (= WPGMA), \code{"median"} (= WPGMC) or \code{"centroid"} (= UPGMC).} 33 | 34 | \item{...}{additional parameters} 35 | } 36 | \value{ 37 | hclust object 38 | } 39 | \description{ 40 | find the hierarchical cluster analysis among the nodes of graph 41 | based on the length of all the shortest paths in the graph. 42 | } 43 | \examples{ 44 | library(igraph) 45 | set.seed(123) 46 | g <- igraph::sample_gnp(100, .1) \%>\% 47 | set_edge_attr(name='weight', value=abs(rnorm(E(.),3))) 48 | tr1 <- find.hclust(g, weights = NA) 49 | tr2 <- find.hclust(g) 50 | tr3 <- find.hclust(g, graph.mst = TRUE) 51 | } 52 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PKGNAME := $(shell sed -n "s/Package: *\([^ ]*\)/\1/p" DESCRIPTION) 2 | PKGVERS := $(shell sed -n "s/Version: *\([^ ]*\)/\1/p" DESCRIPTION) 3 | PKGSRC := $(shell basename `pwd`) 4 | BIOCVER := RELEASE_3_22 5 | 6 | all: rd check clean 7 | 8 | alldocs: rd readme 9 | 10 | rd: 11 | Rscript -e 'library(methods); devtools::document()' 12 | 13 | readme: 14 | Rscript -e 'rmarkdown::render("README.Rmd")' 15 | 16 | codemetar: 17 | Rscript -e 'codemetar::write_codemeta()' 18 | 19 | sticker: 20 | Rscript -e 'source("treeio_sticker.R")'; 21 | rm Rplots.pdf 22 | 23 | build: 24 | #cd ..;\ 25 | # R CMD build $(PKGSRC) 26 | Rscript -e 'devtools::build()' 27 | 28 | build2: 29 | cd ..;\ 30 | R CMD build --no-build-vignettes $(PKGSRC) 31 | 32 | install: build 33 | cd ..;\ 34 | R CMD INSTALL $(PKGNAME)_$(PKGVERS).tar.gz 35 | 36 | 37 | check: 38 | # cd ..;\ 39 | # Rscript -e 'rcmdcheck::rcmdcheck("$(PKGNAME)_$(PKGVERS).tar.gz")' 40 | Rscript -e 'devtools::check()' 41 | 42 | check2: rd build 43 | cd ..;\ 44 | R CMD check $(PKGNAME)_$(PKGVERS).tar.gz 45 | 46 | check3: rd build2 47 | cd ..;\ 48 | R CMD check --ignore-vignettes $(PKGNAME)_$(PKGVERS).tar.gz 49 | 50 | bioccheck: 51 | cd ..;\ 52 | Rscript -e 'BiocCheck::BiocCheck("$(PKGNAME)_$(PKGVERS).tar.gz")' 53 | 54 | gpcheck: 55 | Rscript -e 'goodpractice::gp()' 56 | 57 | clean: 58 | cd ..;\ 59 | $(RM) -r $(PKGNAME).Rcheck/ 60 | 61 | 62 | gitmaintain: 63 | git gc --auto;\ 64 | git prune -v;\ 65 | git fsck --full 66 | 67 | rmrelease: 68 | git branch -D $(BIOCVER) 69 | 70 | release: 71 | git checkout $(BIOCVER);\ 72 | git fetch --all 73 | 74 | update: 75 | git fetch --all;\ 76 | git checkout devel;\ 77 | git merge upstream/devel;\ 78 | git merge origin/devel 79 | 80 | push: update 81 | git push upstream devel;\ 82 | git push origin devel 83 | 84 | biocinit: 85 | git remote add upstream git@git.bioconductor.org:packages/$(PKGNAME).git;\ 86 | git fetch --all 87 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite treeio in publications use:") 2 | 3 | bibentry( 4 | bibtype = "book", 5 | title = "Data Integration, Manipulation and Visualization of Phylogenetic Treess", 6 | author = person("Guangchuang", "Yu"), 7 | publisher = "Chapman and Hall/{CRC}", 8 | year = "2022", 9 | edition = "1st edition", 10 | url = "https://www.amazon.com/Integration-Manipulation-Visualization-Phylogenetic-Computational-ebook/dp/B0B5NLZR1Z/", 11 | textVersion = paste("Guangchuang Yu. (2022).", 12 | "Data Integration, Manipulation and Visualization of Phylogenetic Trees (1st edition).", 13 | "Chapman and Hall/CRC.") 14 | ) 15 | 16 | bibentry( 17 | bibtype = "article", 18 | title = "treeio: an R package for phylogenetic tree input and output with richly annotated and associated data.", 19 | author = c( 20 | person("Li-Gen", "Wang"), 21 | person("Tommy Tsan-Yuk", "Lam"), 22 | person("Shuangbin", "Xu"), 23 | person("Zehan", "Dai"), 24 | person("Lang", "Zhou"), 25 | person("Tingze", "Feng"), 26 | person("Pingfan", "Guo"), 27 | person("Casey W.", "Dunn"), 28 | person("Bradley R.", "Jones"), 29 | person("Tyler", "Bradley"), 30 | person("Huachen", "Zhu"), 31 | person("Yi", "Guan"), 32 | person("Yong", "Jiang"), 33 | person("Guangchuang", "Yu") 34 | ), 35 | year = "2020", 36 | journal = "Molecular Biology and Evolution", 37 | volume = "37", 38 | issue = "2", 39 | number = "", 40 | pages = "599-603", 41 | doi = "10.1093/molbev/msz240", 42 | PMID = "", 43 | url = "", 44 | textVersion = paste("LG Wang, TTY Lam, S Xu, Z Dai, L Zhou, T Feng, P Guo, CW Dunn, BR Jones, T Bradley, H Zhu, Y Guan, Y Jiang, G Yu.", 45 | "treeio: an R package for phylogenetic tree input and output with richly annotated and associated data.", 46 | "Molecular Biology and Evolution 2020, 37(2):599-603. doi: 10.1093/molbev/msz240") 47 | 48 | ) 49 | 50 | 51 | -------------------------------------------------------------------------------- /R/mask.R: -------------------------------------------------------------------------------- 1 | ##' site mask 2 | ##' 3 | ##' 4 | ##' @title mask 5 | ##' @param tree_object tree object 6 | ##' @param field selected field 7 | ##' @param site site 8 | ##' @param mask_site if TRUE, site will be masked. 9 | ##' if FALSE, selected site will not be masked, while other sites will be masked. 10 | ##' @return updated tree object 11 | ##' @export 12 | ##' @author Guangchuang Yu 13 | mask <- function(tree_object, field, site, mask_site=FALSE) { 14 | if (! field %in% get.fields(tree_object)) { 15 | stop("'field' is not available in 'tree_object'...") 16 | } 17 | 18 | in_data_slot <- TRUE 19 | if (field %in% colnames(tree_object@data)) { 20 | field_data <- tree_object@data[[field]] 21 | } else { 22 | field_data <- tree_object@extraInfo[[field]] 23 | in_data_slot <- FALSE 24 | } 25 | 26 | ## field_data <- sapply(field_data, gsub, pattern="\n", replacement="/") 27 | tbl <- tibble(field = field_data, id = seq_along(field_data)) %>% 28 | filter(!is.na(.data$field)) %>% filter(.data$field != "") 29 | 30 | tokens <- strsplit(tbl$field, " / ") 31 | lpos <- lapply(tokens, function(x) { 32 | gsub("^[a-zA-Z]+", "", x) %>% 33 | gsub("[a-zA-Z]\\s*$", "", .) %>% 34 | as.numeric 35 | }) 36 | 37 | pos <- unique(unlist(lpos)) 38 | 39 | if (mask_site == FALSE) { 40 | pos2 <- 1:max(pos) 41 | pos2 <- pos2[-site] 42 | site <- pos2 43 | } 44 | 45 | site <- site[site %in% pos] 46 | 47 | for (i in seq_along(tbl$field)) { 48 | if (any(lpos[[i]] %in% site)) { 49 | j <- which(lpos[[i]] %in% site) 50 | x <- paste(tokens[[i]][-j], collapse = " / ") 51 | if (length(x) == 0) { 52 | tbl$field[[i]] <- "" 53 | } else { 54 | tbl$field[[i]] <- x 55 | } 56 | } 57 | } 58 | 59 | field_data[tbl$id] <- tbl$field 60 | 61 | if (in_data_slot) { 62 | tree_object@data[[field]] <- field_data 63 | } else { 64 | tree_object@extraInfo[[field]] <- field_data 65 | } 66 | 67 | tree_object 68 | } 69 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: treeio 2 | Title: Base Classes and Functions for Phylogenetic Tree Input and Output 3 | Version: 1.35.0 4 | Authors@R: c( 5 | person("Guangchuang", "Yu", email = "guangchuangyu@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-6485-8781")), 6 | person("Tommy Tsan-Yuk", "Lam", email = "tylam.tommy@gmail.com", role = c("ctb", "ths")), 7 | person("Shuangbin", "Xu", email = "xshuangbin@163.com", role = "ctb", comment = c(ORCID="0000-0003-3513-5362")), 8 | person("Bradley", "Jones", email = "brj1@sfu.ca", role = "ctb"), 9 | person("Casey", "Dunn", email = "casey_dunn@brown.edu", role = "ctb"), 10 | person("Tyler", "Bradley", email = "tcb85@drexel.edu", role = "ctb"), 11 | person("Konstantinos", "Geles", email = "konstantinos.geles@studenti.unicz.it", role = "ctb") 12 | ) 13 | Description: 'treeio' is an R package to make it easier to import and store phylogenetic tree with associated data; and to link external data from different sources to phylogeny. It also supports exporting phylogenetic tree with heterogeneous associated data to a single tree file and can be served as a platform for merging tree with associated data and converting file formats. 14 | Depends: 15 | R (>= 3.6.0) 16 | Imports: 17 | ape, 18 | dplyr, 19 | jsonlite, 20 | magrittr, 21 | methods, 22 | rlang, 23 | stats, 24 | tibble, 25 | tidytree (>= 0.4.5), 26 | utils, 27 | yulab.utils (>= 0.1.6) 28 | Suggests: 29 | Biostrings, 30 | cli, 31 | ggplot2, 32 | ggtree, 33 | igraph, 34 | knitr, 35 | rmarkdown, 36 | phangorn, 37 | prettydoc, 38 | purrr, 39 | testthat, 40 | tidyr, 41 | vroom, 42 | xml2, 43 | yaml 44 | VignetteBuilder: knitr 45 | ByteCompile: true 46 | License: Artistic-2.0 47 | Encoding: UTF-8 48 | URL: https://yulab-smu.top/contribution-tree-data/ 49 | BugReports: https://github.com/YuLab-SMU/treeio/issues 50 | biocViews: Software, Annotation, Clustering, DataImport, DataRepresentation, 51 | Alignment, MultipleSequenceAlignment, Phylogenetics 52 | RoxygenNote: 7.3.2 53 | -------------------------------------------------------------------------------- /R/write-jplace.R: -------------------------------------------------------------------------------- 1 | ##' Export \code{jplace} object to jplace file. 2 | ##' @title write.jplace 3 | ##' @param x a jplace object. 4 | ##' @param outfile the output file name 5 | ##' @export 6 | ##' @examples 7 | ##' jp <- system.file("extdata", "sample.jplace", package="treeio") 8 | ##' tr1 <- read.jplace(jp) 9 | ##' outfile <- tempfile() 10 | ##' write.jplace(tr1, outfile) 11 | ##' tr2 <- read.jplace(outfile) 12 | ##' tr2 13 | write.jplace <- function(x, outfile){ 14 | if (!inherits(x, 'jplace')){ 15 | cli::cli_abort("The {.fn write.jplace} only works with {.cls {'jplace'}} class now, but a {.cls {class(x)}} class was provided.") 16 | } 17 | fields <- setdiff( colnames(x@placements), c('name', 'node') ) 18 | 19 | placements.char <- .obtain.placement.char(x@placements, fields) 20 | 21 | fields.char <- paste0('["',paste0(fields, collapse='","'),'"]') 22 | 23 | out <- file(outfile, "w") 24 | 25 | writeLines("{", out) 26 | 27 | tree.char <- paste0('\t"tree": "', x@treetext, '",') 28 | 29 | writeLines(tree.char, out) 30 | 31 | writeLines(paste0('\t"placements": ', placements.char, ','), out) 32 | 33 | writeLines('\t"metadata": {"info": "generated by treeio package"},', out) 34 | 35 | writeLines(paste0('\t"version": ', x@info$version, ","), out) 36 | 37 | writeLines(paste0('\t"fields": ', fields.char), out) 38 | 39 | writeLines("\n}", out) 40 | 41 | close(out) 42 | 43 | } 44 | 45 | .obtain.placement.char <- function(placements, fields){ 46 | rlang::check_installed('tidyr', 'for the `write.jplace()`.') 47 | placements.char <- placements |> 48 | dplyr::select(-"node") |> 49 | tidyr::nest(p=! .data$name) |> 50 | dplyr::rename(n='name') |> 51 | jsonlite::toJSON() 52 | 53 | pattern <- paste0(paste0("\"", fields, "\":"), collapse="|") 54 | placements.char <- gsub(pattern, "", placements.char) 55 | placements.char <- placements.char %>% 56 | chartr("{}", "[]", .) %>% 57 | gsub("\\],\\[\"n","\\},\\{\"n",.) %>% 58 | sub("^\\[\\[", "[{",.) %>% 59 | sub("\\]\\]$","}]",.) 60 | 61 | return(placements.char) 62 | } 63 | -------------------------------------------------------------------------------- /inst/extdata/MEGA7/mtCDNA_timetree.nex: -------------------------------------------------------------------------------- 1 | #NEXUS 2 | 3 | Begin Taxa; 4 | Dimensions ntax=7; 5 | TaxLabels 6 | homo_sapiens 7 | chimpanzee 8 | bonobo 9 | gorilla 10 | orangutan 11 | sumatran 12 | gibbon 13 | ; 14 | End; 15 | 16 | Begin Trees; 17 | Translate 18 | 1 homo_sapiens, 19 | 2 chimpanzee, 20 | 3 bonobo, 21 | 4 gorilla, 22 | 5 orangutan, 23 | 6 sumatran, 24 | 7 gibbon 25 | ; 26 | tree TREE1 = [&R] (((((2[&rate=8.21387638458966E-001,branch_length=6.27635980985610E-002]:7.76603755686346E-002,3[&rate=8.08047027678532E-001,branch_length=6.17442197999256E-002]:7.76603755686346E-002)[&rate=8.14690026837604E-001,branch_length=1.06551791913040E-001,reltime=7.76603755686346E-002,reltime_stderr=1.66322225004909E-002,reltime_95%_CI={4.50612194676725E-002,1.10259531669597E-001},data_coverage=100%]:1.32925460715114E-001,1[&rate=1.14839817218159E+000,branch_length=2.37947876847083E-001]:2.10585836283749E-001)[&rate=9.67258258023612E-001,branch_length=6.82392048602499E-002,reltime=2.10585836283749E-001,reltime_stderr=3.66695942566917E-002,reltime_95%_CI={1.38713431540633E-001,2.82458241026865E-001},data_coverage=100%]:7.17020095880709E-002,4[&rate=9.49741644253964E-001,branch_length=2.63789706511460E-001]:2.82287845871820E-001)[&rate=9.58459935726878E-001,branch_length=2.94031112947650E-001,reltime=2.82287845871820E-001,reltime_stderr=4.16686354669857E-002,reltime_95%_CI={2.00617320356528E-001,3.63958371387112E-001},data_coverage=100%]:3.11787816307430E-001,(5[&rate=1.34822289815278E+000,branch_length=1.52886612438902E-001]:1.15251762438322E-001,6[&rate=8.34007596053647E-001,branch_length=9.45753081954446E-002]:1.15251762438322E-001)[&rate=1.06039055929072E+000,branch_length=4.99576332711077E-001,reltime=1.15251762438322E-001,reltime_stderr=1.98603068330366E-002,reltime_95%_CI={7.63255610455702E-002,1.54177963831074E-001},data_coverage=100%]:4.78823899740928E-001)[&rate=1.00813782158154E+000,branch_length=2.10619528131437E-001,reltime=5.94075662179250E-001,reltime_stderr=7.90987567922010E-002,reltime_95%_CI={4.39042098866536E-001,7.49109225491964E-001},data_coverage=100%]:2.12333512272958E-001,7[&rate=1.00813782158154E+000,branch_length=7.99899733140789E-001]:8.06409174452208E-001); 27 | End; 28 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/AllClasses.R, R/ape.R, R/method-as-phylo.R, 3 | % R/reexport.R 4 | \docType{import} 5 | \name{reexports} 6 | \alias{reexports} 7 | \alias{treedata} 8 | \alias{read.tree} 9 | \alias{read.nexus} 10 | \alias{rtree} 11 | \alias{write.tree} 12 | \alias{write.nexus} 13 | \alias{Nnode} 14 | \alias{Ntip} 15 | \alias{is.rooted} 16 | \alias{root} 17 | \alias{as.phylo} 18 | \alias{\%>\%} 19 | \alias{\%<>\%} 20 | \alias{get.fields} 21 | \alias{get.data} 22 | \alias{as.treedata} 23 | \alias{ancestor} 24 | \alias{parent} 25 | \alias{child} 26 | \alias{offspring} 27 | \alias{rootnode} 28 | \alias{nodeid} 29 | \alias{nodelab} 30 | \alias{MRCA} 31 | \alias{full_join} 32 | \alias{inner_join} 33 | \alias{as_tibble} 34 | \alias{tibble} 35 | \alias{.data} 36 | \alias{drop.tip} 37 | \alias{isTip} 38 | \title{Objects exported from other packages} 39 | \keyword{internal} 40 | \description{ 41 | These objects are imported from other packages. Follow the links 42 | below to see their documentation. 43 | 44 | \describe{ 45 | \item{ape}{\code{\link[ape]{as.phylo}}, \code{\link[ape:root]{is.rooted}}, \code{\link[ape:summary.phylo]{Nnode}}, \code{\link[ape:summary.phylo]{Ntip}}, \code{\link[ape]{read.nexus}}, \code{\link[ape]{read.tree}}, \code{\link[ape]{root}}, \code{\link[ape]{rtree}}, \code{\link[ape]{write.nexus}}, \code{\link[ape]{write.tree}}} 46 | 47 | \item{dplyr}{\code{\link[dplyr:mutate-joins]{full_join}}, \code{\link[dplyr:mutate-joins]{inner_join}}} 48 | 49 | \item{magrittr}{\code{\link[magrittr:compound]{\%<>\%}}, \code{\link[magrittr:pipe]{\%>\%}}} 50 | 51 | \item{rlang}{\code{\link[rlang:dot-data]{.data}}} 52 | 53 | \item{tibble}{\code{\link[tibble]{as_tibble}}, \code{\link[tibble]{tibble}}} 54 | 55 | \item{tidytree}{\code{\link[tidytree]{ancestor}}, \code{\link[tidytree:reexports]{as.phylo}}, \code{\link[tidytree]{as.treedata}}, \code{\link[tidytree]{child}}, \code{\link[tidytree:drop.tip-methods]{drop.tip}}, \code{\link[tidytree:get.data-methods]{get.data}}, \code{\link[tidytree:get.fields-methods]{get.fields}}, \code{\link[tidytree]{isTip}}, \code{\link[tidytree]{MRCA}}, \code{\link[tidytree]{nodeid}}, \code{\link[tidytree]{nodelab}}, \code{\link[tidytree]{offspring}}, \code{\link[tidytree]{parent}}, \code{\link[tidytree]{rootnode}}, \code{\link[tidytree]{treedata}}} 56 | }} 57 | 58 | -------------------------------------------------------------------------------- /R/MCMCTree.R: -------------------------------------------------------------------------------- 1 | ##' read MCMCTree output Tree 2 | ##' 3 | ##' @title read.mcmctree 4 | ##' @param file the output tree file of MCMCTree 5 | ##' @param force.ultrametric logical whether convert the tree 6 | ##' to be ultrametric, if it is not ultrametric, default is FALSE. 7 | ##' When the tree is ultrametric, branch times will be calculated 8 | ##' automatically. 9 | ##' @return treedata object 10 | ##' @export 11 | ##' @examples 12 | ##' file <- system.file("extdata/MCMCTree", "mcmctree_output.tree", package="treeio") 13 | ##' tr <- read.mcmctree(file) 14 | ##' tr 15 | read.mcmctree <- function(file, force.ultrametric = FALSE){ 16 | text <- readLines(file) 17 | ind <- grep("^.*tree.*=.*", text, ignore.case=TRUE) 18 | text[ind] <- gsub("^.*TREE", "TREE", text[ind], ignore.case=TRUE) 19 | text <- paste(text, collapse="\n") 20 | newfile <- tempfile() 21 | writeLines(text, newfile) 22 | obj <- read.beast(file=newfile) 23 | if(inherits(obj, "treedata")){ 24 | obj@file <- filename(file) 25 | obj <- add.branch.time.mcmctree( 26 | obj=obj, 27 | force.ultrametric = force.ultrametric, 28 | ) 29 | }else{ 30 | for (i in seq_len(length(obj))){ 31 | obj[[i]]@file <- filename(file) 32 | obj[[i]] <- add.branch.time.mcmctree( 33 | obj=obj[[i]], 34 | force.ultrametric = force.ultrametric 35 | ) 36 | } 37 | } 38 | return(obj) 39 | } 40 | 41 | #' @importFrom ape branching.times 42 | #' @importFrom ape is.ultrametric 43 | add.branch.time.mcmctree <- function(obj, force.ultrametric=FALSE, ...){ 44 | flag_ultrametric <- is.ultrametric(obj@phylo, option=2) || is.ultrametric(obj@phylo) 45 | if (force.ultrametric && flag_ultrametric){ 46 | message("This tree is not ultrametric, and you has set force.ultrametric to TRUE, so the tree will be converted to ultrametric automatically!") 47 | obj <- as.ultrametric(obj) 48 | } 49 | if (flag_ultrametric){ 50 | xx <- branching.times(obj@phylo) 51 | ntip <- Ntip(obj) 52 | N <- Nnode(obj, internal.only = FALSE) 53 | xx <- data.frame(node=as.character((ntip+1):N), reltime=as.vector(xx)) 54 | obj@data <- full_join(obj@data, xx, by="node") 55 | } 56 | return(obj) 57 | } 58 | -------------------------------------------------------------------------------- /R/jtree.R: -------------------------------------------------------------------------------- 1 | ##' Import tree data from jtree file, which is JSON-based text and probably output by write.jtree 2 | ##' 3 | ##' 4 | ##' @title read.jtree 5 | ##' @rdname read-jtree 6 | ##' @param file tree file 7 | ##' @return treedata object 8 | ##' @export 9 | ##' @author Guangchuang Yu 10 | read.jtree <- function(file) { 11 | jtree <- fromJSON(file) 12 | phylo <- jplace_treetext_to_phylo(jtree$tree) 13 | edgeNum.df <- attr(phylo, "edgeNum") 14 | d <- merge(edgeNum.df, jtree$data, by.x = "edgeNum", by.y = "edge_num") %>% 15 | as_tibble %>% select(- "edgeNum") 16 | new("treedata", 17 | treetext = jtree$tree, 18 | phylo = phylo, 19 | data = d, 20 | file = filename(file) 21 | ) 22 | } 23 | 24 | 25 | ##' Export \code{treedata} object to json tree file 26 | ##' 27 | ##' 28 | ##' @title write.jtree 29 | ##' @rdname write-jtree 30 | ##' @param treedata \code{treedata} object 31 | ##' @param file output file. If file = "", print the output content on screen 32 | ##' @return output file or file content on screen 33 | ##' @importFrom jsonlite toJSON 34 | ##' @importFrom dplyr rename 35 | ##' @export 36 | ##' @author Guangchuang Yu 37 | write.jtree <- function(treedata, file = "") { 38 | phylo <- as.phylo(treedata) 39 | ntip <- Ntip(phylo) 40 | N <- Nnode(phylo, internal.only=FALSE) 41 | tip.label <- phylo[["tip.label"]] 42 | 43 | label <- rep("", N) 44 | 45 | label[1:ntip] <- tip.label 46 | if ( !is.null(phylo$node.label) ) { 47 | label[(ntip+1):N] <- phylo$node.label 48 | } 49 | 50 | label.df <- tibble(node=1:N, label=label) 51 | label.df$label <- paste0(label.df$label, '@@', label.df$node) 52 | 53 | phylo$tip.label <- label.df$label[label.df$node <= ntip] 54 | phylo$node.label <- label.df$label[label.df$node > ntip] 55 | 56 | tt <- write.tree(phylo) 57 | if (is.null(phylo$edge.length)) { 58 | tree_text <- gsub("@@(\\d+)\\D", "{\\1}", tt) 59 | } else { 60 | tree_text <- gsub("@@(\\d+)(:[\\.0-9]+)", "\\2{\\1}", tt) %>% 61 | sub("@@(\\d+)", "{\\1}", .) 62 | } 63 | 64 | buffer <- c("{\n") 65 | buffer <- c(buffer, paste0('\t"tree": "', tree_text, '",\n')) 66 | buffer <- c(buffer, '\t"data":') 67 | 68 | data <- get_tree_data(treedata) 69 | cn <- colnames(data) 70 | data <- data[, c("node", cn[cn != "node"])] 71 | data <- rename(data, edge_num="node") 72 | 73 | buffer <- c(buffer, toJSON(data, pretty=TRUE)) 74 | 75 | metainfo <- ',\n\t"metadata": {"info": "R-package treeio", ' 76 | metainfo <- paste0(metainfo, '"data": ', paste0('"', date(), '"'), '}\n') 77 | buffer <- c(buffer, metainfo) 78 | buffer <- c(buffer, "}\n") 79 | 80 | writeLines(buffer, file) 81 | 82 | invisible(buffer) 83 | } 84 | -------------------------------------------------------------------------------- /inst/extdata/NHX/notung.nhx: -------------------------------------------------------------------------------- 1 | ((((Rhizophysa_filiformis@2564549:0.09666991738603078[&&NHX:S=Rhizophysa_filiformis],((Marrus_claudanielis@2027078:0.03368582974818837[&&NHX:S=Marrus_claudanielis],((Erenna_richardi@1434201:0.014306889954561298[&&NHX:S=Erenna_richardi],Marrus_claudanielis@2027079:0.010842363778569869[&&NHX:S=Marrus_claudanielis])n5940011:0.01779384958849464[&&NHX:S=n57:D=N],(((Agalma_elegans@88626:0.05872379503260147[&&NHX:S=Agalma_elegans],Lychnagalma_utricularia@1828459:0.04211137470826968[&&NHX:S=Lychnagalma_utricularia])n5940018:0.02375590664436535[&&NHX:S=n47:D=N],(((Bargmannia_amoena@3459111:0.19058396964770352[&&NHX:S=Bargmannia_amoena],Bargmannia_elongata@469437:1.00000050002909E-6[&&NHX:S=Bargmannia_elongata])n5939974:0.11560220708003867[&&NHX:S=n22:D=N],Cordagalma_sp_@1115328:0.04829417133033771[&&NHX:S=Cordagalma_sp_])n5939976:0.011316847557531757[&&NHX:S=n62:D=N],Forskalia_asymmetrica@1220430:0.01667566952752948[&&NHX:S=Forskalia_asymmetrica])n5939978:0.0063213422810751655[&&NHX:S=n62:D=Y])n5940014:0.017792661031819083[&&NHX:S=n62:D=Y],(Resomia_ornicephala@2657185:0.004262563771468986[&&NHX:S=Resomia_ornicephala],Frillagalma_vityazi@663744:0.028441637105547157[&&NHX:S=Frillagalma_vityazi])n5939981:0.006136291467151878[&&NHX:S=n51:D=N])n5940013:0.013546839136761205[&&NHX:S=n62:D=Y])n5940012:0.011839606018978143[&&NHX:S=n62:D=Y])n5940008:0.013840645450221475[&&NHX:S=n62:D=Y],(((Chelophyes_appendiculata@1615707:0.007647023552225329[&&NHX:S=Chelophyes_appendiculata],Clytia_hemisphaerica@756642:0.643907456299178[&&NHX:S=Clytia_hemisphaerica])n5939984:0.08603691877960613[&&NHX:S=n67:D=N],(Chuniphyes_multidentata@930929:0.01248550133310033[&&NHX:S=Chuniphyes_multidentata],Kephyes_ovata@1966030:0.014671165587181996[&&NHX:S=Kephyes_ovata])n5939987:0.013285803501636162[&&NHX:S=n27:D=N])n5939988:0.008000411801689693[&&NHX:S=n67:D=Y],(((Hippopodius_hippopus@1084434:0.0505718831943577[&&NHX:S=Hippopodius_hippopus],Prayidae_D27D2@2878798:0.00905875758406546[&&NHX:S=Prayidae_D27D2])n5939991:0.021772123626769023[&&NHX:S=n38:D=N],Prayidae_D27SS7@2181711:0.029009000260863272[&&NHX:S=Prayidae_D27SS7])n5939993:1.00000050002909E-6[&&NHX:S=n38:D=Y],Prayidae_D27D2@2878801:1.00000050002909E-6[&&NHX:S=Prayidae_D27D2])n5939995:0.00916688375355408[&&NHX:S=n38:D=Y])n5939996:0.05191099091093772[&&NHX:S=n67:D=Y])n5940006:0.03953811931719265[&&NHX:S=n67:D=Y])n5940005:0.10134081070615458[&&NHX:S=n67:D=Y],(Podocoryna_carnea@3033951:0.11270255504816476[&&NHX:S=Podocoryna_carnea],Hydractinia_symbiolongicarpus@1679508:0.030168043235021993[&&NHX:S=Hydractinia_symbiolongicarpus])n5939999:0.17223048099362362[&&NHX:S=n11:D=N])n5940003:0.16233679521228994[&&NHX:S=n67:D=Y],Hydra_magnipapillata@801936:0.585696573276294[&&NHX:S=Hydra_magnipapillata])n5940002:0.4403044529817829[&&NHX:S=n68:D=N],Aegina_citrea@825314:0.4403044529817829[&&NHX:S=Aegina_citrea])n5942419[&&NHX:S=n70:D=N]; 2 | -------------------------------------------------------------------------------- /R/phylip.R: -------------------------------------------------------------------------------- 1 | ##' parsing phylip tree format 2 | ##' 3 | ##' 4 | ##' @title read.phylip 5 | ##' @param file phylip file 6 | ##' @return an instance of 'phylip' 7 | ##' @export 8 | ##' @examples 9 | ##' phyfile <- system.file("extdata", "sample.phy", package="treeio") 10 | ##' read.phylip(phyfile) 11 | ##' @author Guangchuang Yu 12 | read.phylip <- function(file) { 13 | tree <- read.phylip.tree(file) 14 | if (is(tree, 'multiPhylo')) { 15 | msg <- paste("input file contains multiple trees and", 16 | "it is currently not supported ...") 17 | stop(msg) 18 | } 19 | new("treedata", 20 | file = filename(file), 21 | phylo = tree, 22 | tip_seq = read.phylip.seq(file) 23 | ) 24 | } 25 | 26 | ##' read aligned sequences from phylip format 27 | ##' 28 | ##' 29 | ##' @title read.phylip.seq 30 | ##' @param file phylip file, currently only sequential format is supported 31 | ##' @return DNAbin object 32 | ##' @export 33 | ##' @author Guangchuang Yu 34 | ##' @references \url{http://evolution.genetics.washington.edu/phylip/doc/sequence.html} 35 | read.phylip.seq <- function(file) { 36 | phylip <- readLines(file) 37 | 38 | phylipInfo <- strsplit(phylip[1], split="\\s") %>% unlist 39 | nseq <- phylipInfo[1] 40 | seqLen <- phylipInfo[2] 41 | 42 | if (nchar(sub('.+\\s+', "", phylip[2])) != phylipInfo[2]) { 43 | stop("only sequential format is supported...") 44 | } 45 | seqlines <- phylip[1+(1:phylipInfo[1])] 46 | seq_with_name <- lapply(seqlines, function(x) unlist(strsplit(x, "\\s+"))) 47 | seqs <- vapply(seq_with_name, function(x) x[2], character(1)) 48 | names(seqs) <- vapply(seq_with_name, function(x) x[1], character(1)) 49 | 50 | if (any(nchar(seqs) != seqLen)) { 51 | stop(paste("sequence length not consistent...\n->", 52 | paste0(nchar(seqs), collapse=" "))) 53 | } 54 | 55 | res <- string2DNAbin(seqs) 56 | attr(res, "seq_type") <- get_seqtype(seqs[1]) 57 | return(res) 58 | } 59 | 60 | 61 | ##' parse tree from phylip file 62 | ##' 63 | ##' 64 | ##' @title read.phylip.tree 65 | ##' @param file phylip file 66 | ##' @return phylo or multiPhylo object 67 | ##' @export 68 | ##' @author Guangchuang Yu 69 | read.phylip.tree <- function(file) { 70 | phylip <- readLines(file) 71 | i <- grep("^\\d+$", phylip) 72 | if (length(i) != 1) { 73 | stop("input file is not phylip tree format...") 74 | } 75 | n <- length(phylip) 76 | ntree <- as.numeric(phylip[i]) 77 | trees <- read.tree(text=phylip[(i+1):n]) 78 | return(trees) 79 | } 80 | 81 | getPhyInfo <- function(phy) { 82 | line1 <- readLines(phy, n=1) 83 | res <- strsplit(line1, split="\\s")[[1]] 84 | res <- res[res != ""] 85 | 86 | return(list(num=as.numeric(res[1]), width=as.numeric(res[2]))) 87 | } 88 | -------------------------------------------------------------------------------- /inst/extdata/phyloxml/test_x2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A phylogenetic tree 5 | Some description 6 | 7 | 8 | 0.38003517943434417248 9 | 10 | 0.77744522131979465485 11 | 12 | 0.93470523110590875149 13 | 14 | t7 15 | 0.21214252128265798092 16 | 17 | 18 | 0.65167376608587801456 19 | 20 | t2 21 | 0.12555509596131742001 22 | 23 | 24 | t3 25 | 0.26722066872753202915 26 | 27 | 28 | 29 | 30 | t8 31 | 0.38611409254372119904 32 | 33 | 34 | 35 | 0.01339033315889537334 36 | 37 | 0.38238795707002282143 38 | 39 | t1 40 | 0.86969084572046995163 41 | 42 | 43 | t5 44 | 0.34034899668768048286 45 | 46 | 47 | 48 | 0.48208011547103524208 49 | 50 | t6 51 | 0.59956582542508840561 52 | 53 | 54 | 0.49354130704887211323 55 | 56 | t9 57 | 0.18621760141104459763 58 | 59 | 60 | t10 61 | 0.82737331860698759556 62 | 63 | 64 | 65 | 66 | 67 | 68 | t4 69 | 0.66846673819236457348 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /R/tree-utilities.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | ##' label branch for PAML to infer selection pressure using branch model 4 | ##' 5 | ##' 6 | ##' @title label_branch_paml 7 | ##' @param tree phylo object 8 | ##' @param node node number 9 | ##' @param label label of branch, e.g. #1 10 | ##' @return updated phylo object 11 | ##' @export 12 | ##' @author Guangchuang Yu 13 | label_branch_paml <- function(tree, node, label) { 14 | sp_id <- offspring(tree, node) 15 | tip_id <- sp_id[sp_id <= Ntip(tree)] 16 | node_id <- c(node, sp_id[sp_id > Ntip(tree)]) 17 | tree$tip.label[tip_id] <- paste(tree$tip.label[tip_id], label) 18 | if (is.null(tree$node.label)) { 19 | tree$node.label <- rep("", Nnode(tree)) 20 | } 21 | node_index <- node_id - Ntip(tree) 22 | tree$node.label[node_index] <- paste(tree$node.label[node_index], label) 23 | return(tree) 24 | } 25 | 26 | 27 | tipIds <- function(tree) { 28 | 1:Ntip(tree) 29 | } 30 | 31 | nodeIds <- function(tree, internal.only=TRUE) { 32 | if (internal.only) { 33 | return(Ntip(tree) + 1:Nnode(tree, internal.only)) 34 | } 35 | 1:Nnode(tree, internal.only) 36 | } 37 | 38 | 39 | ##' calculate total number of nodes 40 | ##' 41 | ##' 42 | ##' @title getNodeNum 43 | ##' @param tree tree object 44 | ##' @return number 45 | ##' @export 46 | ##' @examples 47 | ##' getNodeNum(rtree(30)) 48 | ##' @author Guangchuang Yu 49 | getNodeNum <- function(tree) { 50 | Nnode(tree, internal.only=FALSE) 51 | } 52 | 53 | ##' @rdname getNodeNum 54 | ##' @export 55 | ##' @examples 56 | ##' Nnode2(rtree(30)) 57 | Nnode2 <- getNodeNum 58 | 59 | 60 | ##' test whether input object is produced by ggtree function 61 | ##' 62 | ##' 63 | ##' @title is.ggtree 64 | ##' @param x object 65 | ##' @return TRUE or FALSE 66 | ##' @export 67 | ##' @author Guangchuang Yu 68 | is.ggtree <- function(x) { 69 | if (inherits(x, 'ggtree')) return(TRUE) 70 | 71 | if (!inherits(x, 'gg')) return(FALSE) 72 | 73 | ## to compatible with user using `ggplot(tree) + geom_tree()` 74 | 75 | tree_layer <- vapply(x$layers, 76 | function(y) { 77 | any(grepl("StatTree", class(y$stat))) 78 | }, 79 | logical(1) 80 | ) 81 | return(any(tree_layer)) 82 | } 83 | 84 | 85 | 86 | getNodeName <- function(tr) { 87 | if (is.null(tr$node.label)) { 88 | n <- Ntip(tr) 89 | nl <- 1:Nnode(tr) + n 90 | nl <- as.character(nl) 91 | } 92 | else { 93 | nl <- tr$node.label 94 | } 95 | nodeName <- c(tr$tip.label, nl) 96 | return(nodeName) 97 | } 98 | 99 | 100 | .extract_annotda.treedata <- getFromNamespace('.extract_annotda.treedata', 'tidytree') 101 | 102 | .internal_nest <- getFromNamespace('.internal_nest', 'tidytree') 103 | 104 | .update.td.join <- getFromNamespace('.update.td.join', 'tidytree') 105 | 106 | -------------------------------------------------------------------------------- /R/merge_tree.R: -------------------------------------------------------------------------------- 1 | ##' merge two tree object 2 | ##' 3 | ##' 4 | ##' @title merge_tree 5 | ##' @param obj1 tree object 1 6 | ##' @param obj2 tree object 2 7 | ##' @return tree object 8 | ##' @importFrom dplyr full_join 9 | ##' @export 10 | ##' @author Guangchuang Yu 11 | merge_tree <- function(obj1, obj2) { 12 | ## 13 | ## INFO: 14 | ## ape::all.equal.phylo can be used to test equal phylo topology. 15 | ## 16 | 17 | if (has.slot(obj1, "extraInfo") == FALSE) { 18 | stop("input tree object is not supported...") 19 | } 20 | 21 | if ((is.tree(obj1) & is.tree(obj2)) == FALSE) { 22 | stop("input should be tree objects...") 23 | } 24 | 25 | if (nrow(obj2@data) == 0 && nrow(obj2@extraInfo) == 0) 26 | return(obj1) 27 | 28 | 29 | tr1 <- as.phylo(obj1) 30 | tr2 <- as.phylo(obj2) 31 | 32 | if (getNodeNum(tr1) != getNodeNum(tr2)) { 33 | stop("number of nodes not equals...") 34 | } 35 | 36 | if (Ntip(tr1) != Ntip(tr2)) { 37 | stop("number of tips not equals...") 38 | } 39 | 40 | if (all(tr1$tip.label %in% tr2$tip.label) == FALSE) { 41 | stop("tip names not match...") 42 | } 43 | 44 | idx <- match(tr2$tip.label, tr1$tip.label) 45 | 46 | node_map <- list() 47 | ## node_map$from %<>% c(1:Ntip(tr2)) 48 | ## node_map$to %<>% c(idx) 49 | node_map$from <- c(node_map$from, 1:Ntip(tr2)) 50 | node_map$to <- c(node_map$to, idx) 51 | 52 | node1 <- node_map$to 53 | node2 <- node_map$from 54 | 55 | while(length(node1) > 0) { 56 | ## p1 <- vapply(node1, function(n) parent(tr1, n), numeric(1)) 57 | ## p2 <- vapply(node2, function(n) parent(tr2, n), numeric(1)) 58 | p1 <- parent(tr1, node1) 59 | p2 <- parent(tr2, node2) 60 | if (!all(duplicated(p1) == duplicated(p2))) { 61 | stop("tree structure not identical...") 62 | } 63 | node1 <- unique(p1[p1!=0]) 64 | node2 <- unique(p2[p2!=0]) 65 | node_map$from <- unique(c(node_map$from, node2)) 66 | node_map$to <- unique(c(node_map$to, node1)) 67 | } 68 | 69 | 70 | node_map.df <- do.call("cbind", node_map) 71 | node_map.df <- unique(node_map.df) 72 | node_map.df <- node_map.df[node_map.df[,1] != 0,] 73 | i <- order(node_map.df[,1], decreasing = FALSE) 74 | node_map.df <- node_map.df[i,] 75 | 76 | if (nrow(obj2@data) == 0) { 77 | info2 <- obj2@extraInfo 78 | } else if (nrow(obj2@extraInfo) == 0) { 79 | info2 <- obj2@data 80 | } else { 81 | info2 <- full_join(obj2@data, obj2@extraInfo, by = "node") 82 | } 83 | 84 | info2$node <- node_map.df[match(info2$node, node_map.df[,1]),2] 85 | 86 | extraInfo <- obj1@extraInfo 87 | if (nrow(extraInfo) == 0) { 88 | obj1@extraInfo <- info2 89 | } else { 90 | obj1@extraInfo <- full_join(extraInfo, info2, by = "node") 91 | } 92 | obj1@extraInfo$node <- as.integer(obj1@extraInfo$node) 93 | 94 | obj1@file <- c(obj1@file, obj2@file) 95 | obj1@file <- obj1@file[obj1@file != ""] 96 | return(obj1) 97 | } 98 | -------------------------------------------------------------------------------- /R/nextstrain.json.R: -------------------------------------------------------------------------------- 1 | #' @title read.nextstrain.json 2 | #' @param x the json tree file of auspice from nextstrain. 3 | #' @return treedata object 4 | #' @export 5 | #' @author Shuangbin Xu 6 | #' @examples 7 | #' file1 <- system.file("extdata/nextstrain.json", "minimal_v2.json", package="treeio") 8 | #' tr <- read.nextstrain.json(file1) 9 | #' tr 10 | read.nextstrain.json <- function(x){ 11 | x <- jsonlite::read_json(x) 12 | if (all(c('meta', 'tree') %in% names(x))){ 13 | dt <- parser_children(x$tree) 14 | }else{ 15 | dt <- parser_children(x) 16 | } 17 | if ('branch.length' %in% colnames(dt)){ 18 | rmclnm <- c("parentID", "NodeID", "branch.length") 19 | edgedf <- dt[, rmclnm] 20 | }else{ 21 | rmclnm <- c("parentID", "NodeID") 22 | edgedf <- dt[, rmclnm] 23 | } 24 | dd <- as.phylo(edgedf, "branch.length") 25 | dt$label <- as.character(dt$NodeID) 26 | dt <- dt[, !colnames(dt) %in% rmclnm, drop=FALSE] 27 | dd <- dd |> tidytree::as_tibble() |> dplyr::full_join(dt, by='label') 28 | if ("name" %in% colnames(dd)){ 29 | dd$label <- dd$name 30 | dd$name <- NULL 31 | } 32 | tr <- dd |> as.treedata() 33 | return(tr) 34 | } 35 | 36 | parser_children <- function(x, id=list2env(list(id = 0L)), parent = 1){ 37 | id[["id"]] <- id[["id"]] + 1L 38 | id[["data"]][[id[["id"]]]] <- extract_node_attrs(x, id=id[["id"]], isTip=FALSE, parent=parent) 39 | if ('div' %in% colnames(id[['data']][[id[['id']]]])){ 40 | parent.index <- id[['data']][[id[['id']]]][['parentID']] 41 | id[['data']][[id[['id']]]][['branch.length']] <- as.numeric(id[['data']][[id[['id']]]][['div']]) - 42 | as.numeric(id[['data']][[parent.index]][['div']]) 43 | } 44 | if ('children' %in% names(x)){ 45 | lapply(x$children, 46 | parser_children, 47 | id = id, 48 | parent = ifelse(id[['id']]>=2, id[["data"]][[id[["id"]]-1L]][["NodeID"]], 1) 49 | ) 50 | }else{ 51 | id[["data"]][[id[["id"]]]][["isTip"]] <- TRUE 52 | } 53 | dat <- dplyr::bind_rows(as.list(id[["data"]])) %>% dplyr::mutate_if(check_num, as.numeric) 54 | return(dat) 55 | } 56 | 57 | check_num <- function(x){ 58 | is_numeric(x) && is.character(x) 59 | } 60 | 61 | extract_node_attrs <- function(x, id, isTip, parent){ 62 | if ('node_attrs' %in% names(x)){ 63 | res <- build_node_attrs(x[['node_attrs']]) 64 | }else if('attr' %in% names(x)){ 65 | res <- build_node_attrs(x[['attr']]) 66 | }else{ 67 | res <- data.frame() 68 | } 69 | if ('name' %in% names(x)){ 70 | res$name <- x[['name']] 71 | }else if('strain' %in% names(x)){ 72 | res$name <- x[['strain']] 73 | } 74 | res$parentID <- parent 75 | res$NodeID <- id 76 | res$isTip <- isTip 77 | return(res) 78 | } 79 | 80 | build_node_attrs <- function(x){ 81 | x <- unlist(x) 82 | index <- grepl('\\.value$', names(x)) 83 | names(x)[index] <- gsub('\\.value$', '', names(x)[index]) 84 | x <- tibble::as_tibble(t(x)) 85 | return(x) 86 | } 87 | 88 | -------------------------------------------------------------------------------- /R/sequence-utilities.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom ape as.DNAbin 2 | string2DNAbin <- function(seqs) { 3 | seqlist <- strsplit(seqs, "") 4 | names(seqlist) <- names(seqs) 5 | as.DNAbin(seqlist) 6 | } 7 | 8 | ## seq2codon <- function(x) { 9 | ## substring(x, first=seq(1, nchar(x)-2, 3), last=seq(3, nchar(x), 3)) 10 | ## } 11 | 12 | ## codon2AA <- function(codon) { 13 | ## ## a genetic code name vector 14 | ## aa <- Biostrings::GENETIC_CODE[codon] 15 | ## aa[is.na(aa)] <- "X" 16 | ## return(aa) 17 | ## } 18 | 19 | 20 | 21 | ##' read FASTA file 22 | ##' 23 | ##' This function supports both DNA or AA sequences 24 | ##' @title read.fasta 25 | ##' @param fasta fasta file 26 | ##' @param type sequence type of the input file, one of 'NT' or 'AA'. 27 | ##' Default is 'auto' and guess the sequence type automatically 28 | ##' @return DNAbin or AAbin object 29 | ##' @export 30 | ##' @author Guangchuang Yu 31 | read.fasta <- function(fasta, type = "auto") { 32 | type <- match.arg(type, c("auto", "NT", "AA")) 33 | 34 | if (type == "auto") type <- guess_fasta_type(fasta) 35 | 36 | if (type == "NT") { 37 | class <- "DNAbin" 38 | } else { 39 | class <- "AAbin" 40 | } 41 | 42 | x <- Biostrings::readBStringSet(fasta) 43 | 44 | structure(lapply(x, .BStringSet2bin, class = class), 45 | class = class) 46 | } 47 | 48 | ##' @importFrom ape as.DNAbin.character 49 | ##' @importFrom ape as.AAbin.character 50 | .BStringSet2bin <- function(x, class = "DNAbin") { 51 | chars <- strsplit(tolower(as.character(x)), "")[[1]] 52 | if (class == "DNAbin") { 53 | res <- as.DNAbin.character(chars) 54 | } else { 55 | res <- as.AAbin.character(chars) 56 | } 57 | return(res) 58 | } 59 | 60 | #guess_fasta_type <- function(fasta) { 61 | # ## read second line, the sequence line and convert it to character vector 62 | # a <- strsplit(toupper(readLines(fasta, n=2)[2]), split="")[[1]] 63 | # freq <- mean(a %in% c('A', 'C', 'G', 'T', 'X', 'N', '-') ) 64 | # if (freq > 0.9) { 65 | # return('NT') 66 | # } 67 | # return('AA') 68 | #} 69 | 70 | guess_fasta_type <- function(fasta) { 71 | seqstr <- readLines(fasta, n=3) 72 | if (length(seqstr)==2 || grepl("^>", seqstr[[3]])){ 73 | # >seq1 74 | # AGCGTACGTGACGTAGCGTAGC 75 | # >seq2 76 | a <- seqstr[2] 77 | }else{ 78 | # >seq1 79 | # --------- 80 | # AGCG----C 81 | # --------- 82 | # >seq2 83 | seqstr <- readLines(fasta, n=20) 84 | seqind <- grep("^>", seqstr) 85 | if (length(seqind)==1){ 86 | a <- paste0(seqstr[-1], collapse="") 87 | }else{ 88 | inds <- seqind[1] + 1 89 | inde <- seqind[2] - 1 90 | a <- paste0(seqstr[inds:inde], collapse="") 91 | } 92 | } 93 | a <- strsplit(toupper(a), split="")[[1]] 94 | freq <- mean(a %in% c('A', 'C', 'G', 'T', 'X', 'N', '-')) 95 | # -------KKKKKKK------KKKK---------- 96 | freq2 <- mean(a %in% c("A", "C", "G", "T", "N")) 97 | if (freq > 0.9 && freq2 > 0) { 98 | return('NT') 99 | } 100 | return('AA') 101 | } 102 | -------------------------------------------------------------------------------- /inst/extdata/r8s/H3.tree: -------------------------------------------------------------------------------- 1 | (CY011888_A_New_York_716_1994_H3N2_1994:0.00946162,(EU856894_A_Hong_Kong_CUHK20217_1997_H3N2_1997:0.00545751,(EU856893_A_Hong_Kong_CUHK20213_1997_H3N2_1997:0.00475102,(EU856882_A_Hong_Kong_CUHK18230_1998_H3N2_1998:0.00436993,(DQ487341_A_Moscow_10_1999_H3N2_1999:0.00703614,(EU856852_A_Hong_Kong_CUHK13033_2001_H3N2_2001:0.00656576,(EU856865_A_Hong_Kong_CUHK13658_2001_H3N2_2001:0.00900133,(EU856971_A_Hong_Kong_CUHK31490_1999_H3N2_1999:0.00179226,(EU856862_A_Hong_Kong_CUHK13483_2003_H3N2_2003:0.00358457,(EU856984_A_Hong_Kong_CUHK33851_2004_H3N2_2004:0.00537338,((CY038743_A_Hong_Kong_HKU71_2005_H3N2_2005:0.00059414,(EU857080_A_Hong_Kong_CUHK69904_2006_H3N2_2006:0.00468957,(EU199359_A_Pennsylvania_05_2007_H3N2_2007:0.00593595,((EU716426_A_Uruguay_716_2007_H3N2_2007:0.00248851,EU199366_A_Brisbane_10_2007_H3N2_2007:0.00165910):0.00058940,(FJ532080_A_California_09_2008_H3N2_2008:0.00601428,(FJ966245_A_Victoria_502_2009_H3N2_2009:0.00117851,((A_Kenya_078_2010_H3N2_2010:0.00730680,((((A_Nicaragua_5754_07_2013_H3N2_2013:0.00416809,(A_Czech_Republic_1_2014_H3N2_2014:0.00239077,A_Hokkaido_M1_2014_H3N2_2014:0.00417864):0.00115839):0.00179569,(A_Ontario_41_2014_H3N2_2014:0.00987443,A_Delhi_1191_2013_H3N2_2013:0.00868368):0.00096665):0.00118491,(A_Singapore_H2012_779_2012_H3N2_2012:0.00356697,A_Arizona_M18_2012_H3N2_2012:0.00475781):0.00000002):0.00298805,(A_Uttarakhand_8853_2011_H3N2_2011:0.00418599,A_Moscow_RII05_2012_H3N2_2012:0.00298281):0.00056035):0.00480395):0.00456337,(A_Tennessee_F2084c83_2011_H3N2_2011:0.00654733,(A_New_York_3135_2009_H3N2_2009:0.00416228,(A_Thailand_CU_H1071_2009_H3N2_2009:0.00238007,(A_Singapore_KK581_2011_H3N2_2011:0.00418162,A_Belgrade_WRAIR2379N_2010_H3N2_2010:0.00236473):0.00299327):0.00177746):0.00000003):0.00205447):0.00172691):0.00300160):0.00068414):0.00540943):0.00236701):0.00066448):0.00478151,(EU857082_A_Hong_Kong_CUHK7047_2005_H3N2_2005:0.00231048,((YGSIV1044_Sw_Binh_Duong_03_08_2010:0.00111075,YGSIV1046_Sw_Binh_Duong_03_10_2010:0.00007933):0.00831822,((YGSIV1427_SW_HK_2857_2011:0.00119107,(YGSIV1522_SW_HK_1071_2012:0.00603681,YGSIV1534_SW_HK_2454_2012:0.00362133):0.00053678):0.00826726,(((YGSIV1352_SW_GX_2803_2011:0.00000003,(YGSIV1369_SW_GX_NS3106_2011:0.00178145,YGSIV1370_SW_GX_NS3108_2011:0.00058953):0.00178253):0.00178019,(YGSIV1052_Sw_GX_NS2783_2010:0.00059274,(YGSIV1598_SW_HK_NS2733_2012:0.00725852,(YGSIV1165_Sw_HK_2503_2011:0.00237505,YGSIV1166_Sw_HK_NS2439_2011:0.00357143):0.00000003):0.00118509):0.00118452):0.00000003,(YGSIV1315_SW_GD_3767_2011:0.00475938,(YGSIV1586_SW_GX_NS2394_2012:0.00356092,(YGSIV1416_SW_HK_NS2810_2011:0.00296983,(((YGSIV1597_SW_HK_NS2698_2012:0.00779556,(YGSIV1447_SW_HK_3700_2011:0.00118403,(YGSIV1501_SW_HK_168_2012:0.00118393,YGSIV1338_SW_GD_1599_2012:0.00416246):0.00000003):0.00118407):0.00000003,(YGSIV1507_SW_HK_459_2012:0.00476579,((YGSIV1527_SW_HK_NS1651_2012:0.00601194,YGSIV1574_Sw_GD_2919_2012:0.00179131):0.00177597,(YGSIV1603_SW_HK_3280_2012:0.00416460,((YGSIV1407_SW_GX_NS1409_2012:0.00178360,(YGSIV1562_Sw_GD_NS2701_2012:0.00238944,YGSIV1569_Sw_GD_NS2892_2012:0.00238783):0.00118438):0.00178323,(YGSIV1405_SW_GX_650_2012:0.00356694,(YGSIV1347_SW_GX_2242_2011:0.00000001,YGSIV1404_SW_GX_508_2012:0.00177814):0.00118446):0.00000003):0.00000002):0.00059228):0.00059120):0.00000003):0.00000003,(YGSIV1441_SW_HK_3238_2011:0.00237183,YGSIV1526_SW_HK_1284_2012:0.00177789):0.00000001):0.00000003):0.00000003):0.00000007):0.00476826):0.00320365):0.00593645):0.02056320):0.00110066):0.00505616):0.00236902):0.01846730):0.00175802):0.00180553):0.00256618):0.00232775):0.00584889):0.00480763):0.009); 2 | -------------------------------------------------------------------------------- /R/phangorn.R: -------------------------------------------------------------------------------- 1 | ## tree annotation of sequence substitution by comparing to parent node 2 | ## 3 | ## 4 | ## @title phyPML 5 | ## @param pmlTree tree in pml object, output of phangorn::optim.pml 6 | ## @rdname as.treedata 7 | ## @param type one of 'ml' and 'bayes' for inferring ancestral sequences 8 | ## @return treedata object 9 | 10 | ##' @importFrom ape read.tree 11 | ##' @importFrom ape reorder.phylo 12 | ##' @method as.treedata pml 13 | ##' @export 14 | ##' @author Yu Guangchuang 15 | as.treedata.pml <- function(tree, type = "ml", ...) { 16 | sequences <- pmlToSeqString(tree, type, includeAncestor=TRUE) 17 | tr <- tree$tree 18 | tr <- reorder.phylo(tr) 19 | 20 | if (is.null(tr$node.label)) { 21 | n <- Ntip(tr) 22 | nl <- 1:(Nnode2(tr) - n) + n 23 | tr$node.label <- as.character(nl) 24 | } 25 | names(sequences) <- c(tr$tip.label, tr$node.label) 26 | 27 | 28 | seq_type <- get_seqtype(sequences) 29 | 30 | ## seqlist <- lapply(seq_along(sequences), function(i) sequences[i]) 31 | ## names(seqlist) <- names(sequences) 32 | ## seqs <- as.DNAbin(seqlist) 33 | seqs <- string2DNAbin(sequences) 34 | 35 | tip_seq <- seqs[labels(seqs) %in% tr$tip.label] 36 | anc_seq <- seqs[!labels(seqs) %in% tr$tip.label] 37 | 38 | res <- new("treedata", 39 | phylo = tr, 40 | tip_seq = tip_seq, 41 | anc_seq = anc_seq, 42 | seq_type = seq_type) 43 | 44 | set_substitution(res) 45 | } 46 | 47 | 48 | 49 | pmlToSeqString <- function(pml, type, includeAncestor=TRUE) { 50 | if (includeAncestor == FALSE) { 51 | phyDat <- pml$data 52 | } else { 53 | check_installed('phangorn', 'for `as.treedata()` with pml class and includeAncestor=TRUE.') 54 | phyDat <- phangorn::ancestral.pml(pml, type) 55 | } 56 | 57 | phyDat <- matrix2vector.phyDat(phyDat) 58 | ## defined by phangorn 59 | labels <- c("a", "c", "g", "t", "u", "m", "r", "w", "s", 60 | "y", "k", "v", "h", "d", "b", "n", "?", "-") 61 | labels <- toupper(labels) 62 | 63 | index <- attr(phyDat, "index") 64 | 65 | result <- do.call(rbind, phyDat) 66 | result <- result[, index, drop=FALSE] 67 | 68 | res <- apply(result, 2, function(i) labels[i]) 69 | res <- apply(res, 1, paste, collapse="") 70 | names(res) <- rownames(result) 71 | return(res) 72 | } 73 | 74 | 75 | 76 | matrix2vector.phyDat <- function(x) { 77 | index <- attr(x, "index") 78 | res <- lapply(x, matrix2vector.phyDat.item) 79 | names(res) <- names(x) 80 | attr(res, "index") <- index 81 | class(res) <- "phyDat" 82 | return(res) 83 | } 84 | 85 | matrix2vector.phyDat.item <- function(y) { 86 | ii <- apply(y, 1, function(xx) { 87 | ## return index of a c g and t, if it has highest probability 88 | ## otherwise return index of - 89 | jj <- which(xx == max(xx)) 90 | if ( length(jj) > 1) { 91 | if (length(jj) < 4) { 92 | warning("ambiguous found...\n") 93 | } else { 94 | ## cat("insertion found...\n") 95 | } 96 | ## 18 is the gap(-) index of base character defined in phangorn 97 | ## c("a", "c", "g", "t", "u", "m", "r", "w", "s", 98 | ## "y", "k", "v", "h", "d", "b", "n", "?", "-") 99 | 18 100 | } else { 101 | jj 102 | } 103 | }) 104 | unlist(ii) 105 | } 106 | 107 | -------------------------------------------------------------------------------- /tests/testthat/test-beast.R: -------------------------------------------------------------------------------- 1 | context("beast input and output") 2 | 3 | library(treeio) 4 | 5 | file <- system.file("extdata/BEAST", "beast_mcc.tree", package="treeio") 6 | beast <- read.beast(file) 7 | 8 | test_that("read.beast works", { 9 | 10 | expect_s4_class(beast, 'treedata') 11 | # check some tree attributes 12 | expect_s3_class(beast@phylo, 'phylo') 13 | expect_equal(ape::Ntip(beast@phylo), 15) 14 | expect_equal(ape::Nnode(beast@phylo), 14) 15 | expect_true(ape::is.rooted(beast@phylo)) 16 | expect_true("A_1995" %in% beast@phylo$tip.label) 17 | 18 | expect_s3_class(beast@data, 'data.frame') 19 | expect_equal(nrow(beast@data), 29) # = Ntip + Nnode 20 | 21 | # check a branch at random: Node 18, parent of N_2010 and K_2013 22 | node <- subset(beast@data, node == 18) 23 | # N.b. some annotations are renamed from the attributes in the treefile, 24 | # e.g. height_95%_HPD => height_0.95_HPD 25 | # and these are the values directly from the tree to make sure we get them 26 | # with the precision from the file 27 | expect_equal(node[['length_range']][[1]], c(15.724675549523745,36.72403651916805)) 28 | expect_equal(node[['height_range']][[1]], c(5.941039739620447,15.10397485336565)) 29 | expect_equal(node[['rate_range']][[1]], c(0.0018410123833317064,0.004221113122306114)) 30 | expect_equal(node[['height_median']][[1]], 9.385096430786298) 31 | expect_equal(node[['height_0.95_HPD']][[1]], c(7.322099111116469,11.624410805545125)) 32 | expect_equal(node[['height']][[1]], 9.470517085164637) 33 | expect_equal(node[['posterior']][[1]], 1.0) 34 | expect_equal(node[['rate']][[1]], 0.0029074382448820114) 35 | expect_equal(node[['rate_median']][[1]], 0.002896909674386843) 36 | expect_equal(node[['rate_0.95_HPD']][[1]], c(0.00237138786088183,0.0034784158116179195)) 37 | expect_equal(node[['length']][[1]], 25.719898216070327) 38 | expect_equal(node[['length_median']][[1]], 25.579167352568767) 39 | expect_equal(node[['length_0.95_HPD']][[1]], c(22.048771671275617,30.115400624425263)) 40 | }) 41 | 42 | 43 | test_that(".write.tree3 should works for ordinary phylo object", { 44 | expect_equal(treeio:::.write.tree3(as.phylo(beast)), 45 | ape::write.tree(as.phylo(beast))) 46 | }) 47 | 48 | 49 | beast_nwk <- treeio:::write_beast_newick(beast) 50 | beast_file <- tempfile() 51 | treeio:::write_beast_newick(beast, beast_file) 52 | test_that("write_beast_newick output a newick string with annotation", { 53 | expect_true(grepl('HPD', beast_nwk)) 54 | expect_true(grepl('\\{', beast_nwk)) 55 | expect_true(grepl('^\\(', beast_nwk)) 56 | expect_true(grepl(';$', beast_nwk)) 57 | expect_gt(file.info(beast_file)$size, 0) 58 | }) 59 | 60 | 61 | beast_file <- tempfile() 62 | write.beast(beast, beast_file) 63 | 64 | test_that("write.beast output a valid beast file", { 65 | expect_true(is(read.beast(beast_file), "treedata")) 66 | }) 67 | 68 | 69 | xx <- "(a:2L[&rate=1],(b:[&rate=1.1]1L,c[&rate=0.9]:1):-10e-6[&rate=1]);\n(a[&rate=1]:2,(b[&rate=1.1]:1,c[&rate=0.9]:1)[&rate=1]:1);" 70 | 71 | tree1 <- structure(list(edge=matrix(c(4L, 4L, 5L, 5L, 1L, 5L, 2L, 3L), ncol=2), 72 | edge.length=c(2, -1e-05, 1, 1), 73 | Nnode=2L, 74 | tip.label=c("a", "b", "c")), 75 | class="phylo", 76 | order="cladewise" 77 | ) 78 | trees <- read.beast.newick(textConnection(xx)) 79 | 80 | test_that("read.beast.newick should work for multiple trees",{ 81 | expect_true(inherits(trees, "treedataList")) 82 | expect_equal(trees[[1]]@phylo, tree1) 83 | }) 84 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | md_document: 4 | variant: gfm 5 | html_preview: false 6 | --- 7 | 8 | 9 | 10 | 11 | # treeio: Base classes and functions for phylogenetic tree input and output 12 | 13 | ```{r echo=FALSE, results="hide", message=FALSE} 14 | #library("txtplot") 15 | library("badger") 16 | library("ypages") 17 | 18 | library("yulab.utils") 19 | ``` 20 | 21 | [![](https://badges.ropensci.org/179_status.svg)](https://github.com/ropensci/onboarding/issues/179) 22 | [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/treeio.svg)](https://www.bioconductor.org/packages/devel/bioc/html/treeio.html#since) 23 | [![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) 24 | [![platform](http://www.bioconductor.org/shields/availability/devel/treeio.svg)](https://www.bioconductor.org/packages/devel/bioc/html/treeio.html#archives) 25 | [![codecov](https://codecov.io/gh/GuangchuangYu/treeio/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/treeio) 26 | 27 | 28 | `r badge_bioc_release("treeio", "green")` 29 | `r badge_devel("guangchuangyu/treeio", "green")` 30 | [![Linux Travis Build Status](https://img.shields.io/travis/GuangchuangYu/treeio/master.svg?label=Linux)](https://travis-ci.org/GuangchuangYu/treeio) 31 | [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/Guangchuangyu/treeio/master.svg?label=Windows)](https://ci.appveyor.com/project/GuangchuangYu/treeio) 32 | 33 | 34 | `r badge_bioc_download("treeio", "total", "blue")` 35 | `r badge_bioc_download("treeio", "month", "blue")` 36 | `r badge_bioc_download_rank("treeio")` 37 | 38 | 39 | 40 | ```{r comment="", echo=FALSE, results='asis'} 41 | cat(packageDescription('treeio')$Description) 42 | ``` 43 | 44 | Visit for details. 45 | 46 | 47 | [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&logo=twitter)](https://twitter.com/intent/tweet?hashtags=treeio&url=http://onlinelibrary.wiley.com/doi/10.1111/2041-210X.12628/abstract&screen_name=guangchuangyu) 48 | [![saythanks](https://img.shields.io/badge/say-thanks-ff69b4.svg)](https://saythanks.io/to/GuangchuangYu) 49 | `r badger::badge_custom("follow me on", "WeChat", "green", "https://yulab-smu.top/images/biobabble.jpg")` 50 | 51 | 52 | 53 | 54 | ## :writing_hand: Authors 55 | 56 | Guangchuang YU 57 | 58 | School of Basic Medical Sciences, Southern Medical University 59 | 60 | 61 | 62 | If you use `r Biocpkg('treeio')` in published research, please cite: 63 | 64 | + LG Wang, TTY Lam, S Xu, Z Dai, L Zhou, T Feng, P Guo, CW Dunn, BR Jones, T Bradley, H Zhu, Y Guan, Y Jiang, __G Yu__^\*^. treeio: an R package for phylogenetic tree input and output with richly annotated and associated data. __*Molecular Biology and Evolution*__. 2020, 37(2):599-603. doi: [10.1093/molbev/msz240](http://dx.doi.org/10.1093/molbev/msz240). 65 | 66 | 67 | ## :arrow_double_down: Installation 68 | 69 | Get the released version from Bioconductor: 70 | 71 | ```r 72 | ## try http:// if https:// URLs are not supported 73 | if (!requireNamespace("BiocManager", quietly=TRUE)) 74 | install.packages("BiocManager") 75 | ## BiocManager::install("BiocUpgrade") ## you may need this 76 | BiocManager::install("treeio") 77 | ``` 78 | 79 | Or the development version from github: 80 | 81 | ```r 82 | ## install.packages("devtools") 83 | devtools::install_github("YuLab-SMU/treeio") 84 | ``` 85 | 86 | 87 | 88 | ## :sparkling_heart: Contributing 89 | 90 | We welcome any contributions! By participating in this project you agree to 91 | abide by the terms outlined in the [Contributor Code of Conduct](CONDUCT.md). 92 | 93 | 94 | ## :houses: Package Affiliations 95 | 96 | The `treeio` package is a part of the Bioconductor and rOpenSci projects. 97 | 98 | | [![bioconductor_footer](http://bioconductor.org/images/logo_bioconductor.gif)](http://bioconductor.org) | [![ropensci_footer](http://ropensci.org/public_images/github_footer.png)](http://ropensci.org) | 99 | |:-------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------:| 100 | 101 | -------------------------------------------------------------------------------- /R/nhx.R: -------------------------------------------------------------------------------- 1 | ##' read nhx tree file 2 | ##' 3 | ##' 4 | ##' @title read.nhx 5 | ##' @param file nhx file 6 | ##' @return nhx object 7 | ##' @import tidytree 8 | ##' @importFrom tibble as_tibble 9 | ##' @export 10 | ##' @examples 11 | ##' nhxfile <- system.file("extdata/NHX", "ADH.nhx", package="treeio") 12 | ##' read.nhx(nhxfile) 13 | ##' @author Guangchuang Yu \url{https://guangchuangyu.github.io} 14 | read.nhx <- function(file) { 15 | treetext <- readLines(file, warn=FALSE) 16 | treetext <- treetext[treetext != ""] 17 | treetext <- treetext[treetext != " "] 18 | 19 | if (length(treetext) > 1) { 20 | treetext <- paste0(treetext, collapse = '') 21 | } 22 | treetext <- gsub(" ", "", treetext) 23 | # t1:0.04[&&NHX:test=1] -> t1[&&NHX:test=1]:0.04 24 | pattern <- "(\\w+)?(:?\\d*\\.?\\d*[Ee]?[\\+\\-]?\\d*)?(\\[&&NHX.*?\\])" 25 | treetext <- gsub(pattern, "\\1\\3\\2", treetext) 26 | #t1[&&NHX:test=1]:0.04 -> t1[&&NHX|test=1]:0.04 27 | #treetext <- gsub("\\:(?=[^\\[\\]]*\\])", "|", treetext, perl=TRUE) 28 | phylo <- read.nhx.tree(treetext) 29 | stats <- read.nhx.stats(treetext=treetext, phylo=phylo) 30 | 31 | new("treedata", 32 | file = filename(file), 33 | phylo = phylo, 34 | data = as_tibble(stats) 35 | ) 36 | } 37 | 38 | read.nhx.tree <- function(treetext){ 39 | pattern <- "(\\w+)?(\\[&&NHX.*?\\])(:?\\d*\\.?\\d*[Ee]?[\\+\\-]?\\d*)" 40 | treetext <- gsub(pattern, "\\1\\3", treetext) 41 | tree <- ape::read.tree(text=treetext) 42 | return(tree) 43 | } 44 | 45 | read.nhx.stats <- function(treetext, phylo){ 46 | tree2 <- add_pseudo_label(phylo) 47 | nn <- strsplit(tree2, split=",") %>% unlist %>% 48 | strsplit(., split="\\)") %>% unlist %>% 49 | gsub("\\(*", "", .) %>% 50 | gsub("[:;].*", "", .) %>% 51 | gsub(" ", "", .) %>% 52 | gsub("'", "", .) %>% 53 | gsub('"', "", .) 54 | phylo <- ape::read.tree(text = tree2) 55 | root <- rootnode(phylo) 56 | nnode <- phylo$Nnode 57 | 58 | tree_label <- c(phylo$tip.label, phylo$node.label) 59 | ii <- match(nn, tree_label) 60 | label2 <- as.character(seq_len(getNodeNum(phylo))) 61 | node <- label2[match(nn, tree_label)] 62 | #if (!grepl(":?\\d*\\.?\\d*[Ee]?[\\+\\-]?\\d*", treetext)){ 63 | stats <- strsplit(treetext, "[,\\)]") %>% unlist() 64 | #}else{ 65 | # stats <- strsplit(treetext, ":") %>% unlist() 66 | #} 67 | names(stats) <- node 68 | 69 | stats <- stats[grep("\\[&&NHX", stats)] 70 | stats <- sub("[^\\[]*\\[", "", stats) %>% 71 | # sub("^&&NHX:", "", .) %>% 72 | sub("^&&NHX", "", .) %>% 73 | sub("].*", "", .) %>% 74 | gsub("\"", "", .) 75 | stats <- extract_nhx_feature(stats=stats) 76 | return(stats) 77 | } 78 | 79 | extract_nhx_feature <- function(stats){ 80 | stats2 <- get_nhx_feature(nhx_features=stats) 81 | stats2 <- convert_to_numeric(dat=stats2) 82 | stats2$node <- names(stats) 83 | stats2$node <- as.integer(stats2$node) 84 | stats2 <- as_tibble(stats2) 85 | return(stats2) 86 | 87 | } 88 | 89 | #' @importFrom ape Ntip Nnode 90 | add_pseudo_label <- function(phylo){ 91 | phylo$tip.label <- paste0("T", seq_len(Ntip(phylo))) 92 | phylo$node.label <- paste0("N", seq_len(Nnode(phylo))) 93 | treetext <- ape::write.tree(phylo) 94 | return(treetext) 95 | } 96 | 97 | get_nhx_feature <- function(nhx_features) { 98 | nameSET <- strsplit(nhx_features, split=":") %>% unlist %>% 99 | gsub("=.*", "", .) %>% unique %>% sort 100 | lapply(nhx_features, get_nhx_feature_internal, nameSET=nameSET) %>% 101 | do.call(rbind, .) %>% as.data.frame(., stringsAsFactors = FALSE) 102 | } 103 | 104 | get_nhx_feature_internal <- function(feature, nameSET) { 105 | x <- strsplit(feature, ":") %>% unlist 106 | name <- gsub("=.*", "", x) 107 | val <- gsub(".*=", "", x) 108 | 109 | names(val) <- name 110 | y <- character(length(nameSET)) 111 | for (i in seq_along(nameSET)) { 112 | if (nameSET[i] %in% name) { 113 | y[i] <- val[nameSET[i]] 114 | } else { 115 | y[i] <- NA 116 | } 117 | } 118 | names(y) <- nameSET 119 | return(y) 120 | } 121 | 122 | convert_to_numeric <- function(dat){ 123 | for (i in seq_len(ncol(dat))){ 124 | x <- dat[, i] 125 | x <- x[!is.na(x)] 126 | #if (all(grepl("[-]?[0-9]+[.]?[0-9]*|[-]?[0-9]+[L]?|[-]?[0-9]+[.]?[0-9]*[eE][0-9]+", x))){ 127 | if (is_numeric(x)){ 128 | ## should be numerical varialbe 129 | dat[,i] <- as.numeric(dat[,i]) 130 | } 131 | } 132 | return (dat) 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # treeio: Base classes and functions for phylogenetic tree input and output 4 | 5 | [![](https://badges.ropensci.org/179_status.svg)](https://github.com/ropensci/onboarding/issues/179) 6 | [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/treeio.svg)](https://www.bioconductor.org/packages/devel/bioc/html/treeio.html#since) 7 | [![Project Status: Active - The project has reached a stable, usable 8 | state and is being actively 9 | developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) 10 | [![platform](http://www.bioconductor.org/shields/availability/devel/treeio.svg)](https://www.bioconductor.org/packages/devel/bioc/html/treeio.html#archives) 11 | [![codecov](https://codecov.io/gh/GuangchuangYu/treeio/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/treeio) 12 | 13 | [![](https://img.shields.io/badge/release%20version-1.20.2-green.svg)](https://www.bioconductor.org/packages/treeio) 14 | [![](https://img.shields.io/badge/devel%20version-1.21.3-green.svg)](https://github.com/guangchuangyu/treeio) 15 | [![Linux Travis Build 16 | Status](https://img.shields.io/travis/GuangchuangYu/treeio/master.svg?label=Linux)](https://travis-ci.org/GuangchuangYu/treeio) 17 | [![AppVeyor Build 18 | Status](https://img.shields.io/appveyor/ci/Guangchuangyu/treeio/master.svg?label=Windows)](https://ci.appveyor.com/project/GuangchuangYu/treeio) 19 | 20 | [![](https://img.shields.io/badge/download-284494/total-blue.svg)](https://bioconductor.org/packages/stats/bioc/treeio) 21 | [![](https://img.shields.io/badge/download-12470/month-blue.svg)](https://bioconductor.org/packages/stats/bioc/treeio) 22 | [![download](http://www.bioconductor.org/shields/downloads/release/treeio.svg)](https://bioconductor.org/packages/stats/bioc/treeio) 23 | 24 | ‘treeio’ is an R package to make it easier to import and store 25 | phylogenetic tree with associated data; and to link external data from 26 | different sources to phylogeny. It also supports exporting phylogenetic 27 | tree with heterogeneous associated data to a single tree file and can be 28 | served as a platform for merging tree with associated data and 29 | converting file formats. 30 | 31 | Visit for details. 32 | 33 | [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&logo=twitter)](https://twitter.com/intent/tweet?hashtags=treeio&url=http://onlinelibrary.wiley.com/doi/10.1111/2041-210X.12628/abstract&screen_name=guangchuangyu) 34 | [![saythanks](https://img.shields.io/badge/say-thanks-ff69b4.svg)](https://saythanks.io/to/GuangchuangYu) 35 | [![](https://img.shields.io/badge/follow%20me%20on-WeChat-green.svg)](https://yulab-smu.top/images/biobabble.jpg) 36 | 37 | ## :writing_hand: Authors 38 | 39 | Guangchuang YU 40 | 41 | School of Basic Medical Sciences, Southern Medical University 42 | 43 | 44 | 45 | If you use [treeio](http://bioconductor.org/packages/treeio) in 46 | published research, please cite: 47 | 48 | - LG Wang, TTY Lam, S Xu, Z Dai, L Zhou, T Feng, P Guo, CW Dunn, BR 49 | Jones, T Bradley, H Zhu, Y Guan, Y Jiang, **G Yu**\*. 50 | treeio: an R package for phylogenetic tree input and output with 51 | richly annotated and associated data. ***Molecular Biology and 52 | Evolution***. 2020, 37(2):599-603. doi: 53 | [10.1093/molbev/msz240](http://dx.doi.org/10.1093/molbev/msz240). 54 | 55 | ## :arrow_double_down: Installation 56 | 57 | Get the released version from Bioconductor: 58 | 59 | ``` r 60 | ## try http:// if https:// URLs are not supported 61 | if (!requireNamespace("BiocManager", quietly=TRUE)) 62 | install.packages("BiocManager") 63 | ## BiocManager::install("BiocUpgrade") ## you may need this 64 | BiocManager::install("treeio") 65 | ``` 66 | 67 | Or the development version from github: 68 | 69 | ``` r 70 | ## install.packages("devtools") 71 | devtools::install_github("YuLab-SMU/treeio") 72 | ``` 73 | 74 | ## :sparkling_heart: Contributing 75 | 76 | We welcome any contributions! By participating in this project you agree 77 | to abide by the terms outlined in the [Contributor Code of 78 | Conduct](CONDUCT.md). 79 | 80 | ## :houses: Package Affiliations 81 | 82 | The `treeio` package is a part of the Bioconductor and rOpenSci 83 | projects. 84 | 85 | | [![bioconductor_footer](http://bioconductor.org/images/logo_bioconductor.gif)](http://bioconductor.org) | [![ropensci_footer](http://ropensci.org/public_images/github_footer.png)](http://ropensci.org) | 86 | |:-------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------:| 87 | -------------------------------------------------------------------------------- /inst/extdata/RAxML/RAxML_bestTree.H3: -------------------------------------------------------------------------------- 1 | (A_Delhi_1191_2013_H3N2_2013:0.00868691236106632590,((A_Nicaragua_5754_07_2013_H3N2_2013:0.00416635888853660388,(A_Hokkaido_M1_2014_H3N2_2014:0.00417596832047934137,A_Czech_Republic_1_2014_H3N2_2014:0.00238990596472473662):0.00115803925438144498):0.00179535367243330453,(((((((FJ532080_A_California_09_2008_H3N2_2008:0.00601478344924995072,((EU199359_A_Pennsylvania_05_2007_H3N2_2007:0.00593859417906933071,(EU857080_A_Hong_Kong_CUHK69904_2006_H3N2_2006:0.00468785616106491380,(((EU857082_A_Hong_Kong_CUHK7047_2005_H3N2_2005:0.00233674225994226709,((YGSIV1046_Sw_Binh_Duong_03_10_2010:0.00007858414429717431,YGSIV1044_Sw_Binh_Duong_03_08_2010:0.00111108788821310265):0.00831416763635089463,(((YGSIV1522_SW_HK_1071_2012:0.00603830000635634332,YGSIV1534_SW_HK_2454_2012:0.00362340971890815627):0.00053334362587741037,YGSIV1427_SW_HK_2857_2011:0.00119185857303402676):0.00826555709415139304,((((YGSIV1586_SW_GX_NS2394_2012:0.00356035024799558402,YGSIV1597_SW_HK_NS2698_2012:0.00779332837220633647):0.00000164002045283365,(((YGSIV1338_SW_GD_1599_2012:0.00416149293523036118,(YGSIV1447_SW_HK_3700_2011:0.00118378604426685888,YGSIV1501_SW_HK_168_2012:0.00118367376024801330):0.00000164002045283365):0.00118381712507173724,YGSIV1526_SW_HK_1284_2012:0.00177754003688168952):0.00000164002045283365,((((((YGSIV1407_SW_GX_NS1409_2012:0.00178294528469316962,(YGSIV1562_Sw_GD_NS2701_2012:0.00238855744708306537,YGSIV1569_Sw_GD_NS2892_2012:0.00238764098549560169):0.00118403407839077894):0.00178297053548764667,(YGSIV1404_SW_GX_508_2012:0.00177789202524435770,YGSIV1347_SW_GX_2242_2011:0.00000164002045283365):0.00118426828263038788):0.00000164002045283365,(YGSIV1405_SW_GX_650_2012:0.00356621423148923344,YGSIV1603_SW_HK_3280_2012:0.00416356692791150073):0.00000164002045283365):0.00059242992539092210,(YGSIV1527_SW_HK_NS1651_2012:0.00601123157523174995,YGSIV1574_Sw_GD_2919_2012:0.00179038745303588577):0.00177585912164598980):0.00059110799359596115,YGSIV1507_SW_HK_459_2012:0.00476469082270919442):0.00000164002045283365,(YGSIV1416_SW_HK_NS2810_2011:0.00296854749859014246,YGSIV1441_SW_HK_3238_2011:0.00237145662025663824):0.00000164002045283365):0.00000164002045283365):0.00000164002045283365):0.00000164002045283365,YGSIV1315_SW_GD_3767_2011:0.00475745303689996488):0.00476749482565322086,(((YGSIV1370_SW_GX_NS3108_2011:0.00058952993340679412,YGSIV1369_SW_GX_NS3106_2011:0.00178094880403215734):0.00178176317571863518,YGSIV1352_SW_GX_2803_2011:0.00000164002045283365):0.00177972631860570402,((YGSIV1598_SW_HK_NS2733_2012:0.00725997115598252946,(YGSIV1166_Sw_HK_NS2439_2011:0.00357072534442463060,YGSIV1165_Sw_HK_2503_2011:0.00237458000192828592):0.00000164002045283365):0.00118465126965655696,YGSIV1052_Sw_GX_NS2783_2010:0.00059283025036048248):0.00118425207514875246):0.00000164002045283365):0.00320466233317837947):0.00592771363055713627):0.02051503508560581848):0.00110148703537959352,(EU856984_A_Hong_Kong_CUHK33851_2004_H3N2_2004:0.00535234952537851864,(EU856862_A_Hong_Kong_CUHK13483_2003_H3N2_2003:0.00360961785692645630,(EU856971_A_Hong_Kong_CUHK31490_1999_H3N2_1999:0.00179497517222003715,(EU856865_A_Hong_Kong_CUHK13658_2001_H3N2_2001:0.00899959853905028632,(EU856852_A_Hong_Kong_CUHK13033_2001_H3N2_2001:0.00656143382251588199,(DQ487341_A_Moscow_10_1999_H3N2_1999:0.00703587062624993695,(EU856882_A_Hong_Kong_CUHK18230_1998_H3N2_1998:0.00436882189773474174,(EU856893_A_Hong_Kong_CUHK20213_1997_H3N2_1997:0.00474994712684436576,(CY011888_A_New_York_716_1994_H3N2_1994:0.01845574157698030501,EU856894_A_Hong_Kong_CUHK20217_1997_H3N2_1997:0.00545997802162544090):0.00480326096031524850):0.00584735060291737517):0.00232848534335102029):0.00256551766433388718):0.00180578090690903777):0.00175455820550945020):0.01843086834317913744):0.00236431641130161255):0.00505169496002745751):0.00477799913007876526,CY038743_A_Hong_Kong_HKU71_2005_H3N2_2005:0.00059399708205735177):0.00066565306177425606):0.00236446030225976158):0.00541124032687350948,(EU716426_A_Uruguay_716_2007_H3N2_2007:0.00248805887099402866,EU199366_A_Brisbane_10_2007_H3N2_2007:0.00165970609029193815):0.00058975847751382645):0.00068325945778306663):0.00300150990803736565,FJ966245_A_Victoria_502_2009_H3N2_2009:0.00117877251829190117):0.00172158894442443213,(A_Tennessee_F2084c83_2011_H3N2_2011:0.00654680224008487993,((A_Thailand_CU_H1071_2009_H3N2_2009:0.00238040931525862823,(A_Belgrade_WRAIR2379N_2010_H3N2_2010:0.00236477187595527348,A_Singapore_KK581_2011_H3N2_2011:0.00418077343092119070):0.00299249233530093613):0.00177739920508864684,A_New_York_3135_2009_H3N2_2009:0.00416269921040609940):0.00000164002045283365):0.00208197382375474365):0.00454104140301505015,A_Kenya_078_2010_H3N2_2010:0.00730276965566379211):0.00480122467431950278,(A_Moscow_RII05_2012_H3N2_2012:0.00298057793322805895,A_Uttarakhand_8853_2011_H3N2_2011:0.00418430546479917325):0.00056213020282686304):0.00298613445159914533,A_Arizona_M18_2012_H3N2_2012:0.00475612235380007062):0.00000164002045283365,A_Singapore_H2012_779_2012_H3N2_2012:0.00356603145968508633):0.00118438957988058788):0.00096281225525241508,A_Ontario_41_2014_H3N2_2014:0.00987699252631252939):0.0; 2 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.phylo,data.frame) 4 | S3method(as.phylo,dendro) 5 | S3method(as.phylo,ggtree) 6 | S3method(as.phylo,igraph) 7 | S3method(as.phylo,list) 8 | S3method(as.phylo,matrix) 9 | S3method(as.phylo,phylo4) 10 | S3method(as.phylo,pvclust) 11 | S3method(as.phylo,tbl_df) 12 | S3method(as.treedata,data.frame) 13 | S3method(as.treedata,ggtree) 14 | S3method(as.treedata,matrix) 15 | S3method(as.treedata,phylo) 16 | S3method(as.treedata,phylo4) 17 | S3method(as.treedata,phylo4d) 18 | S3method(as.treedata,pml) 19 | S3method(as.treedata,pvclust) 20 | S3method(as.treedata,tbl_df) 21 | S3method(find.hclust,igraph) 22 | S3method(get.placements,jplace) 23 | S3method(print,treedataList) 24 | S3method(spt,igraph) 25 | export("%<>%") 26 | export("%>%") 27 | export(.data) 28 | export(MRCA) 29 | export(Nnode) 30 | export(Nnode2) 31 | export(Ntip) 32 | export(ancestor) 33 | export(as.phylo) 34 | export(as.treedata) 35 | export(as_tibble) 36 | export(child) 37 | export(drop.tip) 38 | export(find.hclust) 39 | export(full_join) 40 | export(get.data) 41 | export(get.fields) 42 | export(get.placements) 43 | export(get.tree) 44 | export(get.treetext) 45 | export(getNodeNum) 46 | export(inner_join) 47 | export(is.ggtree) 48 | export(is.rooted) 49 | export(isTip) 50 | export(label_branch_paml) 51 | export(mask) 52 | export(merge_tree) 53 | export(nodeid) 54 | export(nodelab) 55 | export(offspring) 56 | export(parent) 57 | export(raxml2nwk) 58 | export(read.astral) 59 | export(read.beast) 60 | export(read.beast.newick) 61 | export(read.codeml) 62 | export(read.codeml_mlc) 63 | export(read.fasta) 64 | export(read.hyphy) 65 | export(read.hyphy.seq) 66 | export(read.iqtree) 67 | export(read.jplace) 68 | export(read.jtree) 69 | export(read.mcmctree) 70 | export(read.mega) 71 | export(read.mega_tabular) 72 | export(read.mrbayes) 73 | export(read.newick) 74 | export(read.nextstrain.json) 75 | export(read.nexus) 76 | export(read.nhx) 77 | export(read.paml_rst) 78 | export(read.phylip) 79 | export(read.phylip.seq) 80 | export(read.phylip.tree) 81 | export(read.phyloxml) 82 | export(read.r8s) 83 | export(read.raxml) 84 | export(read.tree) 85 | export(read.treeqza) 86 | export(read.treetime) 87 | export(rename_taxa) 88 | export(rescale_tree) 89 | export(root) 90 | export(rootnode) 91 | export(rtree) 92 | export(spt) 93 | export(tibble) 94 | export(treedata) 95 | export(write.beast) 96 | export(write.beast.newick) 97 | export(write.jplace) 98 | export(write.jtree) 99 | export(write.nexus) 100 | export(write.tree) 101 | exportClasses(jplace) 102 | import(tidytree) 103 | importClassesFrom(tidytree,treedata) 104 | importFrom(ape,.compressTipLabel) 105 | importFrom(ape,.uncompressTipLabel) 106 | importFrom(ape,Nnode) 107 | importFrom(ape,Ntip) 108 | importFrom(ape,as.AAbin.character) 109 | importFrom(ape,as.DNAbin) 110 | importFrom(ape,as.DNAbin.character) 111 | importFrom(ape,as.phylo) 112 | importFrom(ape,branching.times) 113 | importFrom(ape,checkLabel) 114 | importFrom(ape,is.rooted) 115 | importFrom(ape,is.ultrametric) 116 | importFrom(ape,read.FASTA) 117 | importFrom(ape,read.nexus) 118 | importFrom(ape,read.tree) 119 | importFrom(ape,reorder.phylo) 120 | importFrom(ape,root) 121 | importFrom(ape,rtree) 122 | importFrom(ape,trans) 123 | importFrom(ape,write.nexus) 124 | importFrom(ape,write.tree) 125 | importFrom(dplyr,filter) 126 | importFrom(dplyr,full_join) 127 | importFrom(dplyr,group_by) 128 | importFrom(dplyr,inner_join) 129 | importFrom(dplyr,mutate) 130 | importFrom(dplyr,mutate_if) 131 | importFrom(dplyr,n) 132 | importFrom(dplyr,rename) 133 | importFrom(dplyr,select) 134 | importFrom(dplyr,summarize) 135 | importFrom(jsonlite,fromJSON) 136 | importFrom(jsonlite,toJSON) 137 | importFrom(magrittr,"%<>%") 138 | importFrom(magrittr,"%>%") 139 | importFrom(methods,"slot<-") 140 | importFrom(methods,.hasSlot) 141 | importFrom(methods,is) 142 | importFrom(methods,missingArg) 143 | importFrom(methods,new) 144 | importFrom(methods,setGeneric) 145 | importFrom(methods,slot) 146 | importFrom(parallel,mclapply) 147 | importFrom(rlang,.data) 148 | importFrom(rlang,check_installed) 149 | importFrom(rlang,enexpr) 150 | importFrom(rlang,quo_name) 151 | importFrom(stats,as.dist) 152 | importFrom(stats,hclust) 153 | importFrom(stats,setNames) 154 | importFrom(tibble,as_tibble) 155 | importFrom(tibble,tibble) 156 | importFrom(tidytree,MRCA) 157 | importFrom(tidytree,ancestor) 158 | importFrom(tidytree,as.phylo) 159 | importFrom(tidytree,as.treedata) 160 | importFrom(tidytree,child) 161 | importFrom(tidytree,drop.tip) 162 | importFrom(tidytree,get.data) 163 | importFrom(tidytree,get.fields) 164 | importFrom(tidytree,get_tree_data) 165 | importFrom(tidytree,isTip) 166 | importFrom(tidytree,nodeid) 167 | importFrom(tidytree,nodelab) 168 | importFrom(tidytree,offspring) 169 | importFrom(tidytree,parent) 170 | importFrom(tidytree,rootnode) 171 | importFrom(tidytree,treedata) 172 | importFrom(yulab.utils,use_perl) 173 | importFrom(yulab.utils,yulab_msg) 174 | -------------------------------------------------------------------------------- /inst/extdata/RAxML/RAxML_bipartitions.H3: -------------------------------------------------------------------------------- 1 | ((A_Hokkaido_M1_2014_H3N2_2014:0.00417596832047934137,A_Czech_Republic_1_2014_H3N2_2014:0.00238990596472473662)98:0.00115803925438144498,((((((((FJ532080_A_California_09_2008_H3N2_2008:0.00601478344924995072,((EU199359_A_Pennsylvania_05_2007_H3N2_2007:0.00593859417906933071,(EU857080_A_Hong_Kong_CUHK69904_2006_H3N2_2006:0.00468785616106491380,(((EU857082_A_Hong_Kong_CUHK7047_2005_H3N2_2005:0.00233674225994226709,((YGSIV1046_Sw_Binh_Duong_03_10_2010:0.00007858414429717431,YGSIV1044_Sw_Binh_Duong_03_08_2010:0.00111108788821310265)100:0.00831416763635089463,(((YGSIV1522_SW_HK_1071_2012:0.00603830000635634332,YGSIV1534_SW_HK_2454_2012:0.00362340971890815627)90:0.00053334362587741037,YGSIV1427_SW_HK_2857_2011:0.00119185857303402676)100:0.00826555709415139304,((((YGSIV1586_SW_GX_NS2394_2012:0.00356035024799558402,YGSIV1597_SW_HK_NS2698_2012:0.00779332837220633647)15:0.00000164002045283365,(((YGSIV1338_SW_GD_1599_2012:0.00416149293523036118,(YGSIV1447_SW_HK_3700_2011:0.00118378604426685888,YGSIV1501_SW_HK_168_2012:0.00118367376024801330)35:0.00000164002045283365)80:0.00118381712507173724,YGSIV1526_SW_HK_1284_2012:0.00177754003688168952)12:0.00000164002045283365,((((((YGSIV1407_SW_GX_NS1409_2012:0.00178294528469316962,(YGSIV1562_Sw_GD_NS2701_2012:0.00238855744708306537,YGSIV1569_Sw_GD_NS2892_2012:0.00238764098549560169)96:0.00118403407839077894)99:0.00178297053548764667,(YGSIV1404_SW_GX_508_2012:0.00177789202524435770,YGSIV1347_SW_GX_2242_2011:0.00000164002045283365)92:0.00118426828263038788)23:0.00000164002045283365,(YGSIV1405_SW_GX_650_2012:0.00356621423148923344,YGSIV1603_SW_HK_3280_2012:0.00416356692791150073)26:0.00000164002045283365)53:0.00059242992539092210,(YGSIV1527_SW_HK_NS1651_2012:0.00601123157523174995,YGSIV1574_Sw_GD_2919_2012:0.00179038745303588577)90:0.00177585912164598980)56:0.00059110799359596115,YGSIV1507_SW_HK_459_2012:0.00476469082270919442)8:0.00000164002045283365,(YGSIV1416_SW_HK_NS2810_2011:0.00296854749859014246,YGSIV1441_SW_HK_3238_2011:0.00237145662025663824)6:0.00000164002045283365)1:0.00000164002045283365)3:0.00000164002045283365)67:0.00000164002045283365,YGSIV1315_SW_GD_3767_2011:0.00475745303689996488)100:0.00476749482565322086,(((YGSIV1370_SW_GX_NS3108_2011:0.00058952993340679412,YGSIV1369_SW_GX_NS3106_2011:0.00178094880403215734)93:0.00178176317571863518,YGSIV1352_SW_GX_2803_2011:0.00000164002045283365)97:0.00177972631860570402,((YGSIV1598_SW_HK_NS2733_2012:0.00725997115598252946,(YGSIV1166_Sw_HK_NS2439_2011:0.00357072534442463060,YGSIV1165_Sw_HK_2503_2011:0.00237458000192828592)73:0.00000164002045283365)82:0.00118465126965655696,YGSIV1052_Sw_GX_NS2783_2010:0.00059283025036048248)89:0.00118425207514875246)26:0.00000164002045283365)96:0.00320466233317837947)100:0.00592771363055713627)100:0.02051503508560581848)68:0.00110148703537959352,(EU856984_A_Hong_Kong_CUHK33851_2004_H3N2_2004:0.00535234952537851864,(EU856862_A_Hong_Kong_CUHK13483_2003_H3N2_2003:0.00360961785692645630,(EU856971_A_Hong_Kong_CUHK31490_1999_H3N2_1999:0.00179497517222003715,(EU856865_A_Hong_Kong_CUHK13658_2001_H3N2_2001:0.00899959853905028632,(EU856852_A_Hong_Kong_CUHK13033_2001_H3N2_2001:0.00656143382251588199,(DQ487341_A_Moscow_10_1999_H3N2_1999:0.00703587062624993695,(EU856882_A_Hong_Kong_CUHK18230_1998_H3N2_1998:0.00436882189773474174,(EU856893_A_Hong_Kong_CUHK20213_1997_H3N2_1997:0.00474994712684436576,(CY011888_A_New_York_716_1994_H3N2_1994:0.01845574157698030501,EU856894_A_Hong_Kong_CUHK20217_1997_H3N2_1997:0.00545997802162544090)100:0.00480326096031524850)100:0.00584735060291737517)92:0.00232848534335102029)99:0.00256551766433388718)99:0.00180578090690903777)90:0.00175455820550945020)100:0.01843086834317913744)96:0.00236431641130161255)100:0.00505169496002745751)95:0.00477799913007876526,CY038743_A_Hong_Kong_HKU71_2005_H3N2_2005:0.00059399708205735177)87:0.00066565306177425606)85:0.00236446030225976158)100:0.00541124032687350948,(EU716426_A_Uruguay_716_2007_H3N2_2007:0.00248805887099402866,EU199366_A_Brisbane_10_2007_H3N2_2007:0.00165970609029193815)57:0.00058975847751382645)82:0.00068325945778306663)97:0.00300150990803736565,FJ966245_A_Victoria_502_2009_H3N2_2009:0.00117877251829190117)98:0.00172158894442443213,(A_Tennessee_F2084c83_2011_H3N2_2011:0.00654680224008487993,((A_Thailand_CU_H1071_2009_H3N2_2009:0.00238040931525862823,(A_Belgrade_WRAIR2379N_2010_H3N2_2010:0.00236477187595527348,A_Singapore_KK581_2011_H3N2_2011:0.00418077343092119070)100:0.00299249233530093613)97:0.00177739920508864684,A_New_York_3135_2009_H3N2_2009:0.00416269921040609940)76:0.00000164002045283365)94:0.00208197382375474365)100:0.00454104140301505015,A_Kenya_078_2010_H3N2_2010:0.00730276965566379211)98:0.00480122467431950278,(A_Moscow_RII05_2012_H3N2_2012:0.00298057793322805895,A_Uttarakhand_8853_2011_H3N2_2011:0.00418430546479917325)68:0.00056213020282686304)88:0.00298613445159914533,A_Arizona_M18_2012_H3N2_2012:0.00475612235380007062)34:0.00000164002045283365,A_Singapore_H2012_779_2012_H3N2_2012:0.00356603145968508633)68:0.00118438957988058788,(A_Ontario_41_2014_H3N2_2014:0.00987699252631252939,A_Delhi_1191_2013_H3N2_2013:0.00868691236106632590)71:0.00096281225525241508)97:0.00179535367243330453,A_Nicaragua_5754_07_2013_H3N2_2013:0.00416635888853660388); 2 | -------------------------------------------------------------------------------- /inst/extdata/RAxML/RAxML_bipartitionsBranchLabels.H3: -------------------------------------------------------------------------------- 1 | ((A_Hokkaido_M1_2014_H3N2_2014:0.00417596832047934137,A_Czech_Republic_1_2014_H3N2_2014:0.00238990596472473662):0.00115803925438144498[98],((((((((FJ532080_A_California_09_2008_H3N2_2008:0.00601478344924995072,((EU199359_A_Pennsylvania_05_2007_H3N2_2007:0.00593859417906933071,(EU857080_A_Hong_Kong_CUHK69904_2006_H3N2_2006:0.00468785616106491380,(((EU857082_A_Hong_Kong_CUHK7047_2005_H3N2_2005:0.00233674225994226709,((YGSIV1046_Sw_Binh_Duong_03_10_2010:0.00007858414429717431,YGSIV1044_Sw_Binh_Duong_03_08_2010:0.00111108788821310265):0.00831416763635089463[100],(((YGSIV1522_SW_HK_1071_2012:0.00603830000635634332,YGSIV1534_SW_HK_2454_2012:0.00362340971890815627):0.00053334362587741037[90],YGSIV1427_SW_HK_2857_2011:0.00119185857303402676):0.00826555709415139304[100],((((YGSIV1586_SW_GX_NS2394_2012:0.00356035024799558402,YGSIV1597_SW_HK_NS2698_2012:0.00779332837220633647):0.00000164002045283365[15],(((YGSIV1338_SW_GD_1599_2012:0.00416149293523036118,(YGSIV1447_SW_HK_3700_2011:0.00118378604426685888,YGSIV1501_SW_HK_168_2012:0.00118367376024801330):0.00000164002045283365[35]):0.00118381712507173724[80],YGSIV1526_SW_HK_1284_2012:0.00177754003688168952):0.00000164002045283365[12],((((((YGSIV1407_SW_GX_NS1409_2012:0.00178294528469316962,(YGSIV1562_Sw_GD_NS2701_2012:0.00238855744708306537,YGSIV1569_Sw_GD_NS2892_2012:0.00238764098549560169):0.00118403407839077894[96]):0.00178297053548764667[99],(YGSIV1404_SW_GX_508_2012:0.00177789202524435770,YGSIV1347_SW_GX_2242_2011:0.00000164002045283365):0.00118426828263038788[92]):0.00000164002045283365[23],(YGSIV1405_SW_GX_650_2012:0.00356621423148923344,YGSIV1603_SW_HK_3280_2012:0.00416356692791150073):0.00000164002045283365[26]):0.00059242992539092210[53],(YGSIV1527_SW_HK_NS1651_2012:0.00601123157523174995,YGSIV1574_Sw_GD_2919_2012:0.00179038745303588577):0.00177585912164598980[90]):0.00059110799359596115[56],YGSIV1507_SW_HK_459_2012:0.00476469082270919442):0.00000164002045283365[8],(YGSIV1416_SW_HK_NS2810_2011:0.00296854749859014246,YGSIV1441_SW_HK_3238_2011:0.00237145662025663824):0.00000164002045283365[6]):0.00000164002045283365[1]):0.00000164002045283365[3]):0.00000164002045283365[67],YGSIV1315_SW_GD_3767_2011:0.00475745303689996488):0.00476749482565322086[100],(((YGSIV1370_SW_GX_NS3108_2011:0.00058952993340679412,YGSIV1369_SW_GX_NS3106_2011:0.00178094880403215734):0.00178176317571863518[93],YGSIV1352_SW_GX_2803_2011:0.00000164002045283365):0.00177972631860570402[97],((YGSIV1598_SW_HK_NS2733_2012:0.00725997115598252946,(YGSIV1166_Sw_HK_NS2439_2011:0.00357072534442463060,YGSIV1165_Sw_HK_2503_2011:0.00237458000192828592):0.00000164002045283365[73]):0.00118465126965655696[82],YGSIV1052_Sw_GX_NS2783_2010:0.00059283025036048248):0.00118425207514875246[89]):0.00000164002045283365[26]):0.00320466233317837947[96]):0.00592771363055713627[100]):0.02051503508560581848[100]):0.00110148703537959352[68],(EU856984_A_Hong_Kong_CUHK33851_2004_H3N2_2004:0.00535234952537851864,(EU856862_A_Hong_Kong_CUHK13483_2003_H3N2_2003:0.00360961785692645630,(EU856971_A_Hong_Kong_CUHK31490_1999_H3N2_1999:0.00179497517222003715,(EU856865_A_Hong_Kong_CUHK13658_2001_H3N2_2001:0.00899959853905028632,(EU856852_A_Hong_Kong_CUHK13033_2001_H3N2_2001:0.00656143382251588199,(DQ487341_A_Moscow_10_1999_H3N2_1999:0.00703587062624993695,(EU856882_A_Hong_Kong_CUHK18230_1998_H3N2_1998:0.00436882189773474174,(EU856893_A_Hong_Kong_CUHK20213_1997_H3N2_1997:0.00474994712684436576,(CY011888_A_New_York_716_1994_H3N2_1994:0.01845574157698030501,EU856894_A_Hong_Kong_CUHK20217_1997_H3N2_1997:0.00545997802162544090):0.00480326096031524850[100]):0.00584735060291737517[100]):0.00232848534335102029[92]):0.00256551766433388718[99]):0.00180578090690903777[99]):0.00175455820550945020[90]):0.01843086834317913744[100]):0.00236431641130161255[96]):0.00505169496002745751[100]):0.00477799913007876526[95],CY038743_A_Hong_Kong_HKU71_2005_H3N2_2005:0.00059399708205735177):0.00066565306177425606[87]):0.00236446030225976158[85]):0.00541124032687350948[100],(EU716426_A_Uruguay_716_2007_H3N2_2007:0.00248805887099402866,EU199366_A_Brisbane_10_2007_H3N2_2007:0.00165970609029193815):0.00058975847751382645[57]):0.00068325945778306663[82]):0.00300150990803736565[97],FJ966245_A_Victoria_502_2009_H3N2_2009:0.00117877251829190117):0.00172158894442443213[98],(A_Tennessee_F2084c83_2011_H3N2_2011:0.00654680224008487993,((A_Thailand_CU_H1071_2009_H3N2_2009:0.00238040931525862823,(A_Belgrade_WRAIR2379N_2010_H3N2_2010:0.00236477187595527348,A_Singapore_KK581_2011_H3N2_2011:0.00418077343092119070):0.00299249233530093613[100]):0.00177739920508864684[97],A_New_York_3135_2009_H3N2_2009:0.00416269921040609940):0.00000164002045283365[76]):0.00208197382375474365[94]):0.00454104140301505015[100],A_Kenya_078_2010_H3N2_2010:0.00730276965566379211):0.00480122467431950278[98],(A_Moscow_RII05_2012_H3N2_2012:0.00298057793322805895,A_Uttarakhand_8853_2011_H3N2_2011:0.00418430546479917325):0.00056213020282686304[68]):0.00298613445159914533[88],A_Arizona_M18_2012_H3N2_2012:0.00475612235380007062):0.00000164002045283365[34],A_Singapore_H2012_779_2012_H3N2_2012:0.00356603145968508633):0.00118438957988058788[68],(A_Ontario_41_2014_H3N2_2014:0.00987699252631252939,A_Delhi_1191_2013_H3N2_2013:0.00868691236106632590):0.00096281225525241508[71]):0.00179535367243330453[97],A_Nicaragua_5754_07_2013_H3N2_2013:0.00416635888853660388); 2 | -------------------------------------------------------------------------------- /inst/extdata/ref35extend.jplace: -------------------------------------------------------------------------------- 1 | { 2 | "fields": [ 3 | "edge_num", 4 | "likelihood", 5 | "like_weight_ratio", 6 | "distal_length", 7 | "pendant_length" 8 | ], 9 | "metadata": { 10 | "invocation": "../../run_apples.py -s ref35.fa -q query.fa -t ref35.nwk -T 0" 11 | }, 12 | "placements": [ 13 | { 14 | "n": [ 15 | "L379065" 16 | ], 17 | "p": [ 18 | [ 19 | 61, 20 | 0, 21 | 1, 22 | 0.0, 23 | 0 24 | ] 25 | ] 26 | }, 27 | { 28 | "n": [ 29 | "L1580573" 30 | ], 31 | "p": [ 32 | [ 33 | 64, 34 | 0, 35 | 1, 36 | 0.10716113383427456, 37 | 0 38 | ] 39 | ] 40 | }, 41 | { 42 | "n": [ 43 | "L1415841" 44 | ], 45 | "p": [ 46 | [ 47 | 64, 48 | 0, 49 | 1, 50 | 0.22267036209325047, 51 | 0 52 | ] 53 | ] 54 | }, 55 | { 56 | "n": [ 57 | "L757253" 58 | ], 59 | "p": [ 60 | [ 61 | 62, 62 | 0, 63 | 1, 64 | 0.0, 65 | 0 66 | ] 67 | ] 68 | }, 69 | { 70 | "n": [ 71 | "L1415962" 72 | ], 73 | "p": [ 74 | [ 75 | 64, 76 | 0, 77 | 1, 78 | 0.21158024444276607, 79 | 0 80 | ] 81 | ] 82 | }, 83 | { 84 | "n": [ 85 | "L196079" 86 | ], 87 | "p": [ 88 | [ 89 | 62, 90 | 0, 91 | 1, 92 | 0.0, 93 | 0 94 | ] 95 | ] 96 | }, 97 | { 98 | "n": [ 99 | "L1965590" 100 | ], 101 | "p": [ 102 | [ 103 | 51, 104 | 0, 105 | 1, 106 | 4.913346477589697, 107 | 0 108 | ] 109 | ] 110 | }, 111 | { 112 | "n": [ 113 | "L1516956" 114 | ], 115 | "p": [ 116 | [ 117 | 64, 118 | 0, 119 | 1, 120 | 0.21363243057073034, 121 | 0 122 | ] 123 | ] 124 | }, 125 | { 126 | "n": [ 127 | "L449397" 128 | ], 129 | "p": [ 130 | [ 131 | 48, 132 | 0, 133 | 1, 134 | 0.0225622, 135 | 0 136 | ] 137 | ] 138 | }, 139 | { 140 | "n": [ 141 | "L1551535" 142 | ], 143 | "p": [ 144 | [ 145 | 64, 146 | 0, 147 | 1, 148 | 0.09460070912760843, 149 | 0 150 | ] 151 | ] 152 | } 153 | ], 154 | "tree": "(L1408828:0.271977{0},L1415348:0.206762{1},(L1446078:0.391589{2},((L1806041:0.32914{3},(L1523515:0.322673{4},L1640855:0.295511{5})0.966872:0.025616{6})14.4648:0.0830515{7},(((L50685:0.158879{8},L49952:0.208287{9})164.561:0.194047{10},(L62717:0.374518{11},(L115469:0.368306{12},(L77577:0.341185{13},L121889:0.335629{14})2.38687:0.0232067{15})28.537:0.0836605{16})5.18492:0.0396922{17})68.4627:0.188789{18},(L153039:0.642495{19},(((L617267:0.482233{20},L557202:0.486991{21})6.43384:0.0642771{22},(L694536:0.466184{23},((L788532:0.413878{24},((L943073:0.340254{25},(L846037:0.291179{26},L836319:0.269851{27})16.9809:0.0402935{28})1.07936:0.012571{29},(L1015202:0.303479{30},L1039732:0.292749{31})26.7493:0.0708331{32})15.2055:0.0367029{33})25.1909:0.0458232{34},(((L1129144:0.368523{35},L1062475:0.428881{36})0.940412:0.0145741{37},(L1167268:0.39929{38},L1259289:0.446055{39})0.045326:0.00410425{40})2.39494:0.0152628{41},(L1218735:0.396239{42},L1081296:0.358231{43})0.302875:0.0147761{44})15.1551:0.0273377{45})5.36406:0.0313054{46})83.7028:0.153203{47})2.43175:0.0225622{48},((L541505:0.439449{49},(L522832:0.473112{50},L1983801:5.43083{51})1.34499:7.268e-05{52})11.9642:0.0878123{53},(L495486:0.317903{54},(L279855:0.310724{55},(L377116:0.27581{56},L473089:0.335884{57})6.5209:0.0391233{58})2.45588:0.0168541{59})134.787:0.180241{60})1.06645:0.0216918{61})12.6378:0.0621394{62})7.90107:0.0654683{63})440.828:0.537175{64})16.9142:0.0636092{65})65.4764:0.107272{66}){67};", 155 | "version": 3 156 | } -------------------------------------------------------------------------------- /R/method-spt.R: -------------------------------------------------------------------------------- 1 | ##' @name spt 2 | ##' @rdname spt-methods 3 | ##' @title spt method 4 | ##' @param x a igraph object 5 | ##' @param from a specific node of network. 6 | ##' @param to other nodes of the network, length of it must 7 | ##' be larger than 2. 8 | ##' @param weights a numeric vector giving edge weights or a character. 9 | ##' If this is \code{NULL} and the graph has a \code{weight} edge attribute, 10 | ##' then the attribute is used. If this is \code{NA} then no weights 11 | ##' are used even if the graph has a \code{weight} attribute. If this is a 12 | ##' character, the graph has the edge attribute which is numeric, then it 13 | ##' will be used, default is \code{NULL}. 14 | ##' @param ... additional parameters 15 | ##' @return phylo object 16 | ##' @export 17 | ##' @examples 18 | ##' library(igraph) 19 | ##' set.seed(123) 20 | ##' g <- igraph::sample_gnp(100, .1) %>% 21 | ##' set_edge_attr(name='weight', value=abs(rnorm(E(.),3))) 22 | ##' tr1 <- spt(g, from = 6, to=V(g), weights = 'weight') 23 | ##' tr1 24 | ##' tr2 <- spt(g, from = 6, to = V(g), weights = NA) 25 | ##' tr2 26 | spt <- function(x, from, to, weights = NULL, ...){ 27 | UseMethod('spt') 28 | } 29 | 30 | 31 | #' @method spt igraph 32 | #' @export 33 | spt.igraph <- function(x, from, to, weights = NULL, ...){ 34 | .internal.spt(x, from, to, weights, ...) 35 | } 36 | 37 | ##' find the hierarchical cluster analysis among the nodes of graph 38 | ##' based on the length of all the shortest paths in the graph. 39 | ##' @param x a igraph object 40 | ##' @param graph.mst logical whether obtain the minimum spanning tree first 41 | ##' then find.hclust, default is FALSE. 42 | ##' @param weights a numeric vector giving edge weights or a character. 43 | ##' If this is \code{NULL} and the graph has a \code{weight} edge attribute, 44 | ##' then the attribute is used. If this is \code{NA} then no weights 45 | ##' are used even if the graph has a \code{weight} attribute. If this is a 46 | ##' character, the graph has the edge attribute which is numeric, then it 47 | ##' will be used, default is \code{NULL}. 48 | ##' @param hclust.method the agglomeration method to be used, This should be (an 49 | ##' unambiguous abbreviation of) one of \code{"ward.D"}, \code{"ward.D2"}, 50 | ##' \code{"single"}, \code{"complete"}, \code{"average"} (= UPGMA), \code{"mcquitty"} 51 | ##' (= WPGMA), \code{"median"} (= WPGMC) or \code{"centroid"} (= UPGMC). 52 | ##' @param ... additional parameters 53 | ##' @return hclust object 54 | ##' @export 55 | ##' @examples 56 | ##' library(igraph) 57 | ##' set.seed(123) 58 | ##' g <- igraph::sample_gnp(100, .1) %>% 59 | ##' set_edge_attr(name='weight', value=abs(rnorm(E(.),3))) 60 | ##' tr1 <- find.hclust(g, weights = NA) 61 | ##' tr2 <- find.hclust(g) 62 | ##' tr3 <- find.hclust(g, graph.mst = TRUE) 63 | find.hclust <- function(x, graph.mst = FALSE, weights = NULL, hclust.method = 'average', ...){ 64 | UseMethod('find.hclust') 65 | } 66 | 67 | ##' @method find.hclust igraph 68 | ##' @importFrom stats as.dist hclust 69 | ##' @importFrom rlang check_installed 70 | ##' @export 71 | find.hclust.igraph <- function( 72 | x, 73 | graph.mst = FALSE, 74 | weights = NULL, 75 | hclust.method = 'average', 76 | ... 77 | ){ 78 | check_installed('igraph', 'for `find.hclust()`.') 79 | edge.attr.list <- igraph::edge_attr(x) 80 | wg.nm <- 'weight' 81 | if (is.numeric(weights) && length(weights) == igraph::ecount(x)){ 82 | x <- igraph::set_edge_attr(x, name='weight', value = weights) 83 | weights <- NULL 84 | }else if (is.character(weights) && weights %in% names(edge.attr.list) && is.numeric(edge.attr.list[[weights]])){ 85 | x <- igraph::set_edge_attr(x, name = 'weight', value = edge.attr.list[[weights]]) 86 | weights <- NULL 87 | }else if (is.null(weights)){ 88 | if (!('weight' %in% colnames(edge.attr.list) && is.numeric(edge.attr.list[['weight']]))){ 89 | wg.nm <- NULL 90 | } 91 | }else{ 92 | wg.nm <- NULL 93 | weights <- NA 94 | } 95 | 96 | if (graph.mst){ 97 | x <- igraph::mst(x, weights = weights) 98 | if (!is.null(wg.nm)){ 99 | weights <- igraph::edge_attr(x)[[wg.nm]] 100 | } 101 | } 102 | 103 | d <- igraph::distances(x, weights = weights, ...) 104 | 105 | hc <- hclust(as.dist(d), method = hclust.method) 106 | return(hc) 107 | } 108 | 109 | 110 | .internal.spt <- function(x, from, to, weights = NULL, ...){ 111 | check_installed('igraph', 'for `spt()`.') 112 | edge <- igraph::as_data_frame(x) 113 | flag.weight <- FALSE 114 | if (is.numeric(weights) && length(weights)==nrow(edge)){ 115 | flag.weight <- TRUE 116 | weights <- weights 117 | }else if (is.character(weights) && weights %in% colnames(edge) && is.numeric(edge[[weights]])){ 118 | flag.weight <- TRUE 119 | weights <- edge[[weights]] 120 | }else if (is.null(weights) && 'weight' %in% colnames(edge)){ 121 | flag.weight <- TRUE 122 | weights <- edge[['weight']] 123 | } 124 | res <- igraph::shortest_paths(x, from, to, output = 'epath', weights = weights, ...) 125 | ind <- res$epath |> 126 | lapply(as.numeric) |> 127 | unlist() |> 128 | unique() 129 | edge <- edge[ind,c(1,2)] |> as.matrix() 130 | keep.ind <- !duplicated(edge) 131 | if (flag.weight){ 132 | weights <- weights[ind] 133 | weights <- weights[keep.ind] 134 | } 135 | edge <- edge[keep.ind,] 136 | if (nrow(edge) <=1){ 137 | cli::cli_abort("the shortest path tree can not be found!") 138 | } 139 | if (any(duplicated(edge[,2]))){ 140 | edge <- .adjust.tree.network.edge(edge) 141 | } 142 | if (flag.weight){ 143 | edge <- cbind(edge, branch.length = weights) 144 | tr <- as.phylo(edge, branch.length = 'branch.length') 145 | }else{ 146 | tr <- as.phylo(edge) 147 | } 148 | return(tr) 149 | } 150 | -------------------------------------------------------------------------------- /inst/extdata/MCMCTree/mcmctree_output.tree: -------------------------------------------------------------------------------- 1 | #NEXUS 2 | BEGIN TREES; 3 | 4 | UTREE 1 = ((((((((((((((((Dioscorea_villosa: 1.048609, ((Colchicum_autumnale: 0.680447, Smilax_bona-nox: 0.680447) [&95%={0.365, 0.913}]: 0.278870, ((((Sorghum_bicolor: 0.208728, Zea_mays: 0.208728) [&95%={0.090, 0.386}]: 0.272402, (Oryza_sativa: 0.348895, Brachypodium_distachyon: 0.348895) [&95%={0.194, 0.536}]: 0.132234) [&95%={0.319, 0.653}]: 0.301939, Sabal_bermudana: 0.783068) [&95%={0.624, 0.930}]: 0.111954, Yucca_filamentosa: 0.895023) [&95%={0.767, 1.029}]: 0.064294) [&95%={0.847, 1.091}]: 0.089292) [&95%={0.926, 1.175}]: 0.193469, Acorus_americanus: 1.242078) [&95%={1.151, 1.285}]: 0.419769, ((Sarcandra_glabra: 1.423141, ((Persea_americana: 1.182059, Liriodendron_tulipifera: 1.182059) [&95%={1.109, 1.388}]: 0.129237, (Houttuynia_cordata: 0.761429, Saruma_henryi: 0.761429) [&95%={0.513, 1.050}]: 0.549868) [&95%={1.190, 1.538}]: 0.111844) [&95%={1.282, 1.642}]: 0.120880, (((Vitis_vinifera: 1.069100, (((Hibiscus_cannabinus: 0.756565, (Arabidopsis_thaliana: 0.576251, Carica_papaya: 0.576251) [&95%={0.352, 0.782}]: 0.180314) [&95%={0.556, 0.920}]: 0.104741, Populus_trichocarpa: 0.861306) [&95%={0.698, 1.001}]: 0.104500, (Larrea_tridentata: 0.866345, (Medicago_truncatula: 0.736450, Boehmeria_nivea: 0.736450) [&95%={0.503, 0.913}]: 0.129895) [&95%={0.689, 1.005}]: 0.099462) [&95%={0.834, 1.089}]: 0.103293) [&95%={0.949, 1.168}]: 0.083046, (Kochia_scoparia: 1.070810, (Diospyros_malabarica: 0.972900, ((Rosmarinus_officinalis: 0.760149, ((Allamanda_cathartica: 0.362569, Catharanthus_roseus: 0.362569) [&95%={0.186, 0.573}]: 0.303962, Ipomoea_purpurea: 0.666532) [&95%={0.483, 0.834}]: 0.093617) [&95%={0.583, 0.908}]: 0.126433, (Inula_helenium: 0.455099, Tanacetum_parthenium: 0.455099) [&95%={0.229, 0.727}]: 0.431484) [&95%={0.741, 1.015}]: 0.086318) [&95%={0.837, 1.089}]: 0.097909) [&95%={0.943, 1.170}]: 0.081336) [&95%={1.047, 1.226}]: 0.109845, (Eschscholzia_californica: 1.014447, (Podophyllum_peltatum: 0.783067, Aquilegia_formosa: 0.783067) [&95%={0.472, 1.019}]: 0.231379) [&95%={0.782, 1.180}]: 0.247544) [&95%={1.210, 1.286}]: 0.282031) [&95%={1.390, 1.759}]: 0.117825) [&95%={1.474, 1.893}]: 0.251538, Kadsura_heteroclita: 1.913385) [&95%={1.671, 2.174}]: 0.200808, Nuphar_advena: 2.114193) [&95%={1.853, 2.341}]: 0.215161, Amborella_trichopoda: 2.329353) [&95%={2.068, 2.467}]: 1.186361, ((Ginkgo_biloba: 2.886743, ((Cycas_rumphii: 0.209910, Cycas_micholitzii: 0.209910) [&95%={0.067, 0.511}]: 0.742625, Zamia_vazquezii: 0.952535) [&95%={0.426, 1.932}]: 1.934209) [&95%={2.660, 3.182}]: 0.291213, (((Cedrus_libani: 0.630084, Pinus_taeda: 0.630084) [&95%={0.186, 1.268}]: 1.484077, (Ephedra_sinica: 1.252101, (Gnetum_montanum: 0.893096, Welwitschia_mirabilis: 0.893096) [&95%={0.507, 1.322}]: 0.359005) [&95%={0.835, 1.883}]: 0.862060) [&95%={1.425, 2.791}]: 0.323899, (Prumnopitys_andina: 1.139418, ((Taxus_baccata: 0.684232, (Cunninghamia_lanceolata: 0.346180, Juniperus_scopulorum: 0.346180) [&95%={0.135, 0.684}]: 0.338053) [&95%={0.364, 1.029}]: 0.268541, Sciadopitys_verticillata: 0.952774) [&95%={0.631, 1.329}]: 0.186644) [&95%={0.794, 1.627}]: 1.298642) [&95%={1.701, 3.048}]: 0.739896) [&95%={3.084, 3.372}]: 0.337758) [&95%={3.311, 3.651}]: 0.756559, ((Angiopteris_evecta: 3.572426, (Psilotum_nudum: 2.694459, Ophioglossum_petiolatum: 2.694459) [&95%={1.069, 3.563}]: 0.877967) [&95%={3.215, 3.938}]: 0.470243, ((Pteridium_aquilinum: 1.157837, Alsophila_spinulosa: 1.157837) [&95%={0.498, 2.476}]: 2.748774, Equisetum_diffusum: 3.906612) [&95%={3.848, 4.040}]: 0.136057) [&95%={3.923, 4.196}]: 0.229604) [&95%={4.131, 4.405}]: 0.194226, ((Huperzia_squarrosa: 1.262266, (Pseudolycopodiella_caroliniana: 0.880517, Dendrolycopodium_obscurum: 0.880517) [&95%={0.427, 1.586}]: 0.381749) [&95%={0.751, 2.345}]: 2.827336, (Selaginella_moellendorffii_1kp: 0.118093, Selaginella_moellendorffii_genome: 0.118093) [&95%={0.041, 0.278}]: 3.971509) [&95%={3.927, 4.322}]: 0.376897) [&95%={4.367, 4.509}]: 0.534649, (((Sphagnum_lescurii: 3.997941, (Polytrichum_commune: 3.397907, ((Ceratodon_purpureus: 1.778639, ((((Anomodon_attenuatus: 0.224757, Leucodon_brachypus: 0.224757) [&95%={0.098, 0.429}]: 0.065945, (Rhynchostegium_serrulatum: 0.228452, Thuidium_delicatulum: 0.228452) [&95%={0.104, 0.426}]: 0.062250) [&95%={0.161, 0.498}]: 0.573797, (Bryum_argenteum: 0.323689, Rosulabryum_cf_capillare: 0.323689) [&95%={0.126, 0.642}]: 0.540811) [&95%={0.545, 1.262}]: 0.178913, Hedwigia_ciliata: 1.043413) [&95%={0.699, 1.538}]: 0.735227) [&95%={0.972, 2.746}]: 1.045324, Physcomitrella_patens: 2.823964) [&95%={2.685, 3.177}]: 0.573944) [&95%={2.994, 3.957}]: 0.600034) [&95%={3.494, 4.493}]: 0.673778, ((Sphaerocarpos_texanus: 2.726549, (Ricciocarpos_natans: 1.227130, (Marchantia_emarginata: 0.794260, Marchantia_polymorpha: 0.794260) [&95%={0.332, 1.346}]: 0.432870) [&95%={0.707, 2.209}]: 1.499419) [&95%={2.283, 3.621}]: 1.457978, (Metzgeria_crassipilis: 2.439998, Bazzania_trilobata: 2.439998) [&95%={0.792, 3.922}]: 1.744529) [&95%={4.053, 4.461}]: 0.487192) [&95%={4.397, 4.916}]: 0.198909, (Nothoceros_aenigmaticus: 0.164270, Nothoceros_vincentianus: 0.164270) [&95%={0.053, 0.382}]: 4.706358) [&95%={4.632, 5.065}]: 0.130520) [&95%={4.766, 5.149}]: 0.553137, Chara_vulgaris: 5.554284) [&95%={5.118, 6.145}]: 0.390023, ((((Roya_obtusa: 3.347875, (Cosmarium_ochthodes: 2.066851, Penium_margaritaceum: 2.066851) [&95%={0.860, 3.533}]: 1.281024) [&95%={2.004, 4.445}]: 0.716665, Netrium_digitus: 4.064540) [&95%={2.936, 5.021}]: 0.451107, Spirogyra_sp: 4.515647) [&95%={3.554, 5.409}]: 0.456267, ((Mougeotia_sp: 3.595207, (Cylindrocystis_brebissonii: 3.075276, Cylindrocystis_cushleckae: 3.075276) [&95%={1.413, 4.250}]: 0.519931) [&95%={2.097, 4.690}]: 0.874829, Mesotaenium_endlicherianum: 4.470036) [&95%={3.452, 5.384}]: 0.501878) [&95%={4.089, 5.802}]: 0.972393) [&95%={5.403, 6.633}]: 0.284481, (Chaetosphaeridium_globosum: 4.738019, (Coleochaete_scutata: 3.176622, Coleochaete_irregularis: 3.176622) [&95%={1.125, 4.842}]: 1.561397) [&95%={3.116, 6.056}]: 1.490769) [&95%={5.607, 7.012}]: 0.416060, (Entransia_fimbriata: 4.686396, Klebsormidium_subtile: 4.686396) [&95%={2.547, 6.542}]: 1.958452) [&95%={5.906, 7.652}]: 0.661485, (Mesostigma_viride: 5.884836, (Chlorokybus_atmophyticus: 4.184455, Spirotaenia_minuta: 4.184455) [&95%={2.113, 6.224}]: 1.700381) [&95%={3.952, 7.700}]: 1.421497) [&95%={6.337, 8.634}]: 0.461171, ((Uronema_sp: 5.843147, (Monomastix_opisthostigma: 4.869119, Nephroselmis_pyriformis: 4.869119) [&95%={3.227, 6.683}]: 0.974029) [&95%={4.500, 7.406}]: 0.837307, Pyramimonas_parkeae: 6.680455) [&95%={5.025, 8.412}]: 1.087048) [&95%={6.651, 9.296}]; 5 | END; 6 | -------------------------------------------------------------------------------- /R/utilities.R: -------------------------------------------------------------------------------- 1 | 2 | check_edgelist <- function(edgelist) { 3 | if (dim(edgelist)[2] < 2) 4 | stop("input should be a matrix of edge list that holds the relationships in the first two columns") 5 | if (length(unique(edgelist[,1,drop=TRUE])) > length(unique(edgelist[,2,drop=TRUE]))) { 6 | children <- edgelist[,1,drop=TRUE] 7 | parents <- edgelist[,2,drop=TRUE] 8 | } else { 9 | children <- edgelist[,2,drop = TRUE] 10 | parents <- edgelist[,1,drop = TRUE] 11 | } 12 | root1 <- unique(parents[!(parents %in% children)]) 13 | root2 <- unique(parents[parents == children]) 14 | if ((length(root1) != 1 && length(root2) != 1 )|| any(duplicated(children))) 15 | stop("Cannot find root. network is not a tree!") 16 | if (length(root1) != 1 && length(root2) == 1){ 17 | indx <- parents != children 18 | parents <- parents[indx] 19 | children <- children[indx] 20 | edge <- matrix(c(parents, children), ncol=2) 21 | attr(edge, "indx") <- indx 22 | }else{ 23 | edge <- matrix(c(parents, children), ncol=2) 24 | } 25 | return (edge) 26 | } 27 | 28 | 29 | is_numeric <- function(x) !anyNA(suppressWarnings(as.numeric(as.character(x)))) 30 | 31 | filename <- function(file) { 32 | ## textConnection(text_string) will work just like a file 33 | ## in this case, just set the filename as "" 34 | file_name <- "" 35 | if (is.character(file)) { 36 | file_name <- file 37 | } 38 | return(file_name) 39 | } 40 | 41 | jplace_treetext_to_phylo <- function(tree.text) { 42 | ## move edge label to node label separate by @@ 43 | ## The tree in jplace file format: The edge number is not always in curly braces. 44 | ## they are sometimes in square brackets. 45 | if(grepl("\\{(\\d+)\\}", tree.text)){ 46 | tr <- gsub('(:[0-9\\.eE\\+\\-]+)\\{(\\d+)\\}', '\\@@\\2\\1', tree.text) 47 | } 48 | if(grepl("\\[(\\d+)\\]", tree.text)){ 49 | message("The version of jplace file is 1.0.") 50 | tr <- gsub('(:[0-9\\.eE\\+\\-]+)\\[(\\d+)\\]', '\\@@\\2\\1', tree.text) 51 | } 52 | phylo <- read.tree(text=tr) 53 | if (length(grep('@@', phylo$tip.label)) > 0) { 54 | phylo$node.label[1] <- gsub("(.*)\\{(\\d+)\\}", "\\1@@\\2", phylo$node.label[1]) 55 | tip.edgeNum <- as.numeric(gsub(".*@@(\\d*)", "\\1",phylo$tip.label)) 56 | node.edgeNum <- as.numeric(gsub(".*@@(\\d*)", "\\1",phylo$node.label)) 57 | phylo$tip.label <- gsub("@@\\d+", "", phylo$tip.label) 58 | phylo$node.label <- gsub("@@\\d+", "", phylo$node.label) 59 | if (all(phylo$node.label == "")) { 60 | phylo$node.label <- NULL 61 | } 62 | 63 | N <- getNodeNum(phylo) 64 | edgeNum.df <- data.frame(node=1:N, edgeNum=c(tip.edgeNum, node.edgeNum)) 65 | ## root node is not encoded with edge number 66 | edgeNum.df <- edgeNum.df[!is.na(edgeNum.df[,2]),] 67 | attr(phylo, "edgeNum") <- edgeNum.df 68 | } 69 | 70 | ## using :edge_length{edge_num} to match edge_num to node_num 71 | ## this is not a good idea since there may exists identical edge_length. 72 | ## but we can use it to verify our method. 73 | ## 74 | ## en.matches <- gregexpr(":[0-9\\.eE\\+\\-]+\\{\\d+\\}", tree.text) 75 | ## matches <- en.matches[[1]] 76 | ## match.pos <- as.numeric(matches) 77 | ## match.len <- attr(matches, 'match.length') 78 | 79 | ## edgeLN <- substring(tree.text, match.pos+1, match.pos+match.len-2) 80 | ## edgeLN.df <- data.frame(length=as.numeric(gsub("\\{.+", "", edgeLN)), 81 | ## edgeNum = as.numeric(gsub(".+\\{", "", edgeLN))) 82 | 83 | ## xx <- merge(edgeLN.df, edgeNum.df, by.x="node", by.y="node") 84 | 85 | return(phylo) 86 | } 87 | 88 | 89 | ## convert edge number to node number for EPA/pplacer output 90 | edgeNum2nodeNum <- function(jp, edgeNum) { 91 | edges <- attr(jp@phylo, "edgeNum") 92 | idx <- match(edgeNum, edges$edgeNum) 93 | flagna <- is.na(idx) 94 | idx <- idx[!flagna] 95 | if (any(flagna) & length(idx)>0){ 96 | na_edgeNum <- paste(edgeNum[which(flagna)], collapse="; ") 97 | stop(paste("The following edges: ",na_edgeNum, ", couldn't be found", sep=""), call. = FALSE) 98 | #idx <- idx[!flagna] 99 | } 100 | #idx <- which(edges$edgeNum == edgeNum) 101 | if (length(idx) == 0) { 102 | return(NA) 103 | } 104 | 105 | edges[idx, "node"] 106 | } 107 | 108 | is.tree <- function(x) { 109 | tree_class <- c("phylo", 110 | "phylo4", 111 | "jplace", 112 | "treedata") 113 | 114 | if (inherits(x, tree_class)) { 115 | return(TRUE) 116 | } 117 | return(FALSE) 118 | } 119 | 120 | ##' @importFrom methods .hasSlot is missingArg new slot slot<- 121 | has.slot <- function(object, slotName) { 122 | if (!isS4(object)) { 123 | return(FALSE) 124 | } 125 | .hasSlot(object, slotName) 126 | } 127 | 128 | build_new_labels <- function(tree){ 129 | node2label_old <- tree %>% as_tibble() %>% dplyr::select(c("node", "label")) %>% 130 | suppressMessages() 131 | if (inherits(tree, "treedata")){ 132 | tree <- tree@phylo 133 | } 134 | tree$tip.label <- paste0("t", seq_len(Ntip(tree))) 135 | tree$node.label <- paste0("n", seq_len(Nnode(tree))) 136 | node2label_new <- tree %>% as_tibble() %>% dplyr::select(c("node", "label")) %>% 137 | suppressMessages() 138 | old_and_new <- node2label_old %>% 139 | dplyr::inner_join(node2label_new, by="node") %>% 140 | dplyr::rename(old="label.x", new="label.y") 141 | return (list(tree=tree, node2old_new_lab=old_and_new)) 142 | } 143 | 144 | build_new_tree <- function(tree, node2old_new_lab){ 145 | # replace new label with old label 146 | treeda <- tree %>% as_tibble() 147 | treeda1 <- treeda %>% 148 | dplyr::filter(.data$label %in% node2old_new_lab$new) %>% 149 | suppressWarnings() 150 | treeda2 <- treeda %>% 151 | dplyr::filter(!(.data$label %in% node2old_new_lab$new)) %>% 152 | suppressWarnings() 153 | # original label 154 | treeda1$label <- node2old_new_lab[match(treeda1$label, node2old_new_lab$new), "old"] %>% 155 | unlist(use.names=FALSE) 156 | treeda <- rbind(treeda1, treeda2) 157 | tree <- treeda[order(treeda$node),] %>% as.phylo() 158 | return (tree) 159 | } 160 | 161 | .rev.edge <- function(x, nodes, index){ 162 | ind <- x[,index] %in% nodes 163 | if (sum(ind)>=1){ 164 | x[ind,] <- t(apply(matrix(x[ind,], ncol=2),1,rev)) 165 | } 166 | return(x) 167 | } 168 | 169 | .check.no.tree.network <- function(x, nodes){ 170 | is.tree <- length(table(x)) - nrow(x) != 1 171 | is.tree || any(((x[,1] %in% nodes) + (x[,2] %in% nodes)) ==2) || sum(x[,1]==x[,2])>1 172 | } 173 | -------------------------------------------------------------------------------- /R/hyphy.R: -------------------------------------------------------------------------------- 1 | ##' parse sequences from hyphy output 2 | ##' 3 | ##' 4 | ##' @title read.hyphy.seq 5 | ##' @param file output of hyphy ancestral sequence inference; nexus format 6 | ##' @return DNAbin object 7 | ##' @export 8 | ##' @examples 9 | ##' ancseq <- system.file("extdata/HYPHY", "ancseq.nex", package="treeio") 10 | ##' read.hyphy.seq(ancseq) 11 | ##' @author Guangchuang Yu 12 | read.hyphy.seq <- function(file) { 13 | anc <- scan(file, what="", sep="\n", quiet=TRUE) 14 | end <- grep("END;", anc, ignore.case=TRUE) 15 | 16 | seq.start <- grep("MATRIX", anc, ignore.case=TRUE) 17 | seq.end <- end[end > seq.start][1] 18 | seq <- anc[(seq.start+1):(seq.end-1)] 19 | seq <- seq[seq != ";"] 20 | seq <- gsub("^\\s+", "", seq) 21 | seq <- gsub(";", "", seq) 22 | seq <- seq[seq != ""] 23 | 24 | ## some files may only contains sequences 25 | ## (should have TAXALABELS block that contains seq names). 26 | ## some may contains sequence name like phylip format in 27 | ## MATRIX block (no need to have TAXALABELS block). 28 | ## 29 | ## extract sequence name if available 30 | if (all(grepl("\\s+", seq))) { 31 | ## if contains blank space, may contains seq name 32 | sn <- gsub("(\\w*)\\s.*", "\\1", seq) 33 | } 34 | 35 | seq <- gsub("\\w*\\s+", "", seq) 36 | 37 | label.start <- grep("TAXLABELS", anc, ignore.case = TRUE) 38 | if (length(label.start) == 0) { 39 | if (all(sn == "")) { 40 | stop("taxa labels is not available...") 41 | } 42 | label <- sn 43 | } else { 44 | label.end <- end[end > label.start][1] 45 | label <- anc[(label.start+1):(label.end-1)] 46 | 47 | label <- sub("^\t+", "", label) 48 | label <- sub("^\\s+", "", label) 49 | label <- sub("\\s*;*$", "", label) 50 | label <- label[label != ""] 51 | label <- unlist(strsplit(label, split="\\s+")) 52 | label <- gsub("'|\"", "", label) 53 | } 54 | 55 | names(seq) <- label 56 | res <- string2DNAbin(seq) 57 | 58 | attr(res, "seq_type") <- get_seqtype(seq[1]) 59 | return(res) 60 | } 61 | 62 | ##' read HYPHY output 63 | ##' 64 | ##' 65 | ##' @title read.hyphy 66 | ##' @param nwk tree file in nwk format, one of hyphy output 67 | ##' @param ancseq ancestral sequence file in nexus format, 68 | ##' one of hyphy output 69 | ##' @param tip.fasfile tip sequence file 70 | ##' @return A hyphy object 71 | ##' @importFrom ape read.FASTA 72 | ##' @export 73 | ##' @author Guangchuang Yu \url{https://guangchuangyu.github.io} 74 | ##' @examples 75 | ##' nwk <- system.file("extdata/HYPHY", "labelledtree.tree", package="treeio") 76 | ##' ancseq <- system.file("extdata/HYPHY", "ancseq.nex", package="treeio") 77 | ##' read.hyphy(nwk, ancseq) 78 | read.hyphy <- function(nwk, ancseq, tip.fasfile=NULL) { 79 | anc_seq <- read.hyphy.seq(ancseq) 80 | seq_type <- attr(anc_seq, 'seq_type') 81 | 82 | tr <- read.tree(nwk) 83 | nl <- tr$node.label 84 | ## root node may missing, which was supposed to be 'Node1' 85 | ## 86 | ## from a user's file, which is 'Node0', but it seems 87 | ## the file is not from the output of HYPHY. 88 | ## 89 | ## I am not sure. But it's safe to use "label[!label %in% nl]" 90 | ## instead of just assign it to "Node1". 91 | ## 92 | ## nl[nl == ""] <- "Node1" 93 | label <- labels(anc_seq) 94 | nl[nl == ""] <- label[!label %in% nl] 95 | tr$node.label <- nl 96 | 97 | res <- new("treedata", 98 | treetext = scan(nwk, what='', quiet=TRUE), 99 | phylo = tr, 100 | seq_type = seq_type, 101 | anc_seq = anc_seq, 102 | file = filename(nwk), 103 | ancseq_file = ancseq, 104 | info = list(parser = "read.hyphy") 105 | ) 106 | 107 | if ( !is.null(tip.fasfile) ) { 108 | res@tipseq_file <- tip.fasfile 109 | res@tip_seq <- read.FASTA(tip.fasfile) 110 | } 111 | set_substitution(res) 112 | } 113 | 114 | 115 | set_substitution <- function(object, ...) { 116 | if (length(object@tip_seq) == 0) { 117 | return(object) 118 | } 119 | 120 | if (length(object@anc_seq) == 0) { 121 | return(object) 122 | } 123 | 124 | subs <- get.subs_(object, translate=FALSE, ...) 125 | 126 | if (object@seq_type == "NT") { 127 | AA_subs <- get.subs_(object, translate=TRUE, ...) 128 | AA_subs <- rename(AA_subs, AA_subs = "subs") 129 | subs <- full_join(subs, AA_subs, by=c("node", "parent")) 130 | } 131 | subs <- select(subs, - "parent") 132 | 133 | if (nrow(object@data) == 0) { 134 | object@data <- subs 135 | } else { 136 | object@data <- full_join(object@data, subs, by='node') 137 | } 138 | return(object) 139 | } 140 | 141 | 142 | get.subs_ <- function(object, translate=TRUE, removeGap=TRUE) { 143 | tree <- as.phylo(object) 144 | ancseq <- object@anc_seq 145 | tipseq <- object@tip_seq 146 | 147 | 148 | N <- getNodeNum(tree) 149 | node <- 1:N 150 | ## pp <- vapply(node, function(n) parent(tree, n), numeric(1)) 151 | pp <- parent(tree, node) 152 | 153 | label <- getNodeName(tree) 154 | seqs <- c(as.list(ancseq), as.list(tipseq)) 155 | subs <- vapply(seq_along(node), function(i) { 156 | if (i == rootnode(tree)) { 157 | return('') 158 | } 159 | 160 | res <- getSubsLabel(seqs, label[pp[i]], label[i], translate, removeGap) 161 | if (is.null(res)) { 162 | return('') 163 | } 164 | return(res) 165 | }, character(1)) 166 | 167 | ## if `subs` is too long to plot, user can use 168 | ## `stringr::str_wrap` to format the text 169 | dd <- tibble(node=node, parent=pp, subs=subs) 170 | dd <- dd[dd$parent != 0,] 171 | return(dd) 172 | } 173 | 174 | ##' @importFrom ape trans 175 | getSubsLabel <- function(seqs, A, B, translate, removeGap) { 176 | seqA <- seqs[A] 177 | seqB <- seqs[B] 178 | if (translate) { 179 | seqA <- trans(seqA) 180 | seqB <- trans(seqB) 181 | } 182 | 183 | AA <- unlist(as.character(seqA)) 184 | BB <- unlist(as.character(seqB)) 185 | 186 | if (length(AA) != length(BB)) { 187 | stop("seqA should have equal length to seqB") 188 | } 189 | 190 | ii <- which(AA != BB) 191 | 192 | if (removeGap == TRUE) { 193 | if (length(ii) > 0 && translate == TRUE) { 194 | ii <- ii[AA[ii] != "X" & BB[ii] != "X"] 195 | } 196 | 197 | if (length(ii) > 0 && translate == FALSE) { 198 | ii <- ii[AA[ii] != "-" & BB[ii] != "-"] 199 | } 200 | } 201 | 202 | if (length(ii) == 0) { 203 | return(NULL) 204 | } 205 | 206 | res <- paste(AA[ii], ii, BB[ii], sep="", collapse=" / ") 207 | return(toupper(res)) 208 | } 209 | 210 | 211 | get_seqtype <- function(seq) { 212 | if (grepl("[-ACGT]+", seq[1])) { 213 | seq_type <- "NT" ## NucleoTide 214 | } else { 215 | seq_type <- "AA" ## Amino Acid 216 | } 217 | return(seq_type) 218 | } 219 | -------------------------------------------------------------------------------- /R/jplace.R: -------------------------------------------------------------------------------- 1 | ##' read jplace file 2 | ##' 3 | ##' 4 | ##' @title read.jplace 5 | ##' @param file jplace file 6 | ##' @return \code{jplace} instance 7 | ##' @importFrom jsonlite fromJSON 8 | ##' @export 9 | ##' @author Guangchuang Yu 10 | ##' @examples 11 | ##' jp <- system.file("extdata", "sample.jplace", package="treeio") 12 | ##' read.jplace(jp) 13 | read.jplace <- function(file) { 14 | fields <- tree <- placements <- NULL 15 | version <- metadata <- NULL 16 | jtree <- fromJSON(file) 17 | phylo <- jplace_treetext_to_phylo(jtree$tree) 18 | placements <- extract.placement(jtree, phylo) 19 | info <- c(jtree$metadata, version=jtree$version, parser = "read.jplace") 20 | res <- new("jplace", 21 | treetext = jtree$tree, 22 | phylo = phylo, 23 | placements = placements, 24 | info = info, 25 | file = filename(file) 26 | ) 27 | 28 | res@data <- summarize_placement(res) 29 | return(res) 30 | } 31 | 32 | ##' @importFrom dplyr summarize 33 | ##' @importFrom dplyr mutate 34 | ##' @importFrom dplyr group_by 35 | ##' @importFrom dplyr n 36 | summarize_placement <- function(tree) { 37 | place <- get.placements(tree, by="best") 38 | ids <- tibble(node = nodeIds(tree, internal.only = FALSE)) 39 | group_by(place, .data$node) %>% summarize(nplace=n()) %>% 40 | full_join(ids, by='node') %>% 41 | mutate(nplace = ifelse(is.na(.data$nplace), 0, .data$nplace)) 42 | } 43 | 44 | ##' @method get.placements jplace 45 | ##' @param by one of 'best' and 'all' 46 | ##' @export 47 | ##' @rdname get-placements 48 | ##' @importFrom dplyr group_by 49 | ##' @importFrom dplyr filter 50 | get.placements.jplace <- function(tree, by="best", ...) { 51 | placements <- tree@placements 52 | if (!'likelihood' %in% names(placements)) 53 | return(placements) 54 | 55 | if (by == "best") { 56 | ## http://astrostatistics.psu.edu/su07/R/html/base/html/all.equal.html 57 | ## due to precision, number are identical maynot be equal, 58 | ## so use all.equal which can test nearly equal number 59 | ## if not equals, the output is a descript string of the differences 60 | placements <- group_by(placements, .data$name) %>% 61 | filter(.data$likelihood == min(.data$likelihood)) 62 | } 63 | return(placements) 64 | } 65 | 66 | getplacedf <- function(places, nm){ 67 | ## the first column of placements maybe a matrix or one numeric vector, 68 | ## so when it is numeric vector, the nplaces will be 1. 69 | ## and the type of nm also is various. 70 | if (!inherits(places, "matrix")){ 71 | nplaces <- 1 72 | } else{ 73 | nplaces <- nrow(places) 74 | } 75 | if (inherits(nm, "matrix")){ 76 | nmsize <- nrow(nm) 77 | tmpn <- nm[,1] 78 | } 79 | if (inherits(nm, "list")){ 80 | nmsize <- length(nm) 81 | tmpn <- vapply(nm, function(x)x[1], character(1)) 82 | } 83 | if (inherits(nm, "character")){ 84 | nmsize <- length(nm) 85 | tmpn <- as.vector(nm) 86 | } 87 | ##example: 88 | ## when first column of plamcements is [[1,2,3,4,5],[3,4,5,6,7],[6,7,3,2,4]] (3 row x 5 columns matrix), 89 | ## and the n column is ["read1", "read2"] (the type of n is character vector), so 90 | ## will use "inherits(nm, "character")" block. 91 | ## this will first generate two same matrix contained 3 row x 5 columns, because the length of n is two (the nmsize argument). 92 | places.df <- rep(list(places), nmsize) 93 | ## then this will generate the names of each matrix for the nm. 94 | ## example result is: rep(c("read1", "read2"), rep(3,2)), here 3 is nplaces (the nrow of first column of placements), 95 | ## 2 is the length of nm. 96 | name <- rep(tmpn, rep(nplaces, nmsize)) 97 | places.df <- do.call("rbind", places.df) 98 | places.df <- data.frame(name=name, places.df, stringsAsFactors=FALSE) 99 | return(places.df) 100 | } 101 | 102 | 103 | mergenm <- function(n, nm){ 104 | ## merge the n and nm. 105 | ## it is impossible that n and nm is empty simultaneously, 106 | ## so we will keep the column not NULL. 107 | if(is.null(n)&&!is.null(nm)) {return(nm)} 108 | if(is.null(nm)&&!is.null(n)) {return(n)} 109 | if(is.null(n)&&is.null(nm)){ 110 | stop("the placements of jplace should have corresponding name!") 111 | } 112 | } 113 | 114 | 115 | extract.placement <- function(object, phylo) { 116 | placements <- object$placements 117 | if (ncol(placements)==2){ 118 | ## when placements contained p and n two columns, 119 | ## this will process placements row by row with getplacedf function. 120 | ## The order of `p` and `n` column is not fixed. I think colnames of 121 | ## placements (`p`, `n`, `nm`) are fixed, but when column number is 122 | ## two, the `n` or `nm` is not fixed. 123 | nameidx <- match("p", colnames(placements)) 124 | place.df <- mapply(getplacedf, 125 | placements$p, 126 | placements[,-nameidx], 127 | SIMPLIFY=FALSE) 128 | } 129 | if(ncol(placements)==3){ 130 | ## when placements contained p ,n and nm three columns, 131 | ## first, we merge n and nm row by row. 132 | tmpname <- mapply(mergenm, 133 | placements$n, 134 | placements$nm, 135 | SIMPLIFY=FALSE) 136 | ## then, it becomes the same as two columns. 137 | place.df <- mapply(getplacedf, 138 | placements$p, 139 | tmpname, 140 | SIMPLIFY=FALSE) 141 | } 142 | place.df <- do.call("rbind", place.df) 143 | colnames(place.df) <- c("name", object$fields) 144 | ## place <- placements[,1] 145 | 146 | ## ids <- NULL 147 | ## if (length(placements) == 2) { 148 | ## tmpids <- placements[,2] 149 | ## }else{ 150 | ## tmpids <- list(unlist(placements[,2]), unlist(placements[,3])) 151 | ## } 152 | ## ids <- vapply(tmpids, function(x) x[1], character(1)) 153 | ## names(place) <- ids 154 | ## place.df <- do.call("rbind", place) 155 | ## row.names(place.df) <- NULL 156 | ## if (!is.null(ids)) { 157 | ## nn <- rep(ids, vapply(place, function(x) { 158 | ## nr <- nrow(x) 159 | ## if (is.null(nr)) 160 | ## return(1) 161 | ## return(nr) 162 | ## }, numeric(1))) 163 | ## place.df <- data.frame(name=nn, place.df) 164 | ## colnames(place.df) <- c("name", object$fields) 165 | ## } else { 166 | ## colnames(place.df) <- object$fields 167 | ## } 168 | edgeNum.df <- attr(phylo, "edgeNum") 169 | place.df <- merge(place.df, edgeNum.df, by.x = "edge_num", by.y = "edgeNum") 170 | place.df <- getnewplacements(place.df) 171 | as_tibble(place.df) 172 | } 173 | 174 | ## To avoid the character column 175 | getnewplacements <- function(placedf){ 176 | tmpfile <- tempfile() 177 | utils::write.csv(placedf, tmpfile) 178 | placementdf <- utils::read.csv(tmpfile, row.names=1) 179 | ## file.remove(tmpfile) 180 | return(placementdf) 181 | } 182 | 183 | 184 | -------------------------------------------------------------------------------- /R/phyloxml.R: -------------------------------------------------------------------------------- 1 | #' @title read.phyloxml 2 | #' @param file phyloxml file 3 | #' @return treedata class or treedataList class 4 | #' @export 5 | #' @examples 6 | #' xmlfile1 <- system.file("extdata/phyloxml", "test_x2.xml", package="treeio") 7 | #' px1 <- read.phyloxml(xmlfile1) 8 | #' px1 9 | #' xmlfile2 <- system.file("extdata/phyloxml", "phyloxml_examples.xml", package="treeio") 10 | #' px2 <- read.phyloxml(xmlfile2) 11 | #' px2 12 | read.phyloxml <- function(file){ 13 | check_installed('xml2', 'for `read.phyloxml()`.') 14 | x <- xml2::read_xml(file) 15 | x <- xml2::as_list(x) 16 | x <- x[["phyloxml"]] 17 | index <- which(names(x)=="phylogeny") 18 | if (length(index)==0){ 19 | stop("The input file is not phyloxml format, please check it !") 20 | } 21 | if (length(index)==1){ 22 | objtmp <- single_tree(index, x, file) 23 | obj <- objtmp[[1]] 24 | }else{ 25 | objtmp <- lapply(index, single_tree, x, file) 26 | obj <- lapply(objtmp, function(x)x[[1]]) 27 | names(obj) <- unlist(lapply(objtmp, function(x)x[[2]])) 28 | class(obj) <- "treedataList" 29 | } 30 | return(obj) 31 | } 32 | 33 | #' @keywords internal 34 | single_tree <- function(i, phylogeny, file){ 35 | rootflag <- unname(check_attrs(phylogeny[[i]])) 36 | treename <- extract_treename(i, phylogeny) 37 | dt <- parser_clade(phylogeny[[i]][["clade"]]) 38 | dt <- dt[!is.na(dt$parentID), ] 39 | if ("branch_length" %in% colnames(dt) & !all(is.na(dt[["branch_length"]]))){ 40 | edgedf <- dt[,c("parentID", "NodeID", "branch_length")] 41 | edgedf[(edgedf[,1]!=edgedf[,2] & is.na(edgedf[["branch_length"]])),"branch_length"] <- 0 42 | rmclumn <- c("parentID", "NodeID", "branch_length") 43 | }else{ 44 | edgedf <- dt[,c("parentID", "NodeID")] 45 | rmclumn <- c("parentID", "NodeID") 46 | } 47 | dt <- dplyr::mutate(dt, label = as.character(dt$NodeID)) 48 | if ('branch_length' %in% names(edgedf)){ 49 | dd <- as.phylo(edgedf, length = "branch_length") 50 | }else{ 51 | dd <- as.phylo(edgedf) 52 | } 53 | # check whether is rooted tree 54 | if (any(rootflag == "false")){ 55 | if (ape::is.rooted(dd)){ 56 | dd <- ape::unroot(dd) 57 | } 58 | } 59 | dd <- dd %>% as_tibble() %>% 60 | dplyr::full_join(dt, by='label') 61 | colnm <- colnames(dd) 62 | if ("accession" %in% colnm){ 63 | dd$label <- as.vector(dd[["accession"]]) 64 | rmclumn <- c(rmclumn, "accession") 65 | }else if ("scientific_name" %in% colnm && !"accession" %in% colnm){ 66 | dd$label <- as.vector(dd[["scientific_name"]]) 67 | rmclumn <- c(rmclumn, "scientific_name") 68 | }else if ("name" %in% colnm && !"accession" %in% colnm && !"scientific_name" %in% colnm){ 69 | dd$label <- as.vector(dd[["name"]]) 70 | rmclumn <- c(rmclumn, "name") 71 | } 72 | obj <- dd %>% dplyr::select(-dplyr::all_of(rmclumn)) %>% as.treedata() 73 | obj@file <- filename(file) 74 | return(c(obj, treename)) 75 | } 76 | 77 | 78 | #' @keywords internal 79 | parser_clade <- function(x, id=list2env(list(id = 0L)), parent=NULL){ 80 | # to generate edge data 81 | id[["id"]] <- id[["id"]] + 1L 82 | id[["data"]][[id[["id"]]]] <- extract_values_attrs(x, id=id[["id"]], isTip=FALSE, parent=fill_id(parent)) 83 | index <- which(names(x)=="clade") 84 | if (length(index)){ 85 | lapply(x[index], parser_clade, id=id, parent=id[["data"]][[id[["id"]]-1L]][["NodeID"]]) 86 | }else{ 87 | id[["data"]][[id[["id"]]]][["isTip"]] <- TRUE 88 | } 89 | dat <- dplyr::bind_rows(as.list(id[["data"]])) 90 | return(dat) 91 | } 92 | 93 | #' @keywords internal 94 | fill_id <- function(x){ 95 | if (is.list(x)) { 96 | lapply(x, fill_id) 97 | }else{ 98 | ifelse(length(x), unlist(x), NA) 99 | } 100 | } 101 | 102 | #' @keywords internal 103 | extract_another <- function(x){ 104 | namestmp <- names(x) 105 | index <- which(namestmp != "clade") 106 | if (length(index) >0){ 107 | lapply(x[index], function(i){ 108 | attrs1 <- check_attrs(i) 109 | attrs2 <- extract_attrs(i) 110 | attrs <- c(attrs1, attrs2) 111 | values <- check_value(i) 112 | if(inherits(attrs, "list")){attrs <- remove_names(attrs)} 113 | if(inherits(values,"list")){values <- remove_names(values)} 114 | res <- unlist(c(attrs, values)) 115 | res <- res[!duplicated(res)] 116 | namestmp2 <- names(res) 117 | # rename the duplicated names 118 | dind <- which(duplicated(namestmp2)|duplicated(namestmp2, fromLast=TRUE)) 119 | if (length(dind) & length(unique(res[dind]))>1){ 120 | namestmp2[dind] <- unlist(mapply(paste0, namestmp2[dind],seq_len(length(dind)), SIMPLIFY=FALSE)) 121 | } 122 | names(res) <- unlist(namestmp2) 123 | return(res) 124 | }) 125 | } 126 | } 127 | 128 | #' @keywords internal 129 | check_attrs <- function(x){ 130 | namesattrs <- names(attributes(x)) 131 | index <- which(namesattrs != "names") 132 | if (length(index)){ 133 | unlist(attributes(x)[index]) 134 | } 135 | } 136 | 137 | #' @keywords internal 138 | check_value <- function(x){ 139 | if(length(unlist(x))>1){ 140 | lapply(x, check_value) 141 | }else{ 142 | if (length(unlist(x))==0){ 143 | return(c(check_attrs(x))) 144 | }else{ 145 | return(c(check_attrs(x), remove_names(x))) 146 | } 147 | } 148 | } 149 | 150 | extract_attrs <- function(x){ 151 | lapply(x, check_attrs) 152 | } 153 | 154 | #' @keywords internal 155 | extract_treename <- function(i, phylogeny){ 156 | if ("name" %in% names(phylogeny[[i]])){ 157 | treename <- unlist(phylogeny[[i]][["name"]]) 158 | }else{ 159 | treename <- paste0("phylogeny_", i) 160 | } 161 | return (treename) 162 | } 163 | 164 | remove_names <- function(x){ 165 | for (i in seq_len(length(x))){ 166 | if (!is.null(x[[i]])){ 167 | if (is.null(names(x[[i]])) && !is.null(x[[i]])){ 168 | names(x[[i]]) <- names(x[i]) 169 | }else{ 170 | names(x[[i]])[nchar(names(x[[i]]))==0] <- names(x[i]) 171 | } 172 | } 173 | } 174 | names(x) <- NULL 175 | return(x) 176 | } 177 | 178 | 179 | #' @keywords internal 180 | extract_values_attrs <- function(x, id, parent, isTip){ 181 | # extract attributes of x to avoid them being remove in lapply. 182 | attr <- check_attrs(x) 183 | anothers <- extract_another(x) 184 | anothers <- unlist(remove_names(anothers)) 185 | res <- c(attr, anothers) 186 | if (!is.null(res)){ 187 | res <- data.frame(t(res), check.names=FALSE, stringsAsFactors=FALSE) 188 | res$parentID <- parent 189 | res$NodeID <- id 190 | res$isTip <- isTip 191 | }else{ 192 | res <- data.frame(parentID=parent, NodeID=id, isTip=isTip, 193 | check.names=FALSE, stringsAsFactors=FALSE) 194 | } 195 | if ("confidence" %in% colnames(res)){ 196 | res$confidence <- as.numeric(res$confidence) 197 | } 198 | return(res) 199 | } 200 | 201 | --------------------------------------------------------------------------------