简体   繁体   中英

R methods for custom S3 class

I have my s3 class student

# a constructor function for the "student" class
student <- function(n,a,g) {
  # we can add our own integrity checks
  if(g>4 || g<0)  stop("GPA must be between 0 and 4")
  value <- list(name = n, age = a, GPA = g)
  # class can be set using class() or attr() function
  attr(value, "class") <- "student"
  value
}
stud <- student("name", 10, 3.5)

Now I would like to create a method similar to stud.doubleGPA() which would double the GPA of the student. I know I can achieve this using

stud$GPA <- stud$GPA*2
stud$GPA # 7

However trying to define a function doesn't seem to work.

doubleGPA <- function(student) {
  if(!class(student)=="student") stop("nope")
  student$GPA <- student$GPA*2
}
doubleGPA(stud)
stud$GPA # 7 again (didn't work)

And replacing <- with <<- in the above function gives

Error in student$GPA <<- student$GPA * 2 : 
  object of type 'closure' is not subsettable

How can I define such a method which would belong to an s3 class and therefore be inherited by children?

Cheers

You are thinking of a different kind of object oriented programming than the S3 style, something more like C++ or Java. You can do that in R, just not in the S3 system.

In the S3 system, methods "belong to" generic functions, not to classes. Like most functions in R, generic functions don't modify their arguments, they calculate new values and return those. So you might define a generic function doubleGPA() , and have it work on the "student" class using

doubleGPA <- function(x) UseMethod("doubleGPA")

doubleGPA.student <- function(x) {
  x$GPA <- x$GPA*2
  x
}

and then use it as

stud <- student("name", 10, 3.5)
stud <- doubleGPA(stud)

If you actually want something more like C++ or Java, there are a couple of choices: "reference classes" from the methods package (see ?methods::setRefClass ) and "R6 classes" from the R6 package. There are also several prototype-based styles in packages proto , ggplot2 , R.oo , and are probably more that I've forgotten to mention.

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