can I change property of R object - r

My Ldt1 object has the following property.
> is(Ldt1)
[1] "data.frame" "list" "oldClass" "vector"
I want to change it to data.frame only. How can I do it ?
Edits:
I am answering to question of "why?"
I need to work between two packages. The first package works on different class object and second on different class. In the data manipulation process I have trouble with uncessary class type attached with object giving an error message as:
No method for an object of class genotypeNo method for an object of class factor

You simply cannot. All data.frames are lists and all lists are vectors. (Why would you want to do such a thing anyway?)
Properly written methods will be written to see if the sought-after class is either in the list of the class attribute or in one of its inherited classes. In your case, you (or one of your programs) appear to have made a data input error and turned what you thought should be a numeric vector into a factor vector, or teh designer thought that a factor variable was the logical object to return. It's possible that you could get success by identifying the object or the component and coercing it with 'as.numeric(as.character(facvar))`. (That particular method is a FAQ question.) The better way way forward here is to identify the source of the input or processing error.

Related

Getting type of object in R [duplicate]

Two R questions:
What is the difference between the type (returned by typeof) and the class (returned by class) of a variable? Is the difference similar to that in, say, C++ language?
What are possible types and classes of variables?
In R every "object" has a mode and a class. The former represents how an object is stored in memory (numeric, character, list and function) while the later represents its abstract type. For example:
d <- data.frame(V1=c(1,2))
class(d)
# [1] "data.frame"
mode(d)
# [1] "list"
typeof(d)
# list
As you can see data frames are stored in memory as list but they are wrapped into data.frame objects. The latter allows for usage of member functions as well as overloading functions such as print with a custom behavior.
typeof(storage.mode) will usually give the same information as mode but not always. Case in point:
typeof(c(1,2))
# [1] "double"
mode(c(1,2))
# [1] "numeric"
The reasoning behind this can be found here:
The R specific function typeof returns the type of an R object
Function mode gives information about the mode of an object in the sense of Becker, Chambers & Wilks (1988), and is more compatible with other implementations of the S language
The link that I posted above also contains a list of all native R basic types (vectors, lists etc.) and all compound objects (factors and data.frames) as well as some examples of how mode, typeof and class are related for each type.
type really refers to the different data structures available in R. This discussion in the R Language Definition manual may get you started on objects and types.
On the other hand, class means something else in R than what you may expect. From
the R Language Definition manual (that came with your version of R):
2.2.4 Classes
R has an elaborate class system1, principally controlled via the class attribute. This attribute is a character vector containing the list
of classes that an object inherits from. This forms the basis of the “generic methods” functionality in R.
This attribute can be accessed and manipulated virtually without restriction by users. There is no checking that an object actually contains the components that class methods expect. Thus, altering the class attribute should be done with caution, and when they are available specific creation and coercion functions should be preferred.

What is the difference between new() and setClass() in 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)
}

Use strings to access formal R class object elements

I am writing a function to access elements of a formal R class (Dada2). My elements require a unique identifier to access the class. I am currently parsing a string to get that identifier and then need to use that string to access the information in the data class. I would like to automate this script which is why I am parsing the unique identifier. I can easily access the data manually, however with the shear number of samples that is not ideal.
Variables: Dada_Object (Large list with multiple items)
sample (Character string name)
Goal:
Unique_Identifier = Parsing_Function(sample)
Desired = Dada_Object[Unique_Identifier]$sequences
Problem: Using the unique identifier does not allow access to the sequences information. The unique identifier is currently a string object. Any direction to this problem would be greatly appreciated.
I have solved my problem with an adhoc method.
I began by subsetting the class list then unlisting the elements
Step_1 = Dada_Object[Unique_Identifier]
Step_2 = unlist(Step_1)
From here I was able to subset the named list elements
Desired_Output = names(Step_2)[1:Desired_Output_Length]
This solution was a workaround, however I am still curious if anyone has a better way to access class items using strings.

R: modify any function applied to a S4 class

I've been developing a S4 class which is essentially a data.frame with a little bit of extra information. For the purposes of this question, the "extra" features of this class are irrelevant. What matters is that the class contains a data.frame object stored in one of it's slots. (I put the data.frame in a slot, instead of naming it a superclass, because I find that S4 classes which contain data.frames simplify the data.frames to lists for some reason).
Here's a basic example:
setClass('tmp_class', slots = c(df = 'data.frame'))
test_object <- new('tmp_class', df = data.frame(Num = 1:10, Let = letters[1:10]))
Now what I'd like to do is make it so that essentially any function applied to an object of this class is applied to the data.frame in slot #df. It's easy to write methods for specific functions to do this, like:
setMethod('dim', signature = c(x = 'tmp_class'), function(x) dim(x#df))
But I'm limited to only the functions I can think of, and any function invented by a user wouldn't work.
It is a simple matter to write a sort of wrapper/closure to modify a function to work on my class, like this:
tmp_classize <- function(func){
function(tmp, ...){ func(tmp#df, ...) }
}
So, rather than writing methods for, say, colnames() or ncol(), I could just run:
tmp_classize(colnames)(test_object)
or
tmp_classize(ncol)(test_object)
But what I'd like to do is somehow evoke my "tmp_classize" function on any function applied to my class, automatically. I can't figure out how to do it. I was thinking that if could somehow call a "universal method" with an input signature of class "tmp_class", and then use sys.function() to grab the actual function being called, maybe I could make something work, but A) there are recursion problems B) I don't know how to call such a "universal" method. It seems to me that the solution, if it exists at all, might necessitate non-standard evaluation, which I'd rather avoid, but might use if necessary.
Thanks!
P.S. I realize this undertaking may be unwise/poor programming technique, and I may never actually implement it in a package. Still I'm curious to know if it is possible.
P.P.S. I'd also be interested in the same idea applied to S3 classes!
In principal what you could do is make a classUnion for your class and data.frame and write methods for your class that deal with all of the ways to read and write to data.frames such as $, [, dim(), <- and many more. Then when other functions seek to use your new class as data.frame there will be methods for this to work. This is somewhat explained in John Chambers "Software for Data Analysis" starting on page 375. That said this system may be very difficult to implement.
A simpler system may be to just add an extra attribute to your data.frame with the extra info you need. For example:
x<-data.frame(a=1:3,b=4:6)
attr(x,"Info")<-"Extra info I need"
attributes(x)$Info
[1] "Extra info I need"
This is not as elegant as a S4 class but will do everything a data.frame does. I suspect that someone who is familiar with S3 classes could improve on this idea quite a bit.
The simplest solution is to have your class contain data.frame instead of having it as one of the slots. For example here is a data.frame with a timestamp:
setclass(
"timestampedDF",
slots=c(timestamp="POSIXt"),
contains="data.frame"
)
Now all functions which work for a data.frame (such as head) will automatically work for timestampedDF objects. If you need to get at the "data frame part", then that is held in a hidden slot object#.Data.

Questions regarding the use of S4 methods in R

We were trying to program object oriented programming in R, using S4 methods. During our programming process, we came across some problems. Apparently, the use of S4 methods is not very well documented on the internet yet, therefore we hope that we can get answers to some of our questions here.
First question:
We were trying to make a vector/array/list.. of empty S4 objects. Searching the internet brought us to the following question in this forum:
Create a vector of empty S4 objects
As (similarly) described in one of the answers to the question above, we used the following code to create a list of empty S4 objects:
setClass("Name", representation(pos_x = "numeric", pos_y = "numeric", found =
"logical"), prototype(found = FALSE))
newList <- lapply(rep("Name", 2), new)
This works perfectly fine. However, when we are trying to call one slot (one variable) of the S4 method, this won't work. When we for example want to call the slot "pos_x", the following code
newList[1]#pos_x
is not working. The error message we receive is "Trying to get slot pos_x from an object of a basic class ("list") with no slots.
So, it seems as if the slots were not assigned to the S4 method, although they are clearly defined in the list.
Does anyone know how we can call a slot from one of the S4-methods/objects of the list?
Second question:
We would like to test whether one of the elements of the list above equals "NULL", as we would like to create the objects later on.
To check this, we tried:
newList[1] == NULL
This is however only resulting in "logical(0)".
Does anyone know how to do this?
Suggestions, remarks and questions are very welcome.
Thanks a lot!
The problem is maybe due to the use of [ instead of [[.
The command newList[1] returns a list of length one, whereas the command newList[[1]] returns an element of the list. You should therefore try:
newList[[1]]#pos_x

Resources