Append arguments to an s4 Class - r

Suppose, one forgets to set validity in an s4 class definition, how could one "append" this argument without rewriting the entire class.
Illustration:
setClass("test",slots = c(Taken="numeric",Data="data.frame"))
x<-new("test",Taken=123,Data=data.frame(GPA=0.02,Score=0.01))
Now, suppose I would like to check validity:
validity.test<-function(object){
if(!all(sapply(object#Data,is.numeric))){
print("Data must be all numeric")
} else print(TRUE)
}
I could just call validity.test(x).
However, how do I set it to test without rewriting test?!
We are working on the assumption that someone is new(like me) to s4 and is therefore likely to forget doing this. If the script is so many lines, this can easily get tiresome.
Thanks in advance!

There is a function to do exactly this; it is called setValidity. Just call it with the name of your class and the desired validity checking function.

Related

mget cannot get primitive function like get

I can use get to get primitive function, like:
get('$')
.Primitive("$")
However, mget failed:
mget('$')
Error: value for ‘$’ not found
Why? How to fix this?
The default for get is to use inherits = TRUE (I think, based on the docs, for historical reasons), while the default for mget is inherits = FALSE. So using inherits = TRUE should make it work like get.
If you'd like a really detailed (but also very very good) dive into exactly what's happening here read this. Or just skip to the "Map of the World" section, and remember that $, being a primitive function, is in the environment of the of the base namespace (package:base, essentially).

Why to pass a template parameter in Qt method

I'm trying to read some example code about implicit creation of QVariants from enum values.
About the following line of code:
QVariant::fromValue<Qt::PenStyle>(Qt::SolidLine)
I don't really understand what is the purpose of Qt::PenStyle in the above expression.
I think Qt::SolidLine is unique.
The syntax is OK?
Shouldn't it be something like:
QVariant::fromValue(Qt::SolidLine)
?
Sorry if this question seems dumb.
You can use this form:
1) QVariant::fromValue(Qt::SolidLine)
QVariant::fromValue(const T & value) is a template method. When you call a template method or function you can specify for what type of argument this method should be called. If you don't do that a compiler tries to do it for you. That is why 1) is equal to this:
2) QVariant::fromValue<Qt::PenStyle>(Qt::SolidLine)
But you can call this method for int and pass enum value (if you are not at c++11):
3) QVariant::fromValue<int>(Qt::SolidLine)
or even force creating of QPen:
4) QVariant::fromValue<QPen>(Qt::SolidLine)
EDIT:
If someone is suprised by 4 and want to know how it works: it is the same as if there was a method (actually it is created during the compilation):
QVariant::fromValue(const QPen& pen);
When you call this method with Qt::SolidLine compiler uses an implicit constructor QPen(Qt::PenStyle style) to create a new temporary QPen object and pass it as an argument to the method fromValue.

How to avoid prepending .self when using eval in a reference class in R?

I need to use eval to call a reference class method. Below is a toy example:
MyClass <- setRefClass("MyClass",
fields = c("my_field"),
methods = list(
initialize = function(){
my_field <<- 3
},
hello = function(){
"hello"
},
run = function(user_defined_text){
eval(parse(text = user_defined_text))
}
)
)
p <- MyClass$new()
p$run("hello()") # Error: could not find function "hello" - doesn't work
p$run(".self$hello()") # "hello" - it works
p$run("hello()") # "hello" - now it works?!
p <- MyClass$new()
p$run("my_field") # 3 - no need to add .self
I guess I could do eval(parse(text = paste0(".self$", user_defined_text))), but I don't really understand:
why is .self needed to eval methods, but not fields?
why is .self no longer needed after it has been used once?
'Why' questions are always challenging to answer; usually the answer is 'because'. On ?setRefClass we eventually have
Only methods actually used will be included in the environment
corresponding to an individual object. To declare that a method
requires a particular other method, the first method should
include a call to '$usingMethods()' with the name of the other
method as an argument. Declaring the methods this way is essential
if the other method is used indirectly (e.g., via 'sapply()' or
'do.call()'). If it is called directly, code analysis will find
it. Declaring the method is harmless in any case, however, and may
aid readability of the source code.
I'm not sure this is entirely helpful in your case, where the user is apparently able to specify any method. Offering a little unasked editorial comment, I'm not sure 'why' you'd want to write a method that would parse input text to methods; I've never used that paradigm myself.

