What is the difference between new() and setClass() in R? - r

I am curious as to what the functional difference is between between new() and setClass() in R?
I answered another question that seems to suggest that they operate identically, except that new() is potentially far less "restrictive."

You can refer to this link in the description on top of the page and the Value section:
r documentation setClass
From the link:
A generator function suitable for creating objects from the class is
returned, invisibly. A call to this function generates a call to new
for the class. The call takes any number of arguments, which will be
passed on to the initialize method. If no initialize method is defined
for the class or one of its superclasses, the default method expects
named arguments with the name of one of the slots and unnamed
arguments that are objects from one of the contained classes.
Typically the generator function is assigned the name of the class,
for programming clarity. This is not a requirement and objects from
the class can also be generated directly from new. The advantages of
the generator function are a slightly simpler and clearer call, and
that the call will contain the package name of the class (eliminating
any ambiguity if two classes from different packages have the same
name).
If the class is virtual, an attempt to generate an object from either
the generator or new() will result in an error.

The two functions have completely different side effects. You need to call setClass when you are defining a class. You can't just do
new("square",x=0,y=0,side=1) -> mySquare
and expect R to know what a square is (you will get an error along the lines of "undefined class 'square'"). If you do
setClass("square",
slots=c(
x="numeric",
y="numeric",
side="numeric"
)
) -> square
mySquare <- square(x=0,y=0,side=1)
then you have defined the class square and can then call the function square to create objects from it. You can also at this point call new("square",...) as well but the effect is the same.
If you want to create a constructor function that doesn't just take slot names as arguments, then the recommended approach is to create an ordinary function along the lines of
createSquare <- function(r,theta,side){
square(x=r*cos(theta),y=r*sin(theta),side=side)
}

Related

setGeneric for a list of objects

I have the following function:
myFunction = function(objects,params) {
for (i in 1:length(objects)) {
object = objects[[i]]
object = myOtherFunction(objects, params)
objects[[i]] = object
}
return (objects)
}
#' #rdname myFunction
#' #aliases myFunction
setMethod("myFunction", signature(object ="list"), myFunction)
How can I properly set the setMethod() and setGeneric() methods to accept a list of objects of a given type, let's say a list of objects of type SingleCellExperiment ?
If you want to write different methods to handle lists of class foo and lists of class bar then S4 will need some help, since both objects are of class list and hence the same method will be called in both cases.
There are a few options:
firstly, do you need to use lists at all? Don't forget all the base types in R are vectors, so for simple classes like
setClass("cuboid",slots=list(
height="numeric",
width="numeric",
depth="numeric"
)) -> cuboid
if you want to represent a set of multiple cuboids you don't need to use a list at all, just feed vectors of values to cuboid. This doesn't work as well for more exotic classes, though.
alternatively, you can write a list method with some extra logic to determine which lower-order method to dispatch. You should also think about what to do if the list contains objects of multiple different classes.
in some situations you might be able to use either lapply or a function that takes arbitrary numbers of arguments via .... In the latter case you may be able to make use of dotsMethods (check the help page on that topic for more info).
If you want to write a method that will only be called on lists of objects of class foo and there may exist another method that wants to operate on lists, then you can either:
write a method for class foo directly, and then use sapply or lapply rather than calling your function on the list
write a method for class list that checks whether the list has foos in it and if it doesn't, calls nextMethod.

R like str() function in matlab/GNU Octave

