Dear All....I am really struggling with oo in R. Trying to set attributes of
the base class in a derived class method but the slot is only populated in
the method itself, not when I try to print out the object from the console.
Code is
library(RODBC)
#
# -----------------------------------------------------
# Define a medical event class. This is abstract (VIRTUAL)
# -----------------------------------------------------
#
setClass("Medical_Event",
representation(
Event_Name="character",
Capacity_Profile="numeric",
Delay_Profile="numeric",
"VIRTUAL"),
prototype(Event_Name="An
Event",Capacity_Profile=c(.2,.2,.2,.2,.2,0,0)))
setGeneric("getDelayProfile",function(object){standardGeneric("getDelayProfile")},simpleInheritanceOnly=T)
# ------------------------------------------
# Now define a derived class called GP_Event
# ------------------------------------------
setClass("GP_Event",representation(Surgery_Name="character"),contains=c("Medical_Event"),prototype(Surgery_Name="Unknown"))
# -----------------------------------------
# Now define a derived class called OP_Appt
# -----------------------------------------
setClass("OP_Appt",representation(Clinic_Name="character"),contains=c("Medical_Event"),prototype(Clinic_Name="Unknown"))
setMethod(f="getDelayProfile",signature("OP_Appt"),definition=function(object)
{
OpTablesDB<-odbcDriverConnect("DRIVER=Microsoft Access Driver
(*.mdb,
*.accdb);
DBQ=Z:\\srp\\Development
Code\\Projects\\CancerPathwaySimulation\\Database\\CancerPathway.accdb")
strQuery<-"select * from op_profile"
odbcQuery(OpTablesDB,strQuery)
dfQuery<-odbcFetchRows(OpTablesDB)
odbcClose(OpTablesDB)
delay<-dfQuery$data[[1]][1:70]
prob<-dfQuery$data[[2]][1:70]
# as(object,"Medical_Event")@Delay_Profile<-prob
object at Delay_Profile <- prob
object
}
)
if I instantiate a new instance of the derived class
*aTest<-new("OPP_Appt")*and then try and populate the attribute
Delay_Profile by
*getDelayProfile(aTest) *
the object slot seems to be populated in the method because I can print it
out, viz
An object of class "OP_Appt"
Slot "Clinic_Name":
[1] "Unknown"
Slot "Event_Name":
[1] "An Event"
Slot "Capacity_Profile":
[1] 0.2 0.2 0.2 0.2 0.2 0.0 0.0
*Slot "Delay_Profile":
[1] 14 21 25 29 27 49 72 71 43 65 102 134 223 358 24 14 21 25
35 31 38 43 31 23 21 26 46 54 42 26
[31] 34 24 25 41 48 33 30 17 18 31 24 35 35 24 16 32 36 39
46 36 26 16 27 21 30 32 33 27 7 5
[61] 9 10 9 11 8 6 1 11 14 10*
but when the method returns and I type
*aTest*
I get
An object of class "OP_Appt"
Slot "Clinic_Name":
[1] "Unknown"
Slot "Event_Name":
[1] "An Event"
Slot "Capacity_Profile":
[1] 0.2 0.2 0.2 0.2 0.2 0.0 0.0
*Slot "Delay_Profile":
numeric(0)*
ie the Delay_Profile slot is empty????
What haven't I done - can anybody help me please?
Many Thanks
Steve Creamer
--
View this message in context:
http://r.789695.n4.nabble.com/Setting-Derived-Class-Slots-tp4671683.html
Sent from the R help mailing list archive at Nabble.com.
On 07/16/2013 06:36 AM, Steve Creamer wrote:> Dear All....I am really struggling with oo in R. Trying to set attributes of > the base class in a derived class method but the slot is only populated in > the method itself, not when I try to print out the object from the console. > > Code is > > library(RODBC) > # > # ----------------------------------------------------- > # Define a medical event class. This is abstract (VIRTUAL) > # ----------------------------------------------------- > # > setClass("Medical_Event", > representation( > Event_Name="character", > Capacity_Profile="numeric", > Delay_Profile="numeric", > "VIRTUAL"), > prototype(Event_Name="An > Event",Capacity_Profile=c(.2,.2,.2,.2,.2,0,0))) > > setGeneric("getDelayProfile",function(object){standardGeneric("getDelayProfile")},simpleInheritanceOnly=T) > > # ------------------------------------------ > # Now define a derived class called GP_Event > # ------------------------------------------ > > setClass("GP_Event",representation(Surgery_Name="character"),contains=c("Medical_Event"),prototype(Surgery_Name="Unknown")) > > # ----------------------------------------- > # Now define a derived class called OP_Appt > # ----------------------------------------- > > setClass("OP_Appt",representation(Clinic_Name="character"),contains=c("Medical_Event"),prototype(Clinic_Name="Unknown")) > > > setMethod(f="getDelayProfile",signature("OP_Appt"),definition=function(object) > { > OpTablesDB<-odbcDriverConnect("DRIVER=Microsoft Access Driver (*.mdb, > *.accdb); > DBQ=Z:\\srp\\Development > Code\\Projects\\CancerPathwaySimulation\\Database\\CancerPathway.accdb") > strQuery<-"select * from op_profile" > odbcQuery(OpTablesDB,strQuery) > dfQuery<-odbcFetchRows(OpTablesDB) > odbcClose(OpTablesDB) > delay<-dfQuery$data[[1]][1:70] > prob<-dfQuery$data[[2]][1:70] > # as(object,"Medical_Event")@Delay_Profile<-prob > object at Delay_Profile <- prob > object > } > ) > > if I instantiate a new instance of the derived class > > *aTest<-new("OPP_Appt")*and then try and populate the attribute > Delay_Profile by > > *getDelayProfile(aTest) * > > the object slot seems to be populated in the method because I can print it > out, viz > > An object of class "OP_Appt" > Slot "Clinic_Name": > [1] "Unknown" > > Slot "Event_Name": > [1] "An Event" > > Slot "Capacity_Profile": > [1] 0.2 0.2 0.2 0.2 0.2 0.0 0.0 > > *Slot "Delay_Profile": > [1] 14 21 25 29 27 49 72 71 43 65 102 134 223 358 24 14 21 25 > 35 31 38 43 31 23 21 26 46 54 42 26 > [31] 34 24 25 41 48 33 30 17 18 31 24 35 35 24 16 32 36 39 > 46 36 26 16 27 21 30 32 33 27 7 5 > [61] 9 10 9 11 8 6 1 11 14 10* > > but when the method returns and I type > > *aTest* > > I get > > An object of class "OP_Appt" > Slot "Clinic_Name": > [1] "Unknown" > > Slot "Event_Name": > [1] "An Event" > > Slot "Capacity_Profile": > [1] 0.2 0.2 0.2 0.2 0.2 0.0 0.0 > > *Slot "Delay_Profile": > numeric(0)* > > ie the Delay_Profile slot is empty???? > > What haven't I done - can anybody help me please?It helps to provide a more minimal example, preferably reproducible (no data base queries needed to illustrate your problem); I'm guessing that, just as with f = funtion(l) { l$a = 1; l } lst = list(a=0, b=1) one would 'update' lst with lst = f(lst) and not f(lst) you need to assign the return value to the original object aTest <- getDelayProfile(aTest) Martin> Many Thanks > > Steve Creamer > > > > > -- > View this message in context: http://r.789695.n4.nabble.com/Setting-Derived-Class-Slots-tp4671683.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help at 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. >-- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793
Hi Steve,
it seems to me, that you want to pass an object inside of getDelayProfile. In
this case you must use setReplaceMethod("getDelayProfile<-",....)
in your definition inside the virtual and of course also in the specification of
OP_Appt. R does not know, that your function should give back an object, that
replaces the one on which it was called.
Otherwise making any modifications on the slot of the object inside the function
will never arrive at the object outside of the function. They have two different
environments and as soon as you modify an object inside of a function R builds a
copy of it. See more about this by googling R pass-by-value.
By the way: I wouldn't call this function getDelayProfile as getters and
setters have usually differing a different meaning (encapsulation) in OO
programming. Use rather something like fetchDelayProfile or
initializeDelayProfile. It will probably make it easier for Users and
Programmers to work with your program.
Hope this helps
Best
Simon
On Jul 16, 2013, at 3:36 PM, Steve Creamer <stephen.creamer@nhs.net>
wrote:
>
[[alternative HTML version deleted]]