Search code examples
rr-forestplot

How to add transparent grey stripes on forest plot?


I'm making forest plot with forestplot packages in R

With help of this blog(https://www.r-bloggers.com/forest-plot-with-horizontal-bands/), I barely made forest plot. However, in forestplot packages, the hzrl_lines statement didn't worked as I want.

I want to make transparent grey stripes on my forest plot, overlapping the text. But in hzrl_lines statement, it only covers the two rows, not one rows. For example, in following image, I want to cover the 'age', which is category title.

hrzl_lines=list("4" = gpar(lwd=60, lineend="butt", columns=c(1:5), col="#99999922"))

As you can see, horizontal line covers 'primary analysis' and 'age' category title. The line's center is between primary analysis and age title.

enter image description here

How to cover the only 'Age' title? I used the code below. I really appreciate your help.

library("forestplot")

datafile <- file.path("example.csv")
data <- read.csv(datafile, stringsAsFactors=FALSE)
np <- ifelse(!is.na(data$total), data$total, NA)
nc <- ifelse(!is.na(data$intervention), data$intervention, NA)
nu <- ifelse(!is.na(data$control), data$control, NA)


tabletext <- cbind(c("Subgroup","\n",data$category), 
                    c("No. of\nPatients","\n",np), 
                    c("intervention","\n",np), 
                    c("control","\n",nu),
                    c("Interaction\n P Value","\n",data$prob))
tabletext

names(data)
png(file.path("example.png"),width=750, height=750)
forestplot(labeltext=tabletext, 
           mean=c(NA,NA,data$estimate), 
           lower=c(NA,NA,data$lcl), upper=c(NA,NA,data$ucl),
           hrzl_lines=list("3" = gpar(lwd=1, col="#000000"),
                           "4" = gpar(lwd=60, lineend="butt", columns=c(1:5), col="#99999922")),
           xticks=c(-40,-30,-20,-10,0,10),
           clip=c(-40,10),
           col=fpColors(box="black", lines="black", zero = "gray50"))

dev.off()

Furthermore, rawdata is like below. It is hard to upload the csv file in stackoverflow.

> dput(data)
structure(list(category = c("Primary analysis", "Age", "   60-", 
"   20-40", "   -20", "Sex", "   Female", "   Male", "", "", 
"", "", "", "", "", "", ""), total = c(100L, NA, NA, 40L, 60L, 
NA, 40L, 60L, NA, NA, NA, NA, NA, NA, NA, NA, NA), intervention = c(50L, 
NA, NA, 20L, 30L, NA, 20L, 30L, NA, NA, NA, NA, NA, NA, NA, NA, 
NA), control = c(50L, NA, NA, 20L, 30L, NA, 20L, 30L, NA, NA, 
NA, NA, NA, NA, NA, NA, NA), estimate = c(-17.5, NA, NA, -12, 
-20, NA, -15, -20, NA, NA, NA, NA, NA, NA, NA, NA, NA), lcl = c(-25L, 
NA, NA, -25L, -30L, NA, -22L, -35L, NA, NA, NA, NA, NA, NA, NA, 
NA, NA), ucl = c(-10L, NA, NA, 1L, -10L, NA, -8L, -5L, NA, NA, 
NA, NA, NA, NA, NA, NA, NA), prob = c(NA, 0.5, NA, NA, NA, 0.5, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), class = "data.frame", row.names = c(NA, 
-17L))

enter image description here


Solution

  • In the example URL you provided, the author always had 3 lines covered by the horizontal band. He achieved this by using the middle one and giving it a wide line covering all 3 lines. hrzl_lines is there to create a line under the current line, so you'll always see the center of it in between lines. The only workaround I was able to find for you, was to add an empty line below your Age line and then add the grey transparent band to that line:

    library("forestplot")
    
    #Create empty df row
    emptyRow <- data.frame(X1 = NA, X2 = NA, X3 = NA, X4 = NA, X5 = NA, X6 = NA, X7 = NA, X8 = NA)
    names(emptyRow) <- names(data)
    
    #Insert empty row below the 'Age' line
    data <- rbind(data[c(1:2),], emptyRow, data[c(3:17),])
    
    np <- ifelse(!is.na(data$total), data$total, NA)
    nc <- ifelse(!is.na(data$intervention), data$intervention, NA)
    nu <- ifelse(!is.na(data$control), data$control, NA)
    
    tabletext <- cbind(c("Subgroup","\n",data$category), 
                       c("No. of\nPatients","\n",np), 
                       c("intervention","\n",np), 
                       c("control","\n",nu),
                       c("Interaction\n P Value","\n",data$prob))
    
    png(file.path("example.png"),width=750, height=750)
    forestplot(labeltext=tabletext, 
               mean=c(NA,NA,data$estimate), 
               lower=c(NA,NA,data$lcl), upper=c(NA,NA,data$ucl),
               hrzl_lines=list("3" = gpar(lwd=1, col="#000000"),
                               "5" = gpar(lwd=50, lineend="butt", columns=c(1:5), col="#99999922")),
               xticks=c(-40,-30,-20,-10,0,10),
               clip=c(-40,10),
               col=fpColors(box="black", lines="black", zero = "gray50"))
    dev.off()
    

    enter image description here