我可以在R中创建一个组合操作符:
`%c%` = function(x,y)function(...)x(y(...))
像这样使用:
> numericNull = is.null %c% numeric
> numericNull(myVec)
[2] TRUE FALSE
但是我想知道是否有一个官方的函数集来做这类事情和其他操作,比如在R中进行currying。主要是为了减少我代码中括号,函数关键字等的数量。
我的咖喱功能:
> curry=function(...){
z1=z0=substitute(...);z1[1]=call("list");
function(...){do.call(as.character(z0[[1]]),
as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"
这对于聚合物来说尤其有用:
> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
我觉得它比:
> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
基本上我想知道--这已经对R做过了吗?
6条答案
按热度按时间qc6wkl3g1#
这两个函数实际上都存在于Peter Danenberg的the
roxygen
package(see the source code here)中(最初基于Byron Ellis's solution on R-Help):注意
Reduce
函数的用法,当尝试在R中进行函数式编程时,它会非常有帮助。更多细节请参见?Reduce(它还涵盖了其他函数,如Map
和Filter
)。你举的咖喱的例子(在这个用法上略有不同):
下面的例子展示了
Compose
的实用性(对字母应用三个不同的函数):最后一个例子是这样的:
最后,这里有一种方法可以对
plyr
执行相同的操作(如前所述,也可以轻松地对by
或aggregate
执行相同的操作):92vpleto2#
现在,R中函数式编程的标准位置是
functional
库。从库中:
函数:Curry、Compose和其他高阶函数
示例:
起重机:https://cran.r-project.org/web/packages/functional/index.html
PS:这个库替代了
ROxigen
库。qnyhuwrf3#
roxygen包中有一个名为咖喱的函数。
通过R Mail Archive上的this conversation找到。
pdsfdshx4#
如果您希望变量的“名称”准确地传递,则需要更复杂的方法。
例如,如果你使用
plot(rnorm(1000),rnorm(1000))
,那么你会在x轴和y轴上得到漂亮的标签。并不是说data.frame已经为列指定了有用的名称。
咖喱的一些实现可能无法正确地做到这一点,导致列名和图标签不可读。
这是相当复杂的,但我认为它是正确的。
match.call
将捕获所有的参数,完全记住哪些表达式定义了这些参数(这对于漂亮的标签是必要的)。问题是它捕获了太多的参数--不仅仅是...
,还有FUN
。它还记住了正在调用的函数的名称(Curry
)。因此,我们希望删除
.orig
中的前两个条目,这样.orig
就能真正对应...
的参数,这就是为什么我们执行.orig[[1]]<-NULL
两次--每次删除一个条目,并将其他所有内容左移。这就完成了定义,现在我们可以执行以下操作以获得与上面 * 完全 * 相同的结果
关于
envir=parent.frame()
的最后一点说明。我用它来确保如果你有一个叫做.inner或. orig的外部变量不会有问题。现在,所有的变量都在咖喱被调用的地方求值。wgxvkvu95#
在package purrr中,现在有一个函数partial
s8vozzvw6#
如果你已经在使用tidyverse的purrr包,那么purrr::partial是一个自然的选择,从purrr::partial的描述可以看出: