Chybové zprávy v původním příspěvku, jsou vzhledem k tomu, že d_i$a
a d_i$b
jsou vektory s 1000 prvky a 10 je skalární veličina. Proto, R porovná první prvek v d_i$a
a první prvek v d_i$b
10.
Chcete-li vyřešit chybovou zprávu, musíme porovnat vektor s délkou 1 skalární 10. To vyžaduje restrukturalizaci kódu pro generování náhodných čísel jeden po druhém. Z popisu v původní příspěvek, není jasné, zda toto chování bylo úmyslné.
Budu problém zjednodušit tím, že odstraní sada 10 replikací pro ilustraci, jak vytvořit datový rámec s náhodnými čísly, dokud řadě má i a
a b
hodnoty větší než 10.
Za prvé, jsme se nastavit semeno, aby odpověď reprodukovatelné, a pak inicializovat některé objekty. Nastavením a
a b
0 ujišťujeme, že while()
smyčky bude provádět alespoň jednou.
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
S inicializován a
a b
, while()
smyčky se vyhodnotí na TRUE
generuje dvě náhodná čísla, přiřadí hodnota indexu, a zapíše je jako datový rámec na results
seznam. Logika pro while()
loop znamená, že pokud buď a
je méně než nebo se rovná 10 nebo b
je méně než nebo se rovná 10, smyčka drží iterace. To se zastaví, když oba a
a b
jsou větší než 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
}
Smyčky zastaví provádění po deváté iterace jak můžeme vidět v tisku výsledný datový rámec poté, co jsme kombinovat jednotlivé řádky s do.call()
a rbind()
.
df <- do.call(rbind,results)
df
...a výstup:
> 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
>
Všimněte si, že poslední řádek v datové rám má hodnoty větší než 10 pro oba a
a b
.
Více replikací, zatímco smyčka
Proces opakovat 10 krát jako je tomu v původní příspěvek, končíme provoz v for()
smyčky, a přidat druhý seznam, combined_results
chcete-li uložit výsledky z každé iteraci.
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,]
...a výstupu pro první 4 iterací vnější smyčky:
> 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
>
Opět jsme na vědomí, že poslední řádek v každé iteraci (9, 18, 19, a 21) mají hodnoty větší než 10 pro oba a
a b
.
Všimněte si, že tento přístup nedokáže využít vectorized operace v R, což znamená, že namísto generování z 1000 náhodných čísel s každé volání rnorm()
kód založený na while()
generuje jeden náhodné číslo, na volání rnorm()
. Od rnorm()
je náročná funkce, kód, který minimalizuje počet časy rnorm()
provádí je žádoucí.