【问题标题】:Unquoting inside of map2 with tidyeval使用 tidyeval 在 map2 内部取消引用
【发布时间】:2017-08-02 15:15:01
【问题描述】:

我正在创建一个计算“运行”次数或丢失或完整数据的函数 - 我希望它与 dplyr::group_by 一起使用,因此我将其编写为 S3 方法 - 下面是一个简化的示例代码。

不幸的是,我发现裸露的未加引号的变量名不起作用,但引用它,这确实有效,很奇怪。

下面是带输出的例子

  fun_run <- function(data, var) {

    UseMethod("fun_run")

  }

fun_run.default <- function(data, var) {

  var <- rlang::enquo(var)

  data_pull <- data %>% dplyr::pull(!(!var))

  # find the lengths of the number of missings in a row
  tibble::as_tibble(c(rle(is.na(data_pull))))

}

fun_run.grouped_df <- function(data, var) {

  var <- rlang::enquo(var)

  tidyr::nest(data) %>% dplyr::mutate(data = purrr::map2(.x = data, .y = !(!var), 
                                                         .f = fun_run)) %>% tidyr::unnest()

}

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

airquality %>% fun_run(Ozone)
#> # A tibble: 35 x 2
#> lengths values
#> <int>  <lgl>
#>   4    FALSE
#>   1     TRUE
#>   4    FALSE
#>   1     TRUE
#>  14    FALSE
#>   3     TRUE
#>   4    FALSE
#>   6     TRUE
#>   1    FALSE
#>   1     TRUE
#> ... with 25 more rows

# doesn't work
airquality %>% group_by(Month) %>% fun_run(Ozone)
#> Error in mutate_impl(.data, dots) : Evaluation error: object 'Ozone' not found. 

# does work
airquality %>% group_by(Month) %>% fun_run("Ozone")
#> # A tibble: 37 x 3
#> Month lengths values
#> <int>   <int>  <lgl>
#>     5       4  FALSE
#>     5       1   TRUE
#>     5       4  FALSE
#>     5       1   TRUE
#>     5      14  FALSE
#>     5       3   TRUE
#>     5       4  FALSE
#>     6       6   TRUE
#>     6       1  FALSE
#>     6       1   TRUE
#> # ... with 27 more rows

【问题讨论】:

    标签: r rlang tidyeval


    【解决方案1】:

    您实际上并不想使用 map2,因为您的第二个输入 (var) 不会随着第一个输入(分组/嵌套的 data)而改变。此外,此时“臭氧”列隐藏在嵌套数据中。您可以通过尝试在没有任何 tidyeval 语法的情况下执行代码来看到这一点:

    data <- airquality %>% group_by(Month)
    tidyr::nest(data) %>% dplyr::mutate(data = purrr::map2(.x = data, .y = Ozone, 
                                                           .f = fun_run)) %>% tidyr::unnest()
    #>Error in mutate_impl(.data, dots) : 
    #>  Evaluation error: object 'Ozone' not found.
    

    相反,您想使用标准map

    tidyr::nest(data) %>% dplyr::mutate(data = purrr::map(.x = data, var = Ozone, 
                                                           .f = fun_run)) %>% tidyr::unnest()
    

    重写后用于您的函数:

    fun_run.grouped_df <- function(data, var) {
    
      var <- rlang::enquo(var)
    
      tidyr::nest(data) %>% dplyr::mutate(data = purrr::map(.x = data, var = !!var, 
                                                            .f = fun_run)) %>% tidyr::unnest()
    
    }
    

    这会从您最后引用的示例中产生结果。

    【讨论】:

    • 啊!这正是我想要的。完美,非常感谢!我对嵌套数据框的思考太深入了,我把事情复杂化了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2020-10-11
    • 2018-12-05
    • 2019-06-15
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多