I am creating an RC class and while trying to print(.self$something) within a class method I am getting:
Error in print(.self$something) : unused argument (.self$something)
I am sort of new to R, so am I missing something here?
This is for an assignment which asks us to use RC classes, using R6 is not an option.
myclass <- setRefClass("myclass",
fields = list (
formula = "formula",
data = "data.frame",
something = "numeric"
),
methods = list (
initialize = function(formula, data) {
...
},
print = function() {
...
print(.self$something)
},
)
)
a <- myclass$new(formula,data)
a$print()
> Error in print(.self$something) : unused argument (.self$something)
Edit: Extra info, if I try a$something I get what I should get.
Try to use cat in your print function, you are now in your local print function environment and trying to call your system "print" function. I suggest you use cat as follows:
cat(.self$something)
It will do the job
As #Mohammed mentions, this happened because I was in printing within my own print environment. Though cat() could be an option, later I faced other issues in which cat did not print the object (that could be a thread on its own so I will not go deeper on that here).
What I ended up doing was calling the print function for that specific data type. For instance, if something was a data.frame I called print.data.frame(.self$something) and worked as expected.
Related
I can't figure out what I'm missing. Following Situation:
I wrote a R-Package lets call it "pkg_A"
It depends on "Rcpp" and I have a Module loaded and a class set up like :
Rcpp::loadModule("pkg_A_modul", what = "pkg_A_cppClass_A")
cppClass_A <- setRcppClass(
Class = "pkg_A_cppClass_A",
CppClass = "pkg_A_cppClass_A",
module = "pkg_A_modul",
fields = c(
remark = "character"
)
)
and a additional constructor
classA <- function(a,b){
# some stuff
tmpObj <- cppClass_A()
# some more stuff
return(tmpObj)
}
class(classA ) <- "classA "
The only Thing what I export to the NAMESPACE is the classA function/class.
That all works fine and I can build that package without any warnings and even can check it with "--as-cran" flag.
Now I want to build a second package on top of that package, lets call that "pkg_B" Therefore I list "pkg_A" in the DESCRIPTION Depends of "pkg_B"
as well as I load the class with importFrom(pkg_A, classA) in the NAMESPACE of "pkg_B".
Now I want to implement a class
classB <- setRefClass(
"classB",
contains = c("classA"),
fields = c( b = "numeric)
)
But when I now want to build "pkg_B" I get the error:
Error in getClass(what, where = where) : "classA" is not a defined
class
I also tried to use the "pkg_A_cppClass_A" instead or imprt the whole pkg_A or use pkg_A::classA. Nothing changed.
Hope the question is complete enough. If you missing some info let me know.
Thankful for any suggestions!
In R we can simply type the variable name in the console, the console will automatically print out the value. I have created a new S4/RC class define, and would like to create a nicer way to automatically "print" in the console. How do I edit the console printing functions for a new class?
Here is my code in the console:
ClassA<-setRefClass("ClassA",fields=list(value="numeric"))
"print.ClassA"<-function(object){
cat("--------\n")
cat(object$value,"\n")
cat("--------\n")
}
classobject<-ClassA$new(value=100)
classobject # it doesn't print nicely in the console.
#Reference class object of class "ClassA"
#Field "value":
#[1] 100
print(classobject) # this works
#--------
#100
#--------
My goal is to avoid typing "print" all the time; just type the object name in the console, it will print out nicely, just like calling print().
Thanks!
You need to define a show method for your RefClass object. Read ?setRefClass for details regarding how to write methods. This works:
#the print function: note the .self to reference the object
s<-function(){
cat("--------\n")
cat(.self$value,"\n")
cat("--------\n")
}
#the class definition
ClassA<-setRefClass("ClassA",fields=list(value="numeric"),methods=list(show=s))
classobject<-ClassA$new(value=100)
classobject
#--------
#100
#--------
Im trying to manipulate a large data table (~37 MB) but in a special way: for other (unrelated) reasons I have implemented a 'hook' like structure meaning that the overall process is like
1) load the data.table from disk
2) fire a certain hook
3) the hook structure looks for this name ans checks whether the user (=me :)) has bound a function to this hook and if so, it is called
4) the data is processed further
The functions look like this:
data = readRDS(pathToFile)
data = data.table(data)
fireHook("After_data_read", data, [some other parameters])
some_more_processing(data)
and the region around fireHook looks like
hooksRegistered = list(
"After_data_read" = function(data, ...) {
# do some stuff
}
)
fireHook = function(hookName, ...) {
for (hookNameRegistered in names(hooksRegistered)) {
if (hookName == hookNameRegistered) {
func = .global.hooksRegistered[[hookName]]
func(hookName, ...)
}
}
}
Observe that one needs to cast an object that already is a data.table into it again (otherwise the pass-by-reference does not work), see Adding new columns to a data.table by-reference within a function not always working and Pass by reference bug?
Problem: this line: func(hookName, ...) takes like forever (> 5 minutes).
The debugger never really gets into the function (so its not the code in the function that takes a long time) and I've tested it with small data.tables and it worked. Also, I noted that the following seems to work:
fireHook = function(hookName, ...) {
args = list(...)
for (hookNameRegistered in names(.global.hooksRegistered)) {
if (hookName == hookNameRegistered) {
func = .global.hooksRegistered[[hookName]]
func(hookName, args)
}
}
}
(notice that I substituted ... by list(...)). To me, it seems as if R is trying to copy the whole table when using .... Is this right/desired? Or am I using it wrong?
regards,
FW
I'm looking for a way to tell an instance of a reference class to forget one of its method definitions. For example, I create the class MyReferenceClass and an instance called my_object I can call the method print_hello and everything works:
MyReferenceClass <- setRefClass("MyReferenceClass",
methods = list(
print_hello = function(){
print("hello")
}
)
)
my_object <- MyReferenceClass$new()
my_object$print_hello() # "hello"
If I update the class definition by adding a new method (print_goodbye) my existing object will be able to use it. But if I change a previously defined method (print_hello), it won't update:
MyReferenceClass <- setRefClass("MyReferenceClass",
methods = list(
print_hello = function(){
print("hello_again")
},
print_goodbye = function(){
print("goodbye")
}
)
)
my_object$print_goodbye() # "goodbye" => it works
my_object$print_hello() # "hello" => it doesn't work
Is there a way to tell my_object to forget about its definition of print_hello? This doesn't work: my_object$print_hello <<- NULL
AFAIK the answer is no when trying to inform the object about the class def change "after the fact", i.e. after it has been instantiated/created.
Once you created an instance of a S4 Class, that object is "bound" to the class def as it was when you created the object. And in my opinion this makes perfect sense. Not sure if the "successful" update for formerly missing methods (i.e. print_goodbye()) simply works "by accident" or actually is the desired behavior.
Recommended way to deal with updated class defs
My recommendation: if you decide you want/need to update your class defs, you're just safer off by re-sourcing your entire project code. That way you make sure everything is in place before you create actual instances. I'd consider anything else to be quite a hack that stands on very shaky grounds.
If you decide to hack anyway
There might be some dirty way to hack the hidden .refClassDef object field of an Reference Class instance that actually contains the class def (see my_object$.refClassDef). But setting this field (i.e. using <- on it) didn't work:
my_object$.refClassDef <- MyReferenceClass
Error in envRefSetField(x, what, refObjectClass(x), selfEnv, value) :
'.refClassDef' is not a field in class "MyReferenceClass"
Neither did an explicit assignment via assign():
assign(".refClassDef", MyReferenceClass, my_object)
Error in assign(".refClassDef", MyReferenceClass, my_object) :
cannot change value of locked binding for '.refClassDef'
An even deeper hack would probably involve looking at attributes(my_object$.refClassDef).
There you might find the actual pieces that make up the ref class def. However, I don't know if even changing anything there would be "immediately" reflected.
Also, resetClass() might give you some more insights.
UPDATE: 2014-03-19
For handling your caching-approach two approaches come to mind:
1. The most evident way: use copy()
See ?setRefClass
MyReferenceClass <- setRefClass("MyReferenceClass",
methods = list(
print_hello = function(){
print("hello")
}
)
)
my_object <- MyReferenceClass$new()
MyReferenceClass <- setRefClass("MyReferenceClass",
methods = list(
print_hello = function(){
print("hello_again")
},
print_goodbye = function(){
print("goodbye")
}
)
)
Before copying:
my_object$print_hello()
[1] "hello"
After copying:
my_object <- my_object$copy()
my_object$print_hello()
[1] "hello_again"
2. Hacking at attributes(my_object$.refClassDef)$refMethods (OUTLINE, NOT WORKING YET)
Even though I wouldn't recommend actually relying on something like this, hacks are always a great way to get a deeper understanding of how things work.
In this case, we could try to modify attributes(my_object$.refClassDef)$refMethods which is an environment that contains the actual method defs as I'm guessing that this is where the object "looks" when a method is called.
It's no problem overwriting the actual method defs, yet it seems to have no immediate effect. I'm guessing that there are more "links" to the "old" class def involved that would need to be updated manually in a similar way.
Note that my_object still features the method print_hello that prints "hello":
attributes(my_object$.refClassDef)$refMethods$print_hello
Class method definition for method print_hello()
function ()
{
print("hello")
}
This is how an overwriting function might look like:
ensureRecentMethods <- function(obj, classname) {
## Get generator //
gen <- getRefClass(classname)
## Get names of methods belonging to the class of 'obj' //
## This will serve as an index for the update
idx1 <- names(Filter(function(x) {attr(x, "refClassName") == class(obj)},
as.list(attributes(obj$.refClassDef)$refMethods))
)
#idx2 <- names(Filter(function(x) {attr(x, "refClassName")==gen$className},
# as.list(gen$def#refMethods)
#))
## Note:
## 'idx2' could be used to enforce some validity checks such as
## "all old methods must also be present in the updated class def"
## Overwrite //
for (ii in idx1) {
## Note how we are overwriting the old method defs in environment
## 'attributes(obj$.refClassDef)$refMethods' with the updated
## definitions taken from the generator of the updated class
## 'gen$def#refMethods[[ii]]' by making use of the index retrieved
## one step before ('idx1')
expr <- substitute(
assign(x=X, value=VALUE, envir=ENVIR),
list(
X=ii,
VALUE=gen$def#refMethods[[ii]],
ENVIR=attributes(obj$.refClassDef)$refMethods
)
)
eval(expr)
}
## As at the end of the day ref class objects are nothing more than
## environments, there is no need to explicitly return the actual
## ref class object 'obj' as the original object has already
## been updated (pass-by-reference vs. pass-by-value)
return(TRUE)
}
Applying it:
ensureRecentMethods(obj=my_object, classname="MyReferenceClass")
Even though the def of print_hello was indeed overwritten, the object still grabs the "old" version somehow:
attributes(my_object$.refClassDef)$refMethods$print_hello
## Note the updated method def!
Class method definition for method print_hello()
function ()
{
print("hello_again")
}
my_object$print_hello()
[1] "hello"
Take advantage of my_class#generator$def#refMethods
How about including an update method in the original class, as did here,
Manual modifications of the class definition of a Reference Class instance
I have a function in R that looks somewhat like this:
setMethod('[', signature(x="stack"),definition=function(x,i,j,drop){
new('class', as(x, "SpatialPointsDataFrame")[i,]) })
I use it to get a single element out of a stacked object. For the package I'm building I need a .Rd file to document the function. I stored it as [.Rd but somehow the R CMD check does not see this. It returns:
Undocumented S4 methods: generic '[' and siglist 'MoveStack,ANY,ANY'
The [.Rd file starts with these lines:
\name{[}
\alias{[}
\alias{[,stack,ANY,ANY-method}
\docType{methods}
\title{Returns an object from a stack}
\description{Returning a single object}
\usage{
\S4method{\[}{stack,ANY,ANY}(x,i,y,drop)
}
Any idea how I make R CMD check aware of this file?
If you look at the source code of the sp package, for example SpatialPolygons-class.Rd, the Methods section:
\section{Methods}{
Methods defined with class "SpatialPolygons" in the signature:
\describe{
\item{[}{\code{signature(obj = "SpatialPolygons")}: select subset of (sets of) polygons; NAs are not permitted in the row index}
\item{plot}{\code{signature(x = "SpatialPolygons", y = "missing")}:
plot polygons in SpatialPolygons object}
\item{summary}{\code{signature(object = "SpatialPolygons")}: summarize object}
\item{rbind}{\code{signature(object = "SpatialPolygons")}: rbind-like method}
}
}
method for [ is defined.
Name and class of the file are
\name{SpatialPolygons-class}
\alias{[,SpatialPolygons-method}
If you look at the help page for ?SpatialPolygons you should see
> Methods
>
> Methods defined with class "SpatialPolygons" in the signature:
>
> [ signature(obj = "SpatialPolygons"): select subset of (sets of)
> polygons; NAs are not permitted in the row index
>
So I would venture a guess that if you specify a proper (ASCII named) file name, give it an alias as in the above example, you should be fine.