Menu

Zufallszahlen in R: rnorm, runif, sample und set.seed

Erzeuge Zufallsdaten mit rnorm(), runif(), rbinom() und sample(), mach sie mit set.seed() reproduzierbar und entschlüssle R's d/p/q/r-Namenssystem für Verteilungen.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

set.seed() kommt zuerst

Zufallsziehungen, die sich bei jedem Lauf ändern, sind zum Lehren, Bewerten, Debuggen oder für die Wissenschaft nutzlos - sagt deine Simulation heute 0,146 und morgen 0,153, welche Zahl kommt in den Bericht? set.seed() legt den Startpunkt des Generators fest und macht den gesamten folgenden Strom von "Zufall" exakt wiederholbar:

Gleicher Seed, identische Ziehungen, jedes Mal, auf jedem Rechner. Die Zahlen sind pseudozufällig: eine deterministische Folge, konstruiert, um jeden statistischen Zufallstest zu bestehen, wobei der Seed festlegt, wo in der Folge du beginnst. Der Seed-Wert selbst trägt keine Bedeutung - 42, 7, 20260807 - nimm irgendetwas; schreib es nur auf. Die Gewohnheit, die du aufbauen solltest: ein set.seed() am Anfang jedes Skripts, das Zufall nutzt. (Beachte, dass verbrauchte Ziehungen den Zustand weiterschalten, sodass auch die Reihenfolge der Aufrufe für die Reproduzierbarkeit zählt.)

Das d/p/q/r-System: eine Tabelle entschlüsselt die ganze Bibliothek

R benennt jede Verteilungsfunktion als Präfix + Familie, und sobald du das Raster siehst, kannst du die gesamte Statistikbibliothek lesen:

PräfixFrage, die es beantwortetBeispiel Normalverteilung
rGib mir Zufallsziehungenrnorm(5)
dDichte: wie hoch ist die Kurve bei x?dnorm(0)
pWahrscheinlichkeit: P(X ≤ x)?pnorm(1.96)
qQuantil: welches x liegt an diesem Perzentil?qnorm(0.975)

p und q sind Umkehrungen voneinander, und sie sind das Paar, dem du bei den Konfidenzintervallen als qt(0.975, df) begegnet bist:

Tausch den Familiennamen, und alles überträgt sich: runif/dunif/punif/qunif, rbinom/..., rpois/..., rt/..., rexp/.... Lerne vier Präfixe, bekomme Dutzende Verteilungen.

rnorm(): normalverteilte Ziehungen

rnorm(n, mean, sd) zieht aus einer Glockenkurve - das Arbeitspferd zum Simulieren messwertartiger Daten:

Stichprobenmittelwert und -sd landen nahe bei - nicht genau auf - 100 und 15: Diese Lücke ist Stichprobenrauschen, das mit wachsendem n schrumpft. Die letzte Zeile ist ein Trick, den man klauen sollte: mean() eines logischen Vektors ist der Anteil der TRUEs, und der Anteil jenseits von 130 landet nahe am theoretischen 1 - pnorm(130, 100, 15) ≈ 2,3 %. Die Voreinstellungen sind mean = 0, sd = 1 (die Standardnormalverteilung). Ein Histogramm von iq zeigt die vertraute Glocke.

runif(), rbinom(), rpois()

Drei weitere Familien decken die meisten Simulationsbedürfnisse ab:

runif() verteilt Ziehungen gleichmäßig über einen Bereich ("uniform", nicht "run if" - jede und jeder verliest sich einmal). rbinom(n, size, prob) simuliert n Experimente mit je size Versuchen und gibt deren Erfolgszahl zurück - jeder Wert oben ist also die Anzahl Köpfe aus 10 Würfen. rpois(n, lambda) erzeugt Anzahlen von Ereignissen, die unabhängig mit bekannter Durchschnittsrate auftreten: Supporttickets pro Stunde, Tippfehler pro Seite.

sample(): Ziehen und Mischen

Wo die r*-Funktionen Werte aus einer Verteilung erfinden, zieht sample() aus Werten, die du bereits hast:

Das Argument replace ist die ganze Geschichte: FALSE (Voreinstellung) teilt Karten aus - jeder Wert kann einmal auftauchen, und mehr zu verlangen, als vorhanden ist, ist ein Fehler; TRUE würfelt - jede Ziehung setzt zurück. Das Ziehen mit Zurücklegen aus deinen eigenen Daten ist der Motor des Bootstrappings. Nur mit einem Vektor aufgerufen, gibt sample(x) eine zufällige Permutation zurück - das Idiom zum Mischen.

Zeilen eines Data Frames zu ziehen nutzt sample() innerhalb der Zeilenindexierung:

sample(nrow(mtcars), 5) wählt 5 zufällige Zeilennummern; die Indexierung zieht diese Zeilen heraus. Das ist der Standardzug zum Stichprobenprüfen eines großen Datensatzes oder zum Aufteilen in Trainings- und Testmengen.

