如何在使用“arrow”R 包(arrow::open_dataset)和 dplyr 动词时使用整洁的 eval 编写函数?

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

我想做什么

我正在尝试编写一个使用 dplyr 动词的函数,并将“箭头打开数据集”作为第一个参数,并将该数据集中的列作为第二个参数。由于我想将列作为字符串传递(这对于我正在处理的实际任务的上下文是必需的,即Shiny),因此我使用语法.data[[.column]]。下面是我收到的错误的图像以及一些重现所述错误的代码。任何帮助或见解表示赞赏。

错误消息图片

重现错误的代码

# install.packages(c("dplyr", "ggplot2", "arrow"))
library(dplyr)

arrow::write_parquet(x = ggplot2::mpg, sink = "sample_data.parquet")

dat <- arrow::open_dataset("sample_data.parquet")

glimpse(dat)

get_metric <- function(.data, .metric) {
  
  .data %>%
    group_by(manufacturer, cyl) %>% 
    summarize(
      new_col = sum(.data[[.metric]], na.rm = T)
    ) %>% 
    ungroup() 
}

get_metric(dat, "cty") %>% collect()

其他代码可以工作,但不使用太多箭头,因此速度不理想

在这段代码中,我在整洁的 eval 内容之前收集,因此它本质上只是常规的 dplyr 代码。它可以运行,但比我在将内容提取到所述函数之前成功运行的代码慢。

get_metric2 <- function(.data, .metric) {
  
  .data %>%
    collect() %>% 
    group_by(manufacturer, cyl) %>% 
    summarize(
      new_col = sum(.data[[.metric]], na.rm = T)
    ) %>% 
    ungroup() 
}

get_metric2(dat, "cty")
r dplyr parquet apache-arrow tidyeval
1个回答
0
投票

使用

!!
命名法(并引用存在的列名称)。

arrow::write_parquet(x = ggplot2::mpg, sink = "sample_data.parquet")
dat <- arrow::open_dataset("sample_data.parquet")
get_metric <- function(.data, .metric) {
  .metric <- rlang::sym(.metric)
   .data %>%
    group_by(manufacturer, cyl) %>% 
    summarize(
      new_col = sum(!!.metric, na.rm = T)
    ) %>% 
    ungroup() 
}
get_metric(dat, "hwy") %>%
  collect()
# # A tibble: 32 × 3
#    manufacturer   cyl new_col
#    <chr>        <int>   <int>
#  1 audi             4     225
#  2 audi             6     228
#  3 audi             8      23
#  4 chevrolet        8     278
#  5 chevrolet        4      57
#  6 chevrolet        6      81
#  7 dodge            4      24
#  8 dodge            6     310
#  9 dodge            8     330
# 10 ford             8     277
# # ℹ 22 more rows
# # ℹ Use `print(n = ...)` to see more rows
© www.soinside.com 2019 - 2024. All rights reserved.