多列可信区间、多组别的森林图绘制
💡专注R语言在🩺生物医学中的使用
设为“星标”,精彩不错过
目前R里面绘制森林图最好用的R包我觉得就是forestploter了,我写过多篇推文介绍过森林图,其中都用到了这个R包,比如:
用更简单的方式画森林图R语言亚组分析及森林图绘制R语言亚组分析1行代码实现!亚组分析和多因素回归的森林图比较而且这个包的作者还在积极维护中,没有跑路的趋势~在R中绘制森林图,虽然我介绍过很多R包,但是用到现在我最推荐的绝对是forestploter,没有之一!
今天再给大家介绍下如何使用这个包绘制有多列森林的森林图。
首先大家要明白这个包的使用逻辑,我在画一个好看的森林图一文中就介绍过:
此包在画森林图时,最主要的是2个部分,一个是文字描述部分,即图中红框框住的部分,另一部分就是中间的森林图部分,其余的都是细节修改问题,只要足够耐心,就一定能调整到自己满意。
图片
forest plot其中森林图,中间的绿色方块是均值(或者其他值),横线的两头是最大值和最小值(比如可信区间的上下限之类的),所以你如果想要画出这个森林的部分,就需要提供3个值:中间的方块和两头的值。
理解了这个理念之后,使用这个包就容易多了。实际使用时注意它的要求即可,要了解其中的细节,乱写肯定是不行的。最重要的3个点是(非常重要):
使用空格实现缩进效果添加空列以放置森林文字描述部分的有些NA需要改成空白常见的亚组分析的森林图我就不展示怎么画了,大家参考前面的几篇推文吧,直接演示如何绘制多列可信区间的森林图。
首先是准备数据:
library(forestploter)library(grid)dt <- read.csv(system.file("extdata", "example_data.csv", package = "forestploter"))dt <- dt[1:7, ]# indent the subgroup if there is a number in the placebo columndt$Subgroup <- ifelse(is.na(dt$Placebo), dt$Subgroup, paste0(" ", dt$Subgroup))# 这里的NA要改成空白,否则会在图中显示为NAdt$n1 <- ifelse(is.na(dt$Treatment), "", dt$Treatment)dt$n2 <- ifelse(is.na(dt$Placebo), "", dt$Placebo)# 添加两列空白用来放置“森林”dt$`CVD outcome` <- paste(rep(" ", 20), collapse = " ")dt$`COPD outcome` <- paste(rep(" ", 20), collapse = " ")# 构造可信区间,sprintf是一个非常好用的格式化函数,自己学习下dt$ci1 <- paste(sprintf("%.1f (%.1f, %.1f)", dt$est_gp1, dt$low_gp1, dt$hi_gp1), sprintf("%.1f (%.1f, %.1f)", dt$est_gp3, dt$low_gp3, dt$hi_gp3), sep = "\n")dt$ci1[grepl("NA", dt$ci1)] <- "" # 把NA变成空白,你可以不改变画图看看效果dt$ci2 <- paste(sprintf("%.1f (%.1f, %.1f)", dt$est_gp2, dt$low_gp2, dt$hi_gp2), sprintf("%.1f (%.1f, %.1f)", dt$est_gp4, dt$low_gp4, dt$hi_gp4), sep = "\n")dt$ci2[grepl("NA", dt$ci2)] <- "" # 把NA变成空白
下面是画图:
# 主题设置tm <- forest_theme(base_size = 10, refline_lty = "solid", ci_pch = c(15, 18), ci_col = c("#377eb8", "#4daf4a"), footnote_col = "blue", legend_name = "Group", legend_value = c("Trt 1", "Trt 2"), vertline_lty = c("dashed", "dotted"), vertline_col = c("#d6604d", "#bababa"), # Table cell padding, width 4 and heights 3 core = list(padding = unit(c(4, 3), "mm")))p <- forest(dt[,c(1, 19, 23, 21, 20, 24, 22)], est = list(dt$est_gp1, dt$est_gp2 # ,dt$est_gp3, # dt$est_gp4 ), lower = list(dt$low_gp1, dt$low_gp2 # ,dt$low_gp3, # dt$low_gp4 ), upper = list(dt$hi_gp1, dt$hi_gp2 # ,dt$hi_gp3, # dt$hi_gp4 ), ci_column = c(4, 7), ref_line = 1, vert_line = c(0.5, 2), #nudge_y = 0.4, theme = tm)plot(p)
图片
如何绘制有不同分组的森林图呢?如下图所示,分成了Trt1和Trt2组:
图片
很简单,把上面注释掉的代码加上即可,如下所示。
# 主题设置tm <- forest_theme(base_size = 10, refline_lty = "solid", ci_pch = c(15, 18), ci_col = c("#377eb8", "#4daf4a"), footnote_col = "blue", legend_name = "Group", legend_value = c("Trt 1", "Trt 2"), vertline_lty = c("dashed", "dotted"), vertline_col = c("#d6604d", "#bababa"), # Table cell padding, width 4 and heights 3 core = list(padding = unit(c(4, 3), "mm")))# 第21列和第22列是我们添加的空白列,用来放“森林”的# 在图中,我们想把这两列“森林”放在图的第4列和第7列(看着图数一数),# 所以21放在第4个,22放在第7个p <- forest(dt[,c(1, 19, 23, 21, 20, 24, 22)], est = list(dt$est_gp1, dt$est_gp2 ,dt$est_gp3, dt$est_gp4 ), lower = list(dt$low_gp1, dt$low_gp2 ,dt$low_gp3, dt$low_gp4 ), upper = list(dt$hi_gp1, dt$hi_gp2 ,dt$hi_gp3, dt$hi_gp4 ), ci_column = c(4, 7), # “森林”在图中的位置 ref_line = 1, vert_line = c(0.5, 2), nudge_y = 0.4, theme = tm)plot(p)
图片
这个包对这种情况的处理非常巧妙。
如果你要画2个森林,如果你只有1个组,那么你需要准备2套画森林的数据,比如est=list(dt$est_gp1,dt$est_gp2),就分别对应着2个森林中间点的值;如果你有2个组,也就是上面这个例子,那你要准备4套画森林的数据,比如est=list(dt$est_gp1,dt$est_gp2,dt$est_gp3,dt$est_gp4),对应关系如下图所示:
图片
两侧端点的值,对应关系也是和上图一样的,所以lower和upper也是各需要4列。这是一个倍数关系,不知道你看懂了没~
为了方便你理解,我把只有1组的对应关系也标出来:
图片
所以如果你只有1列森林,但是有3个分组,那你就需要准备3套数据(3列est,3列lower,3列upper),如果你要3列森林,只有1个分组,那你也是需要准备3套数据(3列est,3列lower,3列upper),如果你要3列森林,而且有2个分组,那你需要准备6套数据(6列est,6列lower,6列upper)。
给大家展示一个3列森林,有2个分组的,先准备下数据:
# 再添加1列空白用来放置“森林”dt$`测试outcome` <- paste(rep(" ", 20), collapse = " ")# 添加几列画“森林”的数据Z,偷个懒,直接复制了dt$low_gp5 <- dt$low_gp1dt$low_gp6 <- dt$low_gp3dt$est_gp5 <- dt$est_gp2dt$est_gp6 <- dt$est_gp3dt$hi_gp5 <- dt$hi_gp1dt$hi_gp6 <- dt$hi_gp4
然后选择画图需要的数据,画图即可,注意把森林放在正确的位置上:
# 主题设置tm <- forest_theme(base_size = 10, refline_lty = "solid", ci_pch = c(15, 18), ci_col = c("#377eb8", "#4daf4a"), footnote_col = "blue", legend_name = "Group", legend_value = c("Trt 1", "Trt 2"), vertline_lty = c("dashed", "dotted"), vertline_col = c("#d6604d", "#bababa"), # Table cell padding, width 4 and heights 3 core = list(padding = unit(c(4, 3), "mm")))# 注意正确选择你的“描述”部分和“森林”部分p <- forest(dt[,c(1, 19, 21, 22, 25)], # 这里是选择“描述”部分和放置“森林”的列 est = list(dt$est_gp1, dt$est_gp2 ,dt$est_gp3, dt$est_gp4, dt$est_gp5, dt$est_gp6 ), lower = list(dt$low_gp1, dt$low_gp2 ,dt$low_gp3, dt$low_gp4, dt$low_gp5, dt$low_gp6 ), upper = list(dt$hi_gp1, dt$hi_gp2 ,dt$hi_gp3, dt$hi_gp4, dt$hi_gp5, dt$hi_gp6 ), ci_column = c(3, 4, 5), ref_line = 1, vert_line = c(0.5, 2), nudge_y = 0.4, theme = tm)plot(p)
图片
是不是很easy呢?
这里我值选择了2列描述部分,你可以根据自己的需求随便添加。我通篇没有给大家展示数据长什么样,但是大家自己在学习这个包的时候,一定要对照着数据和图一起看,这样才能更好的理解这个包的理念。
除此之外,这个包的自定义空间非常大,因为是基于grid的,太自由了,行高、列宽、前景色、背景色、字体、对齐方式等等都是可以更改的,多看看帮助文档即可。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。热点资讯
- 家中可备用的中药材列表
- 胖人减肥,瘦人增肥
- 新民艺评丨许悄悄:欢迎来到我们身边,演员于适
- 舒淇易烊千玺合作新片,很大胆很狂野!
- 8月30日精达转债上涨6.13%,转股溢价率4.03%
- 8月30日南航转债上涨0.53%,转股溢价率27.23%
- F1荷兰站: 法拉利表现反差, 梅奔令人失望, 诺里斯又赢维斯塔潘
- 数据备份与恢复策略:保障数据安全免受Rmallox勒索病毒威胁
- 华为云致力推进全域Serverless时代,引领技术创新,赋能行业实践
- 多列可信区间、多组别的森林图绘制