How to add a second vertical line in R package forestplot - r

I'd like to distinguish between statistical significance (OR = 1.0) and clinical significance (OR = 1.5) in my forest plot. I created this plot using the forestplot package, sample code below. Is adding a vertical line possible (while maintaining the line of no difference)?
library(forestplot)
test_data <- structure(list(
mean = c(NA, NA, 1, 0.5, 2),
lower = c(NA, NA, .5, .25, 1.5),
upper = c(NA, NA, 1.5, .75, 2.5)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -5L),
class = "data.frame")
tabletext <- cbind(
c("", "Outcome", "Outcome 1", "Outcome 2", "Outcome 3"),
c("", "OR", "1 (0.5 - 1.5)", "0.5 (0.25 - 0.75)", "2.0 (1.5 - 2.5)"))
forestplot(tabletext,
test_data,
new_page = TRUE,
xlog = TRUE,
boxsize = .25
)

Is this what you were looking for?
forestplot(tabletext,
test_data,
new_page = TRUE,
xlog = TRUE,
grid = structure(c(log(1.5)),
gp = gpar(lty = 2, col = "#CCCCFF")),
zero = 1,
boxsize = .25)

A suboptimal (and not very elegant) solution could be: 1- creating an empty plot with no axis or labels, 2- then plot a vertical line (abline(v=1.5)) and 3- call your forestplot with new_page = F.

Related

message of error when plotting a 3D pie chart on R

