3

我正在使用 S4 oop 在 R 中运行土壤水平衡模型,并且创建了 waterBalance 类的对象,我无法从方法中更新槽。这里必须有一些我没有看到的简单的东西。我的更新代码是:

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
        }
    })

我已经测试了这个类的所有其他方法,它们给出了正确的值,没有错误。此方法是唯一尝试更新槽值的方法。

当我创建类 waterBalance 的对象并尝试运行此更新代码时,我得到:

> 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
> 

所以对象实例中的槽值是不变的。你能告诉我哪里出错了吗?

谢谢,
尤安

4

2 回答 2

4

您忘记返回 的修改后的值object。将return(object)orobject放在函数的最后一行。此外,updateASW(object, ...)您需要做的不是

object <- updateASW(object, ...)

即,您必须将更新的对象分配给某些东西。与其他一些语言不同,R 不会就地修改对象(无需大量繁重的工作)。

于 2013-06-20T15:36:19.777 回答
0

此模式的一个变体,假设您编写的任何初始化方法仍然充当复制构造函数,是沿着

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)
})

(尚不清楚是否getInterception并且penmanMonteith正在对其他参数的旧值或新值起作用;在后一种情况下,上述可能不正确)。

于 2013-06-20T18:52:44.217 回答