My question has two parts. The first is with regard to the frame or environment in which generic functions are defined in packages. It seems as though they are defined (i.e. exist as objects) in frame 1, even when defined in a package. The following is a short example: setClass("track",representation(x="numeric",y="numeric")) plotTrack <- function(x,y,...) plot(x@x,x@y,xlab="",ylab="Value",...) setGeneric("plotT",def=function(x,y,...) standardGeneric("plotT")) setMethod("plotT",signature(x="track",y="missing"),plotTrack) This which works with my 'examples', as follows: x <- new("track",x=1:10,y=rnorm(10)) plotT(x) The above also passes Rcmd CHECK with the following warnings, which I think are not related to my main question: Undocumented code objects: "plotTrack" Objects with usage in documentation object 'track' but missing from code: "plotT" Slightly more worrying, I get the following: * checking examples ... ERROR Running examples failed. Ignoring this (only for the time being), I now do 'make pkg-track', and encounter no errors. Loading the package, my 'examples' work fine. Returning to the ERROR, it is clear how this has come about. ls(.GlobalEnv) [1] "plotT" So the genericFunction object plotT resides in frame 1 i.e. .GlobalEnv. It gets deleted when cleanEx(env=.GlobalEnv) does its job in Rcmd CHECK. The other object defined in this package, plotTrack, is in frame 2: ls(2) [1] "plotTrack" I have tried unsuccessfully to put the genericFunction object plotT into frame 2, using the 'where' argument in setGeneric. To cut a long story short, I can put it anywhere _except_ frame 2. Now it seems to me that I am barking up the wrong tree, but I don't know how to proceed. Any guidance will be gratefully received. The second part of my question is this. I clearly want to define a plot method (not naming it plotT)for the 'track' class, which indeed is what is described in the 'Green Book' p43. However the 'Green Book' is largely unencumbered by S3 methods AFAIK. Venables & Ripley (2000) addresses the issue of defining an S4 generic on the same name as an S3 generic on p108. setMethod("plot",signature(x="fungi",y="missing"),plot.fungi) This clearly works, but I am not clear whether the definition of an S4 generic 'on top of' i.e. with the same name 'plot' as an S3 generic (as in the example above) is generally regarded as bad practice, or is quite OK. If it is done, is the above a suitable template, or should the 'def' argument be used? I know that the above _works_, I am more looking for guidance on what is regarded as 'good practice' and will not lead to too many problems as the S3->S4 migration proceeds. Any indication of the planned S3->S4 migration path and timetable would be a welcome bonus. I realise that the second question has been aired before in different guises, but I regret to say I still do not know the answer. I am using NT, and R1.7.1, for the above examples. Regards Giles Heywood Portfolio & Risk Advisory Group Commerzbank Securities tel + 44 20 7653 7009 fax + 44 20 7562 5347 mobile + 44 7973 266343 mailto:giles.heywood@commerzbankib.com 60 Gracechurch Street, London EC3V 0HR, U.K. http://www.cbksec.com/rsh/portfolio&risk.html ********************************************************************** This is a commercial communication from Commerzbank AG.\ \ T...{{dropped}}
"Heywood, Giles" wrote:> > My question has two parts. > > The first is with regard to the frame or environment in which generic > functions are defined in packages. It seems as though they are defined > (i.e. exist as objects) in frame 1, even when defined in a package.(Frame 1 is an S-Plus concept; presumably you mean the global environment, the first element in the search path.) It seems likely you are not using the "saved image" option in the INSTALL command, which you should use if your package has S4 classes or methods. The simple solution is to have a file called "install.R" in your main package directory (not in the R/ subdirectory). For most packages, the file can be empty. See the online documentation for INSTALL (but ignore the comment about having require(methods) in the install.R file; this is out of date since the methods package is normally included by default now). Standard calls to setClass, setMethod, etc. will then save the definitions in an image file that is loaded when the package is attached. You need this, otherwise the definitions (currently) go to the global environment. That part will be fixed, but you want to use a saved image anyway, since otherwise the call to library() for the package will be much slower.> > The following is a short example: > > setClass("track",representation(x="numeric",y="numeric")) > plotTrack <- function(x,y,...) plot(x@x,x@y,xlab="",ylab="Value",...) > setGeneric("plotT",def=function(x,y,...) standardGeneric("plotT")) > setMethod("plotT",signature(x="track",y="missing"),plotTrack) > > This which works with my 'examples', as follows: > > x <- new("track",x=1:10,y=rnorm(10)) > plotT(x) > > The above also passes Rcmd CHECK with the following warnings, which I > think are not related to my main question: > > Undocumented code objects: "plotTrack" > Objects with usage in documentation object 'track' but missing from code: > "plotT" > > Slightly more worrying, I get the following: > > * checking examples ... ERROR > Running examples failed. > > Ignoring this (only for the time being), I now do 'make pkg-track', > and encounter no errors. Loading the package, my 'examples' work fine. > Returning to the ERROR, it is clear how this has come about. > > ls(.GlobalEnv) > [1] "plotT" > > So the genericFunction object plotT resides in frame 1 i.e. .GlobalEnv. > It gets deleted when cleanEx(env=.GlobalEnv) does its job in Rcmd CHECK. > > The other object defined in this package, plotTrack, is in frame 2: > > ls(2) > [1] "plotTrack" > > I have tried unsuccessfully to put the genericFunction object plotT into > frame 2, using the 'where' argument in setGeneric. To cut a long story > short, I can put it anywhere _except_ frame 2. > > Now it seems to me that I am barking up the wrong tree, but I don't know > how to proceed. Any guidance will be gratefully received. > > The second part of my question is this. I clearly want to define a plot > method (not naming it plotT)for the 'track' class, which indeed is what > is described in the 'Green Book' p43. However the 'Green Book' is largely > unencumbered by S3 methods AFAIK. Venables & Ripley (2000) addresses the > issue of defining an S4 generic on the same name as an S3 generic on p108. > > setMethod("plot",signature(x="fungi",y="missing"),plot.fungi) > > This clearly works, but I am not clear whether the definition of an S4 > generic > 'on top of' i.e. with the same name 'plot' as an S3 generic (as in the > example > above) is generally regarded as bad practice, or is quite OK. If it is > done, > is the above a suitable template, or should the 'def' argument be used?Generally, an S3 "generic" function (i.e., a function that calls UseMethod()) is not much different from an ordinary function with no S3 methods, so far as defining S4 methods is concerned. Either way setGeneric("plot") creates a new generic function and makes the current function the default method. A call to setMethod() where there is no current S4 generic function for this name does the setGeneric call for you. The call to setGeneric with a `def' argument is usually needed only when there is no function of the same name and/or you do not want an existing function to be called as the default. John> I > know that the above _works_, I am more looking for guidance on what is > regarded as 'good practice' and will not lead to too many problems as the > S3->S4 migration proceeds. Any indication of the planned S3->S4 migration > path > and timetable would be a welcome bonus. > > I realise that the second question has been aired before in different > guises, > but I regret to say I still do not know the answer. > > I am using NT, and R1.7.1, for the above examples. > > Regards > > Giles Heywood > Portfolio & Risk Advisory Group > Commerzbank Securities > > tel + 44 20 7653 7009 > fax + 44 20 7562 5347 > mobile + 44 7973 266343 > mailto:giles.heywood@commerzbankib.com > 60 Gracechurch Street, London EC3V 0HR, U.K. > http://www.cbksec.com/rsh/portfolio&risk.html > > ********************************************************************** > This is a commercial communication from Commerzbank AG.\ \ T...{{dropped}} > > ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-devel-- John M. Chambers jmc@bell-labs.com Bell Labs, Lucent Technologies office: (908)582-2681 700 Mountain Avenue, Room 2C-282 fax: (908)582-3340 Murray Hill, NJ 07974 web: http://www.cs.bell-labs.com/~jmc
Thank you for assistance on this. I have created the empty file "install.R" in the right place, and used Rcmd build its --binary If I then use Rcmd INSTALL its --save Everything works fine, with the generics along with other functions listed when I do ls(2) and not when I do ls(). However if I load the zip using the menu in RGUI,I get different behaviour. When I load the package, I get> local({pkg <- select.list(sort(.packages(all.available = TRUE)))+ if(nchar(pkg)) library(pkg, character.only=TRUE)}) Error in open.connection(con, "rb") : unable to open connection In addition: Warning message: cannot open compressed file `C:/PROGRA~1/R/rw1071/library/its/R/all.rda' Error in library(pkg, character.only = TRUE) : .First.lib failed I have looked at ?install.packages, but cannot see the 'saved image' option, equivalent to --save on Rcmd INSTALL. Is the RGUI installation of the zip file a bad idea? Or perhaps I have missed out some qualifier in the Rcmd build stage? Another issue is the one I referred to before - that Rcmd CHECK still errors on the examples. I can get around it of course using dontrun, but of course this a workaround and not a solution. I have re-read section 1.3 of 'Writing R Extensions' and still can't fathom these out - any further help will be gratefully received. If it is along the lines of RTFM, a page or section reference would be appreciated :) Regards Giles Heywood Portfolio & Risk Advisory Group Commerzbank Securities tel + 44 20 7653 7009 fax + 44 20 7562 5347 mobile + 44 7973 266343 mailto:giles.heywood@commerzbankib.com 60 Gracechurch Street, London EC3V 0HR, U.K. http://www.cbksec.com/rsh/portfolio&risk.html> -----Original Message----- > From: John Chambers [mailto:jmc@research.bell-labs.com] > Sent: 09 July 2003 19:07 > To: Heywood, Giles > Cc: 'r-devel@stat.math.ethz.ch' > Subject: Re: [Rd] Packages, generics, S3 and S4 > > > "Heywood, Giles" wrote: > > > > My question has two parts. > > > > The first is with regard to the frame or environment in > which generic > > functions are defined in packages. It seems as though they > are defined > > (i.e. exist as objects) in frame 1, even when defined in a package. > > (Frame 1 is an S-Plus concept; presumably you mean the global > environment, the first element in the search path.) > > It seems likely you are not using the "saved image" option in the > INSTALL command, which you should use if your package has S4 > classes or > methods. > > The simple solution is to have a file called "install.R" in your main > package directory (not in the R/ subdirectory). For most > packages, the > file can be empty. See the online documentation for INSTALL > (but ignore > the comment about having require(methods) in the install.R > file; this is > out of date since the methods package is normally included by default > now). > > Standard calls to setClass, setMethod, etc. will then save the > definitions in an image file that is loaded when the package is > attached. You need this, otherwise the definitions (currently) go to > the global environment. That part will be fixed, but you > want to use a > saved image anyway, since otherwise the call to library() for the > package will be much slower. > > > > > The following is a short example: > > > > setClass("track",representation(x="numeric",y="numeric")) > > plotTrack <- function(x,y,...) > plot(x@x,x@y,xlab="",ylab="Value",...) > > setGeneric("plotT",def=function(x,y,...) standardGeneric("plotT")) > > setMethod("plotT",signature(x="track",y="missing"),plotTrack) > > > > This which works with my 'examples', as follows: > > > > x <- new("track",x=1:10,y=rnorm(10)) > > plotT(x) > > > > The above also passes Rcmd CHECK with the following > warnings, which I > > think are not related to my main question: > > > > Undocumented code objects: "plotTrack" > > Objects with usage in documentation object 'track' but > missing from code: > > "plotT" > > > > Slightly more worrying, I get the following: > > > > * checking examples ... ERROR > > Running examples failed. > > > > Ignoring this (only for the time being), I now do 'make pkg-track', > > and encounter no errors. Loading the package, my > 'examples' work fine. > > Returning to the ERROR, it is clear how this has come about. > > > > ls(.GlobalEnv) > > [1] "plotT" > > > > So the genericFunction object plotT resides in frame 1 > i.e. .GlobalEnv. > > It gets deleted when cleanEx(env=.GlobalEnv) does its job > in Rcmd CHECK. > > > > The other object defined in this package, plotTrack, is in frame 2: > > > > ls(2) > > [1] "plotTrack" > > > > I have tried unsuccessfully to put the genericFunction > object plotT into > > frame 2, using the 'where' argument in setGeneric. To cut > a long story > > short, I can put it anywhere _except_ frame 2. > > > > Now it seems to me that I am barking up the wrong tree, but > I don't know > > how to proceed. Any guidance will be gratefully received. > > > > The second part of my question is this. I clearly want to > define a plot > > method (not naming it plotT)for the 'track' class, which > indeed is what > > is described in the 'Green Book' p43. However the 'Green > Book' is largely > > unencumbered by S3 methods AFAIK. Venables & Ripley (2000) > addresses the > > issue of defining an S4 generic on the same name as an S3 > generic on p108. > > > > setMethod("plot",signature(x="fungi",y="missing"),plot.fungi) > > > > This clearly works, but I am not clear whether the > definition of an S4 > > generic > > 'on top of' i.e. with the same name 'plot' as an S3 generic > (as in the > > example > > above) is generally regarded as bad practice, or is quite > OK. If it is > > done, > > is the above a suitable template, or should the 'def' > argument be used? > > Generally, an S3 "generic" function (i.e., a function that calls > UseMethod()) is not much different from an ordinary function > with no S3 > methods, so far as defining S4 methods is concerned. > > Either way > > setGeneric("plot") > > creates a new generic function and makes the current function the > default method. A call to setMethod() where there is no current S4 > generic function for this name does the setGeneric call for you. > > The call to setGeneric with a `def' argument is usually > needed only when > there is no function of the same name and/or you do not want > an existing > function to be called as the default. > > John > > > I > > know that the above _works_, I am more looking for guidance > on what is > > regarded as 'good practice' and will not lead to too many > problems as the > > S3->S4 migration proceeds. Any indication of the planned > S3->S4 migration > > path > > and timetable would be a welcome bonus. > > > > I realise that the second question has been aired before in > different > > guises, > > but I regret to say I still do not know the answer. > > > > I am using NT, and R1.7.1, for the above examples. > > > > Regards > > > > Giles Heywood > > Portfolio & Risk Advisory Group > > Commerzbank Securities > > > > tel + 44 20 7653 7009 > > fax + 44 20 7562 5347 > > mobile + 44 7973 266343 > > mailto:giles.heywood@commerzbankib.com > > 60 Gracechurch Street, London EC3V 0HR, U.K. > > http://www.cbksec.com/rsh/portfolio&risk.html > > > > > ********************************************************************** > > This is a commercial communication from Commerzbank AG.\ \ > T...{{dropped}} > > > > ______________________________________________ > > R-devel@stat.math.ethz.ch mailing list > > https://www.stat.math.ethz.ch/mailman/listinfo/r-devel > > -- > John M. Chambers jmc@bell-labs.com > Bell Labs, Lucent Technologies office: (908)582-2681 > 700 Mountain Avenue, Room 2C-282 fax: (908)582-3340 > Murray Hill, NJ 07974 web: > http://www.cs.bell-labs.com/~jmc >********************************************************************** This is a commercial communication from Commerzbank AG.\ \ T...{{dropped}}