Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Imports:
tidytree,
treeio,
purrr,
yaml
yaml,
httr
VignetteBuilder: knitr
Collate:
'ConvenientTblTree.R'
Expand All @@ -64,6 +65,7 @@ Collate:
'removeAssemblies.R'
'resultFiles.R'
'subMatrix.R'
'timeTree.R'
'treeHeatMap.R'
'visualizeTree.R'
'zzz.R'
Expand Down
115 changes: 68 additions & 47 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export(eog)
export(extractValues)
export(focalClade)
export(formatStats)
export(getDivergenceTime)
export(getTimeline)
export(makeMatrix)
export(makeTidyTree)
export(makeValueTibble)
Expand All @@ -28,54 +30,73 @@ export(thinByMin)
export(treeHeatMap)
export(visualizeTree)
import(S7)
importFrom(ape,as.phylo)
importFrom(ape,cophenetic.phylo)
importFrom(ape,prop.clades)
importFrom(ape,prop.part)
importFrom(dplyr,across)
importFrom(dplyr,arrange)
importFrom(dplyr,case_when)
importFrom(dplyr,desc)
importFrom(dplyr,filter)
importFrom(dplyr,group_by)
importFrom(dplyr,mutate)
importFrom(dplyr,n)
importFrom(dplyr,pull)
importFrom(dplyr,summarise)
importFrom(dplyr,summarize)
importFrom(dplyr,sym)
importFrom(dplyr,ungroup)
importFrom(dplyr,where)
importFrom(ape,
as.phylo,
cophenetic.phylo,
prop.clades,
prop.part
)
importFrom(dplyr,
across,
arrange,
case_when,
desc,
filter,
group_by,
mutate,
n,
pull,
summarise,
summarize,
sym,
ungroup,
where
)
importFrom(ggforce,geom_mark_ellipse)
importFrom(ggplot2,aes)
importFrom(ggplot2,geom_errorbar)
importFrom(ggplot2,geom_errorbarh)
importFrom(ggplot2,geom_point)
importFrom(ggplot2,ggplot)
importFrom(ggplot2,labs)
importFrom(ggplot2,scale_color_manual)
importFrom(ggplot2,scale_fill_manual)
importFrom(ggplot2,scale_x_continuous)
importFrom(ggplot2,scale_y_continuous)
importFrom(ggplot2,theme_bw)
importFrom(ggplot2,theme_minimal)
importFrom(ggplot2,
aes,
geom_errorbar,
geom_errorbarh,
geom_point,
ggplot,
labs,
scale_color_manual,
scale_fill_manual,
scale_x_continuous,
scale_y_continuous,
theme_bw,
theme_minimal
)
importFrom(httr,
GET,
content
)
importFrom(pheatmap,pheatmap)
importFrom(rlang,.data)
importFrom(stats,as.dist)
importFrom(stats,complete.cases)
importFrom(stats,hclust)
importFrom(stats,loess)
importFrom(stats,mad)
importFrom(stats,na.omit)
importFrom(stats,predict)
importFrom(stats,quantile)
importFrom(stats,sd)
importFrom(tidytree,as.treedata)
importFrom(tidytree,as_tibble)
importFrom(tidytree,child)
importFrom(tidytree,offspring)
importFrom(tidytree,tree_subset)
importFrom(stats,
as.dist,
complete.cases,
hclust,
loess,
mad,
na.omit,
predict,
quantile,
sd
)
importFrom(tidytree,
as.treedata,
as_tibble,
child,
offspring,
tree_subset
)
importFrom(treeio,MRCA)
importFrom(utils,read.delim)
importFrom(yaml,read_yaml)
importFrom(yaml,yaml.load)
importFrom(utils,
read.csv,
read.delim
)
importFrom(yaml,
read_yaml,
yaml.load
)
93 changes: 93 additions & 0 deletions R/timeTree.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#' Timeline - TimeTree
#'
#' Fetches a list of divergence times of nodes in TimeTree from the specified taxon to the common ancestor of all cellular organisms.
#'
#' @param taxid An integer: The NCBI id of a taxon
#'
#' @return A dataframe in which each row corresponds to an ancestor.
#' Each row contains the divergence time (`divtime`), its confidence interval
#' (`divtimeCI_low` and `divtimeCI_high`), and additional information,
#' including the scientific name (`name`) and taxonomic rank (`rank`).
#' If the divergence time is not found in the TimeTree database, it returns `NA`.
#'
#' @author Priscila Biller
#'
#' @examples
#' \dontrun{
#' getTimeline(9555)}
#'
#' @importFrom httr GET content
#' @importFrom utils read.csv
#'
#' @export
getTimeline <- function(taxid) {
timetreeBaseTimeline <- "http://timetree.temple.edu/api/timeline/"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment in the other function below.

# Example of request to the TimeTree's API:
# - Request: http://timetree.temple.edu/api/timeline/9555
# - Answer from TimeTree:
# ncbi-id,scientific_name,common_name,level,rank,summary_age,adjusted_age,ci_high,ci_low
# -1,unnamed,,46,unknown,1.1,1.1,1.48,0.72
# -1,unnamed,,45,unknown,1.27,1.36,1.97,0.56
# -1,unnamed,,44,unknown,1.27,1.58,1.97,0.56
# 9554,Papio,,43,genus,1.9,1.9,2.31,1.48
# -1,unnamed,,42,unknown,4.68,4.68,5.08,4.27
# ...
timetreeRequest <- paste(timetreeBaseTimeline, taxid, sep="")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paste0(timetreeBaseTimeline, taxid) for the lazy people :)

