r - R 如何找到 S3 方法?为什么 R 找不到我的 S3 `+` 方法?

标签 r methods r-s3 search-path method-dispatch

我想创建并附加一个包含S3方法的环境,并让R在搜索路径中找到它们,通过使用方法名称 (即,我应该能够使 infix-style a + b 工作,而不必编写 prefix-style “+.Foo”(a, b))。我究竟做错了什么?虽然相当长,但我可以在合理的时间内想到的最短的例子如下。评论详细阐述了情况和问题。

更新:我已根据所选答案附加了更多代码。

# **** CLEAR THE USER WORKSPACE / GLOBAL ENVIRONMENT ****
rm(list = ls( all = TRUE ))

# **** RESET THE SEARCH PATH. (I'VE NEVER HAD AN R INSTALLATION THAT DOESN'T BOOT ****
# **** WITH package:stats AS THE SECOND-TO-LAST ITEM ON THE SEARCH PATH.)                   ****
while (search()[[2]] != "package:stats") detach()

search ()
# [1] ".GlobalEnv" "package:stats" "package:graphics" "package:grDevices" "package:utils"
# [6] "package:datasets" "package:methods" "Autoloads" "package:base"     

x <- 1L
class (x) <- "Foo"

`+.Foo` <- function ( x , y ) {
    cat("This is `x.Foo`\n")
    # "non-standard" addition on purpose
    z <- -1L * ( as.integer(x) + as.integer(y) )
    class(z) <- "Foo"
    z }

x + x
# This is `x.Foo`
# [1] -2
# attr(,"class")
# [1] "Foo"

# Note that R finds `x.Foo` in the global environment.

FooEnv <- new.env(parent = as.environment(search()[[2]]))
attr(FooEnv, "name") <- "FooEnv"
FooEnv
# <environment: 0xhhhhhhhhhhhhhhhh> ## Each h is a hex-digit.
# attr(,"name")
# [1] "FooEnv"

parent.env(FooEnv)
# <environment: package:stats>
# attr(,"name")
# [1] "package:stats"
# attr(,"path")
# [1] "C:/Program Files/R/R-4.0.3/library/stats"

# The path above will vary with the R installation.

# I want the next 3 lines of R code is to replace `+.Foo` in the global environment
# with `x.Foo` on the search path.
FooEnv $ `+.Foo` <- `+.Foo`
rm(`+.Foo`)
attach(what = FooEnv, name = attr(FooEnv, "name"))

search()
# [1] ".GlobalEnv" "FooEnv" "package:stats" "package:graphics" "package:grDevices"
# [6] "package:utils" "package:datasets" "package:methods" "Autoloads" "package:base"    

x + x
# [1] 2
# attr(,"class")
# [1] "Foo"

## Note lack of "This is `x.Foo`".
## Note the sign.
## This is not the `+` we're looking for.

# `methods` finds `+.Foo`:
methods("+")
# [1] +.Date +.Foo +.POSIXt
# see '?methods' for accessing help and source code

# `find` finds `+.Foo`
find("+.Foo")
# [1] "FooEnv"

# Although the following works, I want to call `x.Foo` using infix style.
`+.Foo`(x, x)
# This is `x.Foo`
# [1] -2
# attr(,"class")
# [1] "Foo"

write.dcf(R.Version())
# platform: x86_64-w64-mingw32
# arch: x86_64
# os: mingw32
# system: x86_64, mingw32
# status:
# major: 4
# minor: 0.3
# year: 2020
# month: 10
# day: 10
# svn rev: 79318
# language: R
# version.string: R version 4.0.3 (2020-10-10)
# nickname: Bunny-Wunnies Freak Out

# `.S3method` seems to do the trick. Acknowledgement: @MrFlick
.S3method("+", "Foo")
x + x
# This is `x.Foo`
# [1] -2
# attr(,"class")
# [1] "Foo"

最佳答案

如果您没有将 S3 方法注册为包命名空间的一部分或在全局环境中,则需要使用 .S3method() 函数显式注册它。所以在这种情况下你会这样做

.S3method("+", "Foo", FooEnv$`+.Foo`)

此问题在此处进一步讨论:https://developer.r-project.org/Blog/public/2019/08/19/s3-method-lookup/

关于r - R 如何找到 S3 方法?为什么 R 找不到我的 S3 `+` 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68076411/

相关文章:

oop - R中的矩阵丢失类属性

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

r - 在 R6 类上实现 S3 调度的正确方法

r - 从数据帧的第 n 列中获取值,每行 n 不同

r - 使用 R/knitr 自动生成 LaTeX Beamer 幻灯片

java - 在文本文件中查找字符串的方法。然后让以下行达到一定限度

android - MediaPlayer.create 和 setDataSource 实现之间的区别

r - R 中 Shiny : Is it possible to output a color using renderText?

r - 使用条件变异分配多个值

java - Java中递归删除字符