简体   繁体   English

如何使用 dplyr 和点椭圆编写嵌套函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM