什么是 setReplaceMethod() 以及它是如何工作的?
What is setReplaceMethod() and how does it work?
我对 setReplaceMethod()
的用法感到困惑。查看 ?setReplaceMethod
并没有提供解释,谷歌搜索也没有什么帮助。
问题:请解释setReplaceMethod()
,它的用法和它是如何工作的(最好有一个例子)。
对于$
、[
或names()
等提取方法,替换方法,例如$<-
、[<-
或 names<-
替换本应提取的值。
以列表为例:
example_object <- list(a = 1, b = 2)
# the extract method $, when called with arguments example_object and a,
# extracts and returns the value 1
example_object$a
# [1] 1
# the replace method $<-, when called with arguments example_object, a, and 42,
# replaces the value 1 (at example_object$a) with the value 42
example_object$a <- 42
example_object
# $a
# [1] 42
#
# $b
# [1] 2
因此,对于 S4 classes,setMethod("$", ...)
将定义提取方法 $
的行为,而 setMethod("$<-", ...)
或等效的 setReplaceMethod("$", ...)
将定义替换方法的行为 $<-
。 setReplaceMethod("$")
只是为了比 setMethod("$<-")
更具表现力,以明确您正在为 $
.
定义替换方法
使用 S4 的示例 class:
setClass("MyClass", representation(a = "numeric", b = "numeric"))
setMethod("$", signature = "MyClass",
function (x, name) {
if ( name == "a" ) {
return(x@a)
}
else if ( name == "b" ) {
return(x@b)
}
else {
stop(paste("No slot", name, "for MyClass"), call. = FALSE)
}
}
)
# [1] "$"
my_object <- new("MyClass", a = 1, b = 2)
my_object@a
# [1] 1
my_object$a
# [1] 1
my_object@a <- 42
my_object@a
# [1] 42
my_object$a <- 3.14 # will not work because we have not set the method for $<-
# Error in `$<-`(`*tmp*`, a, value = 3.14) :
# no method for assigning subsets of this S4 class
my_object@a
# [1] 42
setReplaceMethod("$", signature = "MyClass",
function(x, name, value) {
if ( name == "a" ) {
x@a <- value
return(x)
}
else if ( name == "b" ) {
x@b <- value
return(x)
}
else {
stop(paste("No slot", name, "for MyClass"),
call. = FALSE)
}
}
)
# [1] "$<-"
my_object$a <- 3.14
my_object@a
# [1] 3.14
这是我的发现。正如@Hong Ooi 在评论中所指出的 setReplaceMethod("fun")
与 setMethod("fun<-")
相同,因此 setReplaceMethod
用于在 R 的 S4 对象系统中创建通用替换函数的方法。
什么是替换函数在what-are-replacement-functions-in-r中有解释。非常粗鲁地,如果你有一个名为 fun<-
的函数,因为它的名称以 <-
结尾,你可以写 fun(x)<-a
而 R 将读作 x <- "fun<-"(x,a)
.
S4 对象系统在 S4 - Advanced R 中描述。
举个例子,也许从为 S4 泛型函数创建一个方法开始会更容易,这不是替换函数:
## Define an S4 class 'Polygon' and an object of this class
setClass("Polygon", representation(sides = "integer"))
p1 <- new("Polygon", sides = 33L)
## Define a generic S4 function 'sides'
sides <- function(object){ NA }
setGeneric("sides")
## sides returns NA
sides( p1 )
## Define a method for 'sides' for the class 'Polygon'
setMethod("sides", signature(object = "Polygon"), function(object) {
object@sides
})
## Now sides returns the sides of p1
sides( p1 )
为通用替换函数创建方法类似:
## Define a generic replacement function 'sides<-'
"sides<-" <- function(object, value){ object }
setGeneric( "sides<-" )
## The generic 'sides<-' doesn't change the object
sides( p1 ) <- 12L
sides( p1 )
## Define a method for 'sides<-' for the class 'Polygon',
## setting the value of the 'sides' slot
setMethod( "sides<-", signature(object = "Polygon"), function(object, value) {
object@sides <- value
object
})
## Now 'sides<-' change the sides of p1
sides( p1 ) <- 12L
sides( p1 )
您还询问了 $<-
。我的猜测是:x$name<-value
被解释为 "$"(x,name)<-value
,然后被解释为 x <- "$<-"(x,name,value)
。请注意,已经定义了通用函数 $<-
(isGeneric("$<-")
),因此我们只为我们的 class 多边形定义一个方法:
setMethod( "$<-", signature(x = "Polygon"), function(x, name, value) {
if( name=="sides" ){
x@sides <- value
}
x
})
## Nothing changes if we try to set 'faces'
p1$faces <- 3L
p1
## but we can set the 'sides'
p1$sides <- 3L
p1
请注意参数 x
、name
和 value
由泛型指定。
我对 setReplaceMethod()
的用法感到困惑。查看 ?setReplaceMethod
并没有提供解释,谷歌搜索也没有什么帮助。
问题:请解释setReplaceMethod()
,它的用法和它是如何工作的(最好有一个例子)。
对于$
、[
或names()
等提取方法,替换方法,例如$<-
、[<-
或 names<-
替换本应提取的值。
以列表为例:
example_object <- list(a = 1, b = 2)
# the extract method $, when called with arguments example_object and a,
# extracts and returns the value 1
example_object$a
# [1] 1
# the replace method $<-, when called with arguments example_object, a, and 42,
# replaces the value 1 (at example_object$a) with the value 42
example_object$a <- 42
example_object
# $a
# [1] 42
#
# $b
# [1] 2
因此,对于 S4 classes,setMethod("$", ...)
将定义提取方法 $
的行为,而 setMethod("$<-", ...)
或等效的 setReplaceMethod("$", ...)
将定义替换方法的行为 $<-
。 setReplaceMethod("$")
只是为了比 setMethod("$<-")
更具表现力,以明确您正在为 $
.
使用 S4 的示例 class:
setClass("MyClass", representation(a = "numeric", b = "numeric"))
setMethod("$", signature = "MyClass",
function (x, name) {
if ( name == "a" ) {
return(x@a)
}
else if ( name == "b" ) {
return(x@b)
}
else {
stop(paste("No slot", name, "for MyClass"), call. = FALSE)
}
}
)
# [1] "$"
my_object <- new("MyClass", a = 1, b = 2)
my_object@a
# [1] 1
my_object$a
# [1] 1
my_object@a <- 42
my_object@a
# [1] 42
my_object$a <- 3.14 # will not work because we have not set the method for $<-
# Error in `$<-`(`*tmp*`, a, value = 3.14) :
# no method for assigning subsets of this S4 class
my_object@a
# [1] 42
setReplaceMethod("$", signature = "MyClass",
function(x, name, value) {
if ( name == "a" ) {
x@a <- value
return(x)
}
else if ( name == "b" ) {
x@b <- value
return(x)
}
else {
stop(paste("No slot", name, "for MyClass"),
call. = FALSE)
}
}
)
# [1] "$<-"
my_object$a <- 3.14
my_object@a
# [1] 3.14
这是我的发现。正如@Hong Ooi 在评论中所指出的 setReplaceMethod("fun")
与 setMethod("fun<-")
相同,因此 setReplaceMethod
用于在 R 的 S4 对象系统中创建通用替换函数的方法。
什么是替换函数在what-are-replacement-functions-in-r中有解释。非常粗鲁地,如果你有一个名为 fun<-
的函数,因为它的名称以 <-
结尾,你可以写 fun(x)<-a
而 R 将读作 x <- "fun<-"(x,a)
.
S4 对象系统在 S4 - Advanced R 中描述。
举个例子,也许从为 S4 泛型函数创建一个方法开始会更容易,这不是替换函数:
## Define an S4 class 'Polygon' and an object of this class
setClass("Polygon", representation(sides = "integer"))
p1 <- new("Polygon", sides = 33L)
## Define a generic S4 function 'sides'
sides <- function(object){ NA }
setGeneric("sides")
## sides returns NA
sides( p1 )
## Define a method for 'sides' for the class 'Polygon'
setMethod("sides", signature(object = "Polygon"), function(object) {
object@sides
})
## Now sides returns the sides of p1
sides( p1 )
为通用替换函数创建方法类似:
## Define a generic replacement function 'sides<-'
"sides<-" <- function(object, value){ object }
setGeneric( "sides<-" )
## The generic 'sides<-' doesn't change the object
sides( p1 ) <- 12L
sides( p1 )
## Define a method for 'sides<-' for the class 'Polygon',
## setting the value of the 'sides' slot
setMethod( "sides<-", signature(object = "Polygon"), function(object, value) {
object@sides <- value
object
})
## Now 'sides<-' change the sides of p1
sides( p1 ) <- 12L
sides( p1 )
您还询问了 $<-
。我的猜测是:x$name<-value
被解释为 "$"(x,name)<-value
,然后被解释为 x <- "$<-"(x,name,value)
。请注意,已经定义了通用函数 $<-
(isGeneric("$<-")
),因此我们只为我们的 class 多边形定义一个方法:
setMethod( "$<-", signature(x = "Polygon"), function(x, name, value) {
if( name=="sides" ){
x@sides <- value
}
x
})
## Nothing changes if we try to set 'faces'
p1$faces <- 3L
p1
## but we can set the 'sides'
p1$sides <- 3L
p1
请注意参数 x
、name
和 value
由泛型指定。