如何使用 dplyr 和点省略号编写嵌套函数?
How to write nested functions with dplyr and dots elipse?
我尽量把它说得简单一些
一些示例数据:
library(magrittr)
library(dplyr)
library(rlang)
# sample data
tib <- tibble(
a = 1:3,
b = 4:6,
c = 7:9
)
现在是一个计算两列之和的函数:
foo = function(df, x, y) {
x <- enquo(x)
y <- enquo(y)
df %>%
select( !! x, !! y) %>%
mutate(sum = !! x + !! y)
}
希望它有效:
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
现在我想编写第二个参数数量不固定的函数,它用所有可能的参数对调用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
我已经试过了,但是没有用:
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
}
问题出在 foo 内部:
mutate(sum = !! x + !! y)
我认为评价为:
mutate(sum = args[i] + args[j])
我尝试了很多东西,包括 rlang::quos
的用法,但我受够了,我需要你的帮助。
Edit : Chris 找到了一个巧妙而简单的技巧来纠正我的 foo.each
函数。在这种情况下,有没有更自然的方法来处理 ...
省略号?
例如,有没有比这个更好的方法来在函数的开头获取 args
?
args <- sapply(substitute(list(...))[-1], deparse)
您的 foo
函数期望将变量名传递给它,而您正试图将 args[i]
传递给它,这是字符串。
sym
和取消引用 !!
的组合可以达到目的:
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
}
我尽量把它说得简单一些
一些示例数据:
library(magrittr)
library(dplyr)
library(rlang)
# sample data
tib <- tibble(
a = 1:3,
b = 4:6,
c = 7:9
)
现在是一个计算两列之和的函数:
foo = function(df, x, y) {
x <- enquo(x)
y <- enquo(y)
df %>%
select( !! x, !! y) %>%
mutate(sum = !! x + !! y)
}
希望它有效:
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
现在我想编写第二个参数数量不固定的函数,它用所有可能的参数对调用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
我已经试过了,但是没有用:
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
}
问题出在 foo 内部:
mutate(sum = !! x + !! y)
我认为评价为:
mutate(sum = args[i] + args[j])
我尝试了很多东西,包括 rlang::quos
的用法,但我受够了,我需要你的帮助。
Edit : Chris 找到了一个巧妙而简单的技巧来纠正我的 foo.each
函数。在这种情况下,有没有更自然的方法来处理 ...
省略号?
例如,有没有比这个更好的方法来在函数的开头获取 args
?
args <- sapply(substitute(list(...))[-1], deparse)
您的 foo
函数期望将变量名传递给它,而您正试图将 args[i]
传递给它,这是字符串。
sym
和取消引用 !!
的组合可以达到目的:
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
}