2016-08-16 2 views
1

Wir haben eine große for loop in R für die Simulation verschiedener Daten, wo für einige Iterationen die Daten so generieren, dass eine Menge 0 innerhalb der Schleife kommt , was nicht wünschenswert ist und wir sollten diesen Schritt der Datengenerierung überspringen. Gleichzeitig müssen wir aber auch die Anzahl der Iterationen um einen Schritt erhöhen, da wir sonst weniger Beobachtungen benötigen.Wie man einen Schritt überspringt und die Anzahl der Iterationen in einer for-Schleife erhöht R

Während zum Beispiel den folgenden Code ausgeführt wird, erhalten wir z = 0 in Iteration 1, 8 und 9.

rm(list=ls()) 
n <- 10 
z <- NULL 
for(i in 1:n){ 
    set.seed(i) 
    a <- rbinom(1,1,0.5) 
    b <- rbinom(1,1,0.5) 
    z[i] <- a+b 
} 
z 
[1] 0 1 1 1 1 2 1 0 0 1 

Wir wollen diese Schritte überspringen, so dass wir haben keine z = 0, aber wir wollen auch einen Vektor z der Länge 10. Es kann auf viele Arten erfolgen. Aber was ich besonders gerne sehen möchte, ist, wie wir die Iteration anhalten und den aktuellen Schritt überspringen können, wenn z = 0 angetroffen wird, und zum nächsten Schritt gehen, um schließlich 10 Beobachtungen für z zu erhalten.

Antwort

4

Normalerweise tun wir dies über eine while Schleife, da die Anzahl der erforderlichen Iterationen vorher unbekannt ist.

n <- 10L 
z <- integer(n) 
m <- 1L; i <- 0L 
while (m <= n) { 
    set.seed(i) 
    z_i <- sum(rbinom(2L, 1, 0.5)) 
    if (z_i > 0L) {z[m] <- z_i; m <- m + 1L} 
    i <- i + 1L 
    } 

Output:

z 
# [1] 1 1 1 1 1 2 1 1 1 1 

i 
# [1] 14 

wir 14-mal so abtasten, von denen 4 0 und der Rest 10 bleiben erhalten.


Effizientere vektorisiert Methode

set.seed(0) 
n <- 10L 
z <- rbinom(n, 1, 0.5) + rbinom(n, 1, 0.5) 
m <- length(z <- z[z > 0L]) ## filtered samples 
p <- m/n ## estimated success probability 
k <- round(1.5 * (n - m)/p) ## further number of samples to ensure successful (n - m) non-zero samples 
z_more <- rbinom(k, 1, 0.5) + rbinom(k, 1, 0.5) 
z <- c(z, z_more[which(z_more > 0)[seq_len(n - m)]]) 

Einige Wahrscheinlichkeitstheorie der geometrischen Verteilung ist hier verwendet worden. Zunächst probieren wir n Proben, m von denen beibehalten werden. Die geschätzte Erfolgswahrscheinlichkeit bei der Annahme von Proben ist also p <- m/n. Nach der Theorie der geometrischen Verteilung benötigen wir im Durchschnitt mindestens 1/p Proben, um einen Erfolg zu beobachten. Daher sollten wir mindestens (n-m)/p mehr mal probieren, um (n-m) Erfolg zu erwarten. Die 1.5 ist nur ein Inflationsfaktor. Durch die Probe von 1,5 mal mehr Proben können wir hoffentlich (n-m) Erfolg sicherstellen.

Nach dem Gesetz der großen Zahlen ist der Schätzwert von genauer, wenn n groß ist. Daher ist dieser Ansatz für große n stabil.

Wenn Sie glauben, dass 1,5 nicht groß genug ist, verwenden Sie 2 oder 3. Aber ich habe das Gefühl, dass es ausreicht.

+0

Nein. Sie sollten die Vektorisierung verwenden, mehr Werte als erforderlich erstellen und auf die gewünschte Anzahl von Nicht-Null-Werten unterteilen. – Roland

+2

@Roland Es ist nicht offensichtlich, dass der wahre Code des OP leicht vektorisiert werden kann. Außerdem kann der von Ihnen vorgeschlagene Ansatz immer noch keine "n" Erfolge erzielen (Ergebnisse ungleich null). – Frank

+2

@Frank Wie die Aktualisierung der Antwort zeigt, können Sie eine gute Schätzung der Anzahl der zusätzlichen Werte erhalten. Wenn Sie nicht die erforderliche Anzahl an "guten" Werten erhalten, führen Sie sie erneut aus. Sie werden immer noch schneller als die Schleife Ansatz für jede Simulation der anständigen Größe sein. – Roland

Verwandte Themen