4 min read

ggpubr提高作图效率

ggpubr提高作图效率 。 这个包R的作图省略了好多步骤,类似于爬虫的postman。

实际上,我们主要做统计分析,画太多时间画图,很不情愿。

library(ggpubr)
## Warning: 程辑包'ggpubr'是用R版本3.6.3 来建造的
## 载入需要的程辑包:ggplot2
## Warning: 程辑包'ggplot2'是用R版本3.6.3 来建造的
library(tidyverse)
## Warning: 程辑包'tidyverse'是用R版本3.6.3 来建造的
## -- Attaching packages --------------------------------------------------------------------------- tidyverse 1.3.0 --
## √ tibble  3.0.3     √ dplyr   1.0.2
## √ tidyr   1.1.2     √ stringr 1.4.0
## √ readr   1.3.1     √ forcats 0.5.0
## √ purrr   0.3.4
## Warning: 程辑包'tibble'是用R版本3.6.3 来建造的
## Warning: 程辑包'tidyr'是用R版本3.6.3 来建造的
## Warning: 程辑包'readr'是用R版本3.6.3 来建造的
## Warning: 程辑包'purrr'是用R版本3.6.3 来建造的
## Warning: 程辑包'dplyr'是用R版本3.6.3 来建造的
## Warning: 程辑包'stringr'是用R版本3.6.3 来建造的
## Warning: 程辑包'forcats'是用R版本3.6.3 来建造的
## -- Conflicts ------------------------------------------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

图+均线

mtcars %>% 
  gather(key,value,everything()) %>% 
  group_by(key) %>% 
  summarise(n_distinct(value)) %>% 
  arrange(desc(`n_distinct(value)`))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 11 x 2
##    key   `n_distinct(value)`
##    <chr>               <int>
##  1 qsec                   30
##  2 wt                     29
##  3 disp                   27
##  4 mpg                    25
##  5 drat                   22
##  6 hp                     22
##  7 carb                    6
##  8 cyl                     3
##  9 gear                    3
## 10 am                      2
## 11 vs                      2
mtcars1 <- 
  mtcars %>% 
  mutate(am = as.factor(am))
mtcars1 %>% 
  ggdensity(x = "qsec", # 注意变量str化
            col = "am",
            add = "mean", # 加均线
            rug = TRUE, # rug | logical value. If TRUE, add marginal rug.
            fill = "am", # 这是做频率图我经常忘了,为了好看。
            palette = c("#00AFBB", "#E7B800")) # 这个我真的不记得。

mtcars1 %>% 
  gghistogram(x = "qsec", # 注意变量str化
            col = "am",
            add = "mean", # 加均线
            rug = TRUE, # rug | logical value. If TRUE, add marginal rug.
            fill = "am", # 这是做频率图我经常忘了,为了好看。
            palette = c("#00AFBB", "#E7B800")) # 这个我真的不记得。
## Warning: Using `bins = 30` by default. Pick better value with the argument
## `bins`.

注意变量str化,因此要因子化提前mutate, 这个图唯一好的,就是可以加均线而已, rug就是图下的竖线,不明白。 palette = c("#00AFBB", "#E7B800"))两种对比,推荐的配色。 ggdensitygghistogram取决于离散程度。

ECDF

mtcars1 %>% 
ggplot(aes(qsec)) +
stat_ecdf(aes(color = am,linetype = am), 
              geom = "step", size = 1.5) +
  scale_color_manual(values = c("#00AFBB", "#E7B800"))+
  labs(y = "f(weight)")

不好看。

箱线图、小提琴图和p值

在前面的eda解释中,箱线图主要用于一个分类和一个连续变量的分析。

mtcars2 <- 
mtcars1 %>% 
  mutate(cyl = as.factor(cyl))
mtcars2 %>% 
  ggboxplot(
    x = "cyl",
    y = "qsec",
    col = "cyl",
    palette = c("#00AFBB", "#E7B800", "#FC4E07"),
    add = "jitter") +
  stat_compare_means(
    comparisons = 
    list(
      c("4", "6"), 
      c("4", "8"),
      c("6", "8")
    ))
## Warning in wilcox.test.default(c(18.61, 20, 22.9, 19.47, 18.52, 19.9, 20.01, :
## cannot compute exact p-value with ties
## Warning in wilcox.test.default(c(16.46, 17.02, 19.44, 20.22, 18.3, 18.9, :
## cannot compute exact p-value with ties

经过之前重复抽样的理解,这里对样本间均值差异的p值,应该有很深的理解了,因此,这里还可以比较,这样的话,直接给p值,这样不会让人看图很confuse。 stat_compare_means完成这一目标,直接放入对比pairs就好。 palette = c("#00AFBB", "#E7B800", "#FC4E07")三个比较的配色。

