使用 purrr 时如何自定义 ggplot2 facet_grid 标签中的文本?
How to customize text in ggplot2 facet_grid label when using purrr?
我正在使用 purrr 和 ggplot2 一次创建多个绘图。对于每个方面的名称,我想保留组的名称,但我还想添加每个 sub-group 中的参与者数量。例如,“Manager (N = 200)
”和“Employee (N = 3000)
”。但是,当我尝试添加此标签参数时:
facet_grid(~.data[[group]],
labeller = paste0(~.data[[group]], "(N = ", group_n$n, ")"))
我收到这个错误:
Error in cbind(labels = list(), list(`{`, if (!is.null(.rows) || !is.null(.cols)) { :
number of rows of matrices must match (see arg 2)
下面是一个使用简化数据集的可重现示例。我的目标是让 sub-group 和他们的样本大小出现在他们的 facet 标题中。
library(purrr)
library(dplyr)
library(ggplot2)
#Data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
s2rl = c("Agree", "Neutral", NA),
f1 = c("Strongly agree", NA, "Strongly disagree"),
f2rl = c(NA, "Disagree", "Strongly disagree"),
level = c("Manager", "Employee", "Employee"),
location = c("USA", "USA", "AUS"))
#Get just test items for name
test_items <- test %>%
dplyr::select(s1, s2rl, f1, f2rl)
#titles of plots for R to iterate over
titles <- c("S1 results", "Results for S2RL", "Fiscal Results for F1", "Financial Status of F2RL")
#group levels
group_name <- c("level", "location")
#Custom function to make plots
facet_plots = function(variable, group, title) {
total_n <- test %>%
summarize(n = sum(!is.na(.data[[variable]])))
group_n <- test %>%
group_by(.data[[group]], .data[[variable]]) %>%
summarize(n = sum(!is.na(.data[[variable]])))
plot2 <- test %>%
count(.data[[group]], .data[[variable]]) %>%
mutate(percent = 100*(n / group_n$n)) %>%
drop_na() %>%
ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) +
geom_bar(stat = "identity") +
geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
ylab("\nPercentage") +
labs(
title = title,
subtitle = paste0("(N = ", total_n$n)) +
coord_flip() +
theme_minimal() +
ylim(0, 100) +
facet_grid(~.data[[group]],
labeller = paste0(~.data[[group]], "(N = ", group_n$n, ")")) #issue is likely here
output <- list(plot2)
return(output)
}
#pmap call
my_plots <- expand_grid(tibble(item = names(test_items), title=titles),
group = group_name) %>%
pmap(function(item, group, title)
facet_plots(item, group, title))
my_plots
编辑:我也尝试了详细的解决方案 ,但我收到了同样的错误。
以下将允许您绘制具有特征 variable
的 group
的百分比,同时绘制具有组名称和计数的结果。
library(tidyr)
library(dplyr)
library(ggplot2)
library(purrr)
facet_plots <- function(variable, group, title="Title", dat) {
variable <- sym(variable)
group <- sym(group)
sumdat <- dat %>%
filter(!is.na(!!variable)) %>%
group_by(!!group) %>%
add_count() %>%
mutate(lbl = paste0(!!group, " (N = ", n, ")")) %>%
group_by(!!group, !!variable) %>%
mutate(pct = 100 * n() / n) %>%
slice(1L) %>%
ungroup() %>%
select(!!variable, !!group, n, pct, lbl)
ggplot(sumdat, aes(x = !!variable, y = pct, group = !!group)) +
geom_bar(stat = "identity") +
labs(
title = title
) +
facet_grid(~lbl)
}
## Using starwars data
expand_grid(
tibble(
variable = c("hair_color", "skin_color", "birth_year"),
title = c("Hair color", "Skin color", "Birth year")
),
group = c("sex", "gender")) %>%
mutate(title = paste(title, "by", group)) %>%
pmap(facet_plots, dat = starwars)
使用pmap()
将创建一个以字符串形式存储的组合数据框。因此,facet_plots()
函数的参数将是字符串。前两行将字符串 variable
和 group
转换为 R 可以不带引号使用的符号(阅读更多 here 了解其含义)。 “bang-bang 运算符”!!
告诉 R 您想要存储在变量中的值,而不是名称本身(参见 help("!!")
)。任何时候 R 看到 !!variable
,它都会将值理解为存储在参数 variable
.
中的数据框中的变量名称
下面,我展示了这适用于 OP 的原始数据,而不仅仅是 starwars
示例数据。
## Using OP's data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
s2rl = c("Agree", "Neutral", NA),
f1 = c("Strongly agree", NA, "Strongly disagree"),
f2rl = c(NA, "Disagree", "Strongly disagree"),
level = c("Manager", "Employee", "Employee"),
location = c("USA", "USA", "AUS"))
expand_grid(
tibble(
variable = c("s1", "s2rl", "f1", "f2rl"),
title = c("S1 results", "Results for S2RL",
"Fiscal Results for F1", "Financial Status of F2RL")
),
group = c("level", "location")
) %>%
mutate(title = paste(title, "by", group)) %>%
pmap(facet_plots, dat = test)
我认为您的贴标机无法正常工作的原因是您传递给它的类型不正确。 labeller()
函数采用 var = fxn
形式的参数,其中 var
是 facet 网格中的变量名称 fxn
是一个关于如何转换名称的函数。您向它传递了数据,然后传递了一个调用单独向量的函数。
我正在使用 purrr 和 ggplot2 一次创建多个绘图。对于每个方面的名称,我想保留组的名称,但我还想添加每个 sub-group 中的参与者数量。例如,“Manager (N = 200)
”和“Employee (N = 3000)
”。但是,当我尝试添加此标签参数时:
facet_grid(~.data[[group]],
labeller = paste0(~.data[[group]], "(N = ", group_n$n, ")"))
我收到这个错误:
Error in cbind(labels = list(), list(`{`, if (!is.null(.rows) || !is.null(.cols)) { :
number of rows of matrices must match (see arg 2)
下面是一个使用简化数据集的可重现示例。我的目标是让 sub-group 和他们的样本大小出现在他们的 facet 标题中。
library(purrr)
library(dplyr)
library(ggplot2)
#Data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
s2rl = c("Agree", "Neutral", NA),
f1 = c("Strongly agree", NA, "Strongly disagree"),
f2rl = c(NA, "Disagree", "Strongly disagree"),
level = c("Manager", "Employee", "Employee"),
location = c("USA", "USA", "AUS"))
#Get just test items for name
test_items <- test %>%
dplyr::select(s1, s2rl, f1, f2rl)
#titles of plots for R to iterate over
titles <- c("S1 results", "Results for S2RL", "Fiscal Results for F1", "Financial Status of F2RL")
#group levels
group_name <- c("level", "location")
#Custom function to make plots
facet_plots = function(variable, group, title) {
total_n <- test %>%
summarize(n = sum(!is.na(.data[[variable]])))
group_n <- test %>%
group_by(.data[[group]], .data[[variable]]) %>%
summarize(n = sum(!is.na(.data[[variable]])))
plot2 <- test %>%
count(.data[[group]], .data[[variable]]) %>%
mutate(percent = 100*(n / group_n$n)) %>%
drop_na() %>%
ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) +
geom_bar(stat = "identity") +
geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
ylab("\nPercentage") +
labs(
title = title,
subtitle = paste0("(N = ", total_n$n)) +
coord_flip() +
theme_minimal() +
ylim(0, 100) +
facet_grid(~.data[[group]],
labeller = paste0(~.data[[group]], "(N = ", group_n$n, ")")) #issue is likely here
output <- list(plot2)
return(output)
}
#pmap call
my_plots <- expand_grid(tibble(item = names(test_items), title=titles),
group = group_name) %>%
pmap(function(item, group, title)
facet_plots(item, group, title))
my_plots
编辑:我也尝试了详细的解决方案
以下将允许您绘制具有特征 variable
的 group
的百分比,同时绘制具有组名称和计数的结果。
library(tidyr)
library(dplyr)
library(ggplot2)
library(purrr)
facet_plots <- function(variable, group, title="Title", dat) {
variable <- sym(variable)
group <- sym(group)
sumdat <- dat %>%
filter(!is.na(!!variable)) %>%
group_by(!!group) %>%
add_count() %>%
mutate(lbl = paste0(!!group, " (N = ", n, ")")) %>%
group_by(!!group, !!variable) %>%
mutate(pct = 100 * n() / n) %>%
slice(1L) %>%
ungroup() %>%
select(!!variable, !!group, n, pct, lbl)
ggplot(sumdat, aes(x = !!variable, y = pct, group = !!group)) +
geom_bar(stat = "identity") +
labs(
title = title
) +
facet_grid(~lbl)
}
## Using starwars data
expand_grid(
tibble(
variable = c("hair_color", "skin_color", "birth_year"),
title = c("Hair color", "Skin color", "Birth year")
),
group = c("sex", "gender")) %>%
mutate(title = paste(title, "by", group)) %>%
pmap(facet_plots, dat = starwars)
使用pmap()
将创建一个以字符串形式存储的组合数据框。因此,facet_plots()
函数的参数将是字符串。前两行将字符串 variable
和 group
转换为 R 可以不带引号使用的符号(阅读更多 here 了解其含义)。 “bang-bang 运算符”!!
告诉 R 您想要存储在变量中的值,而不是名称本身(参见 help("!!")
)。任何时候 R 看到 !!variable
,它都会将值理解为存储在参数 variable
.
下面,我展示了这适用于 OP 的原始数据,而不仅仅是 starwars
示例数据。
## Using OP's data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
s2rl = c("Agree", "Neutral", NA),
f1 = c("Strongly agree", NA, "Strongly disagree"),
f2rl = c(NA, "Disagree", "Strongly disagree"),
level = c("Manager", "Employee", "Employee"),
location = c("USA", "USA", "AUS"))
expand_grid(
tibble(
variable = c("s1", "s2rl", "f1", "f2rl"),
title = c("S1 results", "Results for S2RL",
"Fiscal Results for F1", "Financial Status of F2RL")
),
group = c("level", "location")
) %>%
mutate(title = paste(title, "by", group)) %>%
pmap(facet_plots, dat = test)
我认为您的贴标机无法正常工作的原因是您传递给它的类型不正确。 labeller()
函数采用 var = fxn
形式的参数,其中 var
是 facet 网格中的变量名称 fxn
是一个关于如何转换名称的函数。您向它传递了数据,然后传递了一个调用单独向量的函数。