Infix Functions in R: Write Your Own %op% Operators
An infix function sits between its two arguments: x + y instead of `+`(x, y). R lets you create custom infix operators using the %name% syntax.
You use infix operators constantly: +, -, *, %>%, %in%, <-. What most R users don't know is that you can define your own. Any function named %something% automatically works as an infix operator.
Built-in Infix Operators
Every operator in R is actually a function. You can call them in prefix form.
Creating Custom Infix Operators
Define a function with a name wrapped in %...% and backticks.
Practical Custom Operators
Default Value Operator
Not-In Operator
Approximate Equality
How the Pipe Operators Work
The pipe operators %>% and |> are just infix functions (though |> is a language-level construct).
Rules for Custom Operators
| Rule | Example |
|---|---|
Must start and end with % |
%op%, %+%, %between% |
Name goes inside the % signs |
%myop% |
| Must be defined with backticks | ` %myop% <- function(a, b) ... ` |
| Always takes exactly 2 arguments | Left operand and right operand |
Can contain letters, numbers, . |
%do.call%, %v2% |
Practice Exercises
Exercise 1: Range Check Operator
Create a %within% operator that checks if values fall within a named range.
Click to reveal solution
```rSummary
| Operator | Purpose | Package | ||
|---|---|---|---|---|
%>% |
Forward pipe | magrittr | ||
%in% |
Membership test | base | ||
%% |
Modulo | base | ||
%*% |
Matrix multiply | base | ||
%o% |
Outer product | base | ||
| `% | %` | Null coalescing | rlang/custom | |
%+% |
ggplot2 layer add | ggplot2 |
FAQ
Are custom operators slower than regular functions?
No. An infix operator is just a regular function with special syntax. There is no performance penalty.
Can I override built-in operators like + or *?
Yes, but you shouldn't for primitive types. You can define methods for custom S3/S4 classes: "+.myclass" <- function(a, b) .... Overriding for base types creates confusing code.
Why do custom operators need % signs?
The %...% syntax is R's way of distinguishing user-defined infix operators from built-in ones. Without it, the parser wouldn't know if myop is a variable or an operator.
What's Next?
- Functional Programming in R — the parent tutorial
- R Function Operators — compose, negate, and partial
- Operator Overloading in R — define +, -, == for custom classes