我来自 Python 世界,一开始很难用 R 类来思考。最后,我做到了。我认为。
我能够在 R 中将Python 和 Java 类转换为S4 。
创建此包rODE的特定目的是帮助初学者学习S4课程。该软件包是关于求解常微分方程的,并且包含有关 S4 类的所有内容。
希望能帮助到你。链接下方:
https://github.com/f0nzie/rODE
该软件包也在 CRAN 中。
现在,关于答案。在 R 中有很多方法可以做你想做的事。这是第一种方法,使用S4类和原型来初始化变量 A 和 B 的值。
setClass("MyClass", slots = c(
A = "numeric",
B = "numeric"
),
prototype = prototype(
A = 1,
B = 2
)
)
# generic functions
setGeneric("hello", function(object, ...) standardGeneric("hello"))
setGeneric("goodbye", function(object, ...) standardGeneric("goodbye"))
setGeneric("ohDear", function(object, ...) standardGeneric("ohDear"))
# Methods of the class
setMethod("hello", "MyClass", function(object, ...) {
return("Hello")
})
setMethod("goodbye", "MyClass", function(object, ...) {
return("Goodbye")
})
setMethod("ohDear", "MyClass", function(object, ...) {
return("Have no clue")
})
# instantiate a class
mc <- new("MyClass")
# use the class methods
hello(mc)
goodbye(mc)
ohDear(mc)
第二种方法是使用初始化方法。
setClass("MyClass", slots = c(
A = "numeric",
B = "numeric"
)
)
# generic functions
setGeneric("hello", function(object, ...) standardGeneric("hello"))
setGeneric("goodbye", function(object, ...) standardGeneric("goodbye"))
setGeneric("ohDear", function(object, ...) standardGeneric("ohDear"))
# Methods of the class
setMethod("initialize", "MyClass", function(.Object, ...) {
.Object@A <- 1
.Object@B <- 2
return(.Object)
})
# Methods of the class
setMethod("hello", "MyClass", function(object, ...) {
return("Hello")
})
setMethod("goodbye", "MyClass", function(object, ...) {
return("Goodbye")
})
setMethod("ohDear", "MyClass", function(object, ...) {
return("Have no clue")
})
# instantiate a class
mc <- new("MyClass")
# use the class methods
hello(mc)
goodbye(mc)
ohDear(mc)
mc@A # get value on slot A
mc@B # get value on slot B
第三种方法是使用构造函数并使用构造函数初始化类外部的类变量:
setClass("MyClass", slots = c(
A = "numeric",
B = "numeric"
)
)
# generic functions
setGeneric("hello", function(object, ...) standardGeneric("hello"))
setGeneric("goodbye", function(object, ...) standardGeneric("goodbye"))
setGeneric("ohDear", function(object, ...) standardGeneric("ohDear"))
# Methods of the class
setMethod("initialize", "MyClass", function(.Object, ...) {
return(.Object)
})
# Methods of the class
setMethod("hello", "MyClass", function(object, ...) {
return("Hello")
})
setMethod("goodbye", "MyClass", function(object, ...) {
return("Goodbye")
})
setMethod("ohDear", "MyClass", function(object, ...) {
return("Have no clue")
})
# constructor function
MyClass <- function() {
myclass <- new("MyClass")
myclass@A <- 1 # assignment
myclass@B <- 2
return(myclass) # return the class initialized
}
# instantiate a class
mc <- MyClass()
# use the class methods
hello(mc)
goodbye(mc)
ohDear(mc)
mc@A # get value on slot A
mc@B # get value on slot B
这仍然有改进的空间,因为我们不应该在类之外处理插槽的原始名称。封装,还记得吗?这是使用setReplaceMethod的第四种更好的方法:
setClass("MyClass", slots = c(
A = "numeric",
B = "numeric"
)
)
# generic functions
setGeneric("hello", function(object, ...) standardGeneric("hello"))
setGeneric("goodbye", function(object, ...) standardGeneric("goodbye"))
setGeneric("ohDear", function(object, ...) standardGeneric("ohDear"))
setGeneric("getA", function(object, ..., value) standardGeneric("getA"))
setGeneric("getB", function(object, ..., value) standardGeneric("getB"))
setGeneric("setA<-", function(object, ..., value) standardGeneric("setA<-"))
setGeneric("setB<-", function(object, ..., value) standardGeneric("setB<-"))
# Methods of the class
setMethod("initialize", "MyClass", function(.Object, ...) {
return(.Object)
})
# Methods of the class
setMethod("hello", "MyClass", function(object, ...) {
return("Hello")
})
setMethod("goodbye", "MyClass", function(object, ...) {
return("Goodbye")
})
setMethod("ohDear", "MyClass", function(object, ...) {
return("Have no clue")
})
setMethod("getA", "MyClass", function(object, ...) {
return(object@A)
})
setMethod("getB", "MyClass", function(object, ...) {
return(object@B)
})
setReplaceMethod("setA", "MyClass", function(object, ..., value) {
object@A <- value
object
})
setReplaceMethod("setB", "MyClass", function(object, ..., value) {
object@B <- value
object
})
# constructor function
MyClass <- function() {
myclass <- new("MyClass")
return(myclass) # return the class initialized
}
# instantiate a class
mc <- MyClass()
# use the class methods
hello(mc)
goodbye(mc)
ohDear(mc)
setA(mc) <- 1
setB(mc) <- 2
getA(mc) # get value on slot A
getB(mc) # get value on slot B
第 5 种方法是创建一个类方法来实例化类本身,这对于验证输入很有用,即使是缺少参数:
.MyClass <- setClass("MyClass", slots = c(
A = "numeric",
B = "numeric"
)
)
# generic functions
setGeneric("hello", function(object, ...) standardGeneric("hello"))
setGeneric("goodbye", function(object, ...) standardGeneric("goodbye"))
setGeneric("ohDear", function(object, ...) standardGeneric("ohDear"))
setGeneric("getA", function(object, ..., value) standardGeneric("getA"))
setGeneric("getB", function(object, ..., value) standardGeneric("getB"))
setGeneric("setA<-", function(object, ..., value) standardGeneric("setA<-"))
setGeneric("setB<-", function(object, ..., value) standardGeneric("setB<-"))
setGeneric("MyClass", function(A, B, ...) standardGeneric("MyClass"))
# Methods of the class
setMethod("initialize", "MyClass", function(.Object, ...) {
return(.Object)
})
# Methods of the class
setMethod("hello", "MyClass", function(object, ...) {
return("Hello")
})
setMethod("goodbye", "MyClass", function(object, ...) {
return("Goodbye")
})
setMethod("ohDear", "MyClass", function(object, ...) {
return("Have no clue")
})
setMethod("getA", "MyClass", function(object, ...) {
return(object@A)
})
setMethod("getB", "MyClass", function(object, ...) {
return(object@B)
})
setReplaceMethod("setA", "MyClass", function(object, ..., value) {
object@A <- value
object
})
setReplaceMethod("setB", "MyClass", function(object, ..., value) {
object@B <- value
object
})
setMethod("MyClass", signature(A="numeric", B="numeric"), function(A, B, ...) {
myclass <- .MyClass()
myclass@A <- A
myclass@B <- B
return(myclass)
})
# instantiate the class with values
mc <- MyClass(A = 1, B = 2)
# use the class methods
hello(mc)
goodbye(mc)
ohDear(mc)
getA(mc) # get value on slot A
getB(mc) # get value on slot B