dplyr 的函数,参数默认为“.”
function for dplyr with argument that defaults to "."
假设我想对 tibble 中的所有列求和以创建一个名为 "total" 的新列。我能做到:
library(tibble)
library(dplyr)
set.seed(42)
N <- 10
Df <- tibble(p_1 = rnorm(N),
p_2 = rnorm(N),
q_1 = rnorm(N),
q_2 = rnorm(N))
# Works fine
Df %>% mutate(total = apply(., 1, sum))
我可以像这样制作一个辅助函数,
myfun <- function(Df){
apply(Df, 1, sum)
}
# Works fine
Df %>% mutate(total = myfun(.))
但是假设这个 myfun
通常以这种方式使用,即在 dplyr
动词功能中,然后是 "."引用数据框是多余的,如果 myfun
函数可以用默认值替换它就好了。我想要这样的东西:
myfun2 <- function(Df=.){
apply(Df, 1, sum)
}
这不起作用。
Df %>% mutate(total = myfun2())
Error in mutate_impl(.data, dots) :
Evaluation error: object '.' not found.
因为我什至不确定“.”是怎么来的有效,我不认为我可以更好地表述问题,但基本上,我想知道是否有一种说法,实际上,如果 Df
没有在 myfun2
中定义,得到通常由“.”引用的数据框?
一个选项是 quote
函数,然后用 !!
求值
library(tidyverse)
myfun <- function() {
quote(reduce(., `+`))
}
r1 <- Df %>%
mutate(total = !! myfun())
r1
# A tibble: 10 x 5
# p_1 p_2 q_1 q_2 total
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1.37 1.30 -0.307 0.455 2.82
# 2 -0.565 2.29 -1.78 0.705 0.645
# 3 0.363 -1.39 -0.172 1.04 -0.163
# 4 0.633 -0.279 1.21 -0.609 0.960
# 5 0.404 -0.133 1.90 0.505 2.67
# 6 -0.106 0.636 -0.430 -1.72 -1.62
# 7 1.51 -0.284 -0.257 -0.784 0.186
# 8 -0.0947 -2.66 -1.76 -0.851 -5.37
# 9 2.02 -2.44 0.460 -2.41 -2.38
#10 -0.0627 1.32 -0.640 0.0361 0.654
请注意,reduce
用于更符合 tidyverse
,但也可以引用 OP 的函数并获得相同的结果
myfun2 <- function() {
quote(apply(., 1, sum ))
}
r2 <- Df %>%
mutate(total = !! myfun2())
all.equal(r2$total, r1$total)
#[1] TRUE
假设我想对 tibble 中的所有列求和以创建一个名为 "total" 的新列。我能做到:
library(tibble)
library(dplyr)
set.seed(42)
N <- 10
Df <- tibble(p_1 = rnorm(N),
p_2 = rnorm(N),
q_1 = rnorm(N),
q_2 = rnorm(N))
# Works fine
Df %>% mutate(total = apply(., 1, sum))
我可以像这样制作一个辅助函数,
myfun <- function(Df){
apply(Df, 1, sum)
}
# Works fine
Df %>% mutate(total = myfun(.))
但是假设这个 myfun
通常以这种方式使用,即在 dplyr
动词功能中,然后是 "."引用数据框是多余的,如果 myfun
函数可以用默认值替换它就好了。我想要这样的东西:
myfun2 <- function(Df=.){
apply(Df, 1, sum)
}
这不起作用。
Df %>% mutate(total = myfun2())
Error in mutate_impl(.data, dots) :
Evaluation error: object '.' not found.
因为我什至不确定“.”是怎么来的有效,我不认为我可以更好地表述问题,但基本上,我想知道是否有一种说法,实际上,如果 Df
没有在 myfun2
中定义,得到通常由“.”引用的数据框?
一个选项是 quote
函数,然后用 !!
library(tidyverse)
myfun <- function() {
quote(reduce(., `+`))
}
r1 <- Df %>%
mutate(total = !! myfun())
r1
# A tibble: 10 x 5
# p_1 p_2 q_1 q_2 total
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1.37 1.30 -0.307 0.455 2.82
# 2 -0.565 2.29 -1.78 0.705 0.645
# 3 0.363 -1.39 -0.172 1.04 -0.163
# 4 0.633 -0.279 1.21 -0.609 0.960
# 5 0.404 -0.133 1.90 0.505 2.67
# 6 -0.106 0.636 -0.430 -1.72 -1.62
# 7 1.51 -0.284 -0.257 -0.784 0.186
# 8 -0.0947 -2.66 -1.76 -0.851 -5.37
# 9 2.02 -2.44 0.460 -2.41 -2.38
#10 -0.0627 1.32 -0.640 0.0361 0.654
请注意,reduce
用于更符合 tidyverse
,但也可以引用 OP 的函数并获得相同的结果
myfun2 <- function() {
quote(apply(., 1, sum ))
}
r2 <- Df %>%
mutate(total = !! myfun2())
all.equal(r2$total, r1$total)
#[1] TRUE