使用dplyr/ggplot函数在for循环中调用许多变量

Bru*_*iro 5 r ggplot2 dplyr tidyeval

有时,在进行探索性分析或生成报告时,我们希望绘制许多变量的单变量分布.我可以在经过一些整洁的伎俩之后面对这个情节,但是有序因素,我想继续按照情节订购.

因此,为了更有效地完成它,我构建了一个简单dplyr/ ggplot基于函数.我使用vcd包的关节炎数据集在下面做了这个例子.

library(dplyr)
library(ggplot2)

data(Arthritis, package = "vcd")

head(Arthritis)

plotUniCat <- function(df, x) {
  x <- enquo(x)
  df %>%
    filter(!is.na(!!x)) %>%
    count(!!x) %>%
    mutate(prop = prop.table(n)) %>%
    ggplot(aes(y=prop, x=!!x)) +
    geom_bar(stat = "identity")
}

plotUniCat(Arthritis, Improved)
Run Code Online (Sandbox Code Playgroud)

我可以用很短的方式绘制格式化的图形,这很酷,但只有一个变量.

我尝试使用for循环调用多个变量,但它不起作用.代码运行,但没有任何反应.

variables <- c("Improved", "Sex", "Treatment")

for (i in variables) {
  plotUniCat(Arthritis, noquote(i))
}
Run Code Online (Sandbox Code Playgroud)

我搜索了这个,但对我来说仍然不清楚.有人知道我做错了什么或如何使它有效?

提前致谢.

Tun*_*ung 5

您需要使用rlang::sym将字符串转换为符号而不是enquo.我用for循环purrr::map来替换循环variables

library(tidyverse)

data(Arthritis, package = "vcd")

head(Arthritis)
#>   ID Treatment  Sex Age Improved
#> 1 57   Treated Male  27     Some
#> 2 46   Treated Male  29     None
#> 3 77   Treated Male  30     None
#> 4 17   Treated Male  32   Marked
#> 5 36   Treated Male  46   Marked
#> 6 23   Treated Male  58   Marked

plotUniCat2 <- function(df, x) {
  x <- rlang::sym(x)
  df %>%
    filter(!is.na(!!x)) %>%
    count(!!x) %>%
    mutate(prop = prop.table(n)) %>%
    ggplot(aes(y=prop, x=!!x)) +
    geom_bar(stat = "identity")
}

variables <- c("Improved", "Sex", "Treatment")

variables %>% purrr::map(., ~ plotUniCat2(Arthritis, .x))
#> [[1]]
Run Code Online (Sandbox Code Playgroud)

#> 
#> [[2]]
Run Code Online (Sandbox Code Playgroud)

#> 
#> [[3]]
Run Code Online (Sandbox Code Playgroud)

reprex包(v0.2.0)创建于2018-06-13.


Wei*_*ong 4

enquo将函数中的更改为sym, 将变量字符串转换为符号。那是,

plotUniCat <- function(df, x) {
  x <- sym(x)
  df %>%
    filter(!is.na(!!x)) %>%
    count(!!x) %>%
    mutate(prop = prop.table(n)) %>%
    ggplot(aes(y=prop, x=!!x)) +
    geom_bar(stat = "identity")
}
Run Code Online (Sandbox Code Playgroud)

或者,更简洁地说,

plotUniCat <- function(df, x) {
  x <- sym(x)
  df %>%
    filter(!is.na(!!x)) %>%
    ggplot(aes(x = as.factor(!!x))) +
    geom_histogram(stat = "count")
}
Run Code Online (Sandbox Code Playgroud)

进而

out <- lapply(variables, function(i) plotUniCat(Arthritis,i))
Run Code Online (Sandbox Code Playgroud)

最后,用于grid.arrange显示绘图。例如

library(gridExtra)
do.call(grid.arrange, c(out, ncol = 2))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述