[英]How to write nested functions with dplyr and dots elipse?
I am trying to put this as simple as possible我试图把这个尽可能简单
Some sample data :一些示例数据:
library(magrittr)
library(dplyr)
library(rlang)
# sample data
tib <- tibble(
a = 1:3,
b = 4:6,
c = 7:9
)
Now a function that makes the sum of two columns:现在是一个对两列求和的函数:
foo = function(df, x, y) {
x <- enquo(x)
y <- enquo(y)
df %>%
select( !! x, !! y) %>%
mutate(sum = !! x + !! y)
}
Hopefully it works:希望它有效:
foo(tib, a, b) # to show it works
# A tibble: 3 x 3
# a b sum
# <int> <int> <int>
# 1 1 4 5
# 2 2 5 7
# 3 3 6 9
Now I want to write a second function with non-fixed number of arguments, which calls foo
with all possible pairs of arguments:现在我想用非固定数量的参数编写第二个函数,它使用所有可能的参数对调用
foo
:
foo.each(tib, a, b, c)
# calls foo(tib, a, b)
# calls foo(tib, a, c)
# calls foo(tib, b, c)
# i.e calls foo for each possible pair
I've tried this but that does NOT work:我试过这个,但这不起作用:
foo.each = function(df, ...) {
args <- sapply(substitute(list(...))[-1], deparse)
args
nb.args <- args %>% length
for (i in nb.args:2)
for (j in 1:(i - 1))
foo(df, args[i], args[j]) %>% print
}
The issue is inside of foo:问题出在 foo 内部:
mutate(sum = !! x + !! y)
I think that it is evaluated as:我认为它被评估为:
mutate(sum = args[i] + args[j])
I have tried many things included usage of rlang::quos
but I am sick of it and I need your help.我尝试了很多事情,包括使用
rlang::quos
但我厌倦了它,我需要你的帮助。
Edit : Chris has found a clever and simple trick to correct my foo.each
function.编辑:克里斯找到了一个聪明而简单的技巧来纠正我的
foo.each
函数。 Is there a more natural way to deal with the ...
elipse in this case?在这种情况下,有没有更自然的方法来处理
...
椭圆?
For example is there a better way to get args
at the begining of the function than this?例如,有没有比这更好的方法在函数的开头获取
args
?
args <- sapply(substitute(list(...))[-1], deparse)
Your foo
function is expecting variable names to be passed to it, while you are attempting to pass args[i]
to it which are strings.您的
foo
函数期望将变量名传递给它,而您正试图将args[i]
传递给它,它们是字符串。
A combination of sym
and unquoting !!
sym
和 unquoting 的组合!!
does the trick:诀窍:
foo.each = function(df, ...) {
args <- sapply(substitute(list(...))[-1], deparse)
args
nb.args <- args %>% length
for (i in nb.args:2)
for (j in 1:(i - 1))
foo(df, !!sym(args[i]), !!sym(args[j])) %>% print
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.