如何将ggplot和dplyr结合成一个函数?

14
考虑这个简单的例子。
library(dplyr)
library(ggplot2)

dataframe <- data_frame(id = c(1,2,3,4),
                        group = c('a','b','c','c'),
                        value = c(200,400,120,300))

# A tibble: 4 x 3
     id group value
  <dbl> <chr> <dbl>
1     1     a   200
2     2     b   400
3     3     c   120
4     4     c   300

这里我想编写一个函数,它的输入是数据帧和分组变量。理想情况下,在分组和聚合之后,我想要绘制一个ggplot图表。

以下代码可行:

get_charts2 <- function(data, mygroup){

  quo_var <- enquo(mygroup)

  df_agg <- data %>% 
    group_by(!!quo_var) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
    ungroup()

  df_agg
}



> get_charts2(dataframe, group)
# A tibble: 3 x 3
  group  mean count
  <chr> <dbl> <int>
1     a   200     1
2     b   400     1
3     c   210     2

很不幸,将ggplot添加到上述函数中失败了

 get_charts1 <- function(data, mygroup){

  quo_var <- enquo(mygroup)

  df_agg <- data %>% 
    group_by(!!quo_var) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
  ungroup()

  ggplot(df_agg, aes(x = count, y = mean, color = !!quo_var, group = !!quo_var)) + 
    geom_point() +
    geom_line() 
}


> get_charts1(dataframe, group)
Error in !quo_var : invalid argument type

我不理解这里有什么问题。有什么想法吗? 谢谢!

编辑:有趣的后续内容在这里如何在使用ggplot和dplyr的函数中从quosures创建因子变量?


该死!你知道我怎么修复上面的代码吗?谢谢! - ℕʘʘḆḽḘ
2个回答

12

ggplot 目前不支持整洁评估语法(您不能使用 !!)。 您需要使用更传统的标准评估调用。 您可以在 ggplot 中使用 aes_q 来帮助解决这个问题。

get_charts1 <- function(data, mygroup){

  quo_var <- enquo(mygroup)

  df_agg <- data %>% 
    group_by(!!quo_var) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
    ungroup()

  ggplot(df_agg, aes_q(x = quote(count), y = quote(mean), color = quo_var, group = quo_var)) + 
    geom_point() +
    geom_line() 
}


get_charts1(dataframe, group)

3
因为aes_q要求输入符号(或者将解析为符号的变量)。在这种情况下,您只需使用count,而不是一个名为“count”的变量,因此需要引用它。但是,quo_var是一个包含类似于符号的表达式group的变量,所以您需要评估该变量。 - MrFlick
谢谢,我得承认这真的很令人困惑...需要考虑一段时间...:D 再次感谢!!! - ℕʘʘḆḽḘ
只是一个快速的跟进。能否在enquote上使用factor?例如 ggplot(df_agg, aes_q(x = quote(count), y = quote(mean), color = quo_var, group = factor(quo_var))) 问题是,我的变量被视为数字,我想要一个因子.. 再次感谢! - ℕʘʘḆḽḘ
2
这是一个更复杂的问题,最好用一个单独的问题来解决。类似 color = bquote(factor(.(quo_var[[2]])))) 这样的东西可能会起作用。 - MrFlick
https://dev59.com/MaTja4cB1Zd3GeqPDo4i - ℕʘʘḆḽḘ
显示剩余3条评论

7

ggplot2 v3.0.0于2018年7月发布,支持!!(叹号叹号)、!!!:=aes_()/aes_q()aes_string()被软弃用。

原始代码应该可以正常运行。

library(tidyverse)

get_charts1 <- function(data, mygroup){

  quo_var <- enquo(mygroup)

  df_agg <- data %>% 
    group_by(!!quo_var) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
    ungroup()

  ggplot(df_agg, aes(x = count, y = mean, 
                color = !!quo_var, group = !!quo_var)) + 
    geom_point() +
    geom_line() 
}

get_charts1(dataframe, group)

编辑:使用整洁的评估代词.data[]从数据框中切片选择的变量也可以起作用。

get_charts2 <- function(data, mygroup){

  df_agg <- data %>% 
    group_by(.data[[mygroup]]) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
    ungroup()

  ggplot(df_agg, aes(x = count, y = mean, 
                     color = .data[[mygroup]], group = .data[[mygroup]])) + 
    geom_point() +
    geom_line() 
}

get_charts2(dataframe, "group")

这个示例由 reprex软件包 (v0.2.0)在2018年04月04日创建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接