Eine kleine Monte-Carlo-Simulation

Hier ist der Ertrag des ganzen Werkzeugkastens. Frage: Ein Prozess liefert Messwerte, verteilt nach N(100, 15); du mittelst 10 davon - wie wahrscheinlich ist es, dass dieser Durchschnitt 105 übersteigt? Statt die Antwort herzuleiten, simuliere sie - führ das Experiment 10.000-mal durch und zähle:

Die Simulation landet auf wenige Tausendstel genau am exakten Wert (etwa 0,146). Das ist Monte Carlo in einem Atemzug: Schreib einen Versuch als Funktion, replicate() ihn tausendfach, nimm mean() der Erfolge. Die exakte Antwort existierte hier, weil der Aufbau lehrbuchhaft einfach war - sobald die Frage unordentlich wird (seltsame Verteilungen, Maximum korrelierter Ziehungen, ein regelbasiertes Spiel), schließt sich der analytische Weg, und das Simulationsrezept funktioniert unverändert weiter. Beachte das 15 / sqrt(10) in der Kontrolle: Mittelwerte wackeln weniger als Einzelziehungen - dasselbe Wurzelgesetz, das die Breite von Konfidenzintervallen treibt.

Simulationstauglich, nicht geheimnistauglich

Eine Grenze ist zu respektieren: R's Standardgenerator (Mersenne Twister) ist auf statistische Qualität und Geschwindigkeit gebaut, nicht auf Geheimhaltung. Seine Ausgabe ist bei gegebenem Seed deterministisch, und sein interner Zustand lässt sich aus beobachteter Ausgabe rekonstruieren - tödliche Mängel für Passwörter, Tokens oder alles Sicherheitsnahe. Für Simulation, Bootstrapping und Lehre ist er ausgezeichnet; für Kryptografie nutze eine dafür gebaute Bibliothek (z. B. das Paket openssl), nie sample() oder runif().

Was du mitnimmst

  • Ein set.seed() am Anfang macht jedes "zufällige" Ergebnis reproduzierbar - gleicher Seed, gleiche Ziehungen.
  • Die Präfixe d/p/q/r entschlüsseln die gesamte Verteilungsbibliothek: Zufallsziehung, Dichte, kumulative Wahrscheinlichkeit, Quantil.
  • rnorm(n, mean, sd), runif(n, min, max), rbinom(n, size, prob), rpois(n, lambda) decken die meisten Simulationsbedürfnisse ab.
  • sample() zieht aus deinen eigenen Werten - replace = TRUE fürs Würfeln, Voreinstellung fürs Kartengeben, kein size zum Mischen; df[sample(nrow(df), k), ] zieht Zeilen.
  • Monte Carlo = Ein-Versuch-Funktion + replicate() + mean() - das Rezept, das Wahrscheinlichkeitsfragen beantwortet, die die Mathematik nicht bequem erreicht.
  • R's Zufallsgenerator ist für Simulation gedacht, nicht für Kryptografie.

Als Nächstes: Debuggen - was R's Fehlermeldungen tatsächlich bedeuten und wie man einen Traceback liest.

Häufig gestellte Fragen

Was macht set.seed() in R?

Es legt den Startpunkt von R's Zufallszahlengenerator fest, sodass die folgenden "zufälligen" Ziehungen bei jedem Lauf identisch ausfallen. Ruf es einmal am Anfang jedes Skripts auf, das Zufall nutzt - set.seed(42) -, und deine Simulation wird reproduzierbar: Kolleginnen, Prüfer und dein zukünftiges Ich sehen alle dieselben Zahlen.

Wie erzeugt man in R Zufallszahlen?

Wähle die Verteilung: rnorm(n, mean, sd) für normalverteilte Ziehungen, runif(n, min, max) für gleichverteilte, rbinom(n, size, prob) für Erfolgsanzahlen, rpois(n, lambda) für Ereigniszahlen. Zum Ziehen aus vorhandenen Werten nutze sample(x, size).

Was ist der Unterschied zwischen rnorm, dnorm, pnorm und qnorm?

Eine Verteilung, vier Präfixe: r zieht Zufallswerte, d gibt die Höhe der Dichtekurve, p gibt die kumulative Wahrscheinlichkeit P(X ≤ x), und q ist deren Umkehrung - der Wert an einem gegebenen Perzentil. Dieselben vier Präfixe funktionieren für jede Verteilung, die R kennt: runif/dunif/punif/qunif, rbinom/dbinom/pbinom/qbinom und so weiter.

Wie zieht man in R eine Zufallsstichprobe von Zeilen aus einem Data Frame?

Indiziere die Zeilen mit sample(): df[sample(nrow(df), 5), ] wählt 5 Zeilen ohne Zurücklegen. Ergänze replace = TRUE für das Ziehen mit Zurücklegen (der Zug hinter dem Bootstrapping).

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S