【问题标题】:How to write nested functions with dplyr and dots elipse?如何使用 dplyr 和点省略号编写嵌套函数?
【发布时间】:2019-01-28 12:01:41
【问题描述】:

我试图把它尽可能简单

一些样本数据:

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,但我厌倦了它,我需要你的帮助。


编辑:Chris 找到了一个聪明而简单的技巧来纠正我的foo.each 函数。在这种情况下,有没有更自然的方法来处理... 椭圆?

例如,有没有比这更好的方法在函数开头获取args

  args <- sapply(substitute(list(...))[-1], deparse)

【问题讨论】:

  • 我有时也会厌倦它。 foo(df, !!sym(args[i]), !!sym(args[j])) %&gt;% print 是否符合您的预期?
  • 是的!你做到了...写它作为答案,我会接受它

标签: r dplyr nested nse


【解决方案1】:

您的 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 2020-04-23
    • 2011-03-04
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多