Передать аргументы функции как dplyr, так и ggplot
Я смущен тем, как передавать аргумент функции в коды dplyr и ggplot.
Я использую новейшую версию dplyr и ggplot2
Вот мой код для создания барплота (ясность против средней цены)
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 подчеркнутые verbs_() мягко устарели. Похоже, мы должны использовать quosures.
мои вопросы:
- Может ли кто-нибудь уточнить текущую передовую практику для этого?
-
Что случилось с вышеуказанным кодом? (нет слов подчеркивания dplyr, пожалуйста..)
-
В ggplot я знаю, что мы можем использовать aes_string(), но в моем случае только один из параметров в aes передается из аргумента функции.
Спасибо заранее.
Ответы
Ответ 1
Теперь ggplot2 v3.0.0
полностью поддерживается в ggplot2 v3.0.0
поэтому нет необходимости использовать aes_
или aes_string
.
library(rlang)
library(tidyverse)
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_col()
}
diamond_plot(diamonds, "clarity", "price")
![]()
Создано в 2018-04-16 пакетом reprex (v0.2.0).
Ответ 2
Я не думаю, что вы можете так "правильно", но 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)
Чтобы обойти отсутствие поддержки tidyeval в ggplot2, вы могли бы сделать (обратите внимание на кавычки вокруг переменных в вызове функции):
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")
РЕДАКТИРОВАТЬ - после комментария @lionel:
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")
Ответ 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")
Ответ 4
Вы можете пойти еще дальше решения Даниэля, чтобы имя сводной переменной (метрики) изменилось с помощью ввода.
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")
Ответ 5
Самый "tidyeval" путь к этой проблеме для меня выглядит как комбинация функций quo_name
и aes_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)