我正在以下列方式创建 money 类的S4对象:
# Create class ------------------------------------------------------------
# Create S4 class object holding money and export to generator function
setClass(Class = "money",
slots = list(currency = "character",
value = "numeric")) -> money
我稍后定义 show 方法:
# Methods -----------------------------------------------------------------
# Create show method
setMethod("show",
"money",
function(object) {
cat(switch(object@currency,
GBP = intToUtf8(163)),
format(
x = round(object@value, 2),
trim = TRUE,
big.mark = ",",
big.interval = 3
),
sep = "")
})
到目前为止它按照承诺的方式运作:
# Create test object
tst_fig <- new(Class = "money",
value = 1e6,
currency = "GBP")
# Show the object
tst_fig
# £1,000,000
我想在该对象上启用基本算术:
>> tst_fig + 1e6
Error in tst_fig + 1000000 : non-numeric argument to binary operator
> tst_fig + 1e6
# £2,000,000
当然这不起作用:
>> setMethod("+",
... "money",
... function(object, x) {
... object@value + x
... })
Error in conformMethod(signature, mnames, fnames, f, fdef, definition) :
in method for ‘+’ with signature ‘e1="money"’: formal arguments (e1 = "money", e2 = "money") omitted in the method definition cannot be in the signature
excellent answer在S3中实施金钱等级时提供了类似的@Roland;在这个问题的上下文中,我有兴趣创建S4类,除了好奇之外没有任何特定原因会以类似的方式运行。关键要求是该对象上的 isS4()
返回 TRUE
。
它打印得格式化得很好,但允许所有操作都能用普通数字进行操作。
答案 0 :(得分:3)
我在自己的问题here中遇到过如何做到这一点。我通常使用setMethod('Arith')
方法,因为当您打算实现多个操作时它更简洁。如果您搜索文档?Arith
,您会看到它列出了不同的操作以及其他S4组泛型。
由于错误提示您需要为e1
方法定义e2
和Arith
。在您的具体情况下,以下工作。
注意 - 要获得所需的输出(即money
类对象),您需要创建一个新的money
对象。
setMethod("+",
c(e1="money", e2="numeric"),
function(e1, e2){
new(Class = "money", value = e1@value + e2, currency = e1@currency)
}
)
tst_fig + 1e6
[1] £2e+06
但是,正如我所说,您可能希望使用.Generic
更通用,更简洁的版本来解释您正在使用的Arith
方法。
setMethod("Arith",
c(e1="money", e2="numeric"),
function(e1, e2)
{
op = .Generic[[1]]
switch(op,
`+` = return(new(Class = "money", value = e1@value + e2, currency = e1@currency))
)
}
)