For an extraction method such as $
, [
, or names()
, a replacement method such as $<-
, [<-
, or names<-
replaces the value that would have been extracted.
Take, for example, a 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 define the behavior of the extraction method $
while setMethod("$<-", ...)
or equivalently setReplaceMethod("$", ...)
will define the behavior of the replacement method $<-
. setReplaceMethod("$")
is just meant to be more expressive than setMethod("$<-")
, to make clear that you are defining the replacement method for $
.
An example using an 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