【问题标题】:How to combine ggplot and dplyr into a function?如何将 ggplot 和 dplyr 组合成一个函数?
【发布时间】:2018-01-31 03:21:34
【问题描述】:

考虑这个简单的例子

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

这里我想写一个函数,将数据框和分组变量作为输入。理想情况下,在分组和聚合之后,我想打印一个 ggpplot 图表。

这行得通:

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添加到上面的函数中FAILS

 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

我不明白这里有什么问题。有任何想法吗? 谢谢!

编辑:这里有有趣的后续how to create factor variables from quosures in functions using ggplot and dplyr?

【问题讨论】:

  • 该死的!!!你知道我该如何修复上面的代码吗?谢谢!!

标签: r ggplot2 dplyr tidyeval


【解决方案1】:

2018年7月发布的ggplot2 v3.0.0支持!!(砰砰)、!!!:=aes_()/aes_q()aes_string() 已软弃用。

OP 的原始代码应该可以工作

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 package (v0.2.0) 于 2018 年 4 月 4 日创建。

【讨论】:

    【解决方案2】:

    ggplot 还不支持整洁的 eval 语法(你不能使用!!)。您需要使用更传统的标准评估调用。您可以在 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)
    

    【讨论】:

    • 谢谢!真的很整洁。你介意解释一下为什么我需要quote() count 但我可以保持quo_var 原样吗?
    • 因为aes_q 需要符号(或解析为符号的变量)。在这种情况下,您只想使用count,而不是名为“count”的变量,所以您引用它。但是quo_var 是一个包含符号表达式group 的变量,因此您需要评估该变量。
    • 谢谢,我不得不承认这令人困惑......需要考虑一段时间......:D再次感谢!!!!
    • 只是快速跟进。是否可以在enquote 上使用factor?说类似ggplot(df_agg, aes_q(x = quote(count), y = quote(mean), color = quo_var, group = factor(quo_var))) 的问题是,我的变量被视为数字,而我想要一个因子。再次感谢!
    • 这是一个更复杂的问题,最好用一个单独的问题来解决。像color = bquote(factor(.(quo_var[[2]])))) 这样的东西可能会起作用。
    猜你喜欢
    • 2018-09-27
    • 1970-01-01
    • 2017-12-09
    • 2018-01-08
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多