[英]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.