简体   繁体   中英

S3 class methods in R

Why cant I add plot(object) under the plot method? I want to be able to plot x. I seem to be running into an infinite loop here. Could you help me figure out what is wrong here?

    fun1 <- function(x) {
      # Create a class, and return some output in that
      # object, based on the input x:
      my.list <- list("input" = x, "mean" = mean(x))
      class(my.list) <- "my_special_class"
       return(my.list)
      }
      x <- rnorm(10)
      my.object <- fun1(x)
      class(my.object)
      methods(class = "my_special_class") # None, unsurprisingly
    
      # Create one:
      summary.my_special_class <- function(object) {
      cat("This object contains the original input, x:\n")
      print(object$input)
      cat("\n along with the mean of the input:\n")
      print(object$mean)
    }
    
    print.my_special_class <- function(object) {
      cat("This object contains the original input, x:\n")
      print(object$input)
      cat("\n along with the mean of the input:\n")
      print(object$mean)
    }
    
    plot.my_special_class <- function(object) {
     plot(object)
    }
    methods(class = "my_special_class") # Now one method exists, a summary one
    summary(my.object)
    plot(my.object)
    print(my.object)

Constructors and methods

A constructor is not automatically an S3 method. A method for class X must have a name of the form method.X where method and X are the name of the generic it is associated with and X is the name of the class. make_my_class is not a method and is not associated with a generic. It is an ordinary function.

On the other hand summary.my_special_class is a method and it is associated with the summary generic. Note that the constructor could be written like this:

 make_my_class <- function(x) {
   structure(list(input = x, mean = mean(x)), class = "my_special_class")
 }

summary

Also note that normally the summary does not print directly but rather creates an object of class summary.X where X is the class in question and then a print method print.summary.X is defined. For example,

fm <- lm(demand ~ Time, BOD)
s <- summary(fm)

class(s)
## [1] summary.lm

getAnywhere("print.lm")$where
## [1] "registered S3 method for print from namespace stats"
## [2] "namespace:stats"                                    

getAnywhere("print.summary.lm")$where
## [1] "registered S3 method for print from namespace stats"
## [2] "namespace:stats"   

plot

Regarding plot the plot method defined in the question is a recursive function as plot(object) in the body of plot.my_special_method calls plot.my_special_method. To ensure that it does not call itself use this. Argument names should be consistent with the generic so we have used x rather than object.

plot.my_special_class <- function(x, ...) {
 plot(x$input, ...)
 abline(h = x$mean)
}

Updates

Expanded and corrected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM