I messaggi di errore nel post originale, sono dovuti al fatto che d_i$a
e d_i$b
sono vettori con 1.000 elementi e 10 è uno scalare. Pertanto, R confronta il primo elemento d_i$a
e il primo elemento d_i$b
con 10.
Per risolvere il messaggio di errore di cui abbiamo bisogno per confrontare un vettore di lunghezza 1 per scalare 10. Questo richiede di ristrutturazione il codice per generare i numeri casuali, uno alla volta. Dalla descrizione nel post originale, non è chiaro se questo comportamento è stato intenzionale.
Cercherò di semplificare il problema, eliminando il set di 10 repliche per illustrare come creare un frame di dati con numeri casuali fino a quando una riga è presente sia a
e b
con valori superiori a 10.
Primo, abbiamo impostato un seme per rendere la risposta riproducibile e quindi inizializzare alcuni oggetti. Impostando a
e b
a 0 possiamo garantire che il while()
ciclo viene eseguito almeno una volta.
set.seed(950141238) # for reproducibility
results <- list()
a <- 0 # initialize a to a number < 10
b <- 0 # initialize b to a number < 10
i <- 1 # set a counter
Aver inizializzato a
e b
il while()
ciclo di valuta TRUE
genera due numeri casuali, assegna un valore di indice, e li scrive come un frame di dati per la results
elenco. La logica per la while()
ciclo indica che se a
è inferiore o uguale a 10 o b
è inferiore o uguale a 10, il ciclo continua a scorrere. Si ferma quando sia a
e b
sono più di 10.
while(a <= 10 | b <= 10){
a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
b <- rnorm(1,10,1) # ditto
results[[i]] <- data.frame(index = i,a,b)
i <- i + 1 # increment i
}
Il ciclo si interrompe l'esecuzione dopo la nona ripetizione, come si può vedere dalla stampa i dati risultanti fotogramma dopo combinare le singole righe con do.call()
e rbind()
.
df <- do.call(rbind,results)
df
...e l'output:
> df
index a b
1 1 8.682442 8.846653
2 2 9.204682 8.501692
3 3 8.886819 10.488972
4 4 11.264142 8.952981
5 5 9.900112 10.918042
6 6 9.185120 10.625667
7 7 9.620793 10.316724
8 8 11.718397 9.256835
9 9 10.034793 11.634023
>
Si noti che l'ultima riga del frame di dati ha valori maggiori di 10 per entrambi a
e b
.
Più repliche del ciclo while
Ripetere il processo per 10 volte come è fatto nel post originale, concludere l'operazione for()
loop, e aggiungere un secondo elenco, combined_results
per salvare i risultati di ogni iterazione.
set.seed(950141238) # for reproducibility
combined_results <- list()
for(iteration in 1:10){
results <- list()
a <- 0 # initialize a to a number < 10
b <- 0 # initialize b to a number < 10
i <- 1 # set a counter
while((a < 10) | (b < 10)){
a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
b <- rnorm(1,10,1) # ditto
results[[i]] <- data.frame(iteration,index = i,a,b)
i <- i + 1 # increment i
}
combined_results[[iteration]] <- do.call(rbind,results)
}
df <- do.call(rbind,combined_results)
df[df$iteration < 5,]
...e l'uscita per i primi 4 iterazioni del ciclo esterno:
> df[df$iteration < 5,]
iteration index a b
1 1 1 8.682442 8.846653
2 1 2 9.204682 8.501692
3 1 3 8.886819 10.488972
4 1 4 11.264142 8.952981
5 1 5 9.900112 10.918042
6 1 6 9.185120 10.625667
7 1 7 9.620793 10.316724
8 1 8 11.718397 9.256835
9 1 9 10.034793 11.634023
10 2 1 11.634331 9.746453
11 2 2 9.195410 7.665265
12 2 3 11.323344 8.279968
13 2 4 9.617224 11.792142
14 2 5 9.360307 11.166162
15 2 6 7.963320 11.325801
16 2 7 8.022093 8.568503
17 2 8 10.440788 9.026129
18 2 9 10.841408 10.033346
19 3 1 11.618665 10.179793
20 4 1 10.975061 9.503309
21 4 2 10.209288 12.409656
>
Di nuovo si nota che l'ultima riga di ogni iterazione (9, 18, 19 e 21) hanno valori maggiori di 10 per entrambi a
e b
.
Si noti che questo approccio non riesce ad approfittare di vettorializzare le operazioni in R, il che significa che invece di generare 1000 numeri casuali con ogni chiamata a rnorm()
il codice basato su un while()
genera un singolo numero casuale per ogni chiamata a rnorm()
. Dal rnorm()
è una risorsa per la cpu funzione, il codice che riduce al minimo il numero di volte rnorm()
esegue, è auspicabile.