What is the purrr::map equivalent of:
for (i in 1:4) {
for (j in 1:6) {
print(paste(i, j, sep = "-"))
}
}
OR
lapply(1:4, function(i)
lapply(1:6, function(j)
print(paste(i, j, sep = "-"))))
Conceptually, what I'm not getting is how to refer to the outer loop in the inner map function.
map(1:4, ~ map(1:6, ~ print(paste(.x, ????, sep = "-")))
The use of function formulas (~
) is a little limited when trying to nest like this, since it is perfectly unclear which level of map
you are attempting to reference. (Well, that's not correct. It's perfectly clear to me that it is referencing inside-out, and since they both use the same nomenclature, the outer variables are being masked by the inner variables.)
I think your best way around it is to not use the formula method, instead using immediate/anonymous (or predefined) functions:
library(purrr)
str(map(1:2, function(x) map(1:3, function(y) paste(x, y, sep = "-"))))
# List of 2
# $ :List of 3
# ..$ : chr "1-1"
# ..$ : chr "1-2"
# ..$ : chr "1-3"
# $ :List of 3
# ..$ : chr "2-1"
# ..$ : chr "2-2"
# ..$ : chr "2-3"
As @r2evans points out, the .x
from your first call is masked. however you can create a lambda function that takes 2 parameters .x
and .y
, and assign the previous .x
to the new .y
through the ...
argument.
I'll use walk
rather than map
as in this case you're only interested in side effects (printing)
walk(1:4,~ walk(1:6, ~ print(paste(.x, .y, sep = "-")),.y=.x))
Another option is to use expand.grid
to lay out the combinations, and then iterate on those with pwalk
(or pmap
in other circumstances)
purrr::pwalk(expand.grid(1:4,1:6),~print(paste(.x, .y, sep = "-")))
Output in both cases:
[1] "1-1"
[1] "2-1"
[1] "3-1"
[1] "4-1"
[1] "5-1"
[1] "6-1"
[1] "1-2"
[1] "2-2"
[1] "3-2"
[1] "4-2"
[1] "5-2"
[1] "6-2"
[1] "1-3"
[1] "2-3"
[1] "3-3"
[1] "4-3"
[1] "5-3"
[1] "6-3"
[1] "1-4"
[1] "2-4"
[1] "3-4"
[1] "4-4"
[1] "5-4"
[1] "6-4"
Just Running through this now.
walk(1:4,~ walk(1:6, ~ print(paste(.x, .y, sep = "-")),.y=.x))
[1] "1-1"
[1] "2-1"
[1] "3-1"
[1] "4-1"
[1] "5-1"
[1] "6-1"
[1] "1-2"
and
purrr::pwalk(expand.grid(1:4,1:6),~print(paste(.x, .y, sep = "-")))
[1] "1-1"
[1] "2-1"
[1] "3-1"
[1] "4-1"
[1] "1-2"
but to match your nested for loops exactly it fiddled and this works.
for (i in 1:4) {
for (j in 1:6) {
print(paste(i, j, sep = "-"))
}
}
[1] "1-1"
[1] "1-2"
[1] "1-3"
[1] "1-4"
[1] "1-5"
[1] "1-6"
[1] "2-1"
purrr::pwalk(expand.grid(1:6,1:4),~print(paste(.y, .x, sep = "-")))
[1] "1-1"
[1] "1-2"
[1] "1-3"
[1] "1-4"
[1] "1-5"
[1] "1-6"
[1] "2-1"
#or even a map of this
walk(1:4,~ walk(1:6, ~ print(paste(.y, .x, sep = "-")),.y=.x))
I have yet to figure out why the .y=.x
is at the end though.
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