Seite 1 von 2

Pattern Matching

Verfasst: Fr Feb 12, 2021 6:09 pm
von Fisch365
Hallo,

ich möchte aus einer Grundgesamtheit mehrere Stichproben ziehen und zwar relativ viele (30+). Nun möchte ich diese z.B. in einen data frame packen. Ich hatte mir folgendes überlegt.

Code: Alles auswählen

die <- 1:6 # normaler Würfel
pop <- replicate(1000000, sample(die, 1) # Grundgesamtheit

for (i in 1:30) {
  assign(paste0("sample_", i), sample(pop, 30, replace = TRUE))
}
Ich weiß, dass dies etwas umständlich ist, aber mir fällt keine bessere Lösung ein. Nun habe ich ja 30 Vektoren, die alle ähnlich heißen: sample_1 bis sample_30. Eine erste Frage hierzu ist, wie ich einen data frame erstellen kann OHNE jeden einzelnen Vektor zu schreiben, also nicht

Code: Alles auswählen

df <- data.frame(sample_1, sample_2,...)
sondern pattern matching, aber nicht für Elemente eines Vektors sondern für die erstellten Vektoren (unter values bei RStudio).
Besser wäre natürlich den Zwischenschritt mit assign zu vermeiden und direkt einen data frame zu erstellen, dennoch wäre es auch sicherlich für andere Zwecke interessant zu wissen, wie ich pattern matching in RStudio mache.

Viele Grüße

Re: Pattern Matching

Verfasst: Fr Feb 12, 2021 6:20 pm
von bigben
Hallo Fisch365,

wenn Du Dich dabei ertappst, assign verwenden zu wollen, dann lehn Dich zurück, atme tief durch und denke nochmal nach. In aller Regel ist das ein Irrweg.

Du willst 30 Spalten in denen jedes mal 10^n faire Würfel geworfen werden. Es kann so einfach sein:

Code: Alles auswählen

as.data.frame(replicate(30, sample(1:6, 1000, TRUE)))
LG,
Bernhard

Re: Pattern Matching

Verfasst: Fr Feb 12, 2021 6:21 pm
von EDi
assign ist in 99.9% der Fälle kein zu bevorzugender Weg.

Stattdeswen würde ich das funktional schreiben und in eine Liste packen. Die kannst du dann auch falls gewünscht in einen data.frane packen.

Je nachdem was du machen willst kannst du auch list-columns verwenden https://jennybc.github.io/purrr-tutoria ... lumns.html

Das verwende ich oft z.B. im Simulationen.

Für dich würde ich das so umschreiben (ungestet da gerade kein R zur Hand):

Code: Alles auswählen

lapply(1:30, function(i){ sample(pop, 30, replace = TRUE)} )

Re: Pattern Matching

Verfasst: Fr Feb 12, 2021 6:26 pm
von Fisch365
Vielen Dank für eure hilfreichen und schnellen Antworten

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 11:18 am
von Athomas
Warum willst Du Deine simulierten Zufallsexperimente überhaupt "auf Halde legen" - und erzeugst sie nicht "on the fly", dann wenn sie gebraucht werden?

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 1:41 pm
von Fisch365
Ja, weil ich R bisher nur spärlich benutze und mir nichts anderes eingefallen ist. Wie würde denn dieses "on the fly" beispielsweise aussehen?
Viele Grüße

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 2:00 pm
von Athomas
Das hängt davon ab, was Du mit den Zufallszahlen anstellen willst - ob Du wirklich alle auf einmal im Zugriff haben (oder für eine spätere Verwendung verwahren) musst, oder ob Du jeweils eine kleinere Portion vor der Benutzung erzeugen kannst!

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 2:06 pm
von Fisch365
Ich wollte simulieren, wie aus der diskreten Gleichverteilung eines fairen Würfels für dessen Kennwerte (hier: arithmetisches Mittel) eine Normalverteilung entsteht.

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 2:13 pm
von Athomas
So wie ich das sehe, brauchst Du dann doch nur immer eine Serie (z.B. 30 Würfe) auf einmal - und "merkst" Dir lediglich ihren Mittelwert!?

Re: Pattern Matching

Verfasst: Sa Feb 13, 2021 2:28 pm
von bigben
Hallo Fisch365,

Es ist zunächst einmal gar nichts dagegen einzuwenden, sich ein paar hundert Millionen Zufallszahlen auf Halde zu legen und oft genug wird das in R auch zu den kürzesten Rechenzeiten führen. Athomas denkt halt schon einen Schritt weiter und wenn Du wirklich große Zahlen untersuchen willst, dann kann es sein, dass der Speicherplatz im Computer knapp wird. So große Zahlen kommen am ehesten dann zustande, wenn die Kombinatorik greift. Kombinatorik schafft sehr schnell sehr große Zahlen. Da kann es dann schonmal sinnvoll sein, sich Zufallszahlen nicht auf Halde zu legen, sondern sie erst zu erstellen, wenn sie gebraucht werden.

Der Durchschnitt aus 10000 Würfelwürfen kann so aussehen:

Code: Alles auswählen

> mean(sample(1:6, 100000, TRUE))
[1] 3.49476
Da wird dann aber erstmal an einer Stelle Platz für 100000 Zufallszahlen gebraucht. Je größer anzahl wird, umso größer wird der Speicherbedarf.
Noch schlimmer ist:

Code: Alles auswählen

> stichprobe <- sample(1:6, 100000, TRUE)
> mean(stichprobe)
[1] 3.4978


Da wird nicht nur Platz für anzahl Ziehungen reserviert, sondern der bleibt auch noch reserviert, bis die Varialbe stichprobe gezielt gelöscht oder überschrieben wird.

Die Alternative ginge beispielsweise so:

Code: Alles auswählen

> anzahl <- 100000
> summe <-  0
> i <- 1
> 
> while(i <= anzahl){
+   summe <- summe + sample(1:6, 1)
+   i <- i + 1
+ }
> print(summe/anzahl)
[1] 3.50973
Bei jedem Aufruf von sample wird nur eine einzige Zufallszahl generiert und sofort verbraucht, um die Summe zu bilden. Das Ergebnis ist das gleiche, der Fußabdruck im Speicherbedarf ist komplett unabhängig von anzahl. Die Umsetzung mit while-Schleife ist sicher nicht das, was Athomas vorschwebt, aber das Prinzip wird, glaube ich, damit sehr deutlich.

LG,
Bernhard