R语言 强制执行指定的S3方法

m4pnthwp  于 2023-03-27  发布在  其他
关注(0)|答案(2)|浏览(129)

我在我的软件包中使用{patchwork}软件包。我想利用patchwork算术运算符(即|\等)。
我为我的对象类导出方法。例如:

"|.ggsurvfit" <- function(e1, e2) {
  build_and_wrap(e1) | build_and_wrap(e2)
}

在上面的示例中,当传递类'ggsurvfit'的图形时,它会被处理并转换为类'ggplot',然后使用补丁方法"|.ggplot"执行。
我遇到的问题是,用户需要将典型的ggplot与ggsurvfit图结合起来。例如p1 | p2,其中p1具有类'ggplot',p2具有类'ggsurvfit'。补丁包导出了正在使用的|.ggplot方法。但我们得到了一个错误,因为|.ggplot没有'我不知道如何处理第二个参数,即类'ggsurvfit'。
我试图写一个S3方法|.ggplot来适当地处理第二个参数。但是我不能让任何东西工作...唉!
是否有办法通过指定的S3方法强制执行某些代码,即如何使用patchwork的|.ggplot方法强制执行?

"|.ggplot" <- function(e1, e2) {
  e2 <- build_and_wrap(e2) # process the second argument

  # patch together the figures using the patwork `|.ggplot` method
  withr::with_namespace(
    package = "patchwork",
    code = e1 | e2
  )
}
knpiaxh1

knpiaxh11#

S3不是为多重分派而设计的。S4是。一个原则性的方法是将ggsurvfit定义为ggplot的S4子类,然后为|(或任何其他内部通用的二元运算符)定义合适的S4方法。

setOldClass("ggplot")
setClass("ggsurvfit", contains = "ggplot", slots = c(p = "ggplot"))

setMethod("|", c("ggplot", "ggsurvfit"), 
          function(e1, e2) <do stuff with e1   and e2@p here>)
setMethod("|", c("ggsurvfit", "ggplot"), 
          function(e1, e2) <do stuff with e1@p and e2   here>)
setMethod("|", c("ggsurvfit", "ggsurvfit"), 
          function(e1, e2) <do stuff with e1@p and e2@p here>)

您的软件包的DESCRIPTIONNAMESPACE文件需要相应地更改。
我们可以用一个简单的例子来测试这是否有效。这里,类ab代替了类ggplotggsurvfit,S3方法|.a代替了patchwork中的|.ggplot

setOldClass("a")
setClass("b", contains = "a", slots = c(p = "a"))

.S3method("|",   "a",       function(e1, e2) "aa")
setMethod("|", c("a", "b"), function(e1, e2) "ab")
setMethod("|", c("b", "a"), function(e1, e2) "ba")
setMethod("|", c("b", "b"), function(e1, e2) "bb")

a <- structure(1, class = "a")
b <- new("b", p = structure(2, class = "a"))

a | a
## [1] "aa"
a | b
## [1] "ab"
b | a
## [1] "ba"
b | b
## [1] "bb"

有关S3和S4混合使用的更多详细信息,您可以查看?Methods_for_S3?setOldClass?S3Part

qoefvg9y

qoefvg9y2#

以下方法似乎有效。
不要重载运算符|.ggplot,而是使用中缀运算符的标准R语法定义一个新的泛型,然后为"ggplot"类的对象定义一个方法。

library(ggplot2)
library(ggsurvfit)
library(patchwork)

"%|%" <- function(e1, ...) UseMethod("%|%", e1)
"%|%.ggplot" <- function(e1, e2) {
  #e2 <- build_and_wrap(e2) # process the second argument
  
  # patch together the figures using the patwork `|.ggplot` method
  withr::with_namespace(
    package = "patchwork",
    code = e1 | e2
  )
}

g1 <- ggplot(mtcars, aes(disp, mpg)) +
  geom_point()
g2 <- survfit2(Surv(time, status) ~ sex, data = df_lung) |>
  ggsurvfit()

g1 %|% g2

创建于2022-10-14带有reprex v2.0.2

编辑

这里有另一个想法,在新的方法体中,不需要使用中缀符号来调用patchwork:::|.ggplot,所以,不要。

library(ggplot2)
library(ggsurvfit)
library(patchwork)

"|.ggplot" <- function(e1, e2) {
  #e2 <- build_and_wrap(e2) # process the second argument
  
  # patch together the figures using the patwork `|.ggplot` method
  withr::with_namespace(
    package = "patchwork",
    code = patchwork:::`|.ggplot`(e1, e2)
  )
}

g1 <- ggplot(mtcars, aes(disp, mpg)) +
  geom_point()
g2 <- survfit2(Surv(time, status) ~ sex, data = df_lung) |>
  ggsurvfit()

g1 | g2

创建于2022-10-14带有reprex v2.0.2

相关问题