据我所知,当您不修改点时(例如,通过更改其名称),通常无需引用或取消引用点。但是,此示例使我似乎不太了解其工作原理。
这里我们有一个函数依靠点来选择要嵌套的列。它所做的只是从foo
参数添加一列,然后嵌套点中未提及的所有列。
library(tidyverse)
dots_fun <- function(df, foo, ...) {
df %>%
mutate(foo = foo) %>%
nest(data = -c(...))
}
dots_fun(mtcars, "a", cyl)
#> # A tibble: 3 x 2
#> cyl data
#> <dbl> <list>
#> 1 6 <tibble [7 × 11]>
#> 2 4 <tibble [11 × 11]>
#> 3 8 <tibble [14 × 11]>
我希望能够通过使用不同的参数调用它来映射此函数。通过使用常规匿名函数语法来执行此操作的幼稚方法失败,并显示一个令人困惑的错误:
list_of_foos <- c("a", "b")
mapping_fun1 <- function(df, foos, ...) {
map(
.x = foos,
.f = ~ dots_fun(df = df, foo = .x, ...)
)
}
mapping_fun1(mtcars, foos = list_of_foos, cyl)
#> Error: Can't subset columns that don't exist.
#> x The column `a` doesn't exist.
如果我只是将点移到匿名函数之外也无济于事。它不再出错,但是无法根据需要嵌套在cyl
上。
mapping_fun2 <- function(df, foos, ...) {
map(
.x = foos,
.f = ~ dots_fun(df = df, foo = .x),
...
)
}
mapping_fun2(mtcars, foos = list_of_foos, cyl)
#> [[1]]
#> # A tibble: 1 x 1
#> data
#> <list>
#> 1 <tibble [32 × 12]>
#>
#> [[2]]
#> # A tibble: 1 x 1
#> data
#> <list>
#> 1 <tibble [32 × 12]>
我设法通过将点拼接到匿名函数中来使其正常工作,但是我真的不明白为什么这样做是必要的。 (您也可以通过反转映射函数的参数顺序并通过...
的map
提供所有参数来使它起作用,但是dots_fun
的参数顺序错误。它没有如果您使用function()
样式匿名函数来反转参数顺序,则可以正常工作)
mapping_fun3 <- function(df, foos, ...) {
dots <- enquos(...)
map(
.x = foos,
.f = ~ dots_fun(df = df, foo = .x, !!!dots)
)
}
mapping_fun3(mtcars, foos = list_of_foos, cyl)
#> [[1]]
#> # A tibble: 3 x 2
#> cyl data
#> <dbl> <list>
#> 1 6 <tibble [7 × 11]>
#> 2 4 <tibble [11 × 11]>
#> 3 8 <tibble [14 × 11]>
#>
#> [[2]]
#> # A tibble: 3 x 2
#> cyl data
#> <dbl> <list>
#> 1 6 <tibble [7 × 11]>
#> 2 4 <tibble [11 × 11]>
#> 3 8 <tibble [14 × 11]>
我的问题是:您需要在什么条件/情况下引用和取消引用...
才能安全地通过函数传递它们?以及该条件在这里如何适用?
我认为您的问题是,您需要通过各个级别的函数调用来传递...
。因此,...
和内部函数都必须通过map()
。
我无法让您的示例与nest()
一起使用,所以我制作了一个使用select()
的版本
dots_fun <- function(df, foo, ...) {
df %>%
mutate(foo = foo) %>%
select(...)
}
然后,似乎您实际上无法将as_mapper
语法与...
一起使用,并通过this github issue进行非标准评估,因此您需要显式创建一个匿名函数,以便不会将迭代值传递给同样是...
值中的第二次。Hadley said~
语法仅适用于“简单”功能,不适用于具有...
的功能。因此,有效的映射功能可能看起来像这样
mapping_fun1 <- function(df, foos, ...) {
map(
.x = foos,
.f = function(x, ...) dots_fun(df = df, foo = x, ...),
...
)
}
mapping_fun1(mtcars, foos = list_of_foos, cyl, gear)
我们通过匿名函数将...
传递到map()
,最后进入dots_fun
。如果您随时中断该链,它就会崩溃。