Создание оператора конкатенации строк в R

мне было интересно, как можно написать оператор конкатенации строк в R, что-то вроде || в SAS, + в Java/C# или & в Visual Basic.

самый простой способ-создать специальный оператор, используя%, например

`%+%` <- function(a, b) paste(a, b, sep="")

но это приводит к много уродливых %в коде.

Я заметил, что + определяется в группе Ops, и вы можете написать методы S4 для этой группы, поэтому, возможно, что-то подобное было бы способом. Однако у меня нет опыта работы с языковыми функциями S4 вообще. Как изменить вышеуказанную функцию для использования S4?

5 ответов


Как упоминали другие, вы не можете переопределить запечатанный метод S4"+". Однако вам не нужно определять новый класс, чтобы определить функцию добавления для строк; это не идеально, так как это заставляет вас конвертировать класс строк и, таким образом, приводит к более уродливому коду. Вместо этого можно просто перезаписать функцию"+":

"+" = 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"

это решение немного похоже на хак, так как вы не уже используя официальные методы, но это единственный способ получить точное поведение, которое вы хотели.


вы также можете использовать классы 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)

`+` <- 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 будет thoroghlly соответствуют С4, следующее Было бы достаточно:

setMethod("+",
          signature(e1 = "character", e2 = "character"),
          function (e1, e2) {
              paste(e1, e2, sep = "")
      })

но это дает ошибку, что метод не опечатался :((. Надеемся, что это изменится в версии Р.

лучшее, что вы можете сделать, это определить новый класс "string", который будет вести себя точно так же, как класс" character":

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 является функцией, и вы не можете определить новые операторы. Так что %+% Так же хорошо, как он получает.