Remove Ticks on End of CIs in Forest Plot Metafor - r

I have a foresplot in r using the metafor package:
#forestplot
par(mar=c(2.75,0,0,0))
par(font=2,mgp=c(2.3, 0.8, 0), xaxs = "i")
metafor::forest.rma(res, alim=c(-1, 3.75), xlim = c(-5, 3.5), at =
c(-1, -.5, 0 , .5, 1, 1.5, 2, 2.5, 3), xlab = "Cohen's D with 95% CI",
slab = data$Author, annotate = FALSE,
cex=.6, cex.lab = 0.5, refline = 0.68)
I would like to remove the ticks at the end of the confidence intervals for each observation but haven't found a clear way of doing so. In others words, have the confidence intervals just be horizontal lines, no vertical like at the end. Would anyone have any ideas on how to this?

Set the efac argument of metafor::forest.rma to c(0,1):
the first value is the vertical expansion factor for CI limits and arrows; the second is for summary estimates.
library(metafor)
res <- rma(measure="RR", ai=tpos, bi=tneg, ci=cpos, di=cneg, data=dat.bcg,
slab=paste(author, year, sep=", "))
par(mar=c(2.75,0,0,0))
par(font=2,mgp=c(2.3, 0.8, 0), xaxs = "i")
forest(res, alim=c(-1, 3.75), xlim = c(-5, 3.5), at =
c(-1, -.5, 0 , .5, 1, 1.5, 2, 2.5, 3), xlab = "Cohen's D with 95% CI",
annotate = FALSE, cex=0.8, cex.lab=0.8, refline = 0.68, efac=c(0,1))

Related

Forcing sunflower plot to start at x=0

