R使用匿名函数进行流水线操作

时间:2012-11-17 17:24:22

标签: r pipeline

我有一个问题是another question的扩展名。

我希望能够管道匿名函数。在前一个问题中,管道定义函数的答案是创建一个管道运算符“%|>%”并以这种方式定义它:

"%|>%" <- function(fun1, fun2){
              function(x){fun2(fun1(x))}
}

这将允许您在继续将前一个函数的结果传递给下一个函数的同时调用一系列函数。需要注意的是要预定义的功能。现在我试图用匿名函数来计算如何做到这一点。以前使用预定义函数的解决方案如下所示:

square <- function(x){x^2}
add5 <- function(x){x + 5}

pipelineTest <-
  square %|>%
  add5

这给了你这个行为:

> pipelineTest(1:10)
 [1]   6   9  14  21  30  41  54  69  86 105

我希望能够使用这样的匿名函数定义pipelineTest函数:

anonymousPipelineTest <-
  function(x){x^2} %|>%
  function(x){x+5} %|>%
  x

当我尝试用与上面相同的参数调用它时,我得到以下内容:

> anonymousPipelineTest(1:10)
function(x){fun2(fun1(x))}
<environment: 0x000000000ba1c468>

我希望得到的结果与pipelineTest(1:10)相同。我知道这是一个微不足道的例子。我真正想要的是一种管道匿名函数的方法。谢谢你的帮助!

3 个答案:

答案 0 :(得分:4)

使用Compose,并调用结果函数给出:

"%|>%" <- function(...) Compose(...)()

现在摆脱'x'作为最后的“功能”(用实际功能代替,不需要,但在这里例如):

anonymousPipelineTest <-
     function(x){x^2} %|>%
     function(x){x+5} %|>% function(x){x}
anonymousPipelineTest(1:10)

[1]   6   9  14  21  30  41  54  69  86 105

答案 1 :(得分:0)

这是?funprog帮助页面上提供的示例的应用程序:

Funcall <- function(f, ...) f(...)
anonymousPipelineTest <- function(x) Reduce( Funcall, list(
    function(x){x+5}, function(x){x^2}), 
    x, right=TRUE)
 anonymousPipelineTest(1:10)
 #[1]   6   9  14  21  30  41  54  69  86 105

答案 2 :(得分:0)

我正在提出一个答案,这是我找到的其他寻找同样事情的人最接近的答案。我不会给自己指出答案,因为它不是我想要的。

返回功能 如果你想把几个函数放在一起,我发现的最简单的事情就是使用R''Functional'包中的'Compose'函数。它看起来像这样:

anonymousPipe <- Compose(
  function(x){x^2},
  function(x){x+5})

这允许您像这样调用这一系列函数:

> anonymousPipe(1:10)
 [1]   6   9  14  21  30  41  54  69  86 105

返回数据 如果您只想从一些数据开始并通过一系列转换(我的原始意图)发送它,那么'Compose'函数中的第一个函数应该是您的起始数据,并且在'Compose'函数关闭之后添加用于调用函数的括号对。它看起来像这样:

anonymousPipeData <- Compose(
  seq(1:10),
  function(x){x^2},
  function(x){x+5})()

'anonymousPipeData'现在是一系列函数的结果。请注意最后的一对括号。这是导致R返回数据而不是函数的原因。