Change font of specific rows to bold in forestplot - r

I wrote a script using the "forestplot" package. I want to group the variables in certain categories, which I would like to show in bold, in order to accentuate those categories. How can i adjust my script, so that only certain rows, i.e Risk factor OR (95% CI), patient characteristics, medication history, comorbidities, surgical history and other are shown in bold? I have two colums and 18 rows. Can someone help me? I would be much grateful!!
My script is as below:
tabletext <- cbind(
c("Risk factor" ,"Patient characteristics","Sex, male*", "Bmi (5 points)",
"Alcohol (5 units)", "Smoking*","Medication history",
"Steroid use", "Anticoagulant use*","Comorbidities",
"COPD GOLD 1/2", "COPD GOLD 3/4", "Other pulmonary disease",
"Surgical history",
"Previous colorectal surgery*",
"Previous abdominal surgery (other)","Other", "HIPEC*"),
c("OR (95% CI)",NA, "1.78 (1.20-2.68)", "1.15 (0.95-1.38)", "1.04 (0.94-1.14)",
"1.78 (1.11-2.80)", NA," 1.40 (0.68-2.67)", "1.55 (1.02-2.32)",NA,
"1.40 (0.70-2.61)", "1.56 (0.42-4.67)", "1.78 (0.63-4.28)",NA,
"1.61 (1.03-2.49)", "0.80 (0.47-1.32)",NA, "4.14 (2.14-7.73)"))
?fpTxtGp
require(forestplot)
forestplot(tabletext,
txt_gp = fpTxtGp(label = list(gpar(fontfamily = "Times",
fontface="bold"),
gpar(fontfamily = "",
col = "black"))),
df_c,new_page = TRUE,
boxsize = 0.2,
is.summary = c(rep(FALSE,32)),
clip = c(0,17),
xlab = 'Odds ratio with 95% confidence interval
* indicates significance',
xlog = FALSE,
zero = 1,
plotwidth=unit(12, "cm"),
colgap=unit(2, "mm"),
col = fpColors(box = "royalblue",
line = "darkblue",
summary = "royalblue"))

Its not clear what df_c is so I just created it based on your tabletext matrix:
df_c <- data.frame(mean = c(NA, NA, 1.78, 1.15, 1.04, 1.78, NA, 1.4, 1.55,
NA, 1.4, 1.56, 1.78, NA, 1.61, 0.8, NA, 4.14),
lower = c(NA, NA, 1.2, 0.95, 0.94, 1.11, NA, 0.68, 1.02, NA, 0.7,
0.42, 0.63, NA, 1.03, 0.47, NA, 2.14),
upper = c(NA, NA, 2.68, 1.38,1.14, 2.8, NA, 2.67,2.32, NA,
2.61, 4.67, 4.28, NA, 2.49, 1.32, NA, 7.73))
From there, its just a matter of adjusting the values passed to is.summary:
forestplot(tabletext,
txt_gp = fpTxtGp(label = list(gpar(fontfamily = "Times"),
gpar(fontfamily = "",
col = "black"))),
df_c,new_page = TRUE,
boxsize = 0.2,
is.summary = c(TRUE, TRUE, rep(FALSE, 4),
TRUE, FALSE, FALSE, TRUE,
rep(FALSE,3), TRUE, rep(FALSE,4)),
clip = c(0,17),
xlab = 'Odds ratio with 95% confidence interval
* indicates significance',
xlog = FALSE,
zero = 1,
plotwidth=unit(12, "cm"),
colgap=unit(2, "mm"),
col = fpColors(box = "royalblue",
line = "darkblue",
summary = "royalblue"))
Which generates the following figure:

Related

R package "forestplot": Error message re: identifying the upper/lower boundaries from the input matrix

