Re: [R] Change value of a slot of an S4 object within a method.
OK, I admit. It will never win a beauty price, but I won't either so we go pretty well together. Seriously, I am aware this is about the worst way to solve such a problem. But as I said, rewriting the class definitions wasn't an option any more. I'll definitely take your advice for the next project. Cheers Joris On Wed, Aug 25, 2010 at 9:36 PM, Steve Lianoglou mailinglist.honey...@gmail.com wrote: Howdy, My eyes start to gloss over on their first encounter of `substitute` ... add enough `eval`s and (even) an `expression` (!) to that, and you'll probably see me running for the hills ... but hey, if it makes sense to you, more power to you ;-) Glad you found a fix that works, -steve -- Steve Lianoglou Graduate Student: Computational Systems Biology | Memorial Sloan-Kettering Cancer Center | Weill Medical College of Cornell University Contact Info: http://cbio.mskcc.org/~lianos/contact -- Joris Meys Statistical consultant Ghent University Faculty of Bioscience Engineering Department of Applied mathematics, biometrics and process control tel : +32 9 264 59 87 joris.m...@ugent.be --- Disclaimer : http://helpdesk.ugent.be/e-maildisclaimer.php __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] Change value of a slot of an S4 object within a method.
Hi Joris, On Wed, Aug 25, 2010 at 11:56 AM, Joris Meys jorism...@gmail.com wrote: Dear all, I have an S4 class with a slot extra which is a list. I want to be able to add an element called name to that list, containing the object value (which can be a vector, a dataframe or another S4 object) Obviously setMethod(add.extra,signature=c(PM10Data,character,vector), function(object,name,value){ obj...@extra[[name]] - value } ) Contrary to what I would expect, the line : eval(eval(substitute(expression(obj...@extra[[name]] - value gives the error : Error in obj...@extra[[name]] - value : object 'object' not found Substitute apparently doesn't work any more in S4 methods... I found a work-around by calling the initializer every time, but this influences the performance. Returning the object is also not an option, as I'd have to remember to assign that one each time to the original name. Basically I'm trying to do some call by reference with S4, but don't see how I should do that. How would I be able to tackle this problem in an efficient and elegant way? In lots of my own S4 classes I define a slot called .cache which is an environment for this exact purpose. Using this solution for your scenario might look something like this: setMethod(add.extra,signature=c(PM10Data,character,vector), function(object, name, value) { obj...@.cache$extra[[name]] - value }) I'm not sure what your entire problem looks like, but to get your extra list, or a value form it, you could: setMethod(extra, signature=PM10Data, function(object, name=NULL) { if (!is.null(name)) { obj...@.cache$extra[[name]] } else { obj...@.cache$extra }) ... or something like that. The last thing you have to be careful of is that you nave to make sure that each new(PM10Data) object you have initializes its *own* cache: setClass(PM10Data, representation(..., .cache='environment')) setMethod(initialize, PM10Data, function(.Object, ..., .cache=new.env()) { callNextMethod(.Object, .cache=.cache, ...) }) Does that make sense? -- Steve Lianoglou Graduate Student: Computational Systems Biology | Memorial Sloan-Kettering Cancer Center | Weill Medical College of Cornell University Contact Info: http://cbio.mskcc.org/~lianos/contact __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] Change value of a slot of an S4 object within a method.
Hi Steve, thanks for the tip. I'll definitely take a closer look at your solution for implementation for future use. But right now I don't have the time to start rewriting my class definitions. Luckily, I found where exactly things were going wrong. After reading into the documentation about the evaluation in R, I figured out I have to specify the environment where substitute should look explicitly as parent.frame(1). I still don't understand completely why exactly, but it does the job. Thus : eval(eval(substitute(expression(obj...@extra[[name]] - value should become : eval( eval( substitute( expression(obj...@extra[[name]] - value) ,env=parent.frame(1) ) ) ) Tried it out and it works. Cheers Joris On Wed, Aug 25, 2010 at 6:21 PM, Steve Lianoglou mailinglist.honey...@gmail.com wrote: Hi Joris, On Wed, Aug 25, 2010 at 11:56 AM, Joris Meys jorism...@gmail.com wrote: Dear all, I have an S4 class with a slot extra which is a list. I want to be able to add an element called name to that list, containing the object value (which can be a vector, a dataframe or another S4 object) Obviously setMethod(add.extra,signature=c(PM10Data,character,vector), function(object,name,value){ obj...@extra[[name]] - value } ) Contrary to what I would expect, the line : eval(eval(substitute(expression(obj...@extra[[name]] - value gives the error : Error in obj...@extra[[name]] - value : object 'object' not found Substitute apparently doesn't work any more in S4 methods... I found a work-around by calling the initializer every time, but this influences the performance. Returning the object is also not an option, as I'd have to remember to assign that one each time to the original name. Basically I'm trying to do some call by reference with S4, but don't see how I should do that. How would I be able to tackle this problem in an efficient and elegant way? In lots of my own S4 classes I define a slot called .cache which is an environment for this exact purpose. Using this solution for your scenario might look something like this: setMethod(add.extra,signature=c(PM10Data,character,vector), function(object, name, value) { obj...@.cache$extra[[name]] - value }) I'm not sure what your entire problem looks like, but to get your extra list, or a value form it, you could: setMethod(extra, signature=PM10Data, function(object, name=NULL) { if (!is.null(name)) { obj...@.cache$extra[[name]] } else { obj...@.cache$extra }) ... or something like that. The last thing you have to be careful of is that you nave to make sure that each new(PM10Data) object you have initializes its *own* cache: setClass(PM10Data, representation(..., .cache='environment')) setMethod(initialize, PM10Data, function(.Object, ..., .cache=new.env()) { callNextMethod(.Object, .cache=.cache, ...) }) Does that make sense? -- Steve Lianoglou Graduate Student: Computational Systems Biology | Memorial Sloan-Kettering Cancer Center | Weill Medical College of Cornell University Contact Info: http://cbio.mskcc.org/~lianos/contact __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] Change value of a slot of an S4 object within a method.
Howdy, On Wed, Aug 25, 2010 at 1:21 PM, Joris Meys jorism...@gmail.com wrote: Hi Steve, thanks for the tip. I'll definitely take a closer look at your solution for implementation for future use. But right now I don't have the time to start rewriting my class definitions. Luckily, I found where exactly things were going wrong. After reading into the documentation about the evaluation in R, I figured out I have to specify the environment where substitute should look explicitly as parent.frame(1). I still don't understand completely why exactly, but it does the job. Thus : eval(eval(substitute(expression(obj...@extra[[name]] - value should become : eval( eval( substitute( expression(obj...@extra[[name]] - value) ,env=parent.frame(1) ) ) ) My eyes start to gloss over on their first encounter of `substitute` ... add enough `eval`s and (even) an `expression` (!) to that, and you'll probably see me running for the hills ... but hey, if it makes sense to you, more power to you ;-) Glad you found a fix that works, -steve -- Steve Lianoglou Graduate Student: Computational Systems Biology | Memorial Sloan-Kettering Cancer Center | Weill Medical College of Cornell University Contact Info: http://cbio.mskcc.org/~lianos/contact __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.