一个人怎么会成为dput()S4对象?我试过这个
require(sp)
require(splancs)
plot(0, 0, xlim = c(-100, 100), ylim = c(-100, 100))
poly.d <- getpoly() #draw a pretty polygon - PRETTY!
poly.d <- rbind(poly.d, poly.d[1,]) # close the polygon because of Polygons() and its kin
poly.d <- SpatialPolygons(list(Polygons(list(Polygon(poly.d)), ID = 1)))
poly.d
dput(poly.d)
Run Code Online (Sandbox Code Playgroud)
请注意,如果我dput()是S4对象,我无法重新构建它.你的意见?
假设与特定S4泛型函数/方法关联的所有 S4方法共享一个应该具有特定默认值的形式参数.直觉上,我会在S4 泛型的定义中陈述这样一个论点(而不是在每个方法定义中陈述它对我来说似乎有点多余).
但是,我注意到这种方式我遇到了麻烦,因为似乎没有将形式参数的默认值分派给方法,因此抛出了错误.
这有点不符合通用和方法相结合的想法吗?当默认值始终相同时,为什么我必须再次分别在每个方法中声明形式参数?我可以以某种方式明确地发送正式参数的默认值吗?
您可以在下面找到该行为的简短说明
setGeneric(
name="testFoo",
signature=c("x", "y"),
def=function(
x,
y,
do.both=FALSE,
...
) {
standardGeneric("testFoo")
}
)
Run Code Online (Sandbox Code Playgroud)
setMethod(
f="testFoo",
signature=signature(x="numeric", y="numeric"),
definition=function(
x,
y
) {
if (do.both) {
out <- list(x=x, y=y)
} else {
out <- x
}
return(out)
}
)
Run Code Online (Sandbox Code Playgroud)
> testFoo(x=1, y=2)
Error in .local(x, y, ...) : object 'do.both' not found
Run Code Online (Sandbox Code Playgroud)
do.both修复它setMethod(
f="testFoo",
signature=signature(x="numeric", y="numeric"),
definition=function(
x,
y,
do.both=FALSE
) {
if (do.both) { …Run Code Online (Sandbox Code Playgroud) 我是S4参考类的忠实粉丝,因为它们允许混合编程风格(功能/按值传递与oop/pass-by-reference; 示例),从而大大提高了灵活性.
但是,当我要求它通过方法检索某个字段值时,我认为我刚刚遇到了关于R扫描环境/帧的方式的不良行为$field()(请参阅帮助页面).问题是,如果在实际的本地/目标环境中找不到所需的字段(这将构成S4参考类的环境),R似乎也会查看封闭的环境/框架,即它就像运行一样get(<objname>, inherits=TRUE)(请参阅帮助)页面).
为了具有R只是看在本地/目标的环境,我的想法是这样$field(name="<fieldname>", inherits=FALSE),但$field()没有一个...说法,让我通过inherits=FALSE一起get()(我猜是沿途某处调用).这有解决方法吗?
对于那些对更多细节感兴趣的人:这是一个说明行为的小代码示例
setRefClass("A", fields=list(a="character"))
x <- getRefClass("A")$new(a="a")
Run Code Online (Sandbox Code Playgroud)
有一个领域a类A,所以它在目标环境中找到,返回的值:
> x$field("a")
[1] "a"
Run Code Online (Sandbox Code Playgroud)
如果我们尝试访问不是引用类的字段但恰好具有与工作空间/搜索路径中的某个其他对象的名称相同的字段(在本例中"lm"),则情况会有所不同:
require("MASS")
> x$field("lm")
function (formula, data, subset, weights, na.action, method = "qr",
model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
contrasts = NULL, offset, ...)
{ …Run Code Online (Sandbox Code Playgroud) 我想写一个S4对象,以便它可以传递给只接受S3对象的方法.(似乎setOldClass()可能与此有关,但我从文档中不清楚这一点?)
例如,对于一个最小的例子,想象一下我有S3类和函数:
myS3 <- list(a = 1, b = 2)
class(myS3) <- "myS3class"
myS3function.myS3class <- function(x) x$a + x$b
Run Code Online (Sandbox Code Playgroud)
我有S4对象
setClass("myS4class", representation(a = "numeric", b = "numeric"))
obj <- new("myS4class", a = 1, b = 2)
Run Code Online (Sandbox Code Playgroud)
有什么我可以这样做的吗?
myS3function.myS3class(obj)
Run Code Online (Sandbox Code Playgroud)
给了我同样的东西
myS3function.myS3class(myS3)
Run Code Online (Sandbox Code Playgroud)
通过仅修改S4类?
编辑我这种方法的基本原理是利用S3类的所有现有方法(通常可能来自其他包等),而不必重写它们.我意识到一种方法只是编写一个强制方法(setAs()),将我的S4对象转换为S3对象,但用户总是必须手动执行此步骤.(虽然它有效,但我也有点不清楚使用setAs()S4类到S3类是否是不好的做法,而不是在S4类之间进行映射).
从我阅读文档的方式来看setOldClass,听起来这可以使S3对象像S4对象一样?那是对的吗?如果是这样,我的问题是,是否可以反过来(可能是通过prototype在S4类中设置?).
如果这是不可能的,那么解释为什么这会是一个坏主意的理由呢?
使用s4 OOP系统在r中编程时,必须使用?我没有看到添加到函数名称时有什么不同.是否和是平等的吗?setReplaceMethodsetMethod<-setMethod("$<-")setReplaceMethod("$")
?setReplaceMethod或??setReplaceMethod.除了用法之外什么都没有.roxygen2它创建的方法时,我开始搜索这个问题的答案setReplaceMethodlibrary(methods)
# Create a class
setClass("TestClass", slots = list("slot_one" = "character"))
# Test with setMethod -----------------------
setMethod(f = "$<-", signature = "TestClass",
definition = function(x, name, value) {
if (name == "slot_one") x@slot_one <- as.character(value)
else stop("There is no slot called",name)
return(x)
}
)
# [1] "$<-"
test1 <- …Run Code Online (Sandbox Code Playgroud) 我有一个包含shinyjs函数的包show.今天用户向我报告说,这在使用S4对象时会引入问题,因为"打印" - S4对象使用的show方法在附加时被我的包屏蔽.
例:
library(shinyjs)
setClass("testS4Object",
representation(
ID = "numeric",
Name = "character"
),
prototype(
ID = NA_real_,
Name = NA_character_
)
)
x = new("testS4Object")
x
Run Code Online (Sandbox Code Playgroud)
有一个错误,因为当我们打印它的值时x,它似乎show在幕后调用,但它正在使用shinyjs::show而不是methods::show.通过methods::show(x)明确打印,问题就消失了.但我有点困惑的是,为什么默认情况下S4打印系统在show没有命名空间的情况下调用它 - 这不是危险的,而且这个错误发生的并不是我的软件包的错!
拥有与函数同名的函数被认为是一个非常糟糕的主意methods?我的想法是S4系统应该知道调用自己的show函数或继承的S4 show函数.
编辑:我问哈德利他的想法,他似乎也认为这可能是R中的一个错误,我通过电子邮件发送r-devel来获得他们的意见
我对使用它感到困惑setReplaceMethod().看着?setReplaceMethod没有提供解释,谷歌搜索不是很有帮助.
问题:请解释setReplaceMethod(),它的用法及其工作原理(最好以一个例子为准).
我正在使用texreg为plm生成面板回归的输出表.我想压抑所有gof统计数据的输出.这不是显示R2,而是显示R2和N.我只想显示adj R2.有谁知道这样做的简单方法?
我已经使用S4类编写了一个包,并希望使用函数rbind,cbind和这些定义的类.
因为似乎不可能直接定义rbind和定义cbind为我定义的S4方法rbind2,cbind2而是:
setMethod("rbind2", signature(x="ClassA", y = "ANY"),
function(x, y) {
# Do stuff ...
})
setMethod("cbind2", signature(x="ClassA", y = "ANY"),
function(x, y) {
# Do stuff ...
})
Run Code Online (Sandbox Code Playgroud)
从?cbind2我了解到,需要激活这些函数来methods:::bind_activation从base替换rbind和cbind.
我使用以下.onLoad函数将调用包含在包文件R/zzz.R中:
.onLoad <- function(...) {
# Bind activation of cbind(2) and rbind(2) for S4 classes
methods:::bind_activation(TRUE)
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是,运行R CMD检查我现在得到以下注释,因为我在方法中使用了未导出的函数:
* checking dependencies in R code ... NOTE
Unexported object imported by a ':::' call: 'methods:::bind_activation'
See the …Run Code Online (Sandbox Code Playgroud) 这个问题与这个问题非常相似,但是当我尝试答案时,我会收到一个附加的"注意" R CMD check.虽然它只是一个NOTE我真的想要一个完全干净的检查.
* checking Rd line widths ... NOTE
Error: 8: no comma in argument list following \S4method
Execution halted
Run Code Online (Sandbox Code Playgroud)
如果我传递所有其他参数(i,j,drop)并记录所有参数但我不使用它,我可以摆脱这个.在我看来,如果在这种情况下不相关的情况下添加额外的文档将是一种浪费.
#' An S4 class that stores a list.
#' @export
setClass("testClass",
representation(a="list"))
#' Extract parts of testClass.
#' @param x testClass
#'
setMethod("[", signature(x = "testClass"),
function (x){
print("void function")
}
)
Run Code Online (Sandbox Code Playgroud)
Rd文件导致错误:
% Generated by roxygen2 (4.1.1): do not edit by hand
% Please edit documentation in R/test.R
\docType{methods} …Run Code Online (Sandbox Code Playgroud)