I'm trying to use the foreach package in a nested loop, but my inner loop don't recognizes the outer's counter, what m I missing?
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)
}
}
Your for() isn't needed since foreach() already create a loop, you just have to use this loop to increment a value (here called $i) then display it. Also you should avoid to open your php tags ten thousands times for a better visibility into your code :) <?
An important feature of foreach is the %:% operator. I call this the nesting operator because it is used to create nested foreach loops. Like the %do% and %dopar% operators, it is a binary operator, but it operates on two foreach objects.
Parallelizing nested loops. If we have nested for loops, it is often enough to simply parallelize the outermost loop: a(); #pragma omp parallel for for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { c(i, j); } } z(); This is all that we need most of the time.
A nested loop is a (inner) loop that appears in the loop body of another (outer) loop. The inner or outer loop can be any type: while, do while, or for. For example, the inner loop can be a while loop while an outer loop can be a for loop. Of course, they can be the same kind of loops too.
The problem is that you are incorrectly applying the %:%
operator. It is designed to merge two foreach
objects, resulting in a single foreach
object that can be used to repeatedly evaluate whatever expression you supply to it. So, if you want to use %:%
, you need to first merge the two foreach()
statements, and then use the resulting object to drive a single call to %do%
(or in your case, %dopar%
). See (1) below for an example.
Alternatively, if you want to nest the two foreach()
objects, use %do%
twice, as in (2) below.
Either way works, although for parallel jobs I might prefer the one using %:%
. Your code, though, like (3) below, combines elements of the two strategies to produce a hybrid that can't do anything.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With