在函数内使用 highcharter

jor*_*dan 3 r highcharts r-highcharter

如何在函数内使用highcharter :: hchart

这是一个使用该hchart函数的简单折线图。

library(tidyverse)
library(lubridate)
library(highcharter)
library(nycflights13)

flights_2 <- flights %>% 
  mutate(dep_mo = ymd(str_c(year, month, "01", sep = "-"))) %>% 
  group_by(dep_mo) %>% 
  summarize(arr_delay = mean(arr_delay, na.rm = TRUE))

hchart(flights_2, 
       type = "line", 
       hcaes(x = dep_mo, y = arr_delay), 
       name = "Average Arrival Delay")
Run Code Online (Sandbox Code Playgroud)

当我尝试编写一个函数来创建相同的图形时,出现错误。

h_fun <- function(df, x, y) {
  hchart(df, 
         type = "line",
         hcaes(x = x, y = y),
         name = "Average Arrival Delay"
         )
 }

 h_fun(df = flights_2, x = dep_mo, y = arr_delay)
Run Code Online (Sandbox Code Playgroud)

这是错误消息: Error in mutate_impl(.data, dots) : Binding not found: x.

当我回溯错误时,它似乎hchart正在使用dplyr::mutate_. 这让我相信该错误与 NSE 有关,并且可能hchart需要类似于ggplot2::aes_string()链接)的内容。但是,我在highcharter.

在此处输入图片说明

Tun*_*ung 5

我们需要与enquo()&quo_name()一起使用hcaes_string

  • enquo() 捕获由用户作为参数提供的表达式并返回一个 quosure。
  • quo_name() 挤压 quosure 并将其转换为字符串。

如果您还没有听说过,请观看 Hadleytidyeval在这个5 分钟视频中的解释。更多在tidyeval 这里

library(tidyverse)
library(lubridate)
library(highcharter)
library(nycflights13)

flights_2 <- flights %>% 
  mutate(dep_mo = ymd(str_c(year, month, "01", sep = "-"))) %>% 
  group_by(dep_mo) %>% 
  summarize(arr_delay = mean(arr_delay, na.rm = TRUE))

h_fun2 <- function(df, x, y) {
  x <- enquo(x)
  y <- enquo(y)
  hchart(df, 
         type = "line",
         hcaes_string(quo_name(x), quo_name(y)),
         name = "Average Arrival Delay"
  )
}

h_fun2(df = flights_2, x = dep_mo, y = arr_delay)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

编辑:截至2018年4月18日,highcharter支持tidyevalso的开发版本h_fun2可以改写为:

h_fun2 <- function(df, x, y) {
  x <- enexpr(x)
  y <- enexpr(y)
  hchart(df, 
         type = "line",
         hcaes(!!x, !!y),
         name = "Average Arrival Delay"
  )
} 
Run Code Online (Sandbox Code Playgroud)

  • 我会小心,因为`hchart()` 函数本身不支持整洁的评估,所以你不能使用像`!!`(bang-bang)这样的运算符。所以哈德利谈论的大部分事情你可能无法直接做到。但是当然`quo_name(enquo())` 是一种很好的通用方法,可以获取传递给函数的未加引号变量的“名称”。 (3认同)