我有一个函数stacked_plot()
,该函数使用整洁的评估方法来制作堆积图。我想将其包含在我的程序包中,并使该程序包中的另一个函数调用它。这是最小的示例:
stacked_plot <- function(data, what, by = NULL, date_col = date){
by <- rlang::enquo(by)
what <- rlang::ensym(what)
date_col <- rlang::ensym(date_col)
data <- data %>%
dplyr::group_by(!!date_col, !!by) %>%
dplyr::summarise(!!what := sum(!!what, na.rm = TRUE)) %>%
dplyr::ungroup() %>%
tidyr::complete(!!date_col, !!by, fill = rlang::list2(!!what := 0))
p <- data %>%
ggplot2::ggplot(ggplot2::aes(!!date_col, !!what, fill = !!by)) +
ggplot2::geom_area(position = 'stack')
print(p)
}
#' @importFrom rlang .data
call_plot <- function() {
to_plot <- data.frame(date = rep(seq(lubridate::ymd('2020-01-01'),
lubridate::ymd('2020-03-30'),
by = '1 day'), each = 3)) %>%
dplyr::mutate(cat = rep(c('A', 'B', 'C'), 90), v1 = runif(270))
p <- to_plot %>%
stacked_plot(what = .data$v1, by = .data$cat)
return(p)
}
将stacked_plot()
合并到一个程序包中可以很好地工作,我可以进行交互调用。但是,call_plot()
之后的load_all()
导致错误。这是rlang::last_error()
输出:
rlang::last_error()
<error/rlang_error>
Only strings can be converted to symbols
Backtrace:
1. global::call_plot()
10. mmmtools::stacked_plot(., what = .data$v1, by = .data$cat)
11. rlang::ensym(what) R/stacked_plot.R:4:2
Run `rlang::last_trace()` to see the full context.
我相信这是由于整理评估有些特殊性。但是,我真的找不到有关在R包中使用tidyeval
的特殊性的任何资料。我唯一知道的是,我不能真正直接使用带引号的变量,而是使用.data$variable
模式,而这是我在call_plot()
中所做的。
如何使用调整stacked_plot()
以使其可用于其他包装功能?
似乎OP希望使用未加引号的列名。如果是这种情况,请将ensym
更改为enquo
stacked_plot <- function(data, what, by = NULL, date_col = date){
by <- rlang::enquo(by)
what <- rlang::enquo(what)
date_col <- rlang::enquo(date_col)
data %>%
dplyr::group_by(!! date_col, !!by) %>%
dplyr::summarise(!!what := sum(!!what, na.rm = TRUE)) %>%
dplyr::ungroup() %>%
tidyr::complete(!!date_col, !!by, fill = rlang::list2(!!what := 0)) %>%
ggplot2::ggplot(ggplot2::aes(!!date_col, !!what, fill = !!by)) +
ggplot2::geom_area(position = 'stack')
}
call_plot <- function() {
to_plot <- data.frame(date = rep(seq(lubridate::ymd('2020-01-01'),
lubridate::ymd('2020-03-30'),
by = '1 day'), each = 3)) %>%
dplyr::mutate(cat = rep(c('A', 'B', 'C'), 90), v1 = runif(270))
p <- to_plot %>%
stacked_plot(what = v1, by = cat)
return(p)
}
-调用函数
call_plot()
此外,enquo
+ !!
可以完全替换为{{}}
stacked_plot <- function(data, what, by = NULL, date_col = date){
data %>%
dplyr::group_by({{date_col}}, {{by}}) %>%
dplyr::summarise( {{what}} := sum({{what}}, na.rm = TRUE)) %>%
dplyr::ungroup() %>%
tidyr::complete({{date_col}}, {{by}}, fill = rlang::list2({{what}} := 0)) %>%
ggplot2::ggplot(ggplot2::aes({{date_col}}, {{what}}, fill = {{by}})) +
ggplot2::geom_area(position = 'stack')
}
并且可以与上一个相同
call_plot()