简体   繁体   中英

Update value of a slot within an R class method

I am using S4 oop to run a soil water balance model in R, and having created an object of class waterBalance I cannot update slots from within a method. There has to be something simple here that I am not seeing. My update code is:

setGeneric(name="updateASW",def=function(object,...){standardGeneric("updateASW")})

setMethod(f = "updateASW",
signature(object = "WaterBalance"),
    function(object, radiationI, rainfallI, maxTI, minTI, laiTI, laiWI, monthI, yearI) {
        object@maxT<-maxTI
        object@minT<-minTI
        object@laiT<-laiTI
        object@laiW<-laiWI
        object@month<-monthI
        object@year<-yearI
        object@radiation<-radiationI
        object@precipitation<-rainfallI
        object@availableSoilWater<-object@availableSoilWater+rainfallI-getInterception(object)-penmanMonteith(object)
        if (object@availableSoilWater>object@ASWMax) {
            object@availableSoilWater<-object@ASWMax
        }
        if (object@availableSoilWater<object@ASWMin) {
            object@availableSoilWater<-object@ASWMin
        }
    })

I have tested all the other methods for this class and they are giving correct values with no errors. This method is the only one that tries to update slot values.

When I create an object of class waterBalance and try to run this update code I get:

> testWB<-makeWB(100,200,50,"loam",0.02,0.02,58,300,25,-2,15)
> testWB
 ASW =  100 
 ASW Max =  200 
 ASW Min =  50 
 LAI of trees =  3 
 LAI of weeds =  0 
 Soil type =  loam 
 Radiation =   
 Rainfall =   
 Max T =   
 Min T =   
 Latitude =  58 
 Altitude =  300 
 Gs Max for trees =  0.02 
 Gs Max for weeds =  0.02 
 Maximum temp for Ps =  25 
 Minimum temp for Ps =  -2 
 OPtimum temp for Ps =  15
> updateASW(testWB, 25, 0, 25, 10, 6, 0, 7, 2004)
> testWB
 ASW =  100 
 ASW Max =  200 
 ASW Min =  50 
 LAI of trees =  3 
 LAI of weeds =  0 
 Soil type =  loam 
 Radiation =   
 Rainfall =   
 Max T =   
 Min T =   
 Latitude =  58 
 Altitude =  300 
 Gs Max for trees =  0.02 
 Gs Max for weeds =  0.02 
 Maximum temp for Ps =  25 
 Minimum temp for Ps =  -2 
 OPtimum temp for Ps =  15
> 

So the slot values in the object instance are unchanged. Can you please tell me where I am going wrong?

Thanks,
Euan

You forgot to return the modified value of object . Put return(object) or just object as the last line in your function. Also, instead of updateASW(object, ...) , you need to do

object <- updateASW(object, ...)

ie, you have to assign the updated object to something. Unlike some other languages, R doesn't modify objects in-place (without a lot of heavy lifting).

A variant on this pattern , assuming that any initialize method you've written still acts as a copy constructor, is along the lines of

setMethod(f = "updateASW",
signature(object = "WaterBalance"),
    function(object, radiationI, rainfallI, maxTI, minTI, laiTI, laiWI, monthI,
             yearI) 
{
    availableSoilWater<-object@availableSoilWater + rainfallI -
        getInterception(object) - penmanMonteith(object)
    if (availableSoilWater > object@ASWMax) {
        availableSoilWater <- object@ASWMax
    }
    if (availableSoilWater < object@ASWMin) {
        availableSoilWater <- object@ASWMin
    }
    initialize(object, maxT=maxTI, minT=minTI, laiT=laiTI, laiW=laiWI,
               month=monthI, year=yearI, radiation=radiationI,
               precipitation=rainfallI, availableSoilWater=availableSoilWater)
})

(it's not clear whether getInterception and penmanMonteith are acting on old or new values of the other arguments; in the latter case the above may not be correct).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM