R Academy · Lekcja

set.seed() i powtarzalność wyników

Zapewnij powtarzalne generowanie liczb losowych między uruchomieniami za pomocą set.seed().

Lekcja 1 z 413 kroki

set.seed() i powtarzalność wyników to bezpłatna lekcja R Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej R Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs R Academy zawiera 4 lekcji w sumie.

Dlaczego odtwarzalność ma znaczenie

Generowanie liczb losowych jest pseudolosowe: odbywa się za pomocą deterministycznego algorytmu inicjalizowanego wartością początkową. Ustawienie ziarna sprawia, że symulacje są odtwarzalne — ten sam kod zawsze daje te same wyniki, co ma kluczowe znaczenie podczas debugowania, publikowania i nauczania.

# Without set.seed: different every run
runif(3)  # e.g., 0.21, 0.57, 0.89 (changes each run)
runif(3)  # different again!

# With set.seed: always identical
set.seed(42)
runif(3)  # always: 0.9148060 0.9370754 0.2861395

set.seed(42)  # reset seed
runif(3)  # exactly the same three numbers again

cat('set.seed() is your reproducibility guarantee')

Działanie set.seed()

set.seed(n) inicjalizuje stan generatora liczb losowych (RNG). Można użyć dowolnej dodatniej liczby całkowitej. Ziarno określa całą przyszłą sekwencję liczb losowych aż do ponownego ustawienia ziarna. Dla zapewnienia odtwarzalności należy używać stałej wartości.

# Different seeds give different sequences
set.seed(1)
seq1 <- rnorm(5)

set.seed(99)
seq2 <- rnorm(5)

print(seq1)
print(seq2)
identical(seq1, seq2)  # FALSE

# Same seed always gives same sequence
set.seed(1)
seq1_again <- rnorm(5)
identical(seq1, seq1_again)  # TRUE

# Common seed choices
set.seed(123)   # popular convention
set.seed(2024)  # use year for temporal clarity

RNGkind(): algorytm RNG

RNGkind() wyświetla lub ustawia algorytm RNG. Domyślnie R używa algorytmu Mersenne-Twister oraz metody rozkładu normalnego Inversion. Algorytm wpływa na generowaną sekwencję, dlatego dla pełnej odtwarzalności należy udokumentować zarówno ziarno, jak i RNGkind.

# Check current RNG settings
RNGkind()
# [1] 'Mersenne-Twister' 'Inversion' 'Rejection'
# [1] kind, normal.kind, sample.kind

# Set explicitly for maximum reproducibility
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
runif(3)

# Alternative RNG algorithms (rarely needed)
# RNGkind('L'Ecuyer-CMRG') # for parallel RNG
# RNGkind('Super-Duper')   # older algorithm

cat('Default Mersenne-Twister has period 2^19937 - 1')

Sprawdzanie .Random.seed

.Random.seed to globalny wektor liczb całkowitych przechowujący pełny stan generatora RNG. Jest automatycznie aktualizowany po każdym losowaniu. Można go zapisać i przywrócić, aby odtworzyć sekwencję od dowolnego momentu.

set.seed(42)
# .Random.seed is created in .GlobalEnv after first use
length(.Random.seed)  # 626 integers for Mersenne-Twister
.Random.seed[1]       # encodes RNG type

# Generate one number (state advances)
x1 <- runif(1)
state_after <- .Random.seed

# Generate another
x2 <- runif(1)

# Restore state to after x1
.Random.seed <<- state_after
x2_replay <- runif(1)

identical(x2, x2_replay)  # TRUE - we replayed the state
cat('x2:', x2, 'x2_replay:', x2_replay)

Zapisywanie i przywracanie stanu RNG

Zapisz stan RNG przed wykonaniem bloku kodu, a następnie przywróć go później, aby dokładnie odtworzyć działanie tego bloku. Jest to bardziej elastyczne rozwiązanie niż set.seed(), gdy trzeba wznowić sekwencję od środka.

