2012-07-07 11 views
11

R bỏ qua cài đặt .Random.seed bên trong của một lapply. Tuy nhiên, sử dụng set.seed, hoạt động tốt.Làm thế nào tôi có thể nhận được R's lapply (và mclapply) để khôi phục trạng thái của trình tạo số ngẫu nhiên?

Một số mã:

# I can save the state of the RNG for a few seeds 
seed.list <- lapply(1:5, function(x) { 
         set.seed(x) 
         seed.state <- .Random.seed 
         print(rnorm(1)) 
         return(seed.state)}) 
#[1] -0.6264538 
#[1] -0.8969145 
#[1] -0.9619334 

# But I get different numbers if I try to restore 
# the state of the RNG inside of an lapply 
tmp.rest.state <- lapply(1:5, function(x) { 
         .Random.seed <- seed.list[[x]] 
         print(rnorm(1))}) 
# [1] -0.2925257 
# [1] 0.2587882 
# [1] -1.152132 

# lapply is just ignoring the assignment of .Random.seed 
.Random.seed <- seed.list[[3]] 
print(rnorm(1)) # The last printed value from seed.list 
# [1] -0.9619334 
print(rnorm(1)) # The first value in tmp.rest.state 
# [1] -0.2925257 

Mục tiêu của tôi là để trạm kiểm soát MCMC chạy để họ có thể được nối lại một cách chính xác. Tôi có thể dễ dàng lưu trạng thái của RNG, tôi không thể lấy R để tải nó bên trong một vòng lặp lapply!

Có cách nào buộc R phải thông báo đặt .Random.seed không? Hoặc có cách nào đơn giản hơn để thực hiện điều này không?

Trong trường hợp vấn đề, tôi đang sử dụng 64 bit R:

R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows" 
Platform: x86_64-pc-linux-gnu (64-bit) 

Trên Ubuntu 12.04 LTS:

[email protected]:~$ uname -a 
Linux nathanvan-N61Jq 3.2.0-26-generiC#41-Ubuntu SMP Thu Jun 14 17:49:24 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux 
+0

+1 Câu hỏi rất thú vị, cảm ơn bạn – Andrie

Trả lời

10

Điều này xảy ra bởi vì .Random.seed được đánh giá là một đối tượng địa phương trong cuộc gọi của bạn để lapply.

Bạn cần phải gán giá trị của .Random.seed trong môi trường toàn cầu:

tmp.rest.state <- lapply(seed.list, function(x) { 
    assign(".Random.seed", x, envir=globalenv()) 
    print(rnorm(1)) 
    } 
) 

[1] -0.6264538 
[1] -0.8969145 
[1] -0.9619334 
[1] 0.2167549 
[1] -0.8408555 

Lý do mã của bạn không hoạt động là .Random.seed được phân công trong môi trường của hàm vô danh trong lapply, nhưng rnorm() vẻ cho .Random.seed trong môi trường toàn cầu.


Đối với hồ sơ, đây là nỗ lực đầu tiên của tôi, điều này sẽ chỉ làm việc trong một số tình huống:

Dưới đây là một cách để sửa chữa nó, bằng cách sử dụng <<-. (Vâng, tôi biết điều này không được tán thành, nhưng có thể biện minh được. Một thay thế sẽ được sử dụng eval() và đánh giá có hiệu lực trong một môi trường gọi.

tmp.rest.state <- lapply(seed.list, function(x) { 
    .Random.seed <<- x 
    print(rnorm(1)) 
    } 
) 

[1] -0.6264538 
[1] -0.8969145 
[1] -0.9619334 
[1] 0.2167549 
[1] -0.8408555 

Lưu ý rằng giải pháp này sẽ không hoạt động nếu lapply() của bạn được lồng trong một chức năng, vì <<- chỉ đánh giá trong môi trường mẹ, chứ không phải môi trường toàn cầu

+1

Có thể gắn bó .Random.seed trong một môi trường được đặt tên sẽ làm tăng tính tổng quát? ? –

+4

Cũng có thể sử dụng '.GlobalEnv $ .Random.seed <- x' hoặc' .GlobalEnv [[". Random.seed"]] <- x'. –

+0

Điều này hoạt động tuyệt vời, cảm ơn bạn! –

Các vấn đề liên quan