2015-02-16 23 views
14

Đây là ví dụ về đồ chơi để minh họa sự cố của tôi.Sử dụng nguồn() trong vòng lặp song song foreach

library(foreach) 
library(doMC) 
registerDoMC(cores=2) 

foreach(i = 1:2) %dopar%{ 
    i + 2 
} 
[[1]] 
[1] 3 

[[2]] 
[1] 4 

Cho đến nay rất tốt ...

Nhưng nếu mã i + 2 được lưu trong file addition.R và tôi gọi đó là tập tin sử dụng source() sau đó

> foreach(i = 1:2) %dopar%{ 
+ source("addition.R") 
+ } 
Error in { : task 1 failed - "object 'i' not found" 
+3

Hãy thử 'nguồn ("addtition.R", local = T) 'để đánh giá nguồn trong envronment mà nó được gọi là – NicE

+0

Tôi tìm thấy nguồn() gọi trong% dopar% khối làm chậm đáng kể tính toán, như các tiến trình con phải lấy tệp nguồn đó thông qua mạng –

Trả lời

10

tôi không thể tái tạo đầy đủ của bạn đồ chơi, nhưng tôi đã có một vấn đề quen thuộc, mà tôi đã có thể giải quyết bằng cách:

source(file, local = TRUE) 

nên phân tích cú pháp nguồn trong môi trường địa phương, tức là nhận ra i.

3

Nhận xét của NiceE và câu trả lời của Sosel đã giải quyết vấn đề này; khi gọi số source(file), giá trị mặc định là source(file, local = FALSE), có nghĩa là mã trong tệp có nguồn gốc được đánh giá trong môi trường toàn cầu ("không gian làm việc của người dùng") và có, cf. ?source. Lưu ý rằng không có biến số i trong môi trường toàn cầu. Giải pháp là đảm bảo tệp có nguồn gốc trong môi trường gọi là tệp, tức là sử dụng source(file, local = TRUE).

Giải pháp:

library("foreach") 

y <- foreach(i = 1:2) %dopar% { 
    i + 2 
} 
str(y) 

doMC::registerDoMC(cores = 2L) 
y <- foreach(i = 1:2) %dopar% { 
    source("addition.R", local = TRUE) 
} 
str(y) 

Ví dụ về cùng một vấn đề với một vòng lặp for():

Thực tế là source() được đánh giá trong môi trường toàn cầu mà là khác nhau từ môi trường gọi nơi i cuộc sống cũng có thể được được minh họa bằng cách sử dụng vòng lặp thông thường bằng cách chạy vòng lặp for trong môi trường khác so với toàn cục, ví dụ bên trong một hàm hoặc bằng cách:

local({ 
    for(i in 1:2) { 
    source("addition.R") 
    } 
}) 

mang đến cho:

Error in eval(ei, envir) : object 'i' not found 

Bây giờ, lý do tại sao trên foreach(i = 1:2) %dopar% { source("addition.R") } làm việc với registerDoSEQ()khi và chỉ khi gọi từ môi trường toàn cầu, đó là sau đó các foreach iteration được đánh giá trong môi trường gọi, đó là môi trường toàn cầu, đó là môi trường mà sử dụng source(). Tuy nhiên, nếu sử dụng local(foreach(i = 1:2) %dopar% { ... }) thì việc này cũng không tương tự với cuộc gọi local(for(i in 1:2) { ... }) ở trên.

Kết luận: không có phép thuật nào xảy ra, nhưng để hiểu nó hơi tẻ nhạt.

4

Cuối cùng tôi đã giải quyết được sự cố bằng cách chuyển đổi nguồn ("bổ sung.R") thành một hàm và chỉ cần chuyển các biến vào đó. Tôi không biết tại sao nhưng các giải pháp được đề xuất dựa trên source(file, local = TRUE) không hoạt động.

+0

Đó là 'nguồn (" bổ sung.R ", cục bộ = TRUE)' sẽ không hoạt động cho bạn không có ý nghĩa với tôi. Bạn có thể sao chép lỗi với ví dụ tái sản xuất mà tôi đã nhận từ OP của bạn không? Hay bạn đang đề cập đến một tập lệnh R phức tạp hơn? Nếu sau này, có thể có hàng triệu lý do. Ngoài ra, những gì thiết lập/'sessionInfo()'? – HenrikB

+0

Tôi đang nói về kịch bản được đề cập chính xác và lỗi chính xác. – CoderInNetwork

+0

Điều này thật kỳ lạ. Bạn có nhận được lỗi trong ví dụ 'local ({for (i trong 1:12) ...})' không? Nếu vậy, điều đó sẽ loại trừ foreach vv Quan trọng, 'sessionInfo()' của bạn là gì sau khi bạn nhận được lỗi? Tôi nghi ngờ có điều gì đó trong thiết lập của bạn gây ra sự khác biệt này. Chạy R trong thiết bị đầu cuối hoặc trong GUI (ví dụ: RStudio)? – HenrikB

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