R: how does a foreach loop find a function that should be invoked?
They behave differently because registerDoParallel
registers an mclapply
backend on Linux, while it registers a clusterApplyLB
backend on Windows. When using an mclapply
backend, there are essentially no data exporting issues, so it works on Linux. But with clusterApplyLB
, you can run into problems if foreach
doesn't auto-export the functions and data that are needed.
You can solve this problem by modifying FUN3
to export FUN
via the .export
option:
FUN3 <- function(a, b) {
foreach(i=1:3, .export='FUN') %dopar% FUN(i, a, b)
}
This solution works on both Linux and Windows, since .export
is ignored by the mclapply
backend.
As pointed out by Hong Ooi, you have an error in your use of clusterExport
, but I wouldn't use clusterExport
to solve the problem since it is backend specific.
could not find function inside foreach loop
The short answer is that this was a bug in parallel backends such as doSNOW
, doParallel
and doMPI
, but it has since been fixed.
The slightly longer answer is that foreach
exports functions to the workers using a special "export" environment, not the global environment. That used to cause problems for functions that were created in the global environment, because the "export" environment wasn't in their scope, even though they were now defined in that same "export" environment. Thus, they couldn't see any other functions or variables defined in the "export" environment, such as "Posdef" in your case.
The doSNOW
, doParallel
and doMPI
backends now change the associated environment from the global to the "export" environment for functions exported via ".export", and seems to have resolved these issues.
r - foreach unable to find object within function
Try defining the .GlobalEnv
variables within the foreach
loop in every call.
library("ramify")
library("foreach")
algor <- function (vc) {
# initialize A, ybar, and Ia
A <- 0
ybar <- 0
Ia <- 0
# x is the first column of vc
x <- vc[, 1, drop = FALSE]
# y is the second column of vc
y <- vc[, 2, drop = FALSE]
# n is the length of x
n <- length(x)
foreach(i = 1:(n-1), .combine = 'c', .export = c("A", "ybar", "Ia", "x", "y")) %do% {
.GlobalEnv$A <- A
.GlobalEnv$ybar <- ybar
.GlobalEnv$Ia <- Ia
A <- A + 0.5 * (x[i] - x[i+1]) * (y[i] + y[i+1])
ybar <- ybar + (1 / 6) * (x[i] - x[i+1]) * (y[i] ^ 2 + y[i] * y[i+1] + y[i+1] ^ 2)
Ia <- Ia + (1 / 12) * (x[i] - x[i+1]) * (y[i] ^ 3 + y[i] ^ 2 * y[i+1] + y[i] * y[i+1] ^ 2 + y[i+1] ^ 3)
}
props <- mat("A, Ia, ybar", eval = TRUE)
return(props)
}
inner <- mat("0, 300; 300, 300; 300, 695; 0, 695; 0, 300")
algor(inner)
This returns:
[,1] [,2] [,3]
[1,] 118500 30870237500 58953750
improve readability of output list of foreach loop
The .final
may be useful. According to ?foreach
.final - function of one argument that is called to return final result.
With one more nested loop
res_1 <- foreach(a = c("A", "B", "C", "D"),
.final = function(x) setNames(x, c("A", "B", "C", "D"))) %:%
foreach(c = c("a", "b", "c"),
.final = function(x) setNames(x, c("a", "b", "c"))) %:%
foreach(b = 1:4) %do% {paste0(rep(a, b))}
-checking
> res_1[["B"]][["c"]][[2]]
[1] "B" "B"
similar to
res_desired_1 <- list()
for(a in c("A", "B", "C", "D")) {
for(c in c("a", "b", "c")) {
for(b in 1:4) {
res_desired_1[[a]][[c]][[b]] <- paste0(rep(a, b))
}
}
}
> res_desired_1[["B"]][["c"]][[2]]
[1] "B" "B"
How do I print the entries of a foreach loop in R?
You could use foreach
on a list of function names, and get
the associated functions:
library(foreach)
loop_func <- function(funcname){
obj <- f(get(funcname))
return(list(funcname,obj))}
a <- function(x) x
b <- function(x) 2*x
d <- function(x) 3*x
f <- function(func) {func(1)}
func_list <- c("a", "b", "d")
result <- foreach(f = func_list, .combine='rbind') %dopar% {
loop_func(f)
}
result
[,1] [,2]
result.1 "a" 1
result.2 "b" 2
result.3 "d" 3
Function not found in R doParallel 'foreach' - Error in { : task 1 failed - could not find function raster
In the vignette of foreach and the help page of foreach, the argument .packages
is pointed out as necessary to provide when using parallel computation with functions that are not loaded by default. So your code in the first example should be:
ptime<-system.time({
r <- foreach(z = 1:length(files),
.combine=cbind,
.packages='raster') %dopar% {
# some code
# and more code
}
})
Some more explanation
The foreach
package does a lot of setting up behind the scenes. What happens is the following (in principle, technical details are a tad more complicated):
foreach
sets up a system of "workers" that you can see as separate R sessions that are each committed to a different core in a cluster.The function that needs to be carried out is loaded into each "worker" session, together with the objects needed to carry out the function
each worker calculates the result for a subset of the data
The results of the calculation on the different workers is put together and reported in the "master" R session.
As the workers can be seen as separate R sessions, packages from the "master" session are not automatically loaded. You have to specify which packages should be loaded in those worker sessions, and that's what the .package
argument of foreach
is used for.
Note that when you use other packages (e.g. parallel
or snowfall
), you'll have to set up these workers explicitly, and also take care of passing objects and loading packages on the worker sessions.
Using Foreach Loop inside of Invoke
You just need an additional set of {}. Here your code is formatted so it is readable with the braces added.
public void MainLoop()
{
while (true)
{
this.Invoke(new MethodInvoker(() =>
{
foreach(GameObject ob in mygame.scenes[CurrentScene].objects)
{
//run code here
}
}
));
}
}
For and Foreach loop and return with Set. First recurring number in array
In fact the problem with .forEach()
method is that its callback
function always return undefined
, even if you use a return
statement.
If you check the forEach()
method MDN reference you can see that:
forEach()
executes the callback function once for each array element; unlikemap()
orreduce()
it always returns the valueundefined
and is not chainable.
So in your case return el;
inside forEach()
callback is always ignored, and inside the forEach
callback return
is specific to this scope that's why the function
won't return anything.
Solution:
If you want to do it with forEach()
, what you can do is to store this flag
in a variable so you can return it after the forEach()
block:
const recurring = (arr) => {
const set = new Set();
let result;
arr.forEach(el => {
if (set.has(el)) {
result = !result ? el : result;
return;
} else {
set.add(el);
}
});
return result;
}
Demo:
const arr1 = [2, 2, 3, 2, 5, 6, 6, 9];
const recurring = (arr) => {
const set = new Set(); let result;
arr.forEach(el => { if (set.has(el)) { result = !result ? el : result; return; } else { set.add(el); } }); return result;}
console.log(recurring(arr1));
Related Topics
Real Time, Auto Updating, Incremental Plot in R
Convert Data from Many Rows to Many Columns
Insert Portions of a Markdown Document Inside Another Markdown Document Using Knitr
Really Fast Word Ngram Vectorization in R
Dplyr 'Rename' Standard Evaluation Function Not Working as Expected
Creating Tree Diagram for Showing Case Count Using R
R: Unexpected Results from P.Adjust (Fdr)
Raster Package Taking All Hard Drive
Using Dplyr for Frequency Counts of Interactions, Must Include Zero Counts
Is There Any Other Package Other Than "Sentiment" to Do Sentiment Analysis in R
How to Remove the Legend Title in Ggplot2
"Long Vectors Not Supported Yet" Error in Rmd But Not in R Script
Adding Vertical Line in Plot Ggplot
Change Facet Label Text and Background Colour