Skip to content

Instantly share code, notes, and snippets.

@mbjoseph
Last active December 9, 2016 17:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbjoseph/c2bf86f7158cdfafb8dcdb3c5cc72f20 to your computer and use it in GitHub Desktop.
Save mbjoseph/c2bf86f7158cdfafb8dcdb3c5cc72f20 to your computer and use it in GitHub Desktop.
How to unroll a nested for-loop in R so that it can be run in parallel
library(parallel)
# Create matrix to store result -------------------------------------------
M <- 4
N <- 6
A <- matrix(0, nrow = M, ncol = N)
list <- list(3, 4, 6)
# Serial version ----------------------------------------------------------
for (i in 1:M) {
for (j in 1:N) {
A[i, j] <- ifelse(i < j,
i - j,
i + j) +
sum(unlist(list))
}
}
A
# Parallel version --------------------------------------------------------
cl <- makeCluster(getOption("cl.cores", detectCores()))
# 1. Identify the "cases" - basically all the combinations of i and j
cases <- expand.grid(i = 1:M, j = 1:N)
cases
# 2. Write a function to apply to each row
my_sum <- function(x, list) {
# x is a row from a data frame
# extract objects from data frame:
i <- x["i"]
j <- x["j"]
# do your computations:
ifelse(i < j, i - j, i + j) + sum(unlist(list))
}
clusterExport(cl, "list")
# 3. apply your function in parallel over the rows of the data frame
result <- parApply(cl = cl, # our cluster object
X = cases, # the array to iterate over
FUN = my_sum, # the function to apply
MARGIN = 1,
list = list) # iterate over the rows, not the columns
# 4. If you need a matrix as output, create one from the result
# (R fills in the columns first)
A_parallel <- matrix(result, nrow = M, ncol = N)
A_parallel
# confirm that the two are equal
all(A_parallel == A)
stopCluster(cl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment