Last active
December 9, 2016 17:38
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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