I'd be grateful for your help. I'm using the forestplot R package to create a forest plot. It was going well.
library(forestplot)
test_data <- data.frame(
coef = c(1.53, 1.56, 1.11, 1.35, 1.00, 0.94, 1.03),
low = c(1.43, 1.38, 1.08, 1.05, 0.91, 0.87, 0.95),
high = c(1.64, 1.76, 1.15, 1.75, 1.10, 1.01, 1.11),
boxsize = c(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
)
row_names <- cbind(
c("Variable", "BMI", "WHR", "Diabetes", "Insulin resistance", "LDL", "HDL", "ApoB"),
c("SNPs", "807", "368", "386", "53", "213", "510", "241"),
c("OR (95% CI)", "1·53 (1·43−1·64)", "1·56 (1·38−1·76)", "1·11 (1·08−1·15)", "1·35 (1·05−1·75)", "1·00 (0·91−1·10)", "0·94 (0·87−1·01)", "1·03 (0·95−1·11)"),
c("p-value", "6·72E−35", "2·90E−12", "6·61E−10", "0·02", "0·97", "0·083", "0·53")
)
test_data <- rbind(rep(NA, 3), test_data)
forestplot(
labeltext = row_names,
xlab = "Odds ratio",
test_data[, c("coef", "low", "high")],
is.summary = FALSE,
boxsize = test_data$boxsize,
zero = 1,
cex = 0.1,
align = TRUE,
xlog = FALSE,
graphwidth = unit(1.5, "snpc"),
col = fpColors(lines = "royalblue", box = "darkblue")
)
I've been adding one variable at a time and plotting my graph after the addition of each to make sure there were no errors introduced at each step. It was all going well until I added my eighth variable, "Triglycerides", and its associated numbers:
library(forestplot)
test_data <- data.frame(
coef = c(1.53, 1.56, 1.11, 1.35, 1.00, 0.94, 1.03, 1.15),
low = c(1.43, 1.38, 1.08, 1.05, 0.91, 0.87, 0.95, 1.07),
high = c(1.64, 1.76, 1.15, 1.75, 1.10, 1.01, 1.11, 1.11),
boxsize = c(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
)
row_names <- cbind(
c("Variable", "BMI", "WHR", "Diabetes", "Insulin resistance", "LDL", "HDL", "ApoB", "Triglycerides"),
c("SNPs", "807", "368", "386", "53", "213", "510", "241", "427"),
c("OR (95% CI)", "1·53 (1·43−1·64)", "1·56 (1·38−1·76)", "1·11 (1·08−1·15)", "1·35 (1·05−1·75)", "1·00 (0·91−1·10)", "0·94 (0·87−1·01)", "1·03 (0·95−1·11)", "1·15 (1·07−1·11)"),
c("p-value", "6·72E−35", "2·90E−12", "6·61E−10", "0·02", "0·97", "0·083", "0·53", "2·14E−4")
)
test_data <- rbind(rep(NA, 3), test_data)
forestplot(
labeltext = row_names,
xlab = "Odds ratio",
test_data[, c("coef", "low", "high")],
is.summary = FALSE,
boxsize = test_data$boxsize,
zero = 1,
cex = 0.1,
align = TRUE,
xlog = FALSE,
graphwidth = unit(1.5, "snpc"),
col = fpColors(lines = "royalblue", box = "darkblue")
)
On adding this eighth variable, I now receive the following error message:
Error in prFpConvertMultidimArray(mean) :
Sorry did not manage to correctly identify the upper/lower boundaries from the input matrix.
I can't spot a syntax error here, and I'm really at a loss as to why this has only just happened. Any advice would be greatly appreciated.
Thank you.

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"))

merge elements in forestplot format a single element

I am creating a forestplot using the forestplot package in R, and am having trouble with a few things.
Questions:
Is it possible to merge two adjacent text elements
Is it possible to modify either a single text element font, or the font of an entire row
My Code:
library(forestplot)
# creating text
text <- rbind(c('', 'N (%)', 'SRT', 'ART', 'HR [95% CI]'),
c('', '', '5 year survival %', '5 year survival %', ''),
c('Seminal Vesicle Involvement', '', '', '', ''),
c(' Yes', '10 (20%)', '94', '12', '0.73 [0.36, 1.50]'),
c(' No', '40 (80%)', '96', '10', '1.78 [0.73, 4.35]'),
c('Gender', '', '', '', ''),
c(' Male', '13 (22.5%)', '84', '22', '0.06 [-0.2, 0.86]'),
c(' Female', '37 (77.5%)', '93', '13', '1.89 [0.90, 6.67]'))
# creating the plot
forestplot(text,
mean = c(NA, NA, NA, 0.73, 1.78, NA, 0.06, 1.89),
lower = c(NA, NA, NA, 0.36, 0.73, NA, -0.2, 0.90),
upper = c(NA, NA, NA, 1.50, 4.35, NA, 0.86, 6.67),
is.summary=c(T, T, T, F, F, T, F, F),
lineheight = unit(0.9, "cm"),
graph.pos = 5,
graphwidth = unit(4, 'cm'),
xticks = c(-1, 0, 1, 2, 3, 4),
ci.vertices = T,
txt_gp = fpTxtGp(ticks = gpar(cex = 1),
xlab = gpar(cex = 1),
label = gpar(cex = 0.8),
summary = gpar(cex = 0.8)),
col=fpColors(box="black",
line="darkgrey",
summary="black",
zero='grey20',
axes='grey20'),
hrzl_lines = list("2" = gpar(lwd=1, col = "#000044")))
Output:
Desired:
I would like the two 5 year survival % text bits to be combined into 1 (and centered between the two headings above), and either just those elements or the whole row to be italic font.
I have tried using summary=list(gpar(...)) for the txt_gp option, but that only seems to be able to modify the whole column, and I have found nothing on merging cells at all.
If you make the colgap much smaller in forestplot than usual, you can split the text that is currently duplicated in row 2 in columns 3 and 4 into two parts:
> text[2, 4] <- 'survival % '
> text[2, 3] <- '5 year '
>
> forestplot(text,
+ mean = c(NA, NA, NA, 0.73, 1.78, NA, 0.06, 1.89),
+ lower = c(NA, NA, NA, 0.36, 0.73, NA, -0.2, 0.90),
+ upper = c(NA, NA, NA, 1.50, 4.35, NA, 0.86, 6.67),
+ is.summary=c(T, T, T, F, F, T, F, F),
+ lineheight = unit(0.9, "cm"),
+ graph.pos = 5,
+ graphwidth = unit(4, 'cm'),
+ xticks = c(-1, 0, 1, 2, 3, 4),
+ ci.vertices = T,
# add line---------
colgap=unit(.0011,"npc"),
#
+ txt_gp = fpTxtGp(ticks = gpar(cex = 1),
+ xlab = gpar(cex = 1),
+ label = gpar(cex = 0.8),
+ summary = gpar(cex = 0.8)),
+ col=fpColors(box="black",
+ line="darkgrey",
+ summary="black",
+ zero='grey20',
+ axes='grey20'),
+ hrzl_lines = list("2" = gpar(lwd=1, col = "#000044")))

R - display ≥ / more or equal on a forestplot

I prepared the code for forestplot, however I have problem with exporting plot with "≥" / more or equal sign.
library(forestplot)
names6 <- c("Variable",
"A ≥ 4000***",
"B ≥ 50***",
"C**",
"D",
"E***",
"F",
"G*",
"H**",
"I*",
"J***")
coef6 <- c(0.42, 1.58, 1.35, 0.49,
0.46, 0.66, 0.62, 1.34, 0.52, 0.72)
low6 <- c(0.34, 1.29, 1.08, 0.21,
0.33, 0.44, 0.43, 1.08, 0.29, 0.61)
high6 <- c(0.51, 1.93, 1.69, 1.21,
0.64, 0.99, 0.91, 1.66, 0.92, 0.86)
boxsize6 <-c(0.2, 0.2, 0.2,0.2,
0.2,0.2, 0.2,0.2,
0.2, 0.2)
test_data <- data.frame(coef=coef6,
low=low6,
high=high6,
boxsize=boxsize6)
row_names <- cbind(names6,
c("OR",test_data$coef), c("CI-95%", test_data$low), c("CI+95%", test_data$high) )
test_data <- rbind(NA, test_data)
#####FIGURE
forestplot(labeltext = row_names,
mean = test_data$coef, upper = test_data$high,
lower = test_data$low,
is.summary=c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
boxsize = test_data$boxsize,
zero = 1,
xlog = FALSE,
xlab = "OR (95% CI)",
col = fpColors(lines="black", box="black"),
ci.vertices = TRUE,
xticks = c(0,0.5, 1, 1.5, 2.0),
colgap = unit(0.03,'npc'),
lineheight = unit(1.1,"cm"),
txt_gp=fpTxtGp(label = gpar(cex = 0.8),
title = gpar(cex = 1),
ticks = gpar(cex = 0.6),
xlab = gpar(cex = 0.7)))
However I cannot export plot as a .pdf file with present "≥" / more or equal.
Instead of this, I got sign "=" / equal.
What should I change to get this sign on plot?
Edit:
\u2265 do not work...
This solution might be system-specific. Here is something that works on windows:
library("forestplot")
library("withr")
names6 <- c("Variable",
"A \u2265 4000***",
"B \u2265 50***",
"C**",
"D",
"E***",
"F",
"G*",
"H**",
"I*",
"J***")
### Data & params code here....
with_cairo_pdf('forestplot.pdf',
### Forest plot code here....
forestplot(labeltext = row_names,
....)
)

Misplaced grid lines with xlog=TRUE - Forestplot - R

Please, I need some help about using the xlog=TRUE option.
It is requested to provide the mean, lower, upper, zero, grid and clip already as exponentials, but I find the package is drawing the grid lines at the exponential of the numbers I am already providing as exponentials. As a consequence, the grid lines are in the wrong place.
metaan <-
structure(list(
mean = c(NA, NA, NA, 0.27, 0.47, 0.33, 0.69, 0.86, 0.37, 0.08, 0.44, 0.54, 0.41, NA),
lower = c(NA, NA, NA, 0.13, 0.12, 0.19, 0.12, 0.54, 0.17, 0.03, 0.16, 0.06, 0.29, NA),
upper = c(NA, NA, NA, 0.58, 1.81, 0.60, 3.97, 1.36, 0.81, 0.21, 1.25, 4.50, 0.58, NA)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -27L),
class = "data.frame")
tabletext<-cbind(
c("", "AB class", "", " Aminoglycosides", " B-lactams", " Cephalosporins", " Fenicoles", " Fluoroquinolones", " Multiresistance", " Sulphamides", " Tetracyclines", " Tri/Sulpha", " Subtotal", ""),
c("", "OR", "", "0.27", "0.47", "0.33", "0.69", "0.86", "0.37", "0.08", "0.44", "0.54", "0.41", ""),
c("", "n", "", "4", "3", "2", "3", "4", "2", "3", "4", "3", "5", ""))
xticks <- c(0.1, 0.25, 0.5, 1, 1.5, 2, 3)
forestplot(tabletext,
graph.pos = 3,
txt_gp = fpTxtGp(label = gpar(fontsize=10)),
hrzl_lines = list("3" = gpar(lty=1)),
zero = 1,
line.margin = .05,
mean = cbind(metaan[,"mean"]),
lower = cbind(metaan[,"lower"]),
upper = cbind(metaan[,"upper"]),
is.summary=c(FALSE, TRUE, rep(FALSE, 9)),
col=fpColors(box=c("blue"), summary=c("blue")),
grid = structure(0.41,
gp = gpar(lty = 2, col = "#CCCCFF")),
clip=c(0.1, 3),
xlog=T,
xticks=xticks,
xlab="Odds ratio")
The grid line is at the exponential of OR=0.41, instead of at OR=0.41
When provided the log to get the grid lines at the correct place (e.g. -0.38, or log(0.41)), I get the error message that I should provide all parameters already as exponential.
forestplot(tabletext,
graph.pos = 3,
txt_gp = fpTxtGp(label = gpar(fontsize=10)),
hrzl_lines = list("3" = gpar(lty=1)),
zero = 1,
line.margin = .05,
mean = cbind(metaan[,"mean"]),
lower = cbind(metaan[,"lower"]),
upper = cbind(metaan[,"upper"]),
is.summary=c(FALSE, TRUE, rep(FALSE, 9)),
col=fpColors(box=c("blue"), summary=c("blue")),
grid = structure(-0.39,
gp = gpar(lty = 2, col = "#CCCCFF")),
clip=c(0.1, 3),
xlog=T,
xticks=xticks,
xlab="Odds ratio")
Error in forestplot.default(tabletext, graph.pos = 3, txt_gp = fpTxtGp(label = gpar(fontsize = 10)), :
All argument values (mean, lower, upper, zero, grid and clip) should be provided as exponentials when using the log scale. This is an intentional break with the original forestplot function in order to simplify other arguments such as ticks, clips, and more.
I have tried including the grid numbers as lists, but I always encounter the same error message either if I provide the numbers as exponentials (grid misplaced) or as log (error message).
I am wondering what I am doing wrong and if there is any other way to get the grid lines in the correct place.
Thanks in advance,
Magda.
Solved. Updated to 1.8 package version from GitHub and got the correct figure. :)

Resources