set.seed(100)
# Generate some random numbers first
runif(10)

# Save current state
saved_state <- .Random.seed

# Generate block of interest
block1 <- rnorm(5)
print(block1)

# ... later, restore and replay
.Random.seed <<- saved_state
block1_replay <- rnorm(5)

identical(block1, block1_replay)  # TRUE!
cat('RNG state saved and restored successfully')

RNG równoległy z L'Ecuyer-CMRG

Podczas korzystania z obliczeń równoległych każdy proces potrzebuje niezależnego strumienia RNG. Generator L'Ecuyer-CMRG zapewnia długie, niepokrywające się strumienie dla procesów roboczych działających równolegle, dzięki czemu wyniki są niezależne na poszczególnych rdzeniach.

# Set up L'Ecuyer-CMRG for parallel use
RNGkind('L\'Ecuyer-CMRG')
set.seed(42)

# Each parallel worker gets its own stream
# (parallel package handles this automatically)
# library(parallel)
# cl <- makeCluster(4)
# clusterSetRNGStream(cl, iseed = 42)

# Generate numbers with this generator
samples <- rnorm(5)
print(samples)

# Reset to default Mersenne-Twister
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
cat('L\'Ecuyer-CMRG: safe for parallel simulation')

Ziarno w wywołaniach funkcji

Ustawienie ziarna wewnątrz funkcji nie wpływa na stan RNG wywołującego po zakończeniu działania funkcji — ponieważ wywołanie ustawiające ziarno w funkcji modyfikuje globalną zmienną .Random.seed. W przypadku funkcji wielokrotnego użytku należy jawnie zarządzać ziarnem.

# Function that optionally accepts a seed
simulate_data <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  list(
    x = rnorm(n),
    y = rnorm(n)
  )
}

# Reproducible call
result1 <- simulate_data(5, seed = 42)
result2 <- simulate_data(5, seed = 42)
identical(result1$x, result2$x)  # TRUE

# Without seed: different each time
result3 <- simulate_data(5)
result4 <- simulate_data(5)
identical(result3$x, result4$x)  # FALSE

Powtarzalne próbkowanie

Argument sample.kind funkcji RNGkind() wpływa konkretnie na działanie sample(). Od wersji R 3.6.0 wartość domyślna została zmieniona na 'Rejection', aby zapewnić lepszą równomierność — należy używać jej w powtarzalnych procedurach.

# R 3.6+ default sample kind
RNGkind(sample.kind = 'Rejection')  # default
set.seed(42)
sample(1:10, 5)
# [1] 1 5 10 8 2  (with Rejection)

# Old behavior (R < 3.6) for legacy code
RNGkind(sample.kind = 'Rounding')
set.seed(42)
sample(1:10, 5)
# Different result!

# Best practice: reset to modern defaults
RNGkind('Mersenne-Twister', 'Inversion', 'Rejection')
set.seed(42)
sample(1:10, 5)

Dokumentowanie losowości

Dobra praktyka w badaniach powtarzalnych: należy udokumentować wersję R, wartość ziarna oraz RNGkind. Do zapisania pełnych informacji o środowisku należy użyć sessionInfo(). Ziarna należy zapisywać w komentarzach skryptu lub w pliku konfiguracyjnym.

# Reproducibility header for analysis scripts:
# R version: R.version$version.string
# Seed: 42
# RNGkind: Mersenne-Twister / Inversion / Rejection

# Capture R version
R.version$version.string

# Capture full session info
# sessionInfo()  # shows all packages and versions

# In RMarkdown, set seed in setup chunk:
# ```{r setup}
# knitr::opts_chunk$set(echo = TRUE)
# set.seed(42)
# ```

# This ensures all chunks share the same RNG state
set.seed(42)
cat('R version:', R.version$version.string, '\n')
cat('Seed: 42, RNGkind: Mersenne-Twister')

Ziarna w badaniach Monte Carlo

