使用 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

编辑:我也尝试了详细的解决方案 ,但我收到了同样的错误。

以下将允许您绘制具有特征 variablegroup 的百分比,同时绘制具有组名称和计数的结果。

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() 函数的参数将是字符串。前两行将字符串 variablegroup 转换为 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 是一个关于如何转换名称的函数。您向它传递了数据,然后传递了一个调用单独向量的函数。