When creating a sunflower plot for logistic regression, the x-axis starts at 2. Can I change this behaviour to make the x-axis start at 0? I've already tried to manually change this by changing the x-axis, but that didn't make x=0 visible (see #c1).
The Sunflower Plot Image as it currently is, starting at x=2;
# EE contains the Likert Scale values
EE.min <- min(EE)
EE.max <- max(EE)
EE.x <- seq(EE.min, EE.max, length = 500)
New.EE <- data.frame(EE = EE.x)
# Creating prediction
EE.p <- predict(logit, New.EE, type = "response")
sunflowerplot(EE, cb, main = "Effort Expectancy",
xlab= "EE (5-point Likert-Scale)", ylab="Likelihood", yaxt="n", xaxt="n")
# c1:
axis(1, at = seq(0,5,0.5), labels = c(0, 0.5, 1, 1.5, 2, 2.5 , 3, 3.5, 4, 4.5, 5), las=1)
axis(2, at = seq(0,1,0.2), labels = c("No = 0", 0.2, 0.4, 0.6, 0.8, "Yes = 1"), las = 2)
abline(h = seq(0,1,0.2), lty = 2)
lines(EE.x, EE.p)
sunflowerplot has an argument xlim for the limits of the x axis.
Compare
sunflowerplot(iris$Sepal.Length, iris$Sepal.Width)
to
sunflowerplot(iris$Sepal.Length, iris$Sepal.Width, xlim = c(0, 20))

Plot functions in R with coordinate axis and arrows

I'm a relative beginner in R so please forgive me if it's a noob question.
So, is there a package which provides an easy interface to plot (real-real, mathematical) functions? I need coordinate axis with arrows (and their intersection should be (0;0)) and ticks, grid, etc. I want similar plots as in this document.
Background: now I create function plots with LaTeX's tikzpicture and axis but I'm using R to generate randomized exams since few months (R creates tex-files and include them into document) and would be nice if R can create similar plots (png, jpg), because axis in LaTeX is very slow.
Thanks!
I made you a little function for this
math_plot <- function(f, xlim = c(-2,2), ylim = c(-2,2),
xlab = "x", ylab = "f(x)", ax.ext = .02,
frame.plot = F, grid.tick = .1, ...){
curve(f, from = xlim[1], to = xlim[2], ylim = ylim,
axes = F, xlab = "", ylab = "",
frame.plot = frame.plot, ...)
# x-axis
axis(1, pos = 0)
arrows(x0 = xlim[2], x1 = xlim[2] + diff(xlim)*ax.ext, y0 = 0, length = .1)
mtext(text = xlab, side = 4, line = 0, las = 2, at = 0)
# y-axis
axis(2, pos = 0, las = 2)
arrows(y0 = ylim[2], y1 = ylim[2] + diff(ylim)*ax.ext, x0 = 0, length = .1)
mtext(text = ylab, side = 3, line = 0, at = 0)
grid(nx = diff(xlim)/grid.tick, ny = diff(ylim)/grid.tick)
}
# give it a function
math_plot(function(x) 3*x + 2 - 2*x^2, ylim = c(-2,4))
With R graphic tools such as arrows, points, abline, etc. you can draw practically anything.
Example
op <- par(mar=c(1, 1, 1, 1)) ## adjust outer margins
plot(x, y, type="n", axes=F, asp=1, xlab="", ylab="") ## asp=1 to maintain 1:1 aspect ratio
lines(x, y, lwd=2)
arrows(par()$usr[1], 0, par()$usr[2], length=.05) ## par()$usr helps to find xlim and ylim
arrows(0, par()$usr[3], 0, par()$usr[4], length=.05)
points((-5:5)*10, rep(0, 11), pch=3, cex=.6) ## pch=3 for crosses
points(rep(0, 11), (-5:5)*10, pch=3, cex=.6)
mtext("y", 3, -1, adj=.55, font=8)
mtext("x", 4, -1, padj=-1, las=2, font=8)
abline(h=(-5:5)*10, lty=3, col="gray")
abline(v=(-5:5)*10, lty=3, col="gray")
text(10, -4, "10", font=7, cex=.8)
text(-4, 10, "10", font=7, cex=.8)
par(op) ## reset par
Data
x <- (-10):10; y <- x^2 - 50

Log scale for forest plot without changing hazard ratio values or x-axis tick marks

I am trying to use a log scale on my forest plot of hazard ratios. I input the hazard ratio estimates and confidence intervals by hand into my plot, but I need the same values (unchanged) to be on a log scale when plotted. Preferably with the same tick marks as the plot currently has on the arithmetic scale. Is there an easy way to do this?
I tried atransf = exp, which changes all my hazard ratios.
I also tried at = log(c(0.25, 0.5, 1, 2, 4, 6)), which changes all the tick marks drastically. How can I convert to the log scale without changing the numeric tick marks of my axes and the values of my hazards?
Thanks for your help.
#Forest Plot
label1 <- as.character(c("<50", "50 to <60", "60"))
label1 <- factor(label1, levels = unique(label1))
hazards1 <- c(1.42, 1.66, 2.85)
lower1 <- c(1.34, 1.50, 2.59)
upper1 <- c(1.51, 1.85, 3.13)
patient_num1 <- c(240000, 180000, 220000)
event_num1 <- c(2600, 1300, 2900)
forestplot1 <- data.frame(label1, hazards1, lower1, upper1, event_num1, patient_num1)
forestplot1$patient_num1 <- rev(forestplot1$patient_num1)
par(mar=c(4,4,1,2))
pdf(file = "figureex.pdf", width = 15, height = 8.5)
pdf.options(encoding='ISOLatin2.enc')
forest(rev(hazards1), ci.lb = rev(lower1), ci.ub = rev(upper1), slab = rev(label1), xlim = c(-4,0),
xlab = "Adjusted Hazard Ratio for Event",
refline = 1, annotate = T, ylim = c(-1, 29), ilab = cbind(forestplot1$patient_num1, rev(event_num1)),
ilab.xpos=c(-1,-0.25), at = c(0.25, 0.5, 1, 2, 4, 6), rows = c(1:3),
cex = 1, yaxs = "i")
text(-4, 27.29, pos = 4, "Variable")
text(-1.25, 27.67, pos = 4, "No. of \nPatients")
text(-0.45, 27.67, pos = 4, "No. of \nEvents")
text(5.05, 27.69, pos = 4, "Hazard Ratio \n(95% CI)")
dev.off()
It looks like you're using the forest function in the metafor package. The function forestplot in the package forestplot allows you to specify the tick marks with xticks as well as use log scale for the tick marks with xlog.

How To Make Histogram Bins in R-Studio Only Use Integers

I am attempting to create several histograms that display the effects a drug has on the frequency of heart attacks.
Currently, R is organizing my data into the bins [0 - 0.5, 0.5 - 1.0, 1.0 - 1.5, etc.], but I would like for it to only use integer values: [0 - 1, 1 - 2, 2 - 3, etc.].
I have tried using the xaxt="n" argument and the axis() function. They "worked," but they did not solve the problem above. I also tried to use breaks=seq(0,5,l=6), but this converted my y-axis from frequency into density.
Here is the code for my latest two attempts:
hist(fourTrials$red_5, breaks=5, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue")
hist(fourTrials$red_5, breaks=seq(0,5,l=6), freq = F, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue",yaxs="i",xaxs="i")
Thanks for any help!
I believe that what you want is:
hist(fourTrials$red_5, breaks=0:4, freq = TRUE, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400",
col = "lightblue", yaxs="i", xaxs="i")

coefficient plot with first differences

I am running a logistic model in r. I am trying to present the differences in probabilities for my independent variables with a coefficient plot. Specifically, I would like to create the differences in probabilities by shifting the variables of interest from their minimum to their maximum value (while holding the other variables at their means or modes).
In the picture attached, I would like for my graph to look similar to the top half.
I have ran this code:
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")
mylogit <- glm(admit ~ gre + gpa + rank, data = mydata, family =
"binomial")
Afterwards I calculated the predicted probability for each variable for the minimum value and the maximum value and subtracted the two. I repeated this process for the upper and lower bounds of the interval. Attached is my code
plotdat <- data.frame(gre=c(.220, 800), gpa=mean(mydata$gpa, na.rm=TRUE), rank=c(2) )
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
Grebeta<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
Gremin<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))-exp(preddat$fit[1]+1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1]))
Gremax<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))-exp(preddat$fit[1]-1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
plotdat <- data.frame(gpa=c(2.26, 4), gre=mean(mydata$gre, na.rm=TRUE), rank=c(2) )
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
GPAbeta<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
GPAmin<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))-exp(preddat$fit[1]+1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1]))
GPAmax<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))-exp(preddat$fit[1]-1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
plotdat <- data.frame(rank=c(4, 1), gre=mean(mydata$gre, na.rm=TRUE), gpa=mean(mydata$gpa, na.rm=TRUE ))
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
Rankbeta<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
Rankmin<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))-exp(preddat$fit[1]+1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1]))
Rankmax<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))-exp(preddat$fit[1]-1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
Afterwards, I created three vectors containing the difference in probabilities and bands. Attached is my code:
se.max<- c(Gremax , GPAmax , Rankmax )
coef.vec<- c( Grebeta ,GPAbeta , Rankbeta )
se.min<-c(Gremin , GPAmin, Rankmin)
var.names <- c("gre", "gpa", "rank")
Finally, I plotted my graph.
y.axis <- c(length(coef.vec):1)
par(mar=c(2, 13, 0, 0))
plot(coef.vec, y.axis, type = "p", axes = F, xlab = "", ylab = "", pch = 19, cex = 1.2, xlim = c(-2,2.5), xaxs = "r", main = "")
segments(se.max, y.axis,se.min, y.axis, lwd = 1.5)
axis(1, at = seq(-1,1,by=.25), labels = NA, tick = T,cex.axis = 1.2, mgp = c(2,.7,0))
axis(1, at = seq(-1,1,by=.5), labels = c(-1, -.5, 0, .5,1), tick = T,cex.axis = 1.2, mgp = c(2,.7,0))
axis(2, at = y.axis, label = var.names, las = 1, tick = T, ,mgp = c(2,.6,0), cex.axis = 1.2)
segments(0,0,0,17,lty=2)
However, I can't get my confidence intervals to plot. Attached below is my final output.
It appears my confidence bands won't plot. If anyone could provide assistance and point to errors in my calculations or code, I would greatly appreciate it.
plotdat <- data.frame(gre=c(.220, 800), gpa=mean(mydata$gpa, na.rm=TRUE), rank=c(2) )
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
#GRE High
GREbetahigh<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))
GREminhigh<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))
GREmaxhigh<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))
#GRE low
GREbetalow<-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
GREminlow<-(exp(preddat$fit[1]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1])))
GREmaxlow<-exp(preddat$fit[1]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
#GRE Diff
GREbeta.diff<-GREbetahigh-GREbetalow
GREmax.diff<-GREmaxhigh-GREmaxlow
GREmin.diff<-GREminhigh-GREminlow
#GPA
plotdat <- data.frame(gpa=c(2.26, 4), gre=mean(mydata$gre, na.rm=TRUE), rank=c(2) )
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
#GPA high
GPAbetahigh<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))
GPAminhigh<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))
GPAmaxhigh<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))
#GPA low
GPAbetalow<-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
GPAminlow<-(exp(preddat$fit[1]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1])))
GPAmaxlow<-exp(preddat$fit[1]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
#GPA Diff
GPAbeta.diff<-GPAbetahigh-GPAbetalow
GPAmax.diff<-GPAmaxhigh-GPAmaxlow
GPAmin.diff<-GPAminhigh-GPAminlow
#Rank
plotdat <- data.frame(rank=c(4, 1), gre=mean(mydata$gre, na.rm=TRUE), gpa=mean(mydata$gpa, na.rm=TRUE ))
preddat <- predict(mylogit, newdata=plotdat, se.fit=TRUE)
#Rank high
Rankbetahigh<-(exp(preddat$fit[2])/(1+exp(preddat$fit[2])))
Rankminhigh<-(exp(preddat$fit[2]+1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]+1.96*preddat$se.fit[2])))
Rankmaxhigh<-exp(preddat$fit[2]-1.96*preddat$se.fit[2])/(1+exp(preddat$fit[2]-1.96*preddat$se.fit[2]))
#Rank Low
Rankbetalow<-(exp(preddat$fit[1])/(1+exp(preddat$fit[1])))
Rankminlow<-(exp(preddat$fit[1]+1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]+1.96*preddat$se.fit[1])))
Rankmaxlow<-exp(preddat$fit[1]-1.96*preddat$se.fit[1])/(1+exp(preddat$fit[1]-1.96*preddat$se.fit[1]))
#Rank Diff
Rankbeta.diff<-Rankbetahigh-Rankbetalow
Rankmax.diff<-Rankmaxhigh-Rankmaxlow
Rankmin.diff<-Rankminhigh-Rankminlow
#Graph
se.max<- c(GREmax.diff , GPAmax.diff, Rankmax.diff)
coef.vec<- c( GREbeta.diff , GPAbeta.diff, Rankbeta.diff)
se.min<-c(GREmin.diff , GPAmin.diff, Rankmin.diff)
var.names <- c("gre", "gpa", "rank")
y.axis <- c(length(coef.vec):1)
par(mar=c(2, 13, 0, 0))
plot(y.axis, coef.vec, type = "p", axes = F, xlab = "", ylab = "", pch = 19, cex = 1.2, ylim = c(-1,1), xlim=c(1,3.3), xaxs = "r", main = "")
segments(y.axis, se.max,y.axis, se.min, lwd = 1.5)
axis(2, at = seq(-1,1,by=.25), labels = NA, tick = T,cex.axis = 1.2, mgp = c(2,.7,0))
axis(2, at = seq(-1,1,by=.5), labels = c(-1, -.5, 0, .5, 1), tick = T,cex.axis = 1.2, mgp = c(2,.7,0))
axis(1, at = y.axis, label = var.names, las = 1, tick = T, ,mgp = c(2,.6,0), cex.axis = 1.2)
segments(1,0,3.3,0,lty=2)

Resources