我正在使用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
>
因此对象实例中的槽值不变。你能告诉我哪里出错了吗?
谢谢,
尤安
答案 0 :(得分:3)
您忘记返回object
的修改值。将return(object)
或object
作为函数的最后一行。另外,您需要执行
updateASW(object, ...)
object <- updateASW(object, ...)
即,您必须将更新的对象分配给某个东西。与其他一些语言不同,R不会就地修改对象(没有太多繁重的工作)。
答案 1 :(得分:0)
this pattern上的一个变体,假设您编写的任何初始化方法仍然充当复制构造函数,那就是
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
是否对其他参数的旧值或新值起作用;在后一种情况下,上述情况可能不正确。)