gpt4 book ai didi

r - 为什么在将它们传递给 purrr 中的映射函数时需要引用不加引号的点?

转载 作者:行者123 更新时间:2023-12-04 10:28:40 25 4
gpt4 key购买 nike

据我了解,通常您不需要在未修改(例如通过更改名称)时引用或取消引用点。然而,这个例子让我似乎并不真正理解它是如何工作的。

这里我们有一个函数,它依赖于点来选择用于嵌套的列。它所做的只是从 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 .如果你在任何时候打破这条链条,它就会分崩离析。

关于r - 为什么在将它们传递给 purrr 中的映射函数时需要引用不加引号的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60517798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com