使用 dplyr/ggplot 函数在 for 循环中调用多个变量
Call many variables in a for loop with dplyr/ggplot function
有时在执行探索性分析或生成报告时,我们想要绘制多个变量的单变量分布。我可以在一些巧妙的技巧之后对情节进行分面处理,但是有一些有序的因素,我想让它们在情节上保持有序。
因此,为了以更有效的方式完成它,我构建了一个简单的基于 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)
我可以用很短的方式绘制格式化图表,这很酷,但只有一个变量。
我试图用 for 循环调用多个变量,但它不起作用。代码运行,但没有任何反应。
variables <- c("Improved", "Sex", "Treatment")
for (i in variables) {
plotUniCat(Arthritis, noquote(i))
}
我搜索过这个,但我还是不清楚。有人知道我做错了什么或如何让它发挥作用吗?
提前致谢。
将函数中的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")
}
或者,更简洁地说,
plotUniCat <- function(df, x) {
x <- sym(x)
df %>%
filter(!is.na(!!x)) %>%
ggplot(aes(x = as.factor(!!x))) +
geom_histogram(stat = "count")
}
然后
out <- lapply(variables, function(i) plotUniCat(Arthritis,i))
最后,使用grid.arrange
显示绘图。例如
library(gridExtra)
do.call(grid.arrange, c(out, ncol = 2))
您需要使用 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]]
#>
#> [[2]]
#>
#> [[3]]
由 reprex package (v0.2.0) 创建于 2018-06-13。
我猜 OP 希望对带引号和不带引号的变量名使用 plotUniCat
。如果我们更改函数,它将不适用于 plotUniCat(Arthritis, Improved)
.
因此,除了改变函数,我们还可以改变我们调用函数的方式 plotUniCat
为:
for (i in variables) {
plotUniCat(Arthritis, !!rlang::sym(i))
}
但是,这些图是由 for
生成但未返回的。我们可以使用print
或lapply
强制显示或收集生成的图:
lapply(variables, function(i) plotUniCat(Arthritis, !!rlang::sym(i)))
有时在执行探索性分析或生成报告时,我们想要绘制多个变量的单变量分布。我可以在一些巧妙的技巧之后对情节进行分面处理,但是有一些有序的因素,我想让它们在情节上保持有序。
因此,为了以更有效的方式完成它,我构建了一个简单的基于 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)
我可以用很短的方式绘制格式化图表,这很酷,但只有一个变量。
我试图用 for 循环调用多个变量,但它不起作用。代码运行,但没有任何反应。
variables <- c("Improved", "Sex", "Treatment")
for (i in variables) {
plotUniCat(Arthritis, noquote(i))
}
我搜索过这个,但我还是不清楚。有人知道我做错了什么或如何让它发挥作用吗?
提前致谢。
将函数中的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")
}
或者,更简洁地说,
plotUniCat <- function(df, x) {
x <- sym(x)
df %>%
filter(!is.na(!!x)) %>%
ggplot(aes(x = as.factor(!!x))) +
geom_histogram(stat = "count")
}
然后
out <- lapply(variables, function(i) plotUniCat(Arthritis,i))
最后,使用grid.arrange
显示绘图。例如
library(gridExtra)
do.call(grid.arrange, c(out, ncol = 2))
您需要使用 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]]
#>
#> [[2]]
#>
#> [[3]]
由 reprex package (v0.2.0) 创建于 2018-06-13。
我猜 OP 希望对带引号和不带引号的变量名使用 plotUniCat
。如果我们更改函数,它将不适用于 plotUniCat(Arthritis, Improved)
.
因此,除了改变函数,我们还可以改变我们调用函数的方式 plotUniCat
为:
for (i in variables) {
plotUniCat(Arthritis, !!rlang::sym(i))
}
但是,这些图是由 for
生成但未返回的。我们可以使用print
或lapply
强制显示或收集生成的图:
lapply(variables, function(i) plotUniCat(Arthritis, !!rlang::sym(i)))