2012-03-12 50 views
6

Tôi đang cố sử dụng gói foreach trong vòng lặp lồng nhau, nhưng vòng lặp bên trong của tôi không nhận ra bộ đếm của bên ngoài, tôi thiếu gì?Biến vòng lặp ngoài trong vòng lặp R foreach lồng nhau

v3 <- search.compounds.by.mass(100.05,0.5) 
foreach(j=2:length(v2)) %:% { 
    foreach(i=1:length(v3), .combine=rbind) %dopar% { 
     write.table(paste(v3[i], paste(get.reactions.by.compound(v3[i]), collapse=" "), sep=" "), "file1",quote=FALSE, row.names=FALSE, col.names=FALSE, append=TRUE) 
     write.table(paste(v3[i], paste(get.pathways.by.compounds(v3[i]), collapse=" "), sep=" "), "file2",quote=FALSE, row.names=FALSE, col.names=FALSE, append=TRUE) 
     v3 <- search.compounds.by.mass(v2[j],0.5) 
    } 
} 
+0

Thông báo lỗi là gì? Ngoài ra, những gì là trong biến v2 (bạn có thể sử dụng dput (v2) để chúng tôi có thể tái sản xuất nó) –

Trả lời

16

Vấn đề là bạn đang áp dụng sai nhà điều hành %:%. Nó được thiết kế để hợp nhất hai đối tượng foreach, dẫn đến một đối tượng foreach đơn lẻ có thể được sử dụng để đánh giá liên tục bất kỳ biểu thức nào bạn cung cấp cho đối tượng đó. Vì vậy, nếu bạn muốn sử dụng %:%, bạn cần phải đầu tiên hợp nhất hai foreach() báo cáo, và sau đó sử dụng đối tượng kết quả để lái xe một cuộc gọi duy nhất để %do% (hoặc trong trường hợp của bạn, %dopar%). Xem (1) bên dưới để biết ví dụ.

Ngoài ra, nếu bạn muốn tổ hai foreach() đối tượng, sử dụng %do% hai lần, như trong (2) dưới đây.

Dù bằng cách nào hoạt động, mặc dù đối với các công việc song song, tôi có thể thích cách sử dụng %:%. Mã của bạn, mặc dù, như (3) dưới đây, kết hợp các yếu tố của hai chiến lược để tạo ra một lai mà không thể làm bất cứ điều gì.

X <- c("A", "B") 
Y <- 1:3 

## (1) EITHER merge two 'foreach' objects using '%:%' ... 
foreach (j = X, .combine = c) %:% foreach(i = Y, .combine = c) %do% { 
    paste(j, i, sep = "") 
} 
# [1] "A1" "A2" "A3" "B1" "B2" "B3" 


## (2) ... OR Nest two 'foreach' objects using a pair of '%do%' operators ... 
foreach(j = X, .combine = c) %do% { 
    foreach(i = Y, .combine = c) %do% { 
     paste(j, i, sep = "") 
    } 
} 
# [1] "A1" "A2" "A3" "B1" "B2" "B3" 


## (3) ... BUT DON'T use a hybrid of the approaches. 
foreach(j = X, .combine = c) %:% { 
    foreach(i = Y, .combine = c) %do% { 
     paste(j, i, sep = "") 
    } 
} 
# Error in foreach(j = X, .combine = c) %:% { : 
# "%:%" was passed an illegal right operand 
+0

Hi Josh, cảm ơn câu trả lời của bạn nó đã làm việc ngay bây giờ! – user1265067

+2

Tốt để nghe. Nhân tiện, nếu bạn muốn đọc thêm về một số quyết định liên quan đến cách cấu trúc các vòng lặp lồng nhau, hãy gõ 'vignette (" lồng nhau ")' tại dòng lệnh R. –

+1

Thật đáng buồn khi chú ý rằng họa tiết thể hiện đúng cách để làm điều đó, và tuyên bố rõ ràng đó là một toán tử nhị phân, nhưng rất dễ mắc lỗi này. –

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