I have an S3 object in R, something like:
myObject <- list(
someParameter1 = 4,
someList = 1:10
)
class(myObject) <- "myClass"
I created an extraction method for this class:
"[.myClass" <- function(x, i) {
x$someList[i] * x$someParameter1
}
myObject[5]
# 20
Now I want to create an assignment method (from ?Extract
I understand that's called a subassignment), so that I can write:
myObject[5] <- 250
myObject[5]
# 1000
I first naively tried to write this as
"[<-.myClass" <- function(x, i, value) {
x$someList[i] <- value
}
but for some reason this replaces myObject
with value
. I suspect I must modify x
and then assign("someName", x, pos=somewhere)
, but how can I reliably determine someName
and somewhere
?
Or is there an different way to do this?
You need to return x
:
"[<-.myClass" <- function(x, i, value) {
x$someList[i] <- value
x
}
If you don't use return
in your function call, the value of the last evaluated expression will be returned. In the case of your original function, the value of the expression is value
. To illustrate:
"[<-.myClass" <- function(x, i, value) {
print(x$someList[i] <- value)
x
}
myObject[5] <- 250
# [1] 250
To complement Joshua Ulrich's excellent answer, the reason you need to return x
is because R translates
myObject[5] <- 250
into
myObject <- `[<-.myClass`(myObject, 5, 250)
It is immediately clear why you need to return x
(which was myObject
outside the function): the return value is assigned to myObject.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With