我需要另一个运算符,其功能与magrittr的%>%相同。
我尝试过
"%myop%" <- function(x,f) do.call(f, list(x))
但它不起作用。
我希望通过左侧的参数来解决右侧的函数,例如:
> p<-10
> p %>% log()
[1] 2.302585
是x%>%f,可以重写为f(x)
x%>%f(a,b)可以重写为f(x,a,b),但这不起作用
如何定义它?
答案 0 :(得分:1)
您可以签出magrittr implementation,但为了公平起见,由于执行了很多操作,因此代码非常复杂。
简而言之,为了支持所需的语义,您需要提取表达式的未经评估的RHS并将未经评估的LHS插入表达式中,然后对其进行评估。
函数调用表达式是一个列表,其中将函数名称作为其第一个元素,并将其其余参数作为后继元素。因此,您需要将LHS值插入该列表的第二个位置。
然后,您需要将结果列表转回通话中-as.call
会这样做:
`%>%` = function (lhs, rhs) {
lhs = substitute(lhs)
rhs = substitute(rhs)
if (is.name(rhs)) {
do.call(as.character(rhs), list(lhs))
} else if (is.call(rhs)) {
rhs = as.list(rhs)
call = as.call(c(rhs[[1L]], list(lhs), rhs[-1L]))
eval.parent(call)
} else {
stop('Unsupported RHS')
}
}
请注意,由于此实现将未经评估的 LHS插入到RHS调用中,因此将从右到左评估链式管道。也就是说,这
(1 : 5) %>% sapply(`*`, 2) %>% sum()
将被转换为:
sum(sapply((1: 5), `*`, 2))
在评估任何组件之前。