画一个好看的森林图
目前使用R语言画森林图用的最多的应该是forestplot
包(除外meta分析的森林图),在网络上找了很多这个包的介绍,但是都不全,而且这个包细节太多,也不支持图层语法,很难画出高质量的森林图。
最近手头又有一些工作需要用到森林图,于是更加认真地学习了这个包的用法,终于对这个包有了一些新的理解。
这个包主要是需要的数据格式比较复杂,需要各种占位符、NA等构成一些视觉效果,我们可以先在csv表格里把数据整理好。此包在画森林图时,最主要的是2个部分,一个是文字部分,即图中红框框住的部分,另一部分就是中间的森林图部分,其余的都是细节修改问题,只要足够耐心,就一定能调整到自己满意。
接下来将详细介绍使用forestplot
包画森林图(非meta分析森林图)。
以后还会介绍其他绘制森林图的方法。
前言
构造数据
基本森林图
细节调整
加横线和竖线
控制横坐标标签
增加标题,调整各组件大小
有亚组的森林图
前言
一整个森林图可以看成一个个单元格组成的,和你的数据格式一模一样,如果没有数据的地方用NA填充即可。
文字部分和森林图部分的数据可以放在一起,也可以分开准备,文字部分你可以自由添加各种内容,只要格式正确就可以画出来。
文字部分如果是用csv准备的,记得把单元格格式设置为文本,方便设置各种缩进。
一个最基本的森林图只要提供以下4个参数即可完成:
forestplot(
tabletext = xxx,
lower = aaa,
upper = bbb,
mean = ccc,
)
构造数据
下面介绍一个简单的例子,文字部分和森林图部分是分开的。
# 这个包竟然支持管道符!但其实我觉得不实用
library(forestplot)
## 载入需要的程辑包:grid
## 载入需要的程辑包:magrittr
## 载入需要的程辑包:checkmate
# 构造森林图部分的数据,需要最大值最小值和均值3列,需要是数据框格式
df <- data.frame(
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)
)
df
## mean lower upper
## 1 NA NA NA
## 2 NA NA NA
## 3 0.578 0.372 0.898
## 4 0.165 0.018 1.517
## 5 0.246 0.072 0.833
## 6 0.700 0.333 1.474
## 7 0.348 0.083 1.455
## 8 0.139 0.016 1.209
## 9 1.017 0.365 2.831
## 10 NA NA NA
## 11 0.531 0.386 0.731
# 构造文字部分的数据,需要矩阵格式
# 使用 \n 换行
tabletext <- cbind(
c("", "Study", "Auckland", "Block", "Doran", "Gamsu", "Morrison", "Papageorgiou", "Tauesch", NA, "Summary"),
c("Deaths\ntest", "(steroid)", "36", "1", "4", "14", "3", "1", "8", NA, NA),
c("Deaths\njust show", "(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")
)
tabletext
## [,1] [,2] [,3] [,4]
## [1,] "" "Deaths\ntest" "Deaths\njust show" ""
## [2,] "Study" "(steroid)" "(placebo)" "OR"
## [3,] "Auckland" "36" "60" "0.58"
## [4,] "Block" "1" "5" "0.16"
## [5,] "Doran" "4" "11" "0.25"
## [6,] "Gamsu" "14" "20" "0.70"
## [7,] "Morrison" "3" "7" "0.35"
## [8,] "Papageorgiou" "1" "7" "0.14"
## [9,] "Tauesch" "8" "10" "1.02"
## [10,] NA NA NA NA
## [11,] "Summary" NA NA "0.53"
OK,基本的数据就都准备好了,接下来就是画图。
“数就是图,图就是数!
基本森林图
一个基本的森林图:
# 画图
forestplot(labeltext = tabletext,
lower = df$lower,
upper = df$upper,
mean = df$mean)
一个最基本的森林图就
细节调整
先简单调整一下:
forestplot(labeltext = tabletext,
lower = df$lower,
upper = df$upper,
mean = df$mean,
# 这个参数设置每一行的文字部分是否加粗,一行一个逻辑值表示是否加粗,构成一个向量,
is.summary = c(rep(TRUE, 2), rep(FALSE, 8), TRUE),
# 加横线,默认加3条,类似三线表,可以自由控制添加位置
hrzl_lines = gpar(col = "#444444"),
clip = c(0.1, 2.5), # 控制箭头
xlog = TRUE, # 横坐标是否转换,可以看到竖线变成1的位置了,也可以通过zero=1设置
# fpColors控制森林图部分的各组件颜色
col = fpColors(box = "royalblue", # 正方形颜色
lines = "red", # 误差线颜色
summary = "black", # 汇总标志颜色
zero = "yellow" # 0(1)竖线的颜色
)
)
加横线和竖线
修改横线的位置和粗细,以达到一种层次感,不过需要多次调整才能达到自己想要的效果。
forestplot(labeltext = tabletext,
lower = df$lower,
upper = df$upper,
mean = df$mean,
# 这个参数设置每一行的文字部分是否加粗,一行一个逻辑值表示是否加粗,构成一个向量,
is.summary = c(rep(TRUE, 2), rep(FALSE, 8), TRUE),
# 加横线,控制位置,第一行文字上面序号是1,下面序号是2,第2行文字下面序号是3,以此类推
# column参数控制横线出现在哪几列
hrzl_lines = list("1" = gpar(lwd = 2),
"3" = gpar(lwd = 2),
"4" = gpar(lwd = 60, lineend="butt",col = "#99999922"),
"8" = gpar(lwd = 60, lineend="butt",col = "#99999922"),
"11" = gpar(lwd = 2, columns = 1:4)
)
)
加竖线,误差线两头也变成竖线:
forestplot(labeltext = tabletext,
lower = df$lower,
upper = df$upper,
mean = df$mean,
# 这个参数设置每一行的文字部分是否加粗,一行一个逻辑值表示是否加粗,构成一个向量,
is.summary = c(rep(TRUE, 2), rep(FALSE, 8), TRUE),
vertices = TRUE, # 误差线末尾加竖线
# 加竖线,可以直接用TRUE
grid = structure(c(0.5,1, 1.5),
gp = gpar(lty = 2, col = "#CCCCFF")),
)
控制横坐标标签
forestplot(labeltext = tabletext,
lower = df$lower,
upper = df$upper,
mean = df$mean,
# 这个参数设置每一行的文字部分是否加粗,一行一个逻辑值表示是否加粗,构成一个向量,
is.summary = c(rep(TRUE, 2), rep(FALSE, 8), TRUE),
xticks = c(0.1,0.5,1,1.5,2)
)
再稍加调整,就可以变成下面这个样子:
有亚组的森林图也是一样的套路: