dataminingblues
dataminingblues

Reputation: 21

Binary operator %&% in R where quotation marks are optional

These are the instructions I have:

Create a binary operator %&% that will concatenate two strings as a single string with a space as a separator. Write an operator function in which the quotation marks around the terms are optional. The following output is for quoted and/or unquoted arguments.

> Hello %&% World 

[1] “Hello World” 

> “Hello” %&% “World”

[1] “Hello World” 

I built a function that concatenates two strings when put in quotes,

"%&%" = function(x,y) {
  if(is.character(x) || is.character(y))
    return(paste(x , y, sep=" "))
}

but the function does not work if you put > Hello %&% World. How do I get it to accept that argument?

Upvotes: 1

Views: 1481

Answers (2)

IRTFM
IRTFM

Reputation: 263451

This is fairly simple and seems to do the trick.

"%&%" = function(x,y) {
  paste( as.character(substitute(x)) ,as.character(substitute(y)) )
    }
 Hello %&% World
#[1] "Hello World"
 'Hello' %&% 'World'
#[1] "Hello World"

as.character will return a character value from either an expression or a character value. Same caveat applies as given by MrFlick this will not succeed with any arguments that the parser would interpret as compound.

 Hello %&% World View
Error: unexpected symbol in "Hello %&% World View"

If you wanted to give it rudimentary vector capability you would need to evaluate the arguments. Here's a definition that would do so for the second argument:

"%&%" = function(x,y) {
    paste( as.character(substitute(x)) , if( length(substitute(y)) == 1) {                                          
                                                as.character(substitute(y))} else{ 
                                                       eval(substitute(y))} )
                       }

Hello %&% c(123,234)
[1] "Hello 123" "Hello 234"

The first version would have returned [1] "Hello c(123, 234)"

Upvotes: 2

MrFlick
MrFlick

Reputation: 206486

You could maybe do something like this

"%&%" = function(x,y) {
  x = substitute(x)
  y = substitute(y)
  if (!is.character(x)) x <- deparse(x)
  if (!is.character(y)) y <- deparse(y)
  if(is.character(x) || is.character(y))
    return(paste(x , y, sep=" "))
}

which works with

Hello %&% World
# [1] "Hello World"
"Hello" %&% World
[1] "Hello World"

But this is a very fragile solution. Note that the arguments that get passed to this function must be proper symbol names otherwise the R parser cannot process the command.

Upvotes: 2

Related Questions