numeric und integer: R's zwei Zahlentypen
R speichert Zahlen auf zwei Arten. Numeric (als Fließkommazahl doppelter Genauigkeit gespeichert) ist der Standard - jede Zahl, die du tippst, ist ein Double, sofern du nichts anderes sagst. Integer ist ein eigener, exakter Ganzzahltyp, den du mit dem L-Suffix anforderst:
In der Praxis musst du dich selten darum kümmern: R konvertiert stillschweigend zwischen beiden, und is.numeric() ist für beide TRUE (siehe Datentypen für das komplette Typsystem). Die eine Stelle, an der der Unterschied durchschlägt, ist die Division - / liefert immer ein Double, selbst zwischen zwei Integers:
Integers tauchen meist als Ergebnis von Zählfunktionen auf (length(), seq_len(), nrow()) und als Indexwerte. Wenn du Ganzzahldivision brauchst, hat R einen eigenen Operator dafür - weiter unten behandelt.
Die Rundungsfamilie
R bietet dir fünf Wege, eine Zahl zu stutzen, jeder mit eigener Bedeutung:
round(x, digits)- auf eine Anzahl Nachkommastellen (Standard 0).floor(x)- abwärts zur nächsten ganzen Zahl, stets Richtung negativ unendlich.ceiling(x)- aufwärts, stets Richtung positiv unendlich.trunc(x)- schneidet die Nachkommastellen ab, stets Richtung null. Beachte den Unterschied bei negativen Zahlen:trunc(-2.7)ist-2, aberfloor(-2.7)ist-3.signif(x, digits)- auf eine Anzahl signifikanter Stellen, nicht Nachkommastellen:signif(123456, 2)ist120000.
Und eine berühmte Überraschung: round() verwendet bei exakten Hälften round half to even (kaufmännisch-symmetrisches Runden) gemäß IEEE-754-Standard:
Das gibt 0 2 2 4 aus - jede Hälfte rundet zur nächsten geraden Zahl. Das ist kein Bug; es verhindert eine systematische Aufwärtsverzerrung, wenn du viele gerundete Werte summierst. Braucht ein Bericht Schulrundung, füge einen winzigen Aufschlag hinzu oder formatiere stattdessen erst in der Darstellungsschicht.
Alltägliche Mathematikfunktionen
Die Grundlagen funktionieren genau so, wie man es erwartet:
sqrt() ist die Quadratwurzel, abs() der Absolutbetrag, ^ die Potenzierung, und exp(x) ist e hoch x - also ist exp(1) die eulersche Zahl, etwa 2,718282.
Die eine Funktion, die Leute stolpern lässt, ist log(). In R ist log() der natürliche Logarithmus (Basis e), nicht Basis 10:
Die erste Zeile gibt ungefähr 4.60517 aus - nicht die 2, die ein Basis-10-Leser erwartet. Greif zu log10() und log2(), wenn du diese Basen meinst, oder übergib base = explizit. (Diese Konvention ist in der Statistik Standard, wo der natürliche Logarithmus der Normalfall ist.)
Modulo %% und Ganzzahldivision %/%
Zwei Operatoren decken die Restarithmetik ab:
%% ist der Modulo (Rest): 17 geteilt durch 5 ist 3 Rest 2. %/% ist die Ganzzahldivision: wie viele ganze 5er in 17 passen. Zusammen erfüllen sie x == (x %/% y) * y + (x %% y).
Der klassische Einsatz von %% ist das Prüfen der Teilbarkeit:
Eine Feinheit bei negativen Zahlen: R's %% übernimmt das Vorzeichen des Divisors (wie Python, anders als C):
Das ergibt 2, nicht -1 - R beantwortet "Was addiere ich zu einem Vielfachen von 3, um -7 zu erreichen?", was Ergebnisse bei positivem Divisor in 0..2 hält. Praktisch für zyklische Indizes; überraschend, wenn du von C oder Java kommst.
Sonderwerte: Inf, -Inf und NaN
R's Zahlen folgen IEEE 754, weshalb manche Operationen Sonderwerte statt Fehler erzeugen:
1/0 ist Inf (unendlich), -1/0 ist -Inf, und 0/0 - eine wirklich undefinierte Größe - ist NaN, "not a number". Die Unterscheidung zählt: Inf ist eine Antwort ("größer als alles"), NaN das Fehlen einer solchen. Getestet wird mit eigenen Funktionen, denn == NaN funktioniert nie:
Beachte die letzte Zeile: NaN zählt auch als NA, also fängt is.na() es ab - ein weiterer Grund, warum is.na() die Standardprüfung "Ist dieser Wert unbrauchbar?" ist (mehr dazu unter fehlende Werte).
R liest und schreibt außerdem wissenschaftliche Notation nativ - 2.5e3 ist 2500, und sehr kleine oder große Zahlen werden standardmäßig in E-Notation ausgegeben:
Nutze format(x, scientific = FALSE) (oder die scipen-Option), wenn ein Bericht schlichte Dezimalzahlen braucht.
Die Fließkomma-Überraschung
Jede Sprache, die Dezimalzahlen binär speichert, teilt diese eine Eigenheit, und R ist keine Ausnahme:
FALSE - denn 0.1 + 0.2 ist tatsächlich 0.30000000000000004. Weder 0.1 noch 0.2 hat eine exakte Binärdarstellung, und die winzigen Fehler summieren sich. R's Standardausgabe verbirgt das, indem sie 7 signifikante Stellen zeigt - deshalb wirkt das Problem unsichtbar, bis ein ==-Vergleich scheitert.
Die Regel: Vergleiche berechnete Dezimalzahlen nie mit ==. Nutze all.equal(), das innerhalb einer sinnvollen Toleranz vergleicht:
Pack es in isTRUE(), denn all.equal() gibt bei Abweichungen eine Beschreibung des Unterschieds zurück (nicht FALSE). Für Ganzzahlarbeit, bei der Exaktheit zählt, sind Integers bis etwa 2,1 Milliarden exakt - ein weiterer Grund, warum zählender Code den Integer-Typ nutzt.
Was du mitnimmst
- Jede getippte Zahl ist ein Double;
42Lerzeugt einen Integer, und/liefert unabhängig davon ein Double. round()rundet Hälften zur geraden Zahl;floor/ceiling/trunc/signifstutzen jeweils anders - wisse, welches du meinst.log()ist der natürliche Logarithmus; nutzelog10(),log2()oderbase =für andere Basen.%%liefert den Rest (Vorzeichen folgt dem Divisor),%/%den ganzzahligen Quotienten.1/0istInf,0/0istNaN, und0.1 + 0.2 != 0.3- vergleiche Dezimalzahlen mitall.equal(), nie mit==.
Als Nächstes: die andere Hälfte des Datenalltags - Zeichenketten und die Funktionen, die R zum Bauen, Formatieren und Durchsuchen bietet.
Häufig gestellte Fragen
Was ist der Unterschied zwischen numeric und integer in R?
Numeric (double) ist R's Standard für jede getippte Zahl - 42 ist ein Double, auch wenn es ganzzahlig aussieht. Integer ist ein eigener Speichertyp, den du mit L-Suffix anforderst: 42L. Normale Division liefert immer ein Double, selbst zwischen Integers; für Ganzzahldivision nimm %/%.
Ist log() in R der natürliche Logarithmus?
Ja - log(x) ist in R der natürliche Logarithmus (Basis e), nicht Basis 10. Nutze log10() für Basis 10, log2() für Basis 2 oder log(x, base = b) für beliebige Basen. log(100) ist etwa 4,605, nicht 2.
Wie funktioniert round() in R?
round(x, digits) rundet auf die angegebene Zahl von Nachkommastellen, aber exakte Hälften folgen dem "round half to even"-Verfahren (kaufmännisch-symmetrisches Runden): round(2.5) ist 2 und round(3.5) ist 4. Das folgt dem IEEE-754-Standard und reduziert Verzerrungen beim Summieren gerundeter Werte, überrascht aber alle, die Schulrundung erwarten.
Warum ist 0.1 + 0.2 in R nicht gleich 0.3?
Doubles werden binär gespeichert, und 0.1, 0.2 sowie 0.3 haben keine exakte Binärdarstellung, sodass 0.1 + 0.2 tatsächlich 0.30000000000000004 ergibt. Vergleiche berechnete Dezimalzahlen nie mit ==; nutze isTRUE(all.equal(x, y)) oder prüfe abs(x - y) < 1e-9.