Как уже упоминалось, вы не можете переопределить закрытый метод 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 «Помощь» + «Я»
Это решение кажется немного взломанным, так как вы больше не использует формальные методы, но это единственный способ получить точное поведение, которое вы хотели.
Вы дали правильный ответ - все в R является функцией, и вы не можете определить новых операторов. Таким образом, % +%
так же хорошо, как и получается.
Вы также можете использовать для этого классы S3:
String & lt; - function (x) {class (x) & lt; - c ("String", class (x)) x } "+ .String" & lt; - function (x, ...) {x & lt; - paste (x, paste (..., sep = "", collapse = ""), sep = "", collapse = "") String (x)} print.String & lt; - function (x, ...) cat (x) x & lt; - "Быстро коричневый" y & lt; - "лиса перепрыгнул через" z & lt; - " lazy dog "String (x) + y + z
Я попробую это (относительно более чистое решение S3)
`+` & lt; - function (e1, e2) UseMethod ("+") `+ .default` & lt; - функция (e1, e2) .Primitive («+») (e1, e2) `+ .character` & lt; - function (e1, e2) if (length (e1) == length (e2)) {paste (e1 , e2, sep = '')} else stop ('String Vectors of Different Lengths')
Код выше изменит +
на общий и установит +. default
к оригиналу +
, затем добавить новый метод +. character
to +
Если R будет точно соответствовать S4, было бы достаточно:
setMethod («+», подпись (e1 = «character», e2 = «character»), функция (e1, e2) {paste (e1, e2, sep = "")})
Но это дает ошибку, что метод запечатан: ((Надеюсь, это изменится в функциональные версии R.
Лучшее, что вы можете сделать, это определить новую строку класса, которая будет вести себя точно так же, как класс «character»:
setClass ("string" , содержит = "символ") string & lt; - function (obj) new ("string", as.character (obj))
и определяет наиболее общий метод, который позволяет R: [ ! d7]
setMethod ("+", подпись (e1 = "character", e2 = "ANY"), строка функции (e1, e2) (вставить (e1, as.character (e2), sep = "")))
теперь попробуйте:
tt & lt; - string (44444) tt # Объект класса "string" # [1 ] "44444" tt + 3434 # [1] "444443434" "sfds" + tt # [1] "sfds44444" tt + tt # [1] "4444444444" 343 + tt #Error в 343 + tt: нечисловой аргумент до b inary operator "sdfs" + tt + "dfsd" # Объект класса "string" # [1] "sdfs44444dfsd"
примитив («+»)
допускает смешанные типы (например,TRUE + 1L
,1L + 1.0
). Я предлагаю вам добавить свой собственный ответ, а не изменять принятый ответ. – Joshua Ulrich 17 June 2015 в 00:42