Define an S3 method for a generic class

165 Views Asked by At

I would like to create a + method to paste character objects. One possible approach is by doing it with an infix operator:

`%+%` <- function(x, y) paste0(x, y)
"a" %+% "b" # returns "ab"

However, I'm wondering if it is possible to do the same with an S3 method. You could do it by creating a new class, let's say char, and do something like:

# Create a function to coerce to class 'char'
as.char <- function(x, ...) structure(as.character(x, ...), class = "char")

# S3 method to paste 'char' objects
"+.char" <- function(x, y) paste0(x, y)

a <- as.char("a")
b <- as.char("b")

c(class(a), class(b)) # [1] "char" "char"

a + b # returns "ab"

But, if you try to create a +.character method, it does not work:

"+.character" <- function(x, y) paste0(x, y)

a <- "a"
b <- "b"

c(class(a), class(b)) # [1] "character" "character"

a + b # Error in a + b : non-numeric argument to binary operator

However, if you assign the class character manually it does work:

as.character_ <- function(x, ...) structure(as.character(x, ...), class = "character")

a <- as.character_("a")
b <- as.character_("b")

c(class(a), class(b)) # [1] "character" "character"

a + b # returns "ab"

So I'm just wondering what I'm missing here, and if it is possible to actually define an S3 method for a generic class.

Edit: Based on @Csd answer, it is not clear that this is due to the attributes, because if you define your own function, e.g.:

concat <- function(e1, e2) UseMethod("concat")

concat.character <- function(e1, e2) paste0(e1, e2)

concat("a", "b") # returns "ab"

Then it does work.

1

There are 1 best solutions below

1
On

It seems that you need to define the class of the variable to be "character". That's exactly what you do! except one thing... which I didn't know either...

Here is an example:

a <- "a"
class(a) # "character"
attributes(a) # NULL!!!

while using you function:

a <- as.character_("a")
class(a) # "character"
attributes(a) # "class" is "character"

So it seems that it has to be defined the attribute class of the variable.