https://github.com/vsbuffalo/paradox_variation
Revision ca0b5ca255f789993d18992fb3fc2d14ad902386 authored by Vince Buffalo on 11 August 2021, 23:06:18 UTC, committed by Vince Buffalo on 11 August 2021, 23:06:18 UTC
1 parent 04d25ff
Tip revision: ca0b5ca255f789993d18992fb3fc2d14ad902386 authored by Vince Buffalo on 11 August 2021, 23:06:18 UTC
more edits
more edits
Tip revision: ca0b5ca
utilities.r
## utilities.r -- utility functions
library(HDInterval)
library(rstan)
wescols <- c("#75BFC1", "#CD2216", "#E8A252", "#D4DAB2", "#6B7181")
lambda_est <- function(fit) {
sigma_r <- rstan:::extract(fit, pars='sigma_r')$sigma_r
sigma_p <- rstan:::extract(fit, pars='sigma_p')$sigma_p
l <- sigma_p / (sigma_p + sigma_r)
c(mean=mean(l), hdi(l))
}
# bootstrap samples
bs_samp <- function(x) {
x[sample(nrow(x), replace=TRUE), ]
}
hpdi <- function(x, alpha) {
coda::HPDinterval(coda::as.mcmc(x), prob = 1 - alpha)
}
ci_polygon <- function(x, fit=NULL, y=NULL, type='quantile',
par = 'y_rep', alpha=0.05,
color='red', transp=0.4, ...) {
xr <- order(x)
if (!is.null(fit)) {
y <- rstan:::extract(fit, pars=par)[[par]]
}
stopifnot(!is.null(y))
if (type == 'quantile') {
cis <- apply(y, 2, function(p)
quantile(p, probs=c(alpha/2, 1-alpha/2)))
} else if (type == 'hpdi') {
cis <- apply(y, 2, function(p) hpdi(p, alpha))
} else {
stop('type must be hpdi or quantile')
}
polygon(c(x[xr], rev(x[xr])), c(cis[2, xr], rev(cis[1, xr])),
border=0, col=alpha(color, transp), ...)
invisible(cis)
}
maplength_bodysize_plot <- function(x, default_axes=FALSE) {
# wraps global data
with(x, plot(map_length, log10_size, pch=19, cex=0.7, col='gray48'))
if (!default_axes) {
with(x, plot(map_length, log10_size, pch=19, axes=FALSE, cex=0.7,
ylab='', xlab='',
xlim=c(0, 50), ylim=c(-4.3, 1.1),
col='gray48'))
axis(1, seq(0, 50, 10))
axis(2, seq(-4, 1), seq(-4, 1), labels=latex2exp::TeX(sprintf("$10^{%d}$", seq(-4, 1))))
}
}
TAX_GROUPS <- c('kingdom', 'superphylum', 'phylum',
'subphylum', 'class', 'order', 'family',
'genus', 'species')
extract_rank <- function(x, rank = 'Kingdom', default=NULL) {
if (!length(x) || is.na(x))
return(NA)
qry <- rank %in% x$rankname
if (!any(qry)) {
if (!is.null(default)) return(default)
stop('rank not found')
}
x$taxonname[x$rankname == rank[which(qry)]]
}
extract_genus <- function(x, genus_only=FALSE) {
sub('([^_]+) ([^_]+).*', '\\1', x)
}
extract_species <- function(x, genus_only=FALSE) {
replace <- '\\1 \\2'
if (genus_only) {
replace <- '\\1'
}
sub('([^_]+)_([^_]+).*', replace, x)
}
# some Leffler names have multiple species like Genus species1/species2
# etc. This just grabs the first one (ok for tree purposes)
clean_name <- Vectorize(function(x) strsplit(x, '/', fixed=TRUE)[[1]][1])
# confidence intervals
ci <- function(x, est, alpha=0.05, pivot=TRUE, with_est=TRUE) {
cis <- quantile(x, probs=c(alpha / 2, 1-alpha/2))
if (pivot) {
if (!with_est)
return(c(2*est - cis[2], 2*est - cis[1]))
return(c(2*est - cis[2], est, 2*est - cis[1]))
}
if (!with_est)
return(cis)
return(cis[1], est, cis[2])
}
# bootstrap confidence interval polygon (a shaded line for
# figures with posterior densities to compare bayes/freq)
# height is polygon height (x positions are cis)
bs_ci_polygon <- function(ci, height, alpha=0.2) {
polygon(c(ci[1], ci[1], ci[3], ci[3]), c(0, height, height, 0),
border=NA,
col=alpha('gray42', alpha))
}
# posterior plot, with optional CIs
post_plot <- function(post, alpha=0.05, main='', thresh=0.90,
ylab='', cex.main=1, bs_cis=NULL,
title_line=1, cex.lab=1.3,
col='cornflowerblue',
xlim=NULL) {
dns <- density(post)
plot(dns, axes=FALSE, type='n',
xlab='',
ylab='', main=main, cex.main=cex.main, xlim=xlim,
yaxs="i", ylim=c(0, 1.05*max(dns$y)))
hpdi <- hdi(post, thresh)
x <- dns$x
y <- dns$y
idx <- hpdi[1] <= x & hpdi[2] >= x
xx <- x[idx]
yy <- y[idx]
yy[1] <- 0
yy[length(yy)] <- 0
xseq <- seq(min(xx), max(xx), length.out=length(yy))
if (!is.null(bs_cis)) {
bs_ci_polygon(bs_cis, 1.1*max(yy))
}
polygon(xseq, yy, border=NA,
col=alpha(col, 0.4))
if (!is.null(bs_cis)) {
abline(v=bs_cis[2], col='gray22', lend=1)
}
ave <- mean(post)
segments(ave, 0, ave, y[which.min(abs(x - ave))],
col=col, lwd=2, lend=1)
abline(v=0, lty=2, col='gray42', lwd=0.8, lend=1)
lines(dns)
title(ylab=ylab, line=title_line, cex.lab=cex.lab,
xpd=TRUE)
axis(1, tck=-0.08, padj=-1.8, cex.axis=0.7)
# axis(2)
return(hpdi)
}
# from phytools, modified for log values
add.color.bar.log<-function(leg,cols,title=NULL,lims=c(0,1),digits=1,prompt=TRUE,lwd=4,outline=TRUE,...){
if(prompt){
cat("Click where you want to draw the bar\n")
flush.console()
x<-unlist(locator(1))
y<-x[2]
x<-x[1]
} else {
if(hasArg(x)) x<-list(...)$x
else x<-0
if(hasArg(y)) y<-list(...)$y
else y<-0
}
if(hasArg(fsize)) fsize<-list(...)$fsize
else fsize<-1.0
if(hasArg(subtitle)) subtitle<-list(...)$subtitle
else subtitle<-NULL
if(hasArg(direction)) direction<-list(...)$direction
else direction<-"rightwards"
if(direction%in%c("rightwards","leftwards")){
X<-x+cbind(0:(length(cols)-1)/length(cols),1:length(cols)/length(cols))*(leg)
if(direction=="leftwards"){
X<-X[nrow(X):1,]
if(!is.null(lims)) lims<-lims[2:1]
}
Y<-cbind(rep(y,length(cols)),rep(y,length(cols)))
} else if(direction%in%c("upwards","downwards")){
Y<-y+cbind(0:(length(cols)-1)/length(cols),1:length(cols)/length(cols))*(leg)
if(direction=="downwards"){
X<-X[nrow(X):1,]
if(!is.null(lims)) lims<-lims[2:1]
}
X<-cbind(rep(x,length(cols)),rep(x,length(cols)))
}
if(outline) lines(c(X[1,1],X[nrow(X),2]),c(Y[1,1],Y[nrow(Y),2]),lwd=lwd+2,lend=2)
for(i in 1:length(cols)) lines(X[i,],Y[i,],col=cols[i],lwd=lwd,lend=2)
if(direction%in%c("rightwards","leftwards")){
if(!is.null(lims)) text(x=x,y=y,
latex2exp:::TeX(sprintf("$10^{%d}$", as.integer(round(lims[1],digits)))),pos=3,cex=fsize)
if(!is.null(lims)) text(x=x+leg,y=y,
latex2exp:::TeX(sprintf("$10^{%d}$", as.integer(round(lims[2],digits)))),pos=3,cex=fsize)
if(is.null(title)) title<-"P(state=1)"
text(x=(2*x+leg)/2,y=y,title,pos=3,cex=fsize)
if(is.null(subtitle))
text(x=(2*x+leg)/2,y=y,paste("length=",round(leg,3),sep=""),pos=1,cex=fsize)
else text(x=(2*x+leg)/2,y=y,subtitle,pos=1,cex=fsize)
} else if(direction%in%c("upwards","downwards")){
if(!is.null(lims)) text(x=x,y=y-0.02*diff(par()$usr[3:4]),round(lims[1],digits),
pos=1,cex=fsize)
if(!is.null(lims)) text(x=x,y=y+leg+0.02*diff(par()$usr[3:4]),
round(lims[2],digits),
pos=3,cex=fsize)
if(is.null(title)) title<-"P(state=1)"
text(x=x-0.04*diff(par()$usr[1:2]),y=(2*y+leg)/2,title,
pos=3,cex=fsize,srt=90)
if(is.null(subtitle))
text(x=x+0.04*diff(par()$usr[1:2]),y=(2*y+leg)/2,
paste("length=",round(leg,3),sep=""),pos=1,
srt=90,cex=fsize)
else text(x=x+0.04*diff(par()$usr[1:2]),y=(2*y+leg)/2,
subtitle,pos=1,cex=fsize,srt=90)
}
}
Computing file changes ...