W dużych badaniach symulacyjnych należy użyć jednego ziarna głównego do wygenerowania ziaren dla poszczególnych replikacji. Dzięki temu każdą replikację można odtworzyć niezależnie, a cały projekt pozostaje deterministyczny.

# Generate per-replicate seeds from a master seed
set.seed(2024)
n_replicates <- 5
replicate_seeds <- sample.int(1e6, n_replicates)
print(replicate_seeds)

# Each replicate uses its own seed
run_replicate <- function(rep_id) {
  set.seed(replicate_seeds[rep_id])
  mean(rnorm(1000))  # estimate with this seed
}

results <- sapply(seq_len(n_replicates), run_replicate)
print(round(results, 4))

# Any single replicate can be re-run independently:
set.seed(replicate_seeds[3])
mean(rnorm(1000))  # exactly matches results[3]

Testowanie losowości za pomocą withr

Pakiet withr udostępnia funkcję with_seed(seed, expr), która tymczasowo ustawia ziarno, oblicza wyrażenie, a następnie przywraca pierwotny stan RNG — jest to idealne rozwiązanie do testów, ponieważ nie zanieczyszcza stanu globalnego.

# withr::with_seed - restore RNG state automatically
# library(withr)
# result <- with_seed(42, rnorm(5))

# Simulation without withr (manual state save)
old_seed <- if (exists('.Random.seed')) .Random.seed
old_kind <- RNGkind()

set.seed(42)
result <- rnorm(5)

# Restore
if (!is.null(old_seed)) .Random.seed <<- old_seed
cat('Result:', result, '\n')
cat('Caller\'s RNG state preserved')

# set.seed in tests ensures deterministic assertions:
set.seed(1)
stopifnot(round(rnorm(1), 6) == round(-0.6264538, 6))

Szybki test

Sprawdź swoją wiedzę na temat powtarzalności RNG w R.

Podsumowanie: ziarno i powtarzalność

Najważniejsze informacje: set.seed(n) sprawia, że kod losowy daje powtarzalne wyniki. RNGkind() wyświetla lub ustawia algorytm — należy udokumentować zarówno ziarno, jak i jego rodzaj. .Random.seed przechowuje pełny stan RNG i można go zapisać oraz przywrócić. W obliczeniach równoległych należy używać L'Ecuyer-CMRG. Funkcje powinny przyjmować parametr seed. W dużych symulacjach należy używać ziaren dla poszczególnych replikacji, wygenerowanych na podstawie ziarna głównego.

# Reproducibility checklist:
# 1. Set seed at script top
set.seed(42)

# 2. Document RNGkind
RNGkind()  # Mersenne-Twister / Inversion / Rejection

# 3. Save RNG state if needed
saved <- .Random.seed

# 4. For functions, accept seed argument
my_sim <- function(n, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)
  rnorm(n)
}

# 5. For parallel: use L'Ecuyer-CMRG
# RNGkind('L\'Ecuyer-CMRG'); set.seed(42)

cat('Reproducibility = trust in your results')
Bezpłatny start

Ucz się R dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
43
Lekcje
159

Często zadawane pytania

Czy lekcja „set.seed() i powtarzalność wyników” jest bezpłatna?

Tak — pełny tekst „set.seed() i powtarzalność wyników” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu R Academy, przejdź na CoddyKit PRO. Kurs R Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „set.seed() i powtarzalność wyników”?

Zapewnij powtarzalne generowanie liczb losowych między uruchomieniami za pomocą set.seed(). Ćwiczysz R Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć R Academy?

Nie wymagamy żadnego doświadczenia. R Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „set.seed() i powtarzalność wyników”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji R Academy?

Tak. Każda lekcja R Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. set.seed() i powtarzalność wyników
  2. Generowanie rozkładów losowych
  3. Podstawy symulacji Monte Carlo
  4. Bootstrapowe próbkowanie w R
← Powrót do R Academy