R: + = (plus gleich) und ++ (plus plus) äquivalent von c ++ / c # / java usw.?


Antworten:



64

Nach @ GregaKešpret können Sie einen Infix-Operator erstellen:

`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x

6
(+1), aber ein Wort der Warnung. Typing gibt x = %+=% y/2zurück x = (x + y)/2. Das Hinzufügen von Klammern x = %+=% (y/2)löst das Problem.
Knrumsey

@knrumsey Warum ist das so? Ich hätte vermutet, dass Division ein Operator mit höherer Priorität ist.
David Kelley

@ DavidKelley Nicht sicher. Ich bin da bei dir. Ich bin einmal auf dieses Problem gestoßen, als ich an einem Projekt gearbeitet habe, und es hat eine Stunde gedauert, bis ich das Problem gefunden habe.
Knrumsey

Denken Sie daran, dass Sie eine Funktion ausführen und keine Addition ausführen. Funktionen haben die höchste Priorität. Ohne die Klammer wird das y als Funktionseingabe analysiert, wobei die Division der nächste Schritt in der Kette ist. Die Klammern heben die (y / 2) -Operation an den Anfang der Kette.
Justin

33

R hat kein Konzept von increment operator(wie zum Beispiel ++ in C). Es ist jedoch nicht schwierig, eine selbst zu implementieren, zum Beispiel:

inc <- function(x)
{
 eval.parent(substitute(x <- x + 1))
}

In diesem Fall würden Sie anrufen

x <- 10
inc(x)

Es führt jedoch zu einem Funktionsaufruf-Overhead, sodass es langsamer ist als das Eingeben x <- x + 1. Wenn ich mich nicht irre, increment operatorwurde eingeführt, um die Arbeit für den Compiler zu vereinfachen, da er den Code direkt in diese Maschinensprachenanweisungen konvertieren könnte.


3
Diese Funktion kann den Wert nicht zurückgeben und dann wie ein Nachinkrement ++ inkrementieren. Es ist eher ähnlich wie + = oder Vorinkrement ++.
Megatron

Falsch! Inkrementierung wurde nicht eingeführt, um die Arbeit des Compilers zu erleichtern. INCAnweisungen wurden in Prozessoren hauptsächlich zum Implementieren von Zählern eingeführt (vgl. Intel Software Developer's Manual). Ich werde die Antwort aktualisieren.
Banan3'14

19

R hat diese Operationen nicht, da (die meisten) Objekte in R unveränderlich sind. Sie ändern sich nicht. Wenn es so aussieht, als würden Sie ein Objekt ändern, ändern Sie normalerweise eine Kopie.


18
Während Unveränderlichkeit eine großartige / wünschenswerte Eigenschaft für Objekte ist (sprich: weniger Fehler), denke ich nicht, dass Unveränderlichkeit mit der + = Frage zusammenhängt. In anderen Sprachen kann + = auf unveränderliche Typen angewendet werden (wie Zeichenfolgen in .net). Die Operation erstellt einfach ein neues Objekt und weist diesem neuen Objekt die angegebene Variable zu. Die Unveränderlichkeit bleibt erhalten und die Variable wird aktualisiert.
SFun28

4
Guter Punkt. Unveränderlichkeit macht diese Art von Operation jedoch sicherlich weniger natürlich.
Hadley

15

Inkrementieren und Dekrementieren um 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Diese Funktionen scheinen ab HmiscVersion 4.1.0 entfernt worden zu sein.
Lasram

@llasram Wenn ich mir diese Notation ansehe, kann ich niemandem die Schuld geben.
Bers


3

Wir können überschreiben +. Wenn unary +verwendet wird und sein Argument selbst ein unary- +Aufruf ist, erhöhen Sie die relevante Variable in der aufrufenden Umgebung.

`+` <- function(e1,e2){
    # if unary `+`, keep original behavior
    if(missing(e2)) {
      s_e1 <- substitute(e1)
      # if e1 (the argument of unary +) is itself an unary `+` operation
      if(length(s_e1) == 2 && 
         identical(s_e1[[1]], quote(`+`)) && 
         length(s_e1[[2]]) == 1){
        # increment value in parent environment
        eval.parent(substitute(e1 <- e1 + 1,list(e1 = s_e1[[2]])))
      # else unary `+` should just return it's input
      } else e1
    # if binary `+`, keep original behavior
    } else .Primitive("+")(e1,e2)
}

x <- 10
++x
x
# [1] 11

andere Operationen ändern sich nicht:

x + 2
# [1] 13
x ++ 2
# [1] 13
+x
# [1] 11
x
# [1] 11

Tun Sie es aber nicht, da Sie alles verlangsamen werden. Oder machen Sie es in einer anderen Umgebung und stellen Sie sicher, dass diese Anweisungen keine großen Schleifen enthalten.

Sie können dies auch einfach tun:

`++` <- function(x) eval.parent(substitute(x <-x +1))
a <- 1
`++`(a)
a
# [1] 2

-1

Es gibt noch einen anderen Weg, den ich sehr einfach finde, vielleicht ohne Hilfe

Ich benutze <<-für diese Situation Die Operatoren <<-weisen den Wert der übergeordneten Umgebung zu

inc <- function(x)
{
   x <<- x + 1
}

und man kann es so nennen

x <- 0
inc(x)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.