将函数参数传递给 dplyr 和 ggplot
pass function arguments to both dplyr and 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 中只有一个参数是从函数参数传递的。
提前致谢。
我认为你还不能用 "correct" 的方式,因为 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")
编辑 -- 按照@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")
sinQueso 的答案很有希望,但它没有实现函数的目的,即适应不同的数据帧。 "price" 变量在以下行的函数中编码:
summarise(price=mean(!!quo_metric)) %>%
所以这个函数只有在输入变量是"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")
您可以比 Daniel 的解决方案更进一步,以便汇总变量(指标)的名称随输入而变化。
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")
在我看来,解决这个问题的最 "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)
ggplot2 v3.0.0
现在完全支持 Tidy 求值,因此不再需要使用 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")
由 reprex package (v0.2.0) 创建于 2018-04-16。
我对如何将函数参数传递给 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 中只有一个参数是从函数参数传递的。
提前致谢。
我认为你还不能用 "correct" 的方式,因为 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")
编辑 -- 按照@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")
sinQueso 的答案很有希望,但它没有实现函数的目的,即适应不同的数据帧。 "price" 变量在以下行的函数中编码:
summarise(price=mean(!!quo_metric)) %>%
所以这个函数只有在输入变量是"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")
您可以比 Daniel 的解决方案更进一步,以便汇总变量(指标)的名称随输入而变化。
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")
在我看来,解决这个问题的最 "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)
ggplot2 v3.0.0
现在完全支持 Tidy 求值,因此不再需要使用 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")
由 reprex package (v0.2.0) 创建于 2018-04-16。