How is R passing parameters here?

I'm not that much of an OOP guy, so could someone please explain this simple concept in layman terms.
When I call foo.child from the foo.parent function, it seems to pass the A=7 argument
down into the foo.child object and overrides or takes precedence over the A=3 default argument in foo.child as I would expect.
foo.parent <- function(A=7) foo.child(A)
foo.child <- function(A=3) 2+A
foo.parent(A=7)
#[1] 9
But when I instantiate it inside of foo.parent, the parameter A=7 does pass down or force the instantiated object to use A=7; instead it uses the child object's parameter of A=3
foo.child<-function(A=3) 2+A
foo.parent <- function(A=7){
foo.child(A=3)
}
foo.parent(A=7)
#[1] 5
Why does that happen? And what terminology would I use to describe the differences?
In your second example you do not give a value to A (At least not in such a way as you might thought). Try
foo.child<-function(A=3) 2+A
foo.parent<-function(A=7){
foo.child(A=A)
}
foo.parent(A=7)
foo.parent()
instead. So, you mix here two different As. The =sign within a function call defines, what happens if you do not give a value for that variable in the function call.
I think your problem is you don't quite understand how default arguments work. So
foo.child = function(A=1) 2+A
defines the function foo.child that has a default argument A=1. So,
foo.child()
gives 3. Now in this function
foo.parent = function(A=3){
foo.child(A=4)
}
you are always passing the value A=4 to the function foo.child, hence,
foo.parent(A=7)
# 6
Also, when you are trying to figure out what is happening, it's helpful to have different values of A

Setting Global variables inside reference class in R

I'm a bit confused on global variable assignments after reading quite a lot of stack overflow questions. I have gone through
Global variables in R and other similar questions
I have the following situation. I have 2 global variables current_idx and previous_idx. These 2 global variables are being set by a method in a reference class.
Essentially, using <<- assignment operator should work right ? But, I get this warning
Non-local assignment to non-field names (possibly misspelled?)
Where am I going wrong ?
EDIT
Using assign(current_idx, index, envir = .GlobalEnv) works i.e. I do not get the warning. Can some one shed some light on this.
You are confusing "global variables" and Reference Classes which are a type of environment. Executing <<- will assign to a variable with that name in the parent.frame of the function. If you are only one level down from the .GlobalEnv, it will do the same thing as your assign statement.
If you have a Reference Class item you can assign items inside it by name with:
ref_item$varname <- value
Easier said than done, though. First you need to set up the ReferenceClass properly:
http://www.inside-r.org/r-doc/methods/ReferenceClasses
This is happening because the default method for modifying fields of a reference class from within a reference class method is to use <<-. For example, in:
setRefClass(
"myClass",
fields=list(a="integer"),
methods=list(setA=function(x) a <<- x)
)
You can modify the a field of your reference class via the setA method. Because this is the canonical way of setting fields via methods in reference classes, R assumes that any other use of <<- within a reference method is a mistake. So if you try to assign to a variable that exists in an environment other than the reference class, R "helpfully" warns you that maybe you have a typo since it thinks the only probably use of <<- in a reference method is to modify a reference field.
You can still just assign to global objects with <<-. The warning is just a warning that maybe you are doing something you didn't intend to do. If you intended to write to an object in the global environment, then the warning doesn't apply.
By using assign you are bypassing the check that reference methods carry out to make sure you are not accidentally typoing a field name in an assignment within the reference method, so you don't get the warning. Also, note that assign actually targets the environment you supply, whereas <<- will just find the first object of that name in the lexical search path.
All this said, there are really rare instances where you actually want a reference method do be writing directly to the global environment. You may need to rethink what you are doing. You should ask yourself why those two variables are not just fields in the reference class instead of global variables.

Resources