Dear member of the list,
I search for the correct way to handle class.
I learn recently that inherits() was the correct way to test class:
inherits(x, what, which = FALSE)
For this part it is ok.
But now I have questions about the correct procedure to set class.
Previously I used:
result <- "Je suis donc je pense"
class(result) <- "ECFOCF"
But I loose the previous class "character". It is still present in
mode(result) but sometimes it can be a problem.
For example here:
> resultL <- data.frame(A=c(1,2), B=c(3, 4))
> class(resultL)
[1] "data.frame"
> class(resultL) <- "ECFOCF"
> resultL
$A
[1] 1 2
$B
[1] 3 4
attr(,"class")
[1] "ECFOCF"
attr(,"row.names")
[1] 1 2
I lost the data.frame structure when I set the new class. It is seen as
a list by:
> mode(resultL)
[1] "list"
So I use:
result <- "Je suis donc je pense"
class(result) <- unique(append("ECFOCF", class(result)))
I use append because I don't want loose the original class. I use
unique() to prevent the same class being put several times in the object.
However, Using this formula, I am not 100% sure the "ECFOCF" is the
first class. If it is not, it could prevent plot.ECFOCF to take in
charge the plot of this object.
An alternative could be:
> result <- "Je suis donc je pense"
> class(result) <- unique(append("ECFOCF",
class(result)[class(result)
!= "ECFOCF"]))
> class(result)
[1] "ECFOCF"??? "character"
Then I am sure that "ECFOCF" class is the first one.
Is it the correct way to define class or I am in wrong direction?
Thanks a lot
Marc
Hello,
Write a function to set the new class attribute. If other changes need
to be done, you can do them all in one function. For instance, the
as.matrix method for atomic vectors coerces a vector to class "matrix"
*and* gives it a dim attribute. The two changes are done in one call.
In the example below, there's a setter function and a print method for
the new class. It can handle both atomic vectors and with NextMethod
complicated objects such as data.frames.
as_ECFOCF <- function(x, ...) {
if(!inherits(x, "ECFOCF"))
class(x) <- c("ECFOCF", class(x))
x
}
print.ECFOCF <- function(x, ...) {
if(is.atomic(x))
print.default(unclass(x))
else
NextMethod()
}
result2 <- "Je suis donc je pense"
resultL2 <- data.frame(A=c(1,2), B=c(3, 4))
result2 <- as_ECFOCF(result2)
class(result2)
#> [1] "ECFOCF" "character"
result2
#> [1] "Je suis donc je pense"
resultL2 <- as_ECFOCF(resultL2)
class(resultL2)
#> [1] "ECFOCF" "data.frame"
resultL2
#> A B
#> 1 1 3
#> 2 2 4
Hope this helps,
Rui Barradas
?s 11:34 de 14/04/2022, Marc Girondot via R-help
escreveu:> Dear member of the list,
>
> I search for the correct way to handle class.
>
> I learn recently that inherits() was the correct way to test class:
>
> inherits(x, what, which = FALSE)
>
> For this part it is ok.
>
> But now I have questions about the correct procedure to set class.
>
> Previously I used:
>
> result <- "Je suis donc je pense"
> class(result) <- "ECFOCF"
>
> But I loose the previous class "character". It is still present
in
> mode(result) but sometimes it can be a problem.
>
> For example here:
>
> > resultL <- data.frame(A=c(1,2), B=c(3, 4))
> > class(resultL)
> [1] "data.frame"
> > class(resultL) <- "ECFOCF"
> > resultL
> $A
> [1] 1 2
>
> $B
> [1] 3 4
>
> attr(,"class")
> [1] "ECFOCF"
> attr(,"row.names")
> [1] 1 2
>
> I lost the data.frame structure when I set the new class. It is seen as
> a list by:
>
> > mode(resultL)
> [1] "list"
>
> So I use:
>
> result <- "Je suis donc je pense"
> class(result) <- unique(append("ECFOCF", class(result)))
>
> I use append because I don't want loose the original class. I use
> unique() to prevent the same class being put several times in the object.
>
> However, Using this formula, I am not 100% sure the "ECFOCF" is
the
> first class. If it is not, it could prevent plot.ECFOCF to take in
> charge the plot of this object.
>
> An alternative could be:
>
> > result <- "Je suis donc je pense"
> > class(result) <- unique(append("ECFOCF",
class(result)[class(result)
> != "ECFOCF"]))
> > class(result)
> [1] "ECFOCF"??? "character"
>
> Then I am sure that "ECFOCF" class is the first one.
>
> Is it the correct way to define class or I am in wrong direction?
>
> Thanks a lot
>
> Marc
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
There are numerous tutorials, including the "Intro to R" that explain
this. A search on "S3 classes in R" (there are at least **3**
different class systems in R -- S3, S4, and R6) would have found many.
But even ?UseMethod provides the info you need, I think. It says:
"A class attribute is a character **vector** giving the names of the
classes from which the object inherits. ..."
So while what you did is correct, simply using:
class(result) <- c("ECFOCF", class(result))
would suffice. The Help page above or tutorials will provide greater
detail of course.
Bert Gunter
"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
On Thu, Apr 14, 2022 at 3:34 AM Marc Girondot via R-help
<r-help at r-project.org> wrote:>
> Dear member of the list,
>
> I search for the correct way to handle class.
>
> I learn recently that inherits() was the correct way to test class:
>
> inherits(x, what, which = FALSE)
>
> For this part it is ok.
>
> But now I have questions about the correct procedure to set class.
>
> Previously I used:
>
> result <- "Je suis donc je pense"
> class(result) <- "ECFOCF"
>
> But I loose the previous class "character". It is still present
in
> mode(result) but sometimes it can be a problem.
>
> For example here:
>
> > resultL <- data.frame(A=c(1,2), B=c(3, 4))
> > class(resultL)
> [1] "data.frame"
> > class(resultL) <- "ECFOCF"
> > resultL
> $A
> [1] 1 2
>
> $B
> [1] 3 4
>
> attr(,"class")
> [1] "ECFOCF"
> attr(,"row.names")
> [1] 1 2
>
> I lost the data.frame structure when I set the new class. It is seen as
> a list by:
>
> > mode(resultL)
> [1] "list"
>
> So I use:
>
> result <- "Je suis donc je pense"
> class(result) <- unique(append("ECFOCF", class(result)))
>
> I use append because I don't want loose the original class. I use
> unique() to prevent the same class being put several times in the object.
>
> However, Using this formula, I am not 100% sure the "ECFOCF" is
the
> first class. If it is not, it could prevent plot.ECFOCF to take in
> charge the plot of this object.
>
> An alternative could be:
>
> > result <- "Je suis donc je pense"
> > class(result) <- unique(append("ECFOCF",
class(result)[class(result)
> != "ECFOCF"]))
> > class(result)
> [1] "ECFOCF" "character"
>
> Then I am sure that "ECFOCF" class is the first one.
>
> Is it the correct way to define class or I am in wrong direction?
>
> Thanks a lot
>
> Marc
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.