Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an assignment method for an S3 object?

Tags:

r

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?

like image 631
Calimo Avatar asked Mar 21 '23 20:03

Calimo


2 Answers

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 
like image 87
Joshua Ulrich Avatar answered Mar 31 '23 14:03

Joshua Ulrich


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.

like image 34
Calimo Avatar answered Mar 31 '23 16:03

Calimo