首页 > 解决方案 > 将列值传递给 ggplot 函数的标题

问题描述

假设我有这个小标题:

df <- tibble(question_text  = c('Did they do the thing?', 'Did they do the thing?','Did they do the thing?', 'Did they do the thing?'),
             answer_text    = c('They did', 'They did', 'They did not', 'They did not'),
             answer_numeric = c(3, 3, 2, 2),
             gender         = c('Female', 'Male', 'Female', 'Male'),
             n              = c(82000, 41000, 12000, 39000))

df
# A tibble: 4 x 5
  question_text          answer_text  answer_numeric gender     n
  <chr>                  <chr>                 <dbl> <chr>  <dbl>
1 Did they do the thing? They did                  3 Female 82000
2 Did they do the thing? They did                  3 Male   41000
3 Did they do the thing? They did not              2 Female 12000
4 Did they do the thing? They did not              2 Male   39000

我想编写一个函数来打印一个 ggplot 图形并将其值传递question_text给标题。(实际上,我的数据集的问答组合比显示的标题要多得多,但下面的代码复制了我得到的错误)

这是我的代码:

library(tidyverse)
library(scales)
library(viridis)

graph_fcn <- function(catvar, ft_size=12, title, scales){
  df %>%
    ggplot() +
    geom_col(aes(x = reorder(answer_text, answer_numeric), y = n, fill = answer_text)) +
    scale_y_continuous(labels = comma) +
    theme(legend.position = 'none',
          axis.title = element_blank(),
          axis.text=element_text(size={{ft_size}})) +
    scale_fill_viridis(discrete = TRUE, alpha=0.6) +
    ggtitle(paste0("\"",  question_text, "\"", {{title}})) +
    facet_wrap(vars({{catvar}}), scales={{scales}})
}

graph_fcn(catvar = gender,
          ft_size = 8,
          title = 'by gender',
          scales = 'fixed')

如果你运行上面的它会返回错误:

Error in paste0("\"", { : object 'question_text' not found

我已经尝试了很多方法来尝试解决这个问题:

  1. 放入question_text双大括号内,即{{}}
  2. 传递question_text给函数参数并将默认设置为question_text
  3. 传递question_text给函数参数,然后question_text = question_text在函数调用中显式设置

以上都不起作用。有谁知道我在这里做错了什么?以及如何将 through 的值传递question_textggtitle()

如果我question_text从线ggtitle(paste0("\"", question_text, "\"", {{title}}))中删除,图表如下所示:

在此处输入图像描述

附录

由于我df实际上包含更多的问答组合,实际上我正在做的是执行各种突变,然后在函数内将其直接传递到 ggplot() 命令中。IE

graph_fcn <- function(que_id, catvar, ft_size=12, title, scales){
  df %>%
  filter(question_id=={{que_id}}) %>%
  group_by(question_text, answer_text, answer_numeric, {{catvar}}) %>% count() %>% 
  filter(!is.na({{catvar}})) %>%
    ggplot() +
    geom_col(aes(x = reorder(answer_text, answer_numeric), y = n, fill = answer_text)) +
    scale_y_continuous(labels = comma) +
    theme(legend.position = 'none',
          axis.title = element_blank(),
          axis.text=element_text(size={{ft_size}})) +
    scale_fill_viridis(discrete = TRUE, alpha=0.6) +
    ggtitle(paste0("\"",  question_text, "\"", {{title}})) +
    facet_wrap(vars({{catvar}}), scales={{scales}})
}

graph_fcn(catvar = gender,
          ft_size = 8,
          title = 'by gender',
          scales = 'fixed')

因此,如果我将df$question_text[1]ggtitle() 放入其中,它会从 main 中提取第一个值,df而不是只包含一个问题值的小得多的值。

附加解决方案:

以下解决方案适用于只有一个问答组合的小型 df,如果您想为所有问题绘制图表,Sonak's 非常棒。我发现最简单的方法实际上是将 dplyr 转换分配给temp_df函数内的 a,然后在函数内分别将其传递给temp_df调用ggplot

IE

graph_fcn <- function(que_id, catvar, ft_size=12, title, scales){
  temp_df <- df %>%
  filter(question_id=={{que_id}}) %>%
  group_by(question_text, answer_text, answer_numeric, {{catvar}}) %>% count() %>% 
  filter(!is.na({{catvar}}))

temp_df %>%
    ggplot() +
    geom_col(aes(x = reorder(answer_text, answer_numeric), y = n, fill = answer_text)) +
    scale_y_continuous(labels = comma) +
    theme(legend.position = 'none',
          axis.title = element_blank(),
          axis.text=element_text(size={{ft_size}})) +
    scale_fill_viridis(discrete = TRUE, alpha=0.6) +
    ggtitle(paste0("\"",  temp_df$question_text[1], "\"", {{title}})) +
    facet_wrap(vars({{catvar}}), scales={{scales}})
}

标签: rggplot2dplyr

解决方案


添加 df$question_text 有效:

graph_fcn <- function(catvar, ft_size=12, title, scales){
  df %>%
    ggplot() +
    geom_col(aes(x = reorder(answer_text, answer_numeric), y = n, fill = answer_text)) +
    # scale_y_continuous(labels = 'comma') +
    theme(legend.position = 'none',
          axis.title = element_blank(),
          axis.text=element_text(size={{ft_size}})) +
    scale_fill_viridis(discrete = TRUE, alpha=0.6) +
    ggtitle(paste0("\"",  df$question_text, "\"", {{title}})) +
    facet_wrap(vars({{catvar}}), scales={{scales}})
}

在此处输入图像描述


推荐阅读