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.