2017-08-01 5 views
8

dplyrとggplotのコードに関数の引数を渡す方法が混乱しています。 私はここでdplyrとggplot2 の最新バージョンを使用してbarplot(平均価格対明瞭度)を生成するために私のコードですよ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') 

エラー:dplyrの最新バージョンについては

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

、下線を引いたverbs_()はやや非難されています。私たちはquosuresを使用する必要があるようです。

私の質問:

  • 誰かがこのために現在のベストプラクティスを明確にすることはできますか?
  • 上記のコードに何が間違っていましたか?私はaes_string()を使用することができますが、私の場合は、aesの中の1つのパラメータだけが関数の引数から渡されます。

ありがとうございます。

答えて

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") 

EDIT - @のライオネルさんのコメントに続き:

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

は、あなたが、私はだけではなく、その場合には 'parse_quosure()'の 'SYMを()'(または 'as.name()')使用する – zesla

+0

を@sinQuesoありがとうございました。 – lionel

+0

提案のおかげで@リオネル、私は私の答えを – sinQueso

3

sinQuesoの答えは有望ですが、異なるデータフレームに適応できる機能の目的を見逃しています。 "price"変数は、関数内の次の行にコード化されています。

この関数は、入力変数が "price"の場合にのみ機能します。

は、ここで任意のデータフレームのために使用することができ、より良いソリューションです:

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) 
関連する問題