\n
An example for formulation: In order to give a specific example for formulation, suppose you have an object char
that is a character string. You want to create a function that is called on a character string using the prefix _#
and suffix #_
and the function adds five dashes to the front of the character string. If programmed successfully, it would operate as shown below.
char\n[1] "Hello"\n\n_#char#_\n[1] "-----Hello"\n
\n","author":{"@type":"Person","name":"Ben"},"upvoteCount":0,"answerCount":2,"acceptedAnswer":{"@type":"Answer","text":"There is a way to do this as long as your special operator takes a particular form, that is .%_% char %_%.
. This is because the parser will interpret the dot as a variable name. If we use non-standard evaluation, we don't need the dot to actually exist, and we only need to use this as a marker for opening and closing our special operator. So we can do something like this:
`%_%` <- function(a, b) \n{\n if((deparse(match.call()$a) != ".") +\n (deparse(match.call()$b) != ".") != 1)\n stop("Unrecognised SPECIAL")\n \n if(deparse(match.call()$a == "."))\n return(`attr<-`(b, "prepped", TRUE))\n \n if(attr(a, "prepped"))\n return(paste0("-----", a))\n \n stop("Unrecognised SPECIAL")\n}\n\n.%_% "hello" %_%.\n#> [1] "-----hello"\n
\nHowever, this is a weird thing to do in R. It's not idiomatic and uses more keystrokes than a simple function call would. It would also very likely cause unpredictable problems in places where non-standard evaluation is used. This is really just a demo to show that it can be done. Not that it should be done.
\n","author":{"@type":"Person","name":"Allan Cameron"},"upvoteCount":4}}}Reputation: 1556
I have read about prefix functions and infix functions on Hadley Wickham's Advanced R website. I would like to know if there is any way to define functions that are called by placing a prefix and suffix around a single argument, so that the prefix and suffix operate like brackets. Is there any way to create a function like this, and if so, how do you do it?
An example for formulation: In order to give a specific example for formulation, suppose you have an object char
that is a character string. You want to create a function that is called on a character string using the prefix _#
and suffix #_
and the function adds five dashes to the front of the character string. If programmed successfully, it would operate as shown below.
char
[1] "Hello"
_#char#_
[1] "-----Hello"
Upvotes: 0
Views: 636
Reputation: 206566
Writing a simple function seems like a more R-like solution. If terseness is a priority, then maybe something like
._ <- function(x) paste0("-----", x)
._("hello")
# [1] "-----hello"
Or if you wanted something more bracket-like
.. <- structure(list(NULL), class="dasher")
`[.dasher` <- function(a, x) paste0("-----", x)
..["hello"]
# [1] "-----hello"
Another way to use a custom class would be to redefine the -
operator to paste that value in front of the string. For example
literal <- function(x) {class(x)<-"literal"; x}
`-.literal` <- function(e1, e2) {literal(paste0("-", unclass(e1)))}
print.literal <- function(x) print(unclass(x))
Then you can do
val <- literal("hello")
-----val
# [1] "-----hello"
---val
# [1] "---hello"
So here the number of -
you type is the number you get in the output.
You can get creative/weird with syntax, but you need to make sure whatever symbols you come up with can be parsed by the parser otherwise you are out-of-luck.
Upvotes: 3
Reputation: 174536
There is a way to do this as long as your special operator takes a particular form, that is .%_% char %_%.
. This is because the parser will interpret the dot as a variable name. If we use non-standard evaluation, we don't need the dot to actually exist, and we only need to use this as a marker for opening and closing our special operator. So we can do something like this:
`%_%` <- function(a, b)
{
if((deparse(match.call()$a) != ".") +
(deparse(match.call()$b) != ".") != 1)
stop("Unrecognised SPECIAL")
if(deparse(match.call()$a == "."))
return(`attr<-`(b, "prepped", TRUE))
if(attr(a, "prepped"))
return(paste0("-----", a))
stop("Unrecognised SPECIAL")
}
.%_% "hello" %_%.
#> [1] "-----hello"
However, this is a weird thing to do in R. It's not idiomatic and uses more keystrokes than a simple function call would. It would also very likely cause unpredictable problems in places where non-standard evaluation is used. This is really just a demo to show that it can be done. Not that it should be done.
Upvotes: 4