2017-08-01 42 views
8

我很困惑如何函數的參數傳遞到dplyr和ggplot代碼。 我使用dplyr和GGPLOT2 這裏的最新版本是我的代碼產生barplot(淨度VS的平均價格)通功能參數都dplyr和ggplot

diamond.plot<- function (data, group, metric) { 
    group<- quo(group) 
    metric<- quo(metric) 
    data() %>% group_by(!! group) %>% 
      summarise(price=mean(!! metric)) %>% 
      ggplot(aes(x=!! group,y=price))+ 
      geom_bar(stat='identity') 
} 

diamond.plot(diamonds, group='clarity', metric='price') 

錯誤:

Error in UseMethod("group_by_") : no applicable method for 'group_by_' applied to an object of class "packageIQR" 

對於dplyr的最新版本,強調的動詞_()被輕度棄用。看來我們應該使用quards。

我的問題:

  • 有人能澄清這個目前最好的做法?
  • 什麼是錯與上面的代碼? (沒有下劃線dplyr動詞..)

  • 在ggplot中,我知道我們可以使用aes_string(),但在我的情況下,只有一個參數在aes從函數參數傳遞。

在此先感謝。

回答

6

我不認爲你可以說「正確」的方法相當,但作爲GGPLOT2不支持tidyeval語法,但它的到來。

與代碼的dplyr一部分,最好的做法是:

library(tidyverse) 
library(rlang) 

diamond_data <- function (data, group, metric) { 
    quo_group <- enquo(group) 
    quo_metric <- enquo(metric) 
    data %>% 
    group_by(!!quo_group) %>% 
    summarise(price=mean(!!quo_metric)) 
} 
diamond_data(diamonds, clarity, price) 

要解決缺乏支持GGPLOT2的tidyeval的,你可以做(​​請注意函數週圍的變量報價電話):

diamond_plot <- function (data, group, metric) { 
    quo_group <- parse_quosure(group) 
    quo_metric <- parse_quosure(metric) 
    data %>% 
     group_by(!!quo_group) %>% 
     summarise(price=mean(!!quo_metric)) %>% 
     ggplot(aes_(x = as.name(group), y=as.name(metric)))+ 
     geom_bar(stat='identity') 
} 
diamond_plot(diamonds, "clarity", "price") 

編輯 - 繼@梅西的評論:

diamond_plot <- function (data, group, metric) { 
    quo_group <- sym(group) 
    quo_metric <- sym(metric) 
    data %>% 
     group_by(!!quo_group) %>% 
     summarise(price=mean(!!quo_metric)) %>% 
     ggplot(aes_(x = quo_group, y= quo_metric)) + 
     geom_bar(stat='identity') 
} 
diamond_plot(diamonds, "clarity", "price") 
+0

謝謝@sinQueso – zesla

+0

我只想用'符號()'(或'as.name()'),而不是'parse_quosure()'在這種情況下。 – lionel

+0

感謝您的建議@lionel,我更新了我的回答 – sinQueso

3

sinQueso的回答是有希望的,但它忽略的功能,這是要適應不同的數據幀的目的。 「價格」可變編碼的功能在以下行:

summarise(price=mean(!!quo_metric)) %>% 

所以如果輸入變量爲「價格」這個功能纔有效。

這裏是一個更好的解決方案,可用於任何數據幀:

diamond_plot <- function (data, group, metric) { 
     quo_group <- sym(group) 
     quo_metric <- sym(metric) 
     summary <- data %>% 
       group_by(!!quo_group) %>% 
       summarise(mean=mean(!!quo_metric)) 
       ggplot(summary, aes_string(x = group, y= "mean")) + 
       geom_bar(stat='identity') 
} 
diamond_plot(diamonds, "clarity", "price") 
3

你可以走得更遠比丹尼爾的解決方案,以使彙總變量(公制)的名稱與輸入的變化。

diamond_plot <- function(data, group, metric) { 
    quo_group <- rlang::sym(group) 
    quo_metric <- rlang::sym(metric) 
    metric_name <- rlang::sym(stringr::str_c("mean_", metric)) 
    data %>% 
     group_by(!!quo_group) %>% 
     summarize(!!metric_name := mean(!!quo_metric)) %>% 
     ggplot(aes_(x = quo_group, y = metric_name)) + 
     geom_bar(stat = 'identity') 
} 
diamond_plot(diamonds, "clarity", "price") 
0

最「tidyeval」的方式解決這個問題對我來說看起來的quo_nameaes_string功能組合。避免使用尾隨下劃線動詞,如aes_,因爲他們得到的棄用。

diamond_plot <- function(data, group, metric) { 
    quo_group <- enquo(group) 
    str_group <- quo_name(quo_group) 

    quo_metric <- enquo(metric) 

    summary <- data %>% 
    groupby(!!quo_group) %>% 
    summarise(mean = mean(!!quo_metric)) 

    ggplot(summary) + 
    geom_bar(aes_string(x = str_group, y = "mean"), stat = "identity") 
} 

diamond_plot(diamnonds, clarity, price)