Reputation: 55
In the documentation of the metafor
library it says, that if the optional argument psize
is unspecified, the point sizes are drawn proportional to the precision of the estimates. As far as I know, precision is the reciprocal of the variance.
How does the metafor library calculate the point size from the confidence interval?
How can I enlarge only the point size? cex
also affects the text size.
example
library(metafor)
model_data <- read.table(dec = ",", text="
OR lower upper
age 0,9678479 0,9326182 1,002493
sex 1,0679667 0,4987457 2,280504
ApacheeII 0,9288701 0,8728417 0,984529",
header=T)
forest(x=model_data$OR,
ci.lb=model_data$lower,
ci.ub=model_data$upper,
annotate=TRUE,
cex=1.2,
at=seq(0,6,1),
refline=1,
digits=c(3,1),
xlim=c(-1,2),
xlab="OR",
slab=rownames(model_data))
Upvotes: 1
Views: 1591
Reputation: 55
Thanks for your help!
With your hints and the source code of the function I finally managed to give a factor to the point size alone:
library(metafor)
model_data <- read.table(dec = ",", text="
OR lower upper
age 0,9678479 0,9326182 1,002493
sex 1,0679667 0,4987457 2,280504
ApacheeII 0,9288701 0,8728417 0,984529",
header=T)
dat <- log(model_data)
ci.lb = dat$lower
ci.ub = dat$upper
#taken from forest.default source code
level = 95
alpha <- ifelse(level > 1, (100 - level)/100, 1 - level)
vi <- ((ci.ub - ci.lb)/(2 * qnorm(alpha/2, lower.tail = FALSE)))^2
wi <- 1/sqrt(vi)
psize <- wi/sum(wi, na.rm = TRUE)
psize <- (psize - min(psize, na.rm = TRUE))/(max(psize,
na.rm = TRUE) - min(psize, na.rm = TRUE))
psize <- (psize * 1) + 0.5
forest(x=dat$OR,
ci.lb = ci.lb,
ci.ub = ci.ub,
cex = 1.5,
annotate=FALSE,
at=seq(-1,1,1),
xlim=c(-1.1,1.1),
xlab="OR",
slab=rownames(dat),
psize=psize*.7,
atransf=exp
)
Upvotes: 1
Reputation: 3395
As for 1:
The relevant line of code in forest.default()
is:
vi <- ((ci.ub - ci.lb) / (2*qnorm(alpha/2, lower.tail=FALSE)))^2
So, the function assumes you are supplying the bounds of a symmetric Wald-tye confidence interval (CI) to the function and then back-calculates the variance based on that. This would be appropriate for log odds ratios and the corresponding CI bounds on the log scale, but you are apparently directly applying the ORs and CI bounds on the raw scale to the function. Then this makes less sense. Usually, CIs for odds ratios are actually first calculated on the log scale (and are then exponentiated). This also appears to the case for these data:
round(with(model_data, log(upper) - log(OR)), 2)
round(with(model_data, log(OR) - log(lower)), 2)
This shows that on the log scale, the CI bounds are symmetric (around log(OR)). So, these CI bounds are very likely Wald-type CIs on the log scale. So, it would make more sense to do this:
dat <- log(model_data)
forest(x=dat$OR, ci.lb=dat$lower, ci.ub=dat$upper,
annotate=TRUE, cex=1.2, at=seq(-2,2,1), digits=c(3,1),
xlim=c(-5,7), xlab="OR", slab=rownames(dat), atransf=exp)
So, supply log(OR) and the corresponding CI bounds to the function and then use the atransf
argument for the back-transformation. In essence, this puts the x-axis on the log-scale.
As for 2:
You will have to compute the point sizes yourself and then supply them to the function via the psize
argument.
Upvotes: 2