如何使用方法在 S4 对象 r 中设置值(无需输入值)
how to set value in S4 object r using a method (no input value needed)
这是一个由两部分组成的问题。我想根据不同的插槽值设置原型 s4 对象的值,或者我想将其实现为一种方法。
我有一个要创建的对象。它有一些插槽。我想根据从另一个插槽输入的值设置一个插槽值。这是我想做的事情的简化版本。
即
setClass("Person",
representation(name = "character", age = "numeric", doubleAge = "numeric"),
prototype(name = "Bob", age = 5, doubleAge = 10) )
现在我想创建一个对象,但要根据年龄段自行设置 doubleAge 值。
p1 <- new("Person", name = "Alice", age = 6)
明白了
An object of class "Person"
Slot "name":
[1] "Alice"
Slot "age":
[1] 6
Slot "doubleAge":
[1] 10
但我想看到 doubleAge 为 12。在原型中,我不知道如何将 doubleAge = 10
更改为 doubleAge = 2*age
因此,作为解决方案,我尝试创建一个设置函数 init
,它在创建后设置值。这是第 2 部分的问题。
setGeneric("init", "Person", function(object) {
standardGeneric("init")
}
setMethod("init","Person", function(object) {
object@doubleAge <- object@age*2
object
}
如果我在方法中打印 object@doubleAge
returns 12,但似乎范围结束了,因为当它 returns
时它是 10
目前的工作原理非常相似,但并不正确。
setGeneric("init<-", "Person", function(object) {
standardGeneric("init<-")
}
setMethod("init<-","Person", function(object) {
object@doubleAge <- object@age*2
object
}
但后来我不得不像 init(p1) <- NULL
那样打电话,这看起来很奇怪。我知道这个例子看起来微不足道,但它只是更复杂的现实世界问题的一个准系统示例。
似乎覆盖初始化方法对我有用。例如
setClass("Person",
representation(name = "character", age = "numeric", doubleAge = "numeric"),
prototype(name = "Bob", age = 5, doubleAge = 10) )
setMethod("initialize", "Person", function(.Object, ...) {
.Object <- callNextMethod()
.Object@doubleAge <- .Object@age*2
.Object
})
(p1 <- new("Person", name = "Alice", age = 6))
# An object of class "Person"
# Slot "name":
# [1] "Alice"
# Slot "age":
# [1] 6
# Slot "doubleAge":
# [1] 12
callNextMethod()
运行 "default" 初始化程序来设置我们没有搞乱的所有值。然后我们只需更改我们想要的值和 return 更新的对象。
除了上述 initialize
的方法外,您可能还想为 @<-
设置一个方法。这样做的原因是如果你做类似
x <- new("person", age=5)
那么你有一个 age=5
和 doubleage=10
的有效人选。但是如果你现在做
x@age <- 6
?现在 age
是 6 但 doubleage
仍然是 10 所以对象不再有效。
R 文档声称您可以为 @<-
编写一个方法来解决此问题:
setMethod("@<-",signature(object="Person"),function(object,name,value){
if(name=="age"){
object@age <- x
object@doubleAge <- x*2
} else if(e2=="doubleAge"){
object@doubleAge <- x
object@age <- value/2
} else slot(object,name) <- value
object
})
然而,当你实际 运行 以上时,你会得到一个错误:
Error in setGeneric(f, where = where) : ‘@<-’ dispatches
internally; methods can be defined, but the generic function is
implicit, and cannot be changed.
这是一个看起来很奇怪的错误,因为我们并不是要重新定义泛型。事实上我们发现,当我们尝试
method.skeleton("@<-",signature(object="Person"))
那个R不情愿的告诉我们
Error in genericForBasic(name) : methods may not be defined for
primitive function ‘@<-’ in this version of R
所以如果你想让插槽可靠地保持一致,我们将不得不按照
的方式编写自己的 getter 和 setter
setAge <- function(x,value){
x@age <- value
x@doubleAge <- value*2
x
}
这是一个由两部分组成的问题。我想根据不同的插槽值设置原型 s4 对象的值,或者我想将其实现为一种方法。
我有一个要创建的对象。它有一些插槽。我想根据从另一个插槽输入的值设置一个插槽值。这是我想做的事情的简化版本。
即
setClass("Person",
representation(name = "character", age = "numeric", doubleAge = "numeric"),
prototype(name = "Bob", age = 5, doubleAge = 10) )
现在我想创建一个对象,但要根据年龄段自行设置 doubleAge 值。
p1 <- new("Person", name = "Alice", age = 6)
明白了
An object of class "Person"
Slot "name":
[1] "Alice"
Slot "age":
[1] 6
Slot "doubleAge":
[1] 10
但我想看到 doubleAge 为 12。在原型中,我不知道如何将 doubleAge = 10
更改为 doubleAge = 2*age
因此,作为解决方案,我尝试创建一个设置函数 init
,它在创建后设置值。这是第 2 部分的问题。
setGeneric("init", "Person", function(object) {
standardGeneric("init")
}
setMethod("init","Person", function(object) {
object@doubleAge <- object@age*2
object
}
如果我在方法中打印 object@doubleAge
returns 12,但似乎范围结束了,因为当它 returns
目前的工作原理非常相似,但并不正确。
setGeneric("init<-", "Person", function(object) {
standardGeneric("init<-")
}
setMethod("init<-","Person", function(object) {
object@doubleAge <- object@age*2
object
}
但后来我不得不像 init(p1) <- NULL
那样打电话,这看起来很奇怪。我知道这个例子看起来微不足道,但它只是更复杂的现实世界问题的一个准系统示例。
似乎覆盖初始化方法对我有用。例如
setClass("Person",
representation(name = "character", age = "numeric", doubleAge = "numeric"),
prototype(name = "Bob", age = 5, doubleAge = 10) )
setMethod("initialize", "Person", function(.Object, ...) {
.Object <- callNextMethod()
.Object@doubleAge <- .Object@age*2
.Object
})
(p1 <- new("Person", name = "Alice", age = 6))
# An object of class "Person"
# Slot "name":
# [1] "Alice"
# Slot "age":
# [1] 6
# Slot "doubleAge":
# [1] 12
callNextMethod()
运行 "default" 初始化程序来设置我们没有搞乱的所有值。然后我们只需更改我们想要的值和 return 更新的对象。
除了上述 initialize
的方法外,您可能还想为 @<-
设置一个方法。这样做的原因是如果你做类似
x <- new("person", age=5)
那么你有一个 age=5
和 doubleage=10
的有效人选。但是如果你现在做
x@age <- 6
?现在 age
是 6 但 doubleage
仍然是 10 所以对象不再有效。
R 文档声称您可以为 @<-
编写一个方法来解决此问题:
setMethod("@<-",signature(object="Person"),function(object,name,value){
if(name=="age"){
object@age <- x
object@doubleAge <- x*2
} else if(e2=="doubleAge"){
object@doubleAge <- x
object@age <- value/2
} else slot(object,name) <- value
object
})
然而,当你实际 运行 以上时,你会得到一个错误:
Error in setGeneric(f, where = where) : ‘@<-’ dispatches internally; methods can be defined, but the generic function is implicit, and cannot be changed.
这是一个看起来很奇怪的错误,因为我们并不是要重新定义泛型。事实上我们发现,当我们尝试
method.skeleton("@<-",signature(object="Person"))
那个R不情愿的告诉我们
Error in genericForBasic(name) : methods may not be defined for primitive function ‘@<-’ in this version of R
所以如果你想让插槽可靠地保持一致,我们将不得不按照
的方式编写自己的 getter 和 settersetAge <- function(x,value){
x@age <- value
x@doubleAge <- value*2
x
}