多列可信区间、多组别的森林图绘制

  • 首页
  • 关于安信11娱乐
  • 业务范围
  • 最新动态
  • 联系我们
  • 你的位置:安信11娱乐 > 关于安信11娱乐 > 多列可信区间、多组别的森林图绘制

    多列可信区间、多组别的森林图绘制

    发布日期:2024-07-22 03:53    点击次数:160

    💡专注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的,太自由了,行高、列宽、前景色、背景色、字体、对齐方式等等都是可以更改的,多看看帮助文档即可。

    本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。

    TOP