我如何使用同名变量存在的函数参数?
How can I use function arguments where variables exist with the same name?
如果我在 data.frame
中有一个列与我的函数的参数之一同名,则在尝试 mutate
或 filter
时使用列名.
有没有办法显式使用函数参数?
可重现的例子:
my_function <- function(x) {
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_tib %>%
mutate(z = x * y)
}
my_function(x=100)
## A tibble: 3 x 3
# x y z
# <dbl> <dbl> <dbl>
#1 1 5 5
#2 2 10 20
#3 3 15 45
想要的结果:
my_function(x=100)
## A tibble: 3 x 3
# x y z
# <dbl> <dbl> <dbl>
#1 1 5 500
#2 2 10 1000
#3 3 15 1500
您可以使用 {{
运算符,尽管首先避免冲突似乎是避免可能出现的麻烦的更好方法。
library(dplyr)
my_function <- function(x) {
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_tib %>%
mutate(z = {{x}} * y)
}
my_function(100)
# A tibble: 3 x 3
x y z
<dbl> <dbl> <dbl>
1 1 5 500
2 2 10 1000
3 3 15 1500
目前接受的答案中,建议使用curly-curly代替函数参数。
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_function_nse <- function(data, x) {
data %>% mutate(z = {{ x }} * y)
}
这适用于文字数字:
my_tib %>% my_function_nse(100)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
但是,当您使用变量时,您会遇到同样的数据屏蔽问题:
x <- 100
my_tib %>% my_function_nse(x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 5
#> 2 2 10 20
#> 3 3 15 45
这里发生的事情是数据变量 x
优先于环境变量 x
。要解决此问题,用户需要使用强制运算符 !!
:
强制 env-var x
my_tib %>% my_function_nse(!!x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
你也可以在函数内部强制:
my_function_se <- function(data, x) {
data %>% mutate(z = !!x * y)
}
在这种情况下,您的函数根本不使用 NSE。它没有数据屏蔽问题:
my_tib %>% my_function_se(x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
当然,不利的一面是您根本无法引用数据变量:
my_tib %>% my_function_se(y + 10)
#> Error : object 'y' not found
my_tib %>% my_function_nse(y + 10)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 75
#> 2 2 10 200
#> 3 3 15 375
如果我在 data.frame
中有一个列与我的函数的参数之一同名,则在尝试 mutate
或 filter
时使用列名.
有没有办法显式使用函数参数?
可重现的例子:
my_function <- function(x) {
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_tib %>%
mutate(z = x * y)
}
my_function(x=100)
## A tibble: 3 x 3
# x y z
# <dbl> <dbl> <dbl>
#1 1 5 5
#2 2 10 20
#3 3 15 45
想要的结果:
my_function(x=100)
## A tibble: 3 x 3
# x y z
# <dbl> <dbl> <dbl>
#1 1 5 500
#2 2 10 1000
#3 3 15 1500
您可以使用 {{
运算符,尽管首先避免冲突似乎是避免可能出现的麻烦的更好方法。
library(dplyr)
my_function <- function(x) {
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_tib %>%
mutate(z = {{x}} * y)
}
my_function(100)
# A tibble: 3 x 3
x y z
<dbl> <dbl> <dbl>
1 1 5 500
2 2 10 1000
3 3 15 1500
目前接受的答案中,建议使用curly-curly代替函数参数。
my_tib <- tribble(
~x, ~y,
1, 5,
2, 10,
3, 15
)
my_function_nse <- function(data, x) {
data %>% mutate(z = {{ x }} * y)
}
这适用于文字数字:
my_tib %>% my_function_nse(100)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
但是,当您使用变量时,您会遇到同样的数据屏蔽问题:
x <- 100
my_tib %>% my_function_nse(x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 5
#> 2 2 10 20
#> 3 3 15 45
这里发生的事情是数据变量 x
优先于环境变量 x
。要解决此问题,用户需要使用强制运算符 !!
:
x
my_tib %>% my_function_nse(!!x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
你也可以在函数内部强制:
my_function_se <- function(data, x) {
data %>% mutate(z = !!x * y)
}
在这种情况下,您的函数根本不使用 NSE。它没有数据屏蔽问题:
my_tib %>% my_function_se(x)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 500
#> 2 2 10 1000
#> 3 3 15 1500
当然,不利的一面是您根本无法引用数据变量:
my_tib %>% my_function_se(y + 10)
#> Error : object 'y' not found
my_tib %>% my_function_nse(y + 10)
#> # A tibble: 3 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 1 5 75
#> 2 2 10 200
#> 3 3 15 375