Forestplot in R superscript in tabletext matrix - r

I am creating a forestplot in R. Since I cannot display my own data I am using example code and data that I found here
https://cran.r-project.org/web/packages/forestplot/vignettes/forestplot.html
cochrane_from_rmeta <-
structure(list(
mean = c(NA, NA, 0.578, 0.165, 0.246, 0.700, 0.348, 0.139, 1.017, NA, 0.531),
lower = c(NA, NA, 0.372, 0.018, 0.072, 0.333, 0.083, 0.016, 0.365, NA, 0.386),
upper = c(NA, NA, 0.898, 1.517, 0.833, 1.474, 1.455, 1.209, 2.831, NA, 0.731)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -11L),
class = "data.frame")
tabletext<-cbind(
c("", "Study", "Auckland", "Block",
"Doran", "Gamsu", "Morrison", "Papageorgiou",
"Tauesch", NA, "Summary"),
c("Deaths", "(steroid)", "36", "1",
"4", "14", "3", "1",
"8", NA, NA),
c("Deaths", "(placebo)", "60", "5",
"11", "20", "7", "7",
"10", NA, NA),
c("", "OR", "0.58", "0.16",
"0.25", "0.70", "0.35", "0.14",
"1.02", NA, "0.53"),
c("",NA,NA,NA,NA,NA,NA,NA,NA,NA,"Heterogeniety I^2 = 20%"))[enter image description here][1]
library(forestplot)
forestplot(tabletext,
cochrane_from_rmeta,new_page = TRUE,
is.summary=c(TRUE,TRUE,rep(FALSE,8),TRUE),
clip=c(0.1,2.5),
xlog=TRUE,
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"))
I would like to superscript the very last label for Heterogeniety. I tried expression(Heterogeniety~I^2), but I get the following error message:
Error in cbind(c("Outcome", "Death or BPD", NA, NA, NA, "Interaction p value = .xx", : cannot create a matrix from type 'expression'
How do I include a superscript in my forestplot?

R does not allow you to create a matrix of expression. Also mentioned in the documentation for forestplot,
You can also provide a matrix although this cannot have expressions by design
Luckily, the documentation for forestplot also mentioned that it can take in a list for labeltext.
The list should be wrapped in m x n number to resemble a matrix: list(list("rowname 1 col 1", "rowname 2 col 1"), list("r1c2", expression(beta))
Hence, you might want to convert your tabletext into a nested list as follows:
tabletext <- list(
list("", "Study", "Auckland", "Block",
"Doran", "Gamsu", "Morrison", "Papageorgiou",
"Tauesch", NA, "Summary"),
list("Deaths", "(steroid)", "36", "1",
"4", "14", "3", "1",
"8", NA, NA),
list("Deaths", "(placebo)", "60", "5",
"11", "20", "7", "7",
"10", NA, NA),
list("", "OR", "0.58", "0.16",
"0.25", "0.70", "0.35", "0.14",
"1.02", NA, "0.53"),
list("",NA,NA,NA,NA,NA,NA,NA,NA,NA, expression(Heterogeniety~I^2==20~'%')))
forestplot(tabletext,
cochrane_from_rmeta,new_page = TRUE,
is.summary=c(TRUE,TRUE,rep(FALSE,8),TRUE),
clip=c(0.1,2.5),
xlog=TRUE,
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"))
HTH.

Related

How do I create a line graph using multiple variables when the multiple variables are all in the same column?

structure(list(Sample.Id = c(NA, "2", "2", "2", "2", "2", "2",
"2", "2", "2", "2", "3", "3", "3", "3", "3", "3", "3", "3", "3"
), Sampling..Date = c(NA, "08-Sep-14", "14-Oct-14", "02-Nov-14",
"21-Nov-14", "03-Dec-14", "15-Dec-14", "11-Jan-15", "08-Feb-15",
"01-Mar-15", "06-Apr-15", "03-Sep-14", "08-Sep-14", "14-Oct-14",
"02-Nov-14", "21-Nov-14", "03-Dec-14", "15-Dec-14", "11-Jan-15",
"26-Jan-15"), Tot.P = c("µg/ml", "0.002", "0.017", "0.035",
"0.04", "0.059", "0.155", "0.021", "0.022", "0.025", "<0.009",
"0.021", "0.003", "0.036", "0.141", "0.041", "0.044", "0.01",
"0.023", "0.016"), DOC = c("µg/ml", NA, "12.3", "13.4", "12.5",
"9.9", "14.7", "8.8", "8.3", "0.026", "7.5", "13.4", NA, "14.6",
"16.6", "14.7", "12.6", "12.6", "10.6", "11.4"), Tot.N = c("µg/ml",
NA, "3.63", "4.12", "3.98", "4.08", "3.38", "3.63", "4.88", "8.3",
"2.74", "2.48", NA, "3.07", "3.38", "3.3", "3.43", "2.19", "2.77",
"4.25"), DOC.1 = c("µg/ml", "13.6", NA, NA, NA, NA, NA, NA,
NA, NA, NA, "14.44", "16.85", NA, NA, NA, NA, NA, NA, NA), Tot.P.1 = c("µg/ml",
"0.053", NA, NA, NA, NA, NA, NA, NA, NA, NA, "0.08", "0.071",
NA, NA, NA, NA, NA, NA, NA), Total.N = c("µg/ml", "3.363", NA,
NA, NA, NA, NA, NA, NA, NA, NA, "2.645", "2.637", NA, NA, NA,
NA, NA, NA, NA)), row.names = c(NA, 20L), class = "data.frame"
I have a set of water quality data from 2014-2022 over different sites and different time periods. Each site has a different monitoring period and the data was analysed using two different devices of which there are only two periods of overlap where the samples were analysed using both machines. I am trying to plot a time series showing the P, N and DOC across each site over time and shade in the areas where one machine was used instead of another. This is all a bit complicated and I am so new to R so have been running in circles for a week. My problem is I am unsure how to select the section of a column I need to create the variable I want so it makes sense.
I have tried to look it up on blogs but can't seem to mash the different pieces of advice together to make it work. Any tips would be much appreciated. Here is the data that I'm on about.
You will definitely need to clean up your data to fit this solution, but your basic way about this is pivoting from wide to long form.
Then you need to ensure that your dates are the propper POSIXct format.
Then it is just a matter of grouping by your relevant variables and plotting with geom_line()
I added the facet_grid to separate by Sample.Id.
library(tidyverse)
#> Warning: pakke 'ggplot2' blev bygget under R version 4.2.2
#> Warning: pakke 'tidyr' blev bygget under R version 4.2.2
#> Warning: pakke 'purrr' blev bygget under R version 4.2.2
#> Warning: pakke 'dplyr' blev bygget under R version 4.2.2
#> Warning: pakke 'stringr' blev bygget under R version 4.2.2
#> Warning: pakke 'forcats' blev bygget under R version 4.2.2
df <- structure(list(Sample.Id = c("2", "2", "2", "2", "2", "2", "2",
"2", "2", "2", "3", "3", "3", "3", "3", "3", "3", "3", "3"),
Sampling..Date = c("08-Sep-14", "14-Oct-14", "02-Nov-14",
"21-Nov-14", "03-Dec-14", "15-Dec-14", "11-Jan-15", "08-Feb-15",
"01-Mar-15", "06-Apr-15", "03-Sep-14", "08-Sep-14", "14-Oct-14",
"02-Nov-14", "21-Nov-14", "03-Dec-14", "15-Dec-14", "11-Jan-15",
"26-Jan-15"), Tot.P = c("0.002", "0.017", "0.035", "0.04",
"0.059", "0.155", "0.021", "0.022", "0.025", "<0.009", "0.021",
"0.003", "0.036", "0.141", "0.041", "0.044", "0.01", "0.023",
"0.016"), DOC = c(NA, "12.3", "13.4", "12.5", "9.9", "14.7",
"8.8", "8.3", "0.026", "7.5", "13.4", NA, "14.6", "16.6",
"14.7", "12.6", "12.6", "10.6", "11.4"), Tot.N = c(NA, "3.63",
"4.12", "3.98", "4.08", "3.38", "3.63", "4.88", "8.3", "2.74",
"2.48", NA, "3.07", "3.38", "3.3", "3.43", "2.19", "2.77",
"4.25"), DOC.1 = c("13.6", NA, NA, NA, NA, NA, NA, NA, NA,
NA, "14.44", "16.85", NA, NA, NA, NA, NA, NA, NA)), row.names = 2:20, class = "data.frame")
df |>
mutate(Tot.P = str_replace(Tot.P, "<", ""),
across(Tot.P:DOC.1, as.numeric),
Sampling..Date = as.POSIXct(Sampling..Date, format = "%d-%b-%y")) |>
select(-c(DOC.1)) |>
pivot_longer(cols = c(Tot.P, DOC, Tot.N)) |>
ggplot(aes(x = Sampling..Date, y = value, group = name, col = name)) +
geom_line() +
facet_grid(~Sample.Id)
#> Warning: Removed 5 rows containing missing values (`geom_line()`).
Created on 2023-02-14 with reprex v2.0.2

How can I add another row of text to the bottom of a forest plot made with forestplot?

I have created a forest plot using the forestplot package:
As you can see, the list of heterogeneity statistics in the final row of the first column is quite long, and it widens the column. I would like to remove this text from the labeltext argument (where I put it to generate the above plot, making the first column wider) and draw it once, separately, so it appears where it is but it extends under the other columns without making the first one wider.
I know I can use something like this to draw what I am looking for:
grid.text("test", x=unit(?????), y=unit(?????), rot=0,
gp=gpar(col="red"))
How can I get the location of the start of the first cell of the final row, underneath 'Overall'?
Is there some way I can get the width of the entire plot so I can then find x by subtracting half the width from the middle of the viewport?
If anybody knows a better way of going about this, please let me know.
You could use grid.text where you need to specify npc in the units of the grid like this:
library(forestplot)
cochrane_from_rmeta <- structure(list(mean = c(NA, NA, 0.578, 0.165, 0.246, 0.700, 0.348, 0.139, 1.017, NA, 0.531),
lower = c(NA, NA, 0.372, 0.018, 0.072, 0.333, 0.083, 0.016, 0.365, NA, 0.386),
upper = c(NA, NA, 0.898, 1.517, 0.833, 1.474, 1.455, 1.209, 2.831, NA, 0.731)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -11L),
class = "data.frame")
tabletext <- cbind(c("", "Study", "Auckland", "Block", "Doran", "Gamsu", "Morrison", "Papageorgiou", "Tauesch", NA, "Summary"),
c("Deaths", "(steroid)", "36", "1", "4", "14", "3", "1", "8", NA, NA),
c("Deaths", "(placebo)", "60", "5", "11", "20", "7", "7", "10", NA, NA),
c("", "OR", "0.58", "0.16", "0.25", "0.70", "0.35", "0.14", "1.02", NA, "0.53"))
forestplot(cochrane_from_rmeta, labeltext = tabletext,
is.summary = c(rep(TRUE, 2), rep(FALSE, 8), TRUE),
clip = c(0.1, 2.5),
xlog = TRUE,
col = fpColors(box = "royalblue",
line = "darkblue",
summary = "royalblue"))
x <- unit(.05, 'npc')
y <- unit(.05, 'npc')
grid.text('A test text', x, y, gp = gpar(fontsize=10, font = 3))
Created on 2022-07-17 by the reprex package (v2.0.1)

Forest plot using risk ratio and confidence intervals

How to make forest plot like this using risk ratio and confidence intervals with the comparison labels?
I don't want R to automatically group the comparison, I just want to plot the forest plot with the labels at the left hand side. Thank you.
I use this code:
d=result
df=data.frame(d)
cochrane_from_rmeta <-
structure(list(
mean = df$RiskRatio,
lower = df$LowerLimit,
upper = df$UpperLimit),
.Names = c("RiskRatio", "lower", "upper"),
row.names = c(NA, -14L),
class = "data.frame")
tabletext<-cbind(
c(df$Outcomes),
c(df$Comparison),
c(df$...4),
c(df$RiskRatio))
forestplot(tabletext,
cochrane_from_rmeta,new_page = TRUE,
is.summary=c(TRUE,TRUE,rep(FALSE,8),TRUE),
clip=c(0.1,2.5),
xlog=TRUE,
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"))
but it shows error
Is this what you're trying to achieve?
#install.packages("forestplot")
library(forestplot)
# Cochrane data from the 'rmeta'-package
cochrane_from_rmeta <-
structure(list(
mean = c(NA, NA, 0.578, 0.165, 0.246, 0.700, 0.348, 0.139, 1.017, NA, 0.531),
lower = c(NA, NA, 0.372, 0.018, 0.072, 0.333, 0.083, 0.016, 0.365, NA, 0.386),
upper = c(NA, NA, 0.898, 1.517, 0.833, 1.474, 1.455, 1.209, 2.831, NA, 0.731)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -11L),
class = "data.frame")
tabletext<-cbind(
c("", "Study", "Auckland", "Block",
"Doran", "Gamsu", "Morrison", "Papageorgiou",
"Tauesch", NA, "Summary"),
c("",
"Comparison",
"Placebo 1",
"Placebo 2",
"Placebo 3",
"Placebo 4",
"Placebo 5",
"Treatment 1",
"Treatment 2",
NA,
""),
c("",
"Relative Risk \n 95% CI",
"0.88 (0.84-0.92)",
"0.87 (0.81-0.94)",
"0.88 (0.84-0.92)",
"0.87 (0.81-0.94)",
"0.88 (0.84-0.92)",
"0.88 (0.84-0.92)",
"0.87 (0.81-0.94)",
NA,
"0.87 (0.81-0.94)"),
c("", "OR", "0.58", "0.16",
"0.25", "0.70", "0.35", "0.14",
"1.02", NA, "0.53"),
c("", "F", "1.1", "1.3",
"0.2", "5", "3.1", "0",
"0.1", NA, "4.1"))
forestplot(tabletext,
cochrane_from_rmeta,
graph.pos = 3,
new_page = TRUE,
is.summary=c(rep(FALSE,11)),
clip=c(0.1,2.5),
xlog=TRUE,
col=fpColors(box="royalblue",
line="darkblue",
summary="royalblue"))

Adjust margin for forestplot, footnotes

I'm trying to use the forestplot and I want to include a lengthy footnote (3 lines of text). I can't get enough space at the bottom and I don't think the par() options are doing anything. Here's the example given in the vingette along with my attempt at making a footnote:
library(forestplot)
# Cochrane data from the 'rmeta'-package
cochrane_from_rmeta <-
structure(list(
mean = c(NA, NA, 0.578, 0.165, 0.246, 0.700, 0.348, 0.139, 1.017, NA, 0.531),
lower = c(NA, NA, 0.372, 0.018, 0.072, 0.333, 0.083, 0.016, 0.365, NA, 0.386),
upper = c(NA, NA, 0.898, 1.517, 0.833, 1.474, 1.455, 1.209, 2.831, NA, 0.731)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -11L),
class = "data.frame")
tabletext<-cbind(
c("", "Study", "Auckland", "Block",
"Doran", "Gamsu", "Morrison", "Papageorgiou",
"Tauesch", NA, "Summary"),
c("Deaths", "(steroid)", "36", "1",
"4", "14", "3", "1",
"8", NA, NA),
c("Deaths", "(placebo)", "60", "5",
"11", "20", "7", "7",
"10", NA, NA),
c("", "OR", "0.58", "0.16",
"0.25", "0.70", "0.35", "0.14",
"1.02", NA, "0.53"))
dev.new()
par(mar = c(4, 1, 1, 1))
forestplot(tabletext,
cochrane_from_rmeta,new_page = TRUE,
is.summary=c(TRUE,TRUE,rep(FALSE,8),TRUE),
clip=c(0.1,2.5),
xlog=TRUE,
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"))
grid.text('* Adjusted for demographic & baseline variables,blur blur blur',
x = unit(.43, 'npc'),
y = unit(1, 'lines'))
Any suggestions on how to create some more space?
Thanks!
I find a solution, first I though that I could change the margine thanks to the ggplot option of the theme :
+ theme(plot.margin = margin(2, 2, 2, 2, "cm"))
But it was not possible to have access to the plot object in forestplot, so I look closly the option of forestplot function and there is an argument mar which take units as parameter, the following solution works for me :
forestplot(tabletext,
cochrane_from_rmeta,new_page = TRUE,
is.summary=c(TRUE, TRUE, rep(FALSE,8), TRUE),
clip=c(0.1, 2.5),
xlog=TRUE,
mar = unit(rep(10, times = 4), "mm"),
col=fpColors(box="royalblue",
line="darkblue",
summary="royalblue"))
grid.text('* Adjusted for demographic & baseline variables,blur blur blur',
x = unit(.43, 'npc'),
y = unit(1, 'lines'))

Modify font of single element in forestplot

I'm trying to modify make a single element in labeltext italics without making the entire column italics, with no luck. The following code will make the 1 italics:
library(forestplot)
Cochrane data from the 'rmeta'-package
cochrane_from_rmeta <-
structure(list(
mean = c(NA, NA, 0.578, 0.165, 0.246, 0.700, 0.348, 0.139, 1.017, NA, 0.531),
lower = c(NA, NA, 0.372, 0.018, 0.072, 0.333, 0.083, 0.016, 0.365, NA, 0.386),
upper = c(NA, NA, 0.898, 1.517, 0.833, 1.474, 1.455, 1.209, 2.831, NA,
0.731)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -11L),
class = "data.frame")
tabletext<-cbind(
c("", "Study", "Auckland", "Block",
"Doran", "Gamsu", "Morrison", "Papageorgiou",
"Tauesch", NA, "Summary"),
c("Deaths", "(steroid)", "36", "1",
"4", "14", "3", "1",
"8", NA, NA),
c("Deaths", "(placebo)", "60", "5",
"11", "20", "7", "7",
"10", NA, NA),
c("", "OR", "0.58", "0.16",
"0.25", "0.70", "0.35", "0.14",
"1.02", NA, "0.53"))
forestplot(tabletext,
txt_gp = fpTxtGp(label = list(gpar(fontface = 3),
gpar(fontface = 1,
)),
ticks = gpar(fontfamily = "", cex=1),
xlab = gpar(fontfamily = "HersheySerif", cex = 1.5)),
rbind(HRQoL$Sweden),
col=clrs,
xlab="EQ-5D index")
But how do I modify the script to only make "Male vs Female" italics (i.e. element 1,1 of label text).
More details on the function can be found here: https://cran.r-project.org/web/packages/forestplot/forestplot.pdf
There is only support to style individual columns with the fpTxtGp for this at the moment but you can do a hack that gives you the same result if you don't have any summary elements in your table (from the vignette):
forestplot(tabletext,
boxsize = .05,
is.summary=c(FALSE, FALSE, TRUE, FALSE),
txt_gp = fpTxtGp(summary = list(
gpar(fontfamily = "HersheyScript", fontface=1),
gpar(fontface=1)
)
),
rbind(HRQoL$Sweden),
col=clrs,
fn.ci_sum=function(col, size, ...) {
fpDrawNormalCI(clr.line = col, clr.marker = col, size=.05, ...)
},
xlab="EQ-5D index")

Resources