在R中创build一个string连接运算符
我想知道如何在R中编写一个string连接运算符,比如|| SAS,+ Java / C#或Visual Basic中。
最简单的方法就是使用%来创build一个特殊的运算符
`%+%` <- function(a, b) paste(a, b, sep="")
但是这会导致代码中很多丑陋的%
。
我注意到,在Ops组中定义了+
,你可以为这个组编写S4方法,所以也许这样的东西就是要走的路。 不过,我完全没有使用S4语言的经验。 我如何修改上面的函数来使用S4?
正如其他人所说,你不能重写密封的S4方法“+”。 但是,您不需要定义一个新的类来定义string的附加function; 这是不理想的,因为它迫使你转换string类,从而导致更难看的代码。 相反,可以简单地覆盖“+”function:
"+" = function(x,y) { if(is.character(x) || is.character(y)) { return(paste(x , y, sep="")) } else { .Primitive("+")(x,y) } }
那么下面应该都按预期工作:
1 + 4 1:10 + 4 "Help" + "Me"
这个解决scheme有点像黑客攻击,因为你不再使用forms化的方法,而是获得你想要的确切行为的唯一方法。
你也可以使用S3类:
String <- function(x) { class(x) <- c("String", class(x)) x } "+.String" <- function(x,...) { x <- paste(x, paste(..., sep="", collapse=""), sep="", collapse="") String(x) } print.String <- function(x, ...) cat(x) x <- "The quick brown " y <- "fox jumped over " z <- "the lazy dog" String(x) + y + z
我会尝试这个(相对更干净的S3解决scheme)
`+` <- function (e1, e2) UseMethod("+") `+.default` <- function (e1, e2) .Primitive("+")(e1, e2) `+.character` <- function(e1, e2) if(length(e1) == length(e2)) { paste(e1, e2, sep = '') } else stop('String Vectors of Different Lengths')
上面的代码将把+
改成一个通用的,并将+.default
设置为原来的+
,然后将新的方法+.character
添加到+
如果R完全遵守S4,那么以下就足够了:
setMethod("+", signature(e1 = "character", e2 = "character"), function (e1, e2) { paste(e1, e2, sep = "") })
但这给出了一个错误,该方法是密封的:((希望这将改变在R的function版本。
你可以做的最好的是定义新的类“string”,其行为将完全符合“字符”类:
setClass("string", contains="character") string <- function(obj) new("string", as.character(obj))
并定义R允许的最一般的方法:
setMethod("+", signature(e1 = "character", e2 = "ANY"), function (e1, e2) string(paste(e1, as.character(e2), sep = "")))
现在尝试:
tt <- string(44444) tt #An object of class "string" #[1] "44444" tt + 3434 #[1] "444443434" "sfds" + tt #[1] "sfds44444" tt + tt #[1] "4444444444" 343 + tt #Error in 343 + tt : non-numeric argument to binary operator "sdfs" + tt + "dfsd" #An object of class "string" #[1] "sdfs44444dfsd"
你已经给出了自己正确的答案 – R中的所有内容都是一个函数,你不能定义新的操作符。 所以%+%
是一样的好。