Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在S3*data.frame上分派自定义方法_R_R S3 - Fatal编程技术网

在S3*data.frame上分派自定义方法

在S3*data.frame上分派自定义方法,r,r-s3,R,R S3,我想为a的乘法定义我自己的行为(方法) 带有新S3类对象的data.frame。但我不知道该怎么做 方法分派以查找我的方法。有办法吗 首先,我定义S3对象“a”(oldClass“a”)和“df”(oldClass“data.frame”): 我可以为类“A”定义一个S3方法 所以那是行不通的 remove(Ops.A) 那么改用S4方法呢?这需要定义S4类“A”,但通常S4调度仍会找到具有旧类“A”的S3对象 setClass("A", list("numeric")) # Required

我想为a的乘法定义我自己的行为(方法) 带有新S3类对象的data.frame。但我不知道该怎么做 方法分派以查找我的方法。有办法吗

首先,我定义S3对象“a”(oldClass“a”)和“df”(oldClass“data.frame”):

我可以为类“A”定义一个S3方法

所以那是行不通的

remove(Ops.A)
那么改用S4方法呢?这需要定义S4类“A”,但通常S4调度仍会找到具有旧类“A”的S3对象

setClass("A", list("numeric")) # Required to define a method for "A"
setGeneric("ATypicalMethod", function(e1, e2) {print("ATypicalMethod - default")})
setMethod("ATypicalMethod", signature=c("A","A"), function(e1, e2) {print("ATypicalMethod - A,A")})
ATypicalMethod(a,a)
# [1] "ATypicalMethod - A,A"
setOldClass("A", S4Class="A")
a*df
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16
然而,这对老年退休金计划不起作用

setMethod("Ops", signature=c("A","data.frame"), function(e1, e2) {
  print("Ops(A,data.frame)")
  callGeneric(e1@.Data, e2)
})
# Nope - when the scalar is an S3 object, we never find Ops(A,data.frame):
a*df
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16
adf的这种行为由Martin Morgan解释 ()和?方法,谁说如果 直接调用S3泛型,则永远找不到S4方法; 这似乎发生在adf中,因为a和df都是S3对象

同时调用
setOldClass
,对任何人都没有帮助;问题不在于S4方法调度无法识别S3对象,而是当两个S3对象被传递给
*
之类的方法时,没有找到它。在这些情况下,将直接调用S3泛型,并且S4标记的数量不会导致S4调度

setClass("A", list("numeric")) # Required to define a method for "A"
setGeneric("ATypicalMethod", function(e1, e2) {print("ATypicalMethod - default")})
setMethod("ATypicalMethod", signature=c("A","A"), function(e1, e2) {print("ATypicalMethod - A,A")})
ATypicalMethod(a,a)
# [1] "ATypicalMethod - A,A"
setOldClass("A", S4Class="A")
a*df
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16
所以现在我不知所措。我找不到方法让
*
为我的S3对象发现一个S4方法,也找不到方法编写一个S3方法来取代data.frame方法

如果我愿意将标量作为S4对象,我可以得到我想要的分派:

a <- new("A", 4)
a*df
# [1] "Ops(A,data.frame)"
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16

a非常丑陋的方法:重写'*'函数

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

my_add_df <- function(e1, e2) {
  print('my_add_df')
  print(e1)
  print(e2)
}

`*` <- function(e1, e2) {
  if (inherits(e1, 'A') && inherits(e2, 'data.frame'))
    my_add_df(e1, e2)
  else 
    .Primitive("*")(e1, e2)
}

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

my_add_df <- function(e1, e2) {
  print('my_add_df')
  print(e1)
  print(e2)
}

`*` <- function(e1, e2) {
  if (inherits(e1, 'A') && inherits(e2, 'data.frame'))
    my_add_df(e1, e2)
  else 
    .Primitive("*")(e1, e2)
}

a
help(“groupGeneric”)
:“如果只为一个参数找到了一个方法,或者为两个参数找到了相同的方法,则会使用该方法。如果找到不同的方法,则会发出关于“不兼容方法”的警告:在这种情况下,或者如果没有为任一参数找到方法,则会使用内部方法。”@Roland-right。有没有办法解决这个问题,或者我必须放弃?我相信S3是做不到的。我对S4的了解不足以完全回答这个问题。@Roland-好的,这是一个有用的部分答案。谢谢。如果您使用setOldCLass将S3升级为S4会怎么样?
a <- new("A", 4)
a*df
# [1] "Ops(A,data.frame)"
# [1] "Ops.data.frame"
# x  y
# 1 4 12
# 2 8 16
a <- 4
oldClass(a) <- "A"
df <- data.frame(x=1:2,y=3:4)

my_add_df <- function(e1, e2) {
  print('my_add_df')
  print(e1)
  print(e2)
}

`*` <- function(e1, e2) {
  if (inherits(e1, 'A') && inherits(e2, 'data.frame'))
    my_add_df(e1, e2)
  else 
    .Primitive("*")(e1, e2)
}

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

my_add_df <- function(e1, e2) {
  print('my_add_df')
  print(e1)
  print(e2)
}

`*` <- function(e1, e2) {
  if (inherits(e1, 'A') && inherits(e2, 'data.frame'))
    my_add_df(e1, e2)
  else 
    .Primitive("*")(e1, e2)
}