简体   繁体   English

如何在R中定义一个用于存储用户定义函数的类?

[英]How can I define a class in R for storing user defined functions?

I come from using C#, PHP, javascript, etc. To me, it makes sense to be able to do something like: 我来自使用C#,PHP,javascript等。对我来说,能够执行以下操作很有意义:

class SomeClass {
    public function myFunction($var) {
        echo $var;
    }
}

$myClass = new SomeClass();

$myClass->myFunction('test');

I want to do this with R - is there something equivalent to this to help avoid naming conflicts? 我想用R做到这一点-是否有与此等效的方法来帮助避免命名冲突? every time I load a package it tells me there are functions with common names in other packages and I just want to do avoid this. 每次加载一个程序包时,它都会告诉我其他程序包中有一些具有通用名称的函数,我只是想避免这种情况。

R reference classes have that 'feel' R参考类具有“感觉”

.SomeClass <- setRefClass("SomeClass",
    methods = list(
      myFunction = function(var) {
          message(var)
      }))

and then 接着

> myClass <- .SomeClass()
> myClass$myFunction('test')
test

In many cases a different solution is to use the S3 or S4 object system, and to implement methods on existing or newly created generics. 在许多情况下,不同的解决方案是使用S3或S4对象系统,并在现有或新创建的泛型上实现方法。 The S4 version might look like S4版本可能看起来像

.A <- setClass("A",
  representation=representation(
    name="character",
    age="integer"))

A <- function(name=character(), age=integer(), ...)
    ## constructor: type check / coercion, then create
    .A(name=as.character(name), age=as.integer(age), ...)

setMethod("length", "A", function(x) {
    ## getGeneric("length") to discover existing generic
    length(x@name)
})

setMethod("show", "A", function(object) {
    ## how to display the object -- existing generic 'show'
    cat("class:", class(object), "\n")
    cat("length:", length(object), "\n")
    cat("name:", paste(sQuote(object@name), collapse=", "), "\n")
    cat("age:", paste(object@age, collapse=", "), "\n")
})

setGeneric("toupper")                   # no existing generic; create one

setMethod("toupper", "A", function(x) {
    ## use default 'initialize' method as copy constructor; return a
    ## new (updated) instance
    initialize(x, name=toupper(x@name))
})

and in use: 并在使用中:

> a <- A(c("fred", "ginger"), c(88, 83))
> a
class: A 
length: 2 
name: 'fred', 'ginger' 
age: 88, 83 
> toupper(a)
class: A 
length: 2 
name: 'FRED', 'GINGER' 
age: 88, 83 

And the S3 version (note that there is no class definition, other than in the constructor): 和S3版本(请注意,除了构造函数外,没有类定义):

B <- function(name, age) {
    obj <- list(name=as.character(name), age=as.integer(age))
    class(obj) <- "B"
    obj
}

length.B <- function(x)
    ## 'length' is an S3 generic, but hard to know
    length(x$name)

print.B <- function(x, ...) {
    ## 'print' at the command line contains body UseMethod --
    ## signalling an existing S3 generic
    cat("class:", class(x), "\n")
    cat("length:", length(x), "\n")
    cat("name:", paste(sQuote(x$name), collapse=", "), "\n")
    cat("age:", paste(x$age, collapse=", "), "\n")
}

toupper.default <- base::toupper

toupper <- function(x, ...)
    UseMethod("toupper")

toupper.B <- function(x, ...) {
    x$name <- toupper(x$name)
    x
}

Perhaps both S3 and S4 implementations of new generics on existing functions cause a message about 'masking' when the new generic is exported from your package, so that doesn't really help with your question. 在从您的包中导出新泛型时,可能对现有函数的新泛型的S3和S4实现都会引起有关“屏蔽”的消息,因此这实际上对您的问题没有帮助。 In the example above the functionality of toupper() available in the base package is retained even if your generic masks the original definition; 在上面的示例中,即使通用屏蔽了原始定义,基本包中toupper()的功能仍然保留。 problems arise in S4 when package A defines a generic toupper, and package B defines a generic toupper, so that the user needs to disambiguate A::toupper() to get the correct table of methods. 当程序包A定义一个通用的toupper,而程序包B定义一个通用的toupper时,S4中会出现问题,因此用户需要消除A::toupper()歧义以获得正确的方法表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM