在R包中使用整齐的评估

问题描述 投票:1回答:1

我有一个函数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()以使其可用于其他包装功能?

r dplyr r-package rlang tidyeval
1个回答
0
投票

似乎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()

enter image description here


此外,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()
© www.soinside.com 2019 - 2024. All rights reserved.