What is setReplaceMethod () and how does it work?

I am confused about using setReplaceMethod() . A look at ?setReplaceMethod provides no explanation, and Google is equally useful.

QUESTION Please explain setReplaceMethod() , its use and how it works (preferably with an example).

+7
r s4
source share
2 answers

Here is what I found. As @Hong Ooi pointed out in the comments, setReplaceMethod("fun") same as setMethod("fun<-") , so setReplaceMethod used to create a method for a common replacement function in an S4 object system R.

What is a replacement function is explained in what-are-replacement-functions-in-r . It's very rude if you have a function called fun<- , because its name ends with <- , you can write fun(x)<-a , and R will read x <- "fun<-"(x,a)

The S4 object system is described in S4 - Advanced R.

To give an example, it’s easier to start by creating a method for the general function S4, which is not a replacement function:

 ## Define an S4 class 'Polygon' and an object of this class setClass("Polygon", representation(sides = "integer")) p1 <- new("Polygon", sides = 33L) ## Define a generic S4 function 'sides' sides <- function(object){ NA } setGeneric("sides") ## sides returns NA sides( p1 ) ## Define a method for 'sides' for the class 'Polygon' setMethod("sides", signature(object = "Polygon"), function(object) { object@sides }) ## Now sides returns the sides of p1 sides( p1 ) 

Creating a method for a common replacement function is similar to:

 ## Define a generic replacement function 'sides<-' "sides<-" <- function(object, value){ object } setGeneric( "sides<-" ) ## The generic 'sides<-' doesn't change the object sides( p1 ) <- 12L sides( p1 ) ## Define a method for 'sides<-' for the class 'Polygon', ## setting the value of the 'sides' slot setMethod( "sides<-", signature(object = "Polygon"), function(object, value) { object@sides <- value object }) ## Now 'sides<-' change the sides of p1 sides( p1 ) <- 12L sides( p1 ) 

You also asked about $<- . I assume the following: x$name<-value interpreted as "$"(x,name)<-value , and then as x <- "$<-"(x,name,value) . Note that the generic $<- function $<- already defined ( isGeneric("$<-") ), so we only define a method for our Polygon class:

 setMethod( "$<-", signature(x = "Polygon"), function(x, name, value) { if( name=="sides" ){ x@sides <- value } x }) ## Nothing changes if we try to set 'faces' p1$faces <- 3L p1 ## but we can set the 'sides' p1$sides <- 3L p1 

Note that the arguments x , name and value dictated by a common one.

+4
source share

For an extraction method, such as $ , [ or names() , a replacement method, such as $<- , [<- or names<- , replaces the value that would be extracted.

Take for example the list:

 example_object <- list(a = 1, b = 2) # the extract method $, when called with arguments example_object and a, # extracts and returns the value 1 example_object$a # [1] 1 # the replace method $<-, when called with arguments example_object, a, and 42, # replaces the value 1 (at example_object$a) with the value 42 example_object$a <- 42 example_object # $a # [1] 42 # # $b # [1] 2 

So, for S4 classes, setMethod("$", ...) will determine the behavior of the $ extraction method, and setMethod("$<-", ...) or equivalently setReplaceMethod("$", ...) will determine the replacement method’s behavior $<- . setReplaceMethod("$") should be more expressive than setMethod("$<-") so that it is clear that you are defining a replacement method for $ .

An example of using the S4 class:

 setClass("MyClass", representation(a = "numeric", b = "numeric")) setMethod("$", signature = "MyClass", function (x, name) { if ( name == "a" ) { return( x@a ) } else if ( name == "b" ) { return( x@b ) } else { stop(paste("No slot", name, "for MyClass"), call. = FALSE) } } ) # [1] "$" my_object <- new("MyClass", a = 1, b = 2) my_object@a # [1] 1 my_object$a # [1] 1 my_object@a <- 42 my_object@a # [1] 42 my_object$a <- 3.14 # will not work because we have not set the method for $<- # Error in `$<-`(`*tmp*`, a, value = 3.14) : # no method for assigning subsets of this S4 class my_object@a # [1] 42 setReplaceMethod("$", signature = "MyClass", function(x, name, value) { if ( name == "a" ) { x@a <- value return(x) } else if ( name == "b" ) { x@b <- value return(x) } else { stop(paste("No slot", name, "for MyClass"), call. = FALSE) } } ) # [1] "$<-" my_object$a <- 3.14 my_object@a # [1] 3.14 
+5
source share

All Articles