timetreeResponse <- GET(timetreeRequest)
lines <- content(timetreeResponse, as="text", encoding="UTF-8")
header <- lines |> strsplit(split="\n", fixed=TRUE) |> (\(x) x[[1]][1])() |> strsplit(split = ",", fixed = TRUE) |> (\(x) x[[1]])() # First line: header; Other lines: data.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude says that the following works too:

header <- scan(text = lines, what = "", sep = ",", nlines = 1, quiet = TRUE)

if(length(header) >= 8) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also have if(length(header) <8) return(NA) and continue without indentation.

df <- read.csv(text=lines)
# In TimeTree there are two possibilities for the divergence time (here we go with "adjusted age"):
# - "Summary age" is the median of all studies.
# - "Adjusted age" is the adjusted time, computed in cases where a node is older than its parent in the global timetree reconstructed from individual timetrees.
df <- df[ c("ncbi.id", "scientific_name", "rank", "adjusted_age", "ci_low", "ci_high")]
names(df) <- c("NCBIid", "name", "rank", "divtime", "divtimeCI_low", "divtimeCI_high")
df
} else {
NA
}
}

#' Divergence time - TimeTree
#'
#' Retrieves the divergence time of two species via the TimeTree API.
#'
#' @param taxid1 An integer: The NCBI id of one taxon
#' @param taxid2 An integer: The NCBI id of the other taxon
#'
#' @return A list in which the first item is the divergence time (`divtime`),
#' and the last two items are the divergence time confidence interval
#' (`divtimeCI_low` and `divtimeCI_high`).
#' If the divergence time is not found in the TimeTree database, it returns `NA`.
#'
#' @author Priscila Biller
#'
#' @examples
#' \dontrun{
#' getDivergenceTime(9555,9601)}
#'
#' @importFrom httr GET content
#'
#' @export
getDivergenceTime <- function(taxid1, taxid2) {
timetreeBasePairwise <- "http://timetree.temple.edu/api/pairwise/"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe getDivergenceTime <- function(taxid1, taxid2, timetreeBasePairwise="http://timetree.temple.edu/api/pairwise/") { so that we can transiently fix scripts without fixing the package if the URL changes.

# Example of request to the TimeTree's API:
# - Request: http://timetree.temple.edu/api/pairwise/9555/9601
# - Answer from TimeTree:
# taxon_a_id,taxon_b_id,scientific_name_a,scientific_name_b,all_total,precomputed_age,precomputed_ci_low,precomputed_ci_high,adjusted_age
# 9555,9601,Papio anubis,Pongo abelii,83,28.82,26.8,30.6,0
timetreeRequest <- paste(timetreeBasePairwise, taxid1, "/", taxid2, sep="")
timetreeResponse <- GET(timetreeRequest)
lines <- content(timetreeResponse, as="text", encoding="UTF-8")
# Break the whole content into lines, and gets the second line (data).
lineData <- strsplit(lines, "\n", fixed = TRUE)[[1]][2] # First line: header; Second line: data.
# Break the line into data.
data <- strsplit(lineData, ",", fixed = TRUE)[[1]]
# Check if the request returned something valid.
if(length(data) >= 8) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

list(divtime=as.numeric(data[6]),divtimeCI_low=as.numeric(data[7]),divtimeCI_high=as.numeric(data[8]))
} else {
NA
}
}
5 changes: 0 additions & 5 deletions man/ConvenientTblTree.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/Haloarchaea.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions man/MRCA_2D_plot.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions man/childSpecies.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions man/ellipsePlot.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions man/eog.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions man/extractValues.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions man/focalClade.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/formatStats.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading