问题描述
我有一个称为foo
的通用函数.它在类bar
和baz
上的操作不同,但是有一些共享的预处理仅需要执行一次. R的惯用方式是什么?
I have a generic function called foo
. It operates differently on the classes bar
and baz
but there is some shared pre-processing that needs to only be done once. What is the idiomatic R way of carrying this out?
在下面的愚蠢示例中,我想将传递给泛型的对象乘以10.但是,当调用该方法时,原始值将打印到控制台.我已经阅读了语言定义,并且知道以下模式不起作用.我的问题是:在调用该方法之前,应该在哪里或应该在哪里处理通用参数的共享处理?
In my silly example below, I want to multiply the object being passed to the generic by 10. Yet when the method is called, the original value is printed to the console. I have read the language definition and know that the below pattern does not work. My question is: Where or how should I handle shared processing of generic arguments before calling the method?
a <- structure(1:5, class="bar")
b <- structure(6:10, class="baz")
foo <- function(x) {
x <- x * 10 # where should shared preprocessing go?
UseMethod("foo")
}
foo.bar <- function(x) {
cat("Foo!", x)
}
foo.baz <- function(x) {
cat("Baz!", x)
}
# does not propagate the operations carried out `foo`
foo(a)
foo(b)
推荐答案
1)在实际泛型之上的foo层更改foo
以执行初步代码并调用foo_
新泛型如图所示.将foo.bar
和foo.baz
分别重命名为foo_.bar
和foo_.baz
,以便我们可以使用(在示例中还添加了换行符):
1) Layer foo on top of actual generic Change foo
to perform the preliminary code and invoke foo_
a new generic as shown. Rename foo.bar
and foo.baz
to foo_.bar
and foo_.baz
respectively so that we are left with (have also added newlines to the example):
foo <- function(x) {
x <- x * 10
foo_(x)
}
foo_ <- function(x) UseMethod("foo_")
foo_.bar <- function(x) cat("Foo!", x, "\n")
foo_.baz <- function(x) cat("Baz!", x, "\n")
现在进行测试:
a <- structure(1:5, class="bar")
b <- structure(6:10, class="baz")
foo(a)
## Foo! 10 20 30 40 50
foo(b)
## Baz! 60 70 80 90 100
有关广泛使用的软件包中的此示例,请参见 dplyr :: mutate
For an example of this in a widely used package see the source of dplyr::mutate
2)NextMethod 另一种方法是给每个对象一个具有两个类的类向量,其中"foo"
在a
和"baz"
的情况下是"bar"
的子类.在b
的情况下.然后使用NextMethod
.解决方案(1)似乎更简单,并且"foo"
是"bar"
和"baz"
的子类似乎很奇怪,但是这里是一个示例,以防万一:
2) NextMethod Another way would be to give every object a class vector of two classes with "foo"
made a subclass of "bar"
in the case of a
and of "baz"
in the case of b
. Then use NextMethod
. Solution (1) seems simpler and it may seem weird that "foo"
is a subclass of both "bar"
and "baz"
but here is an example of this one just in case:
foo <- function(x) UseMethod("foo")
foo.foo <- function(x) {
x <- x * 10
NextMethod()
}
foo.bar <- function(x) cat("Foo!", x, "\n")
foo.baz <- function(x) cat("Baz!", x, "\n")
测试一下,注意到我们已经更改了a
和b
的定义,以便它们可以使用这种方法:
Test it noting that we have changed the definitions of a
and b
so that they work with this approach:
a <- structure(1:5, class= c("foo", "bar"))
b <- structure(6:10, class = c("foo", "baz"))
foo(a)
## Foo! 10 20 30 40 50
foo(b)
## Baz! 60 70 80 90 100
这篇关于R模式修改传递给泛型函数的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!