2014-07-11 26 views
8

在R用户定义的运营商是允许的,但似乎只有% %类似的运营商被接受。是否有可能绕过此限制来定义运营商,例如>>或与% %不相似的运营商?是否可以定义没有%%的运算符?

运营商必须是真正的运营商,以便我们可以像1 >> 2那样使用它,而不必像">>"(1,2)那样使用它。

+1

,你只能使用引号或反引号访问它。即使如此,很少以方便的方式。例如:'\'>> \'<- \'+\'; ">>“(4,2)' – A5C1D2H2I1M1N2O1R2T1

+0

是:查看'sos :: ???'或'cgwtools :: splatnd'的例子,但要注意所有警告回答和评论 –

回答

4

你可以做这样的事情,但你可能想分配这些对象到一个新的环境是安全的。

> "^" <- function(x, y) `-`(x, y) ## subtract y from x 
> 5^3 
# [1] 2 

> "?" <- function(x, y) sum(x, y) ## add x and y 
> 5 ? 5 
# [1] 10 
+5

这些只是因为你正在重新分配一个退出的操作符(即'^'用于指数运算而'?'通常用于帮助)。如果你尝试使用一组不同的符号像'<<'解析器不会理解并且会抛出一个错误,根据其标准定义,重新分配其他函数可能不是一个好主意 – MrFlick

+1

@MrFlick虽然这是一个重要的警告,请参阅我的答案,以便仔细覆盖操作符,它可以解决这个限制 –

+1

你也可以把它分配给不同的环境,对吗?它自己的环境。 –

12

编号R只允许

  1. 重新定义现有的运算符(如+或实际上<-),
  2. 通过与%…%围绕它们定义新的中缀运算符。

这些是我们必须玩的规则。但是,在这些规则中,所有的都是公平的和游戏。例如,我们可以重新定义+对字符串进行串联,而不会破坏其正常的意义(除了):

> `+` 
function (e1, e2) .Primitive("+") 

这是旧的定义,这是我们希望保留的数字:

> `+.default` = .Primitive('+') 
> `+.character` = paste0 
> `+` = function (e1, e2) UseMethod('+') 
> 1 + 2 
[1] 3 
> 'hello' + 'world' 
[1] "helloworld" 

这利用R中的S3类系统在其第一个参数的类型上使+泛型。

因此可以重新定义的运算符列表是相当不拘一格的。在第一次计数,它包含以下运算符:

+-*/^**&|::::::$$<-=<-<<-==<,<=,>,>=,!=,~, &&||!???@@<-

(从modules source code服用。)

此外,还可以通过重新定义<-覆盖->。这似乎是它很少会意义 - 但是这至少一个很好的例子存在,定义更简洁lambda表达式:即使你没有使用``>>作为一个经营者

> sapply(1 : 4, x -> 2 * x) 
[1] 2 4 6 8 

Implementation as a gist

相关问题