mtcars2 %>% 
    ggviolin(
    x = "cyl",
    y = "qsec",
    fill = "cyl",
    palette = c("#00AFBB", "#E7B800", "#FC4E07"),
    add = "boxplot",
    add.params = list(fill="white")) +
  stat_compare_means(
    comparisons = 
    list(
      c("4", "6"), 
      c("4", "8"),
      c("6", "8")
    ),
    label = "p.signif",
    label.y = 50
    )
## Warning in wilcox.test.default(c(18.61, 20, 22.9, 19.47, 18.52, 19.9, 20.01, :
## cannot compute exact p-value with ties
## Warning in wilcox.test.default(c(16.46, 17.02, 19.44, 20.22, 18.3, 18.9, :
## cannot compute exact p-value with ties

这里修改add,换成内置箱形图。 add.params改变箱形图的颜色。 label = "p.signif",我也觉得数字很烦,这个比较简洁。其中ns: p > 0.05

  • ns: p > 0.05
  • *: p <= 0.05
  • **: p <= 0.01
  • ***: p <= 0.001
  • ****: p <= 0.0001

label.y = 50定位p值图中显示位置。

条形图+不分组排序

这个我一直在ggplot里面没有实现好。 可以借鉴一下。

for (i in c(TRUE,FALSE)){
print(
mtcars %>% 
  mutate(cyl = as.factor(cyl),
         ) %>% 
  rownames_to_column(var = "name") %>% 
  ggbarplot(x="name", 
            y="mpg", 
            fill = "cyl", 
            color = "white",
            palette = "jco",#杂志jco的配色
            sort.val = "desc",#下降排序
            sort.by.groups=i,#不按组排序
            x.text.angle=60)
)
}

参考ggplot2中实现for循环

我之前一直没有很容易的放在一张图比较。

x.text.angle=60这个更加简单了。 theme(axis.text.x = element_text(angle = 70, hjust = 1)) 比较复杂。

偏差图

这些美化,都是我需要提前做好的。

mtcars %>% 
  rownames_to_column(var = "name") %>% 
  mutate(cyl = as.factor(cyl),
         mpg_z = (mpg-mean(mpg))/sd(mpg),
         mpg_grp = case_when(
           mpg_z<0 ~ "low",
           TRUE ~ "high"
         ),
         mpg_grp = as.factor(mpg_grp),
         mpg_grp = fct_relevel(mpg_grp,"low", "high")
         ) %>% 
  ggbarplot(
    x="name", 
    y="mpg_z", 
    fill = "mpg_grp",
    color = "white",
    palette = "jco",
    sort.val = "asc",
    sort.by.groups = FALSE,
    x.text.angle=60,
    ylab = "MPG z-score",
    xlab = FALSE,
    legend.title="MPG Group"
    )

这里其实使用了标准化处理\(\frac{x-\mu}{\sigma}\)

mpg_z = (mpg-mean(mpg))/sd(mpg),
mpg_grp = case_when(
 mpg_z<0 ~ "low",
 TRUE ~ "high"
),
mpg_z = fct_relevel(mpg_z,"low", "high")

棒棒糖图(Lollipop chart)

这个之前当初我搞了很久了。 终于出了简单的方法了。

for (i in c(TRUE,FALSE)) {
mtcars %>% 
  rownames_to_column(var = "name") %>% 
  mutate(cyl = as.factor(cyl)) %>% 
  ggdotchart(
    x="name", 
    y="mpg", 
    color = "cyl", 
    palette = c("#00AFBB", "#E7B800", "#FC4E07"), 
    sorting = "ascending", 
    add = "segments", 
    rotate=i,
    ggtheme = theme_minimal()
    )
}

rotate决定是否旋转,比ggplot简单多了,coord_flip

mtcars %>% 
  rownames_to_column(var = "name") %>% 
  mutate(cyl = as.factor(cyl)) %>% 
  ggdotchart(
    x="name", 
    y="mpg", 
    color = "cyl", 
    palette = c("#00AFBB", "#E7B800", "#FC4E07"), 
    sorting = "ascending", 
    add = "segments", 
    rotate=TRUE,
    group = "cyl", 
    dot.size = 6, 
    label = round(mtcars$mpg),
    font.label = list(color="white", size=9, vjust=0.5),
    
    ggtheme = theme_minimal()
  )

label = round(mtcars$mpg),这是目前这个包的一个bug,必须这么做,但是呢,已经非常出色了。