什么是purrr :: map等效于:
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 = "-"))))
从概念上讲,我没有得到的是如何在内部地图函数中引用外部循环。
map(1:4, ~ map(1:6, ~ print(paste(.x, ????, sep = "-")))
答案 0 :(得分:16)
尝试像这样嵌套时function formulas (~
)的使用有点受限,因为完全不清楚你试图引用哪个级别的map
。 (嗯,这不正确。我非常清楚它正在引用由内而外,并且因为它们都使用相同的命名法,所以外部变量被屏蔽由内部变量。)
我认为你最好的方法是不使用公式方法,而是使用立即/匿名(或预定义)函数:
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"
答案 1 :(得分:8)
正如@ r2evans指出的那样,第一次通话中的.x
被屏蔽了。但是你可以创建一个带有2个参数.x
和.y
的lambda函数,并通过.x
参数将之前的.y
分配给新的...
。< / p>
我将使用walk
而不是map
,因为在这种情况下,您只对副作用(打印)感兴趣
walk(1:4,~ walk(1:6, ~ print(paste(.x, .y, sep = "-")),.y=.x))
另一种选择是使用expand.grid
来布局组合,然后对pwalk
(或其他情况下为pmap
)进行迭代
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] "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"
答案 2 :(得分:0)
现在就开始运行吧。
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"
和
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"
但是要完全匹配嵌套的for循环,它会摆弄,这是可行的。
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))
我还没有弄清楚.y=.x
到底为什么。
答案 3 :(得分:0)
这里是已经非常好的答案和答案注释的补充。我想制作一个可以实现OP目标的类似purr的功能。因此,我制作了一个loop_map
函数,其行为与主要Purrr map
函数类似。
loop_map <- function(why, ecks, fun) {
# 2: for every call of this (the previous .f) the new .f is called for each
# value of ecks, supplied the same value of why each time
iterate_over_x = function(x_in,y_in,fun_in){
return(pmap(.l = list(x = x_in), .f = fun_in ,y = y_in ) %>%
set_names(nm = as.character(x_in)))
}
# 1: this ".f" argument is called once for each element of why, and is
# supplied one value of why and every value of ecks each time
pmap(.l = list(y_in = why), .f = iterate_over_x, x_in = ecks, fun_in = fun) %>%
set_names(nm = as.character(why))
}
my_paste <- function(x,y) {
paste(x,y)
}
loop_map(list("a","b"),list("c","d"),my_paste)
作为奖励,我为输出命名,以便可以更轻松地对其进行索引,或者以某种方式将其转换为数据框。我想通过添加任意循环许多输入列表的功能来改进此功能,并可能使用带有...
参数的功能(现在必须命名所有功能)。如果有人对此有想法,请随时告诉我。