相关疑难解决方法(0)

使用正式方法定义为S3对象调度S3样式

问题相关,但略有不同,希望更清楚.

我正在寻找一种干净的方式来正式注册S4和S3类的方法,但不依赖于可怕的S3-dot-naming-scheme进行调度.一个例子:

setClass("foo");
setClass("bar");

setGeneric("test", function(x, ...){
    standardGeneric("test");
});

setMethod("test", "bar", function(x, ...){
    return("success (bar).");
});

obj1 <- 123;
class(obj1) <- "bar";
test(obj1);
Run Code Online (Sandbox Code Playgroud)

这个例子展示了我们如何test为类的S3对象注册一个方法bar,而不需要命名该函数test.bar,这很好.但是,限制是如果我们以这种方式注册方法,它们将仅被分派到对象的第一个S3类.例如:

obj2 <- 123;
class(obj2) <- c("foo", "bar");
test(obj2);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为S4方法调度只会尝试类foo及其超类.如何扩展此示例,test以便bar在找不到合适的方法时自动选择方法foo?例如S3风格调度,但无需返回命名一切test.footest.bar

总结一下:如何创建一个使用形式方法调度的泛型函数,但另外还要回到具有多个类的S3对象的对象的第二,第三等类.

r cran s4

7
推荐指数
1
解决办法
289
查看次数

将S4调度添加到基本R S3泛型

我正在尝试添加一个merge需要为S4 的空间方法(因为它会调度两个不同对象的类型).

我尝试使用如下的早期解决方案:

#' Merge a SpatialPolygonsDataFrame with a data.frame
#' @param SPDF A SpatialPolygonsDataFrame
#' @param df A data.frame
#' @param \dots Parameters to pass to merge.data.frame
#' 
#' @export
#' @docType methods
#' @rdname merge-methods
setGeneric("merge", function(SPDF, df, ...){
  cat("generic dispatch\n")
  standardGeneric("merge")
})
#' @rdname merge-methods
#' @aliases merge,SpatialPolygonsDataFrame,data.frame-method
setMethod("merge",c("SpatialPolygonsDataFrame","data.frame"), function(SPDF,df,...) {
  cat("method dispatch\n")
})
Run Code Online (Sandbox Code Playgroud)

哪个工作:

x <- 1
class(x) <- "SpatialPolygonsDataFrame"
y <- data.frame()
> merge(x,y)
generic dispatch
method dispatch
Run Code Online (Sandbox Code Playgroud)

你将不得不相信我,如果x实际上是一个SPDF而不是伪造的,它不会返回你实际运行该代码时得到的插槽错误(或者没有,只是使用更宽松的通用以下不会返回错误).SPDF是一种痛苦的创造.

问题是它似乎覆盖了S3调度:

> …
Run Code Online (Sandbox Code Playgroud)

r s4

7
推荐指数
1
解决办法
613
查看次数

使用S3为"+"方法模拟多个调度 - 可能吗?

我有两个类(ab),我想+为它们定义方法.我需要两种类的四种可能组合的不同方法,即:

a + a  method 1
a + b  method 2
b + a  method 3
b + b  method 4
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用S4进行多次调度,但我想知道是否有办法使用S3模拟这种行为.我的方法如下:

a <- "b"
class(a) <- "a"

b <- "e"
class(b) <- "b"

Ops.a <- function(e1, e2){
  if (class(e1) == "a" &
      class(e2) == "a")
    print("a & a")
  if (class(e1) == "a" &
        class(e2) == "b")
    print("a & b")
  if (class(e1) == "b" &
        class(e2) == "a")
    print("b & a")
  NULL
}

a …
Run Code Online (Sandbox Code Playgroud)

r r-s3

7
推荐指数
1
解决办法
667
查看次数

在S3*data.frame上调度自定义方法

我想定义自己的行为(方法),用于将data.frame与新S3类的对象相乘.但我无法弄清楚如何让方法调度以找到我的方法.有办法吗?

首先,我定义S3对象'a'(oldClass"A")和'df'(oldClass"data.frame"):

a <- 4
oldClass(a) <- "A"
df <- data.frame(x=1:2,y=3:4)
Run Code Online (Sandbox Code Playgroud)

然后我使用trace(Ops.data.frame,edit = TRUE)在第一行添加print("Ops.data.frame").这样,我知道何时调用Ops.data.frame.这是一个演示:

a*df
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16
Run Code Online (Sandbox Code Playgroud)

我可以为类"A"定义一个S3方法.

Ops.A <- function(e1, e2) {
  print("Ops.A")
  oldClass(e1) <- oldClass(e1)[oldClass(e1) != "A"]
  oldClass(e2) <- oldClass(e2)[oldClass(e2) != "A"]
  callGeneric(e1, e2)
}
Run Code Online (Sandbox Code Playgroud)

这被称为a而不是 df:

# This successfully calls Ops.A
a*a
# [1] "Ops.A"
# [1] 16

# But this throws an error
a*df
# Error in a * df : non-numeric argument …
Run Code Online (Sandbox Code Playgroud)

r r-s3

6
推荐指数
1
解决办法
270
查看次数

标签 统计

r ×4

r-s3 ×2

s4 ×2

cran ×1