I currently have trouble plotting a 3D pie chart whereas it had worked well with a very similar dataset.
Here is my dataset :
structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
And here is my code :
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
pie3D(pie1_PGS$nb_sejours_2021, radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
I get the following message of error :
"Error in seq.default(start, end, by = angleinc) :
(to - from) / by incorrect"
Also, I would like to plot a legend to indicate what the colours mean (they take the values of variable type_de_sejour). I have seen several posts here, but I can't seem to manage to do it on this dataset, so I would welcome any help regarding this issue too.
Here is the code I added :
legend(0.5, 1.5, c("Ambulatoires","Externes", "Hospitalisé",
"Séances"), cex = 0.3,
fill = rainbow(length(lab)))
I think the problem is that the legend is too big as regards the plot...
Add legend
You can use the function legend like this:
pie1_PGS <- structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
pie1_PGS <- pie1_PGS[!(pie1_PGS$nb_sejours_2021 == 0),]
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
library(plotrix)
pie3D(pie1_PGS$nb_sejours_2021,
radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
legend(0.1, 0.9, pie1_PGS$type_de_sejour, cex = 0.7, fill = rainbow(length(lab)))
Created on 2022-08-11 by the reprex package (v2.0.1)
You should remove the rows with 0 value because you can't show them in a pie chart. You can use the following code:
pie1_PGS <- structure(list(type_de_sejour = structure(1:4, levels = c("Ambulatoires",
"Externes", "Fictifs", "Hospitalisé"), class = "factor"), nb_sejours_2021 = c(20794,
365, 0, 7866)), row.names = c(NA, -4L), class = "data.frame")
pie1_PGS <- pie1_PGS[!(pie1_PGS$nb_sejours_2021 == 0),]
lab <- paste0(round(pie1_PGS$nb_sejours_2021/sum(pie1_PGS$nb_sejours_2021) * 100, 2),
"%")
library(plotrix)
pie3D(pie1_PGS$nb_sejours_2021,
radius = 0.75,
height = 0.1,
theta = 0.7,
border = "white",
col = rainbow(length(lab)),
shade = 0.5,
labels = lab,
labelcol = "red",
labelcex = 0.75,
explode = 0.2,
main = "Répartition des séjours 2021 par type")
Created on 2022-08-10 by the reprex package (v2.0.1)

Forestplot in R. How to add arrows, x axis breaks and extend the x axis?

I have created a forestplot using the forestplot package and code below.
There are three things I would like to add:
Add arrows and text under the x axis (ie. an arrow in either direction explain the association).
I have reviewed these posts using a different package.
How to add arrows to forest plot in survminer (ggforest)
How to add arrows to a forest plot?
I would also like to put a break the x axis as I have one variable with a very wide CI.
I would also like to extend the negative side of the x-axis to -5, to balance the figure (even though most datapoints are on the right).
I am using the forest plot package. Any ideas how to do it with this package?
table2OR_ex <- structure(list(X = c("Aeroplanes", "Sex (F)", "1", "2", "Cars", "Sex (F)", "1", "2"),
mean = c(NA, 1.35, 7.81, 6.14, NA, 1.17, 0.15, 0.4),
lower = c(NA, 1.13, 5.69, 4.36, NA, 0.74, 0.05, 0.16),
upper = c(NA, 1.61, 11.01, 8.83, NA, 1.88, 0.35, 0.89),
p.value = c("", "< 0.001", "< 0.001", "< 0.001", "", "0.509", "< 0.001", "0.034")),
.Names = c("Transport", "mean", "lower", "upper", "p value"),
class = "data.frame", row.names = c(NA, -8L))
tabletext <- cbind(c("Transport","\n",table2OR_ex$Transport),
c("Odds ratio","\n",table2OR_ex$mean),
c("Confidence Interval","\n",
ifelse(is.na(table2OR_ex$lower), "", paste(table2OR_ex$lower, table2OR_ex$upper,
sep= " - "))))
mat <- rbind(rbind(rep(NA, 3), rbind(rep(NA, 3), as.matrix(table2OR_ex[, 2:4]))))
fn <- local({
i = 0
no_lines <- sum(!is.na(mat[,"mean"]))
b_clrs = colorRampPalette(colors=c("pink", "blue"))(no_lines)
l_clrs = colorRampPalette(colors=c("blue", "pink"))(no_lines)
function(..., clr.line, clr.marker){
i <<- i + 1
fpDrawDiamondCI(..., clr.line = l_clrs[i], clr.marker = b_clrs[i])
}
})
forestplot(labeltext=tabletext,
mat,
graphwidth=unit (70, "mm"),
graph.pos=3,
fn.ci_norm = fn,
clip =c(-.125, max(table2OR_ex$upper, na.rm = TRUE)),
is.summary=c(TRUE, TRUE, rep(FALSE, 8)),
txt_gp=fpTxtGp(label=gpar(fontsize=12, cex=1),
ticks=gpar(fontsize=12, cex=1.4),
xlab=gpar(fontsize=12,cex = 1),
title=gpar(fontsize=12,cex = 1.2)),
zero=1,
boxsize=0.4)
This doesn't have everything you wanted, but it's a start. Maybe someone else can improve on this answer.
I've added labels to the left and the right of the null value using grid.text, but it doesn't have arrows. You may need to adjust the grid.text y values so that the labels don't overlap with the x-axis ticks.
I don't know how to put a break in the x-axis, but odds ratios should be plotted on a log scale (see https://doi.org/10.1002/sim.4780070807), and I think that solves the problem.
It doesn't make sense to have a negative value on the x-axis when you're plotting ORs, but with a log scale you can make the x-axis symmetric by setting the lower bound to the reciprocal of the upper bound, which is what I've done.
library(forestplot)
table2OR_ex <- structure(list(X = c("Aeroplanes", "Sex (F)", "1", "2", "Cars", "Sex (F)", "1", "2"),
mean = c(NA, 1.35, 7.81, 6.14, NA, 1.17, 0.15, 0.4),
lower = c(NA, 1.13, 5.69, 4.36, NA, 0.74, 0.05, 0.16),
upper = c(NA, 1.61, 11.01, 8.83, NA, 1.88, 0.35, 0.89),
p.value = c("", "< 0.001", "< 0.001", "< 0.001", "", "0.509", "< 0.001", "0.034")),
.Names = c("Transport", "mean", "lower", "upper", "p value"),
class = "data.frame", row.names = c(NA, -8L))
tabletext <- cbind(c("Transport","\n",table2OR_ex$Transport),
c("Odds ratio","\n",table2OR_ex$mean),
c("Confidence Interval","\n",
ifelse(is.na(table2OR_ex$lower), "", paste(table2OR_ex$lower, table2OR_ex$upper,
sep= " - "))))
mat <- rbind(rbind(rep(NA, 3), rbind(rep(NA, 3), as.matrix(table2OR_ex[, 2:4]))))
fn <- local({
i = 0
no_lines <- sum(!is.na(mat[,"mean"]))
b_clrs = colorRampPalette(colors=c("pink", "blue"))(no_lines)
l_clrs = colorRampPalette(colors=c("blue", "pink"))(no_lines)
function(..., clr.line, clr.marker){
i <<- i + 1
fpDrawDiamondCI(..., clr.line = l_clrs[i], clr.marker = b_clrs[i])
}
})
ticks <- c(0.04, 0.2, 1, 5, 25) # ADDITION
attr(ticks, "labels") <- as.character(ticks) # ADDITION
#attr(ticks, "labels") <- c("1/25", "1/5", "1", "5", "25") # ADDITION
forestplot(labeltext=tabletext,
mat,
graphwidth=unit (70, "mm"),
graph.pos=3,
fn.ci_norm = fn,
mar = unit(rep(10, times = 4), "mm"), # ADDITION
xlog=TRUE, # ADDITION
xticks=ticks, # ADDITION
clip =c(0.04, 25), # CHANGE
is.summary=c(TRUE, TRUE, rep(FALSE, 8)),
txt_gp=fpTxtGp(label=gpar(fontsize=12, cex=1),
ticks=gpar(fontsize=12, cex=1.4),
xlab=gpar(fontsize=12,cex = 1),
title=gpar(fontsize=12,cex = 1.2)),
zero=1,
boxsize=0.4)
# ADDITION
downViewport("forestplot_margins")
downViewport("axis_margin")
downViewport("axis")
grid.text("Favors X", x=0.46, y=-0.25, just=c("right", "center"))
grid.text("Favors Y", x=0.54, y=-0.25, just=c("left", "center"))

Not able to print forestplot in high resolution format in R

I need to create a forestplot of high resolution. I used the forestplot() function from library(forestplot) to create my plot, and then attempted to use the tiff() function to create a high resolution image for publication. However, my image turned blank.
It works if I export directly from R but not as high resolution as it was supposed to.
library(forestplot)
df <- structure(list(
mean = c(NA, 0.22, 0.20, 0.27),
lower = c(NA, 0.05, 0.04, 0.01),
upper = c(NA, 0.95, 1.08, 9.12)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -4L),
class = "data.frame")
tabletext <- cbind(
c("", "Pooled", "Group 1", "Group 2"),
c("N", "4334", "3354", "980"),
c("HR (95% CI)", "0.22 (0.05, 0.95)", "0.20 (0.04, 1.08)", "0.27 (0.01, 9.12)"),
c("p-value", "0.042", "0.061", "0.467")
)
ggfp <- forestplot(tabletext,
df,
new_page = TRUE,
is.summary = c(TRUE, rep(FALSE, 3)),
clip = c(0, 2),
colgap = unit(5, "mm"),
line.margin = unit(2, "mm"),
lineheight = unit(1, "in"),
txt_gp = fpTxtGp(label = gpar(cex = 1),
ticks = gpar(cex = 1)),
align = c("l", "c", "c", "c"),
boxsize = 0.2,
xticks = seq(0, 2.0, 0.5),
zero = 1,
col = fpColors(box = "royalblue",
line = "darkblue"),
mar = unit(c(-1, 0.5, -2, 0.5), "in"))
tiff("forestplot.tiff", units = "in", width = 9, height = 7, res = 300)
ggfp
dev.off()
The file was created but it was a blank page
This works for me (output file is 17MB):
library(forestplot)
setwd("/path/to/directory/for/plot")
df <- structure(list(
mean = c(NA, 0.22, 0.20, 0.27),
lower = c(NA, 0.05, 0.04, 0.01),
upper = c(NA, 0.95, 1.08, 9.12)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -4L),
class = "data.frame")
tabletext <- cbind(
c("", "Pooled", "Group 1", "Group 2"),
c("N", "4334", "3354", "980"),
c("HR (95% CI)", "0.22 (0.05, 0.95)", "0.20 (0.04, 1.08)", "0.27 (0.01, 9.12)"),
c("p-value", "0.042", "0.061", "0.467")
)
tiff("forestplot.tiff", units = "in", width = 9, height = 7, res = 300)
forestplot(tabletext,
df,
new_page = TRUE,
is.summary = c(TRUE, rep(FALSE, 3)),
clip = c(0, 2),
colgap = unit(5, "mm"),
line.margin = unit(2, "mm"),
lineheight = unit(1, "in"),
txt_gp = fpTxtGp(label = gpar(cex = 1),
ticks = gpar(cex = 1)),
align = c("l", "c", "c", "c"),
boxsize = 0.2,
xticks = seq(0, 2.0, 0.5),
zero = 1,
col = fpColors(box = "royalblue",
line = "darkblue"),
mar = unit(c(-1, 0.5, -2, 0.5), "in"))
dev.off()

How to squeeze rows together in forestplot using forestplot package in R

I'm making a forest plot using the forestplot package in R. I have a lot of white space between the rows in my plot. How can I remove the space, or squeeze the rows together, to make a neater smaller graph? Many thanks.
library(forestplot)
main5 <-
structure(list(
mean = c(NA, NA, 0.80, 0.90, 0.7, 1.2),
lower = c(NA, NA, 0.70, 0.50, 0.59, 1.11),
upper = c(NA, NA, 1.02, 1.25, 1.04, 1.94)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -6L),
class = "data.frame")
tabletext5<-cbind(
c("", "Analysis", "Outcome: X", Outcome: Y", "Outcome: Z", "Outcome: xx"),
c("", "A
time", "115987.8", "117604.4", "118518.6","115493.2"),
c("", "A
Outcomes", "813", "51", "715", "2114"),
c("", "B
time", "114516.2", "118728.5", "117896.2","119096.3"),
c("", "B
Outcomes", "1199", "71", "911","1109"),
c("", "HR", "0.8", "0.9", "0.7", "1.2"),
c("", "99% CI", "0.70, 1.02", "0.50, 1.25", "0.59, 1.04", "1.11, 1.94"))
forestplot(tabletext5,
main5,new_page = TRUE,
hrzl_lines=list("3" = gpar(lwd=1, col="#444444")),
is.summary=c(TRUE, TRUE, rep(FALSE, 5)),
txt_gp = fpTxtGp(label=gpar(cex=0.7)
),
boxsize=0.3,
xlog=T,
graphwidth = unit(9, "cm"),
graphheight = unit(6, "cm"),
clip= c(0.5, 3.0),
xticks=c(0.5, 1.0, 1.5, 2.0, 2.5),
xlab=" B worse A worse ",
fs.xlab=60,
col=fpColors(box="#7570B3",line="#7570B3")) ##have picked the blue colour from the "dark2 palette
lineheight property in the forestplot() does the job
forestplot(your_table, lineheight='lines')
If You want to set a custom height, use lineheight=unit(1,'cm'), where the the expected value is float.

Putting x-axis labels directly under tick marks in barplots in R

I have a table (below) showing the percentage of tree species (categorical variable) present in a group experiment. My objective is to plot the percentage of tree species on the y-axis and 'Species' on the x-axis within a barplot.
Issue
My problem is that I am experiencing problems with formatting the x-axis correctly. My objective is to ensure that the x-axis labels for**'Species'** are:-
Positioned directly underneath their bar at the tick mark
Do not overlap onto the plotting area
If anyone can help solve this issue, I would be incredibly grateful.
R code
df <- leaf.percent[order(leaf.percent$Leaf.Percentge, decreasing = TRUE),]
Tree.labels<-c("Quercus robar", "Quercus Patraea",
"Deciduous", "Oak",
"Plant", "Shrub")
par(mar=c(6, 6, 3, 3))
Tree<-barplot(df$Leaf.Percentge, names.arg = df$Species,
xaxt = "n",
ylab="Percentage %",
xlab="Tree Species",
col="lightblue",
ylim = c(0, 60))
axis(1, at=Tree, labels=FALSE)
text(seq(1, 6, by=1), par("usr")[3] - 0.2,
labels=unique(Tree.labels),
srt = 25, pos = 1,
xpd = TRUE, cex=0.7)
DATA
structure(list(Species = structure(1:6, .Label = c("Deciduous",
"Oak", "Plant", "Quercus_petraea", "Quercus_robur", "Shrub"), class = "factor"),
Frequency = c(48L, 29L, 6L, 70L, 206L, 4L), Leaf.Percentge = c(13.2231404958678,
7.98898071625344, 1.65289256198347, 19.2837465564738, 56.7493112947658,
1.10192837465565)), .Names = c("Species", "Frequency", "Leaf.Percentge"
), row.names = c(NA, -6L), class = "data.frame")

Resources