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

146

Hat R ein Konzept von +=(plus gleich) oder ++(plus plus) wie c ++ / c # / andere?

SFun28
quelle
8
Nein, zu tun x += 1oder x++- x = x + 1funktioniert.
Joshua Dawson

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
Baptiste
quelle
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.

Grega Kešpret
quelle
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.

Hadley
quelle
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
Wanderer
quelle
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
Moody_Mudskipper
quelle
-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)
Thevandalyst
quelle