I'd like to be able to view the structure of objects in Matlab/GNU Octave the same way as I do in R (using the str() function). Is there a function that does this? An example task would be returning nr rows and cols in matrix, but also all the arguments for a given function.
I'm aware that I could use both size() and help() (but not for function files) separately to get this information.
There are several useful functions for displaying some information about Matlab objects (I can't say anything about Octave compatibility), but I'm not sure they'll provide the same detail as R's str(). You can display all of the methods of a class with the methods function, e.g.:
methods('MException')
which returns
Methods for class MException:
addCause getReport ne throw
eq isequal rethrow throwAsCaller
Static methods:
last
The what function will return similar results. Or methods can be used on an object of a given class:
ME = MException('Test:test','Testing');
methods(ME)
Similarly, you can view the properties with properties and the events with events.

Add extra arguments to implicit S4 generic for a primitive function

Take the function names: that's a primitve function in R. For primitive functions, an implicit S4 generic is created, so it is possible to construct S4 methods for that function.
Take an S4 class defined as follows :
setClass("aClass",
representation=list(
values = "character",
id = "numeric"
),
prototype=list(
values = character(0),
id = numeric(0)),
validity=function(object){
length(object#values)==length(object#id)
}
)
Now I want to create a function to extract the names, either sorted or unsorted. I wanted to do this using the function names to avoid having to make a new function getNames() or whatever, as that's less intuitive.
The following gives an idea of what needs to be done:
setMethod("names",signature="aClass",
function(x,ordered=TRUE){
if(ordered)
x#values[x#id]
else
x#values
}
This won't work, as names is a primitive function and ordered is not an argument for the implicit generic.
How can I make this work under the following conditions:
the names function should keep its original behaviour for all other objects, including objects from other packages.
the code should be acceptable for use in a package
the code should be acceptable by the high standards set by eg Bioconductor.
The generic is available as
> getGeneric("names")
standardGeneric for "names" defined from package "base"
function (x)
standardGeneric("names", .Primitive("names"))
<environment: 0x459c9c0>
Methods may be defined for arguments: x
Use showMethods("names") for currently available ones.
so from the signature you can see that the short answer is that you can't add arguments. You'd definitely not want to create your own function names. A hack would use a package-global variable getOption("pkg_names_ordered") but I wouldn't partake of that solution myself.
In some ways the contract set out by names does not say anything about order (for instance, names and numerical indecies are often used to subset; are the numerical indices for the ordered names, or the unordered names?), so you're really proposing a new generic anyway.

Defining classes at runtime

I am trying to write a function that takes a list of classes (or class names) and returns a class that has all given classes as superclasses. This should return the same class again when given the same list twice, so I am using a hash table for memoization.
I can not use defclass for that purpose as it doesn't evaluate it's DIRECT-SUPERCLASSES parameter. I didn't find any corresponding function in the HyperSpec.
Is there any way I can do this portably?
Just create the DEFCLASS form and evaluate it with EVAL.
You can also use the CLOS function ENSURE-CLASS.

Confused about R terminology: Attributes, parameters, and arguments

Once and for all I want to get the R terminology right. However, none of the books I was reading was of big help, and it seems to me the authors choose the names sometimes arbitrarily. So, my question is when exactly are the names "attribute", "parameter", and "argument" used?
From what I read and understood so far, a parameter is what a function can take as input. For example if I have a function that calculates the sum of two values, sum(value1, value2), 'value1' and 'value2' are the function's parameters.
If we are calling a function, we call the values passed to the function arguments. For the sum-function example, "23" and "48" would be the function arguments for:
sum(23,48).
So basically we call it parameter when we define a function, and we call it argument when we call the function (so the arguments are passed to the function's parameters)
But what about "attributes"? From what I understand, attributes are the equivalent of parameters in methods (and methods are functions of a class object)?
For example, if I would have something like:
heatmap(myData, Colv=NA, Rowv=NA)
... , would 'myData' be an argument or attribute? And what about Colv=NA and Rowv=NA? Isn't heatmap() a function and thus everything in the parentheses should be called arguments?
Suppose we have:
f <- function(x) x + 1
comment(f) <- "my function"
f(3)
Arguments We distinguish between formal arguments and actual arguments. In the above x is the formal argument to f. The names of the formal arguments of f are given by:
> names(formals(f))
[1] "x"
The actual arguments to a function vary from one call to another and in the above example there is a single actual argument 3.
The function args can be used to display the entire function signature of a function including the formal arguments and the default arguments and if you are debugging a function you can enter match.call() to list the function signature with the actual arguments substituted.
Attributes The attributes of an R object are given by attributes(f) like this:
> attributes(f)
$srcref
function(x) x + 1
$comment
[1] "my function"
There is one exception and that is that an object's class is also regarded as an attribute but is not given by the above but rather is given by class:
> class(f)
[1] "function"
Parameters Sometimes function arguments are referred to as parameters or sometimes one refers to those arguments which are fixed as parameters but this tends to be related more to mathematics and statistics than R.
In statistical models the model is typically a function of the data and the model parameters often via the likelihood. For example, here:
> lm(demand ~ Time, BOD)
Call:
lm(formula = demand ~ Time, data = BOD)
Coefficients:
(Intercept) Time
8.521 1.721
the linear regression coefficients of Intercept and Time (viz. 8.521 and 1.721) are often referred to as model parameters.
As Dwin has already pointed out the various values influencing graphics in R are also termed parameters and can be displayed via:
> par()
and the corresponding concepts in other R graphics systems are often also referred to as parameters.
I suppose colloquial use of the term "attribute" might refer to several features of data objects, but there is a very specific meaning in R. An attribute is a value returned by either the functions: attributes or attr. These are critical to the language in that classes and names are stored as attributes. There two other assignment functions: attributes<- and attr<- that allow additional attributes to be assigned in support of class specific objectives.
?attributes
?attr
There is a par function which sets graphical "parameters" that control the base graphics behavior. So that would be an R-specific use of parameter than might be slightly different than use of "argument" which is generally applied to the formal arguments to functions.
?par
The is a function args which applied to a function name or an anonymous function will return its arguments (as a "closure" which gets printed on the console just as a user would type during a function definition) along with their default values. The function formals will return the same "argument" information in the form of a list.
?args
?formals
I realize I am implicitly arguing with Matthew whose R skills are excellent. Contrary to him, I think that attributes and arguments have more specific meanings in the context of R and that careful authors will make an effort to keep their meanings separate. I would not have a problem understanding someone who uses parameter as a synonym for argument if the context were clearly a discussion of applying a function, since that is the typical parlance in mathematics. I would agree with the conclusion of your last sentence. Those are 'arguments' and most emphatically not attributes. The attributes of an object returned by heatmap are:
> attributes(hv) #from first example in ?heatmap
#$names
# [1] "rowInd" "colInd" "Rowv" "Colv"
But only some of the arguments became attributes and then only after being assigned to the returned value during the function execution.
I am not sure how analogous R is to Python, but I think most of the terms should be consistent across different languages. From what I read and learned in the last couple of days, a parameter is basically what a function takes as its input when you define it:
my_function <- function (param1, param2){
...
}
and it is called argument if you are invoking a function with certain input values (that are passed to the function as parameters):
my_function(arg1, arg2)
Functions that are part of a class are called method. And an attribute can be either a value or method associated with a class object (or so-called instance)
So the question whether we call something argument or attribute depends on what we are calling: a function or a method. But I would say now argument is an appropriate term if we call the heatmap function, for example:
heatmap(my_data)
Attribute : Object's properties, e.g. Person has String fName, lName;
Parameter: appears in function/method definition e.g. public void setName(fName, lName)
Argument: value passed for a method/function's parameter when invoking/calling the method/function e.g. myPerson.setName("Michael", "Jackson")

Resources