首页 > 解决方案 > 在嵌套函数中使用相同的参数名称会导致意外输出

问题描述

为什么前三个函数(f2、f3、f4)只返回 y 中 id = 1 的行,而 f5 返回 y 的所有行?

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

y <- tibble(id = c(1, 2))


f1 <- function(y, id) {
  y %>% filter(.data$id == {{id}})
}


f2 <- function(id) {
  f1(y, !!id)
}

f3 <- function(id) {
  f1(y, {{id}})
}

f4 <- function(x) {
  f1(y, x)
}

f5 <- function(id) {
  f1(y, id)
}


f2(1)
#> # A tibble: 1 x 1
#>      id
#>   <dbl>
#> 1     1
f3(1)
#> # A tibble: 1 x 1
#>      id
#>   <dbl>
#> 1     1
f4(1)
#> # A tibble: 1 x 1
#>      id
#>   <dbl>
#> 1     1
f5(1)
#> # A tibble: 2 x 1
#>      id
#>   <dbl>
#> 1     1
#> 2     2

reprex 包(v0.3.0)于 2020 年 11 月 15 日创建

标签: rdplyrfunctional-programmingnested

解决方案


如果您更改函数以显示它正在评估的内容,则可能更有意义

f1 <- function(y, id) {
  print(rlang::quo_squash(quo(y %>% filter(.data$id == {{id}}))))
  y %>% filter(.data$id == {{id}})
}

f5,你得到

y %>% filter(.data$id == id)

所以它返回列id等于列id(即每一行)的所有行。

您应该{{}}在从 data.frame 中选择列时使用。您尝试指定文字 data.value 是没有用的。

如果您将所有示例定义f1

f1 <- function(y, id) {
  y %>% filter(.data$id == .env$id)
}

推荐阅读