Die Operatoren, die R dir gibt
R's Operatoren teilen sich in vier Arbeitsgruppen: Arithmetik (+ - * / ^ %% %/%), Vergleich (== != < <= > >=), Logik (& | && || ! xor) und den Zugehörigkeitstest %in%. Zwei Dinge unterscheiden sie von den meisten Sprachen: Fast alle sind vektorisiert - sie arbeiten auf ganzen Vektoren gleichzeitig, elementweise - und R hat zwei UND-Operatoren und zwei ODER-Operatoren, die nicht austauschbar sind. Diese Seite behandelt sie alle, dazu die Vorrangfallen, die still falsche Ergebnisse erzeugen.
Arithmetik: +, -, *, /, ^, %% und %/%
Die ersten fünf tun, was du erwartest. Die beiden prozentumrahmten - %% (Modulo, der Rest) und %/% (Ganzzahldivision, der Quotient) - sind die, nach denen Leute suchen:
Beachte, dass / immer eine Fließkommadivision ausführt - 17 / 5 ist 3.4, nie 3. Willst du den ganzzahligen Teil, ist genau dafür %/% da.
Die Alltagsaufgabe von %% ist Teilbarkeit. Eine Zahl ist gerade, wenn die Division durch 2 keinen Rest lässt:
Diese zweite Zeile ist eine Pause wert: Bei einem negativen Operanden gibt R's %% ein Ergebnis mit dem Vorzeichen des Divisors zurück (-7 %% 3 ist 2, denn -7 = -3 * 3 + 2). Manche Sprachen machen es andersherum; falls du Code portierst, prüf das.
Vergleichsoperatoren sind vektorisiert
==, !=, <, <=, >, >= vergleichen elementweise und geben einen logischen Vektor zurück, keine einzelne Antwort:
Das ist der Motor hinter fast allem Filtern in R - du vergleichst einen ganzen Vektor mit einem Wert, bekommst eine logische Maske und nutzt die Maske zum Teilmengenbilden. Eine Warnung zu == bei Dezimalzahlen: Fließkommazahlen werden näherungsweise gespeichert, deshalb ist 0.1 + 0.2 == 0.3 gleich FALSE. Für Dezimalvergleiche nimm lieber all.equal() oder prüfe abs(x - y) < 1e-9.
Logische Operatoren: & vs. && (die klassische Verwirrung)
R hat zwei UND-Operatoren und zwei ODER-Operatoren, und den falschen zu wählen ist ein Initiationsritus.
& und | sind vektorisiert. Sie kombinieren zwei logische Vektoren elementweise:
Nutze diese immer dann, wenn du einen Filter über Daten baust: df[df$age > 30 & df$city == "Lisbon", ].
&& und || sind skalar und werten verkürzt aus. Sie nehmen Einzelwerte, geben ein einzelnes TRUE/FALSE zurück und überspringen den zweiten Operanden vollständig, wenn der erste die Antwort bereits festlegt:
Diese zweite Zeile zeigt die verkürzte Auswertung: Weil x < 0 gleich FALSE ist, wertet R den stop()-Aufruf nie aus. Genau deshalb gehört && in if()-Bedingungen - du kannst if (!is.na(x) && x > 10) schreiben, und der Teil x > 10 wird sicher übersprungen, wenn x gleich NA ist.
Die Faustregel: &/| für Vektoren und Datenfilter, &&/|| für if()-Bedingungen. Und seit R 4.3 wird das mit Zähnen durchgesetzt: && oder || einen Vektor der Länge größer 1 zu übergeben ist ein Fehler (ältere R-Versionen nutzten stillschweigend nur das erste Element, was jahrelang echte Bugs verbarg).
xor(a, b) rundet die Sammlung ab - TRUE, wenn genau einer der beiden TRUE ist:
%in%: Zugehörigkeit prüfen
x %in% table fragt für jedes Element von x: "Kommt das irgendwo in table vor?" Es ist einer der meistgenutzten Operatoren in echtem R-Code:
Die geprüfte Seite darf ein ganzer Vektor sein, was %in% zum natürlichen Werkzeug macht, um Zeilen anhand einer Menge erlaubter Werte zu filtern.
Es schlägt außerdem die Alternative, die du sonst schreiben würdest - eine Kette von ==, mit | zusammengeklebt:
Bei fünf erlaubten Werten wird die ==-Kette zu einer Wand aus Wiederholung; die %in%-Version lässt einfach den Vektor wachsen. Es gibt einen zweiten, subtileren Vorteil - %in% gibt nie NA zurück:
NA == 1 ist NA, weil R nicht wissen kann, ob ein unbekannter Wert gleich 1 ist - ein Verhalten, das ausführlich unter fehlende Werte behandelt wird. Dieses NA vergiftet dann jedes if(), das es erreicht. %in% umgeht das ganze Problem, indem es stets TRUE oder FALSE antwortet - deshalb ist es die sicherere Wahl für Bedingungen auf möglicherweise fehlenden Daten.
Vorrangfallen
Zwei Operator-Vorrangfallen machen einen überproportionalen Anteil an "R ist kaputt"-Momenten aus. Erstens bindet ^ stärker als das unäre Minus:
Zweitens bindet der Doppelpunkt stärker als binäre Arithmetik:
Im Zweifel setz Klammern. Sie kosten nichts, und jeder Leser (auch dein zukünftiges Ich) liest sie genauso wie der Interpreter.
$ und [ ]: die Zugriffsoperatoren
Du wirst außerdem ständig $, [ ] und [[ ]] sehen - technisch ebenfalls Operatoren, genutzt zum Herausholen von Werten aus Strukturen statt zum Rechnen:
Sie werden ausführlich auf den Seiten zu Vektoren, Listen und Data Frames behandelt - hier reicht es, sie als Mitglieder derselben Operatorfamilie zu erkennen.
Was du mitnimmst
%%liefert den Rest,%/%den ganzzahligen Quotienten;x %% 2 == 0prüft auf gerade Zahlen.- Vergleiche sind vektorisiert - sie geben einen logischen Vektor zurück, mit dem du filtern kannst.
&/|kombinieren Vektoren elementweise;&&/||sind für Einzelwerte inif()und werten verkürzt aus. Seit R 4.3 ist&&auf einem längeren Vektor ein Fehler.x %in% tableersetzt verkettete==und gibt nieNAzurück.-2^2ist-4und1:n - 1beginnt bei 0 - im Zweifel klammern.
Als Nächstes: diese Operatoren in if, else und ifelse() einsetzen - R's bedingte Anweisungen.
Häufig gestellte Fragen
Was macht %% in R?
%% ist der Modulo-Operator - er gibt den Rest einer Division zurück. 17 %% 5 ist 2. Sein Gegenstück %/% führt eine Ganzzahldivision durch und liefert den Quotienten ohne Rest: 17 %/% 5 ist 3. Der klassische Einsatz von %% ist der Test auf gerade Zahlen: x %% 2 == 0.
Was ist der Unterschied zwischen & und && in R?
& ist vektorisiert: Es vergleicht zwei Vektoren elementweise und gibt einen Vektor gleicher Länge zurück. && arbeitet nur mit Einzelwerten, wertet verkürzt aus (überspringt den zweiten Operanden, wenn der erste das Ergebnis bereits entscheidet) und liefert genau ein TRUE oder FALSE. Nutze & beim Filtern von Vektoren und && in if()-Bedingungen. Seit R 4.3 ist es ein Fehler, && oder || einen Vektor länger als 1 zu übergeben, keine Warnung.
Was macht %in% in R?
x %in% table prüft, ob jedes Element von x irgendwo in table vorkommt, und gibt pro Element TRUE oder FALSE zurück. "mango" %in% basket ersetzt eine Kette von ==-Vergleichen, die mit | verknüpft sind, und anders als == gibt es nie NA zurück - ein fehlender Wert auf der geprüften Seite ergibt einfach FALSE.
Warum ergibt -2^2 in R -4?
Weil ^ stärker bindet als das unäre Minus, liest R -2^2 als -(2^2), also -4. Wenn du das Quadrat von minus zwei meinst, schreib (-2)^2, was 4 ergibt. Der Doppelpunkt hat eine ähnliche Falle: 1:n - 1 bedeutet (1:n) - 1, nicht 1:(n - 1).