在函数内部使用purrr::pmap

编程语言 2026-07-12

我有兴趣在函数中使用 purrr::pmap()。我在将数据变量名从 我的函数 传递给pmap() 使用的匿名函数时遇到了困难。

library("purrr")
library("dplyr")

# Example data
df = tribble(
  ~x, ~y, ~z,       
  1,  5,  "A",
  4,  6,  "B")         
df

# Sum of x and y (outside function)
pmap(df, \(x, y, ...) x + y)
#> [[1]]
#> [1] 6
#> 
#> [[2]]
#> [1] 10

# Naively wrap that in a function - doesn't work
add_cols = function(dat, a, b){

  pmap(dat, \(first = a, second = b, ...) first + second)

}
add_cols(dat = df, a = x, b = y)
#> Error in `pmap()`:
#> ℹ In index: 1.
#> Caused by error:
#> ! object 'x' not found

当我之前尝试类似的事情时,我曾使用来自rlang包的 {{ }} 来注入数据变量名,但我无法在 pmap() 中让它起作用。

# Example where inject works within mutate
add_cols2 = function(dat, a, b){

dat |>
mutate(sum = {{a}} + {{b}})

}

add_cols2(dat = df, a = x, b = y)
#> # A tibble: 2 × 4
#>       x     y z       sum
#>   <dbl> <dbl> <chr> <dbl>
#> 1     1     5 A         6
#> 2     4     6 B        10

# But this approach does not work within pmap
add_cols3 = function(dat, a, b){

  pmap(dat, \(first = {{a}}, second = {{b}}, ...) first + second)

}
add_cols3(dat = df, a = x, b = y)
#> Error in `pmap()`:
#> ℹ In index: 1.
#> Caused by error:
#> ! object 'x' not found

我的问题是如何将未带引号的数据变量名传递给pmap() 内的匿名函数。

对于这个简单的例子,除了使用pmap之外还有更好的方法(尤其是使用mutate),但我想了解如何实现这一点,并且我的实际问题需要 pmap()。我也知道一些变通方法,包括在add_cols函数中在pmap() 之前重命名变量或创建一个新的数据对象(列表或df),但如果可能的话,我想直接知道如何执行这个操作。

# An example work-around
add_cols4 = function(dat, a, b){

  dat = dat |>
    rename(c(first = {{a}}, second = {{b}}))


  pmap(dat, \(first, second, ...) first + second)

}
add_cols4(dat = df, a = x, b = y)
#> [[1]]
#> [1] 6
#> 
#> [[2]]
#> [1] 10

解决方案

我们可以这样做:

add_cols = function(dat, a, b){
  purrr::pmap(
    unname(as.list(select(dat, {{a}}, {{b}}))),
    \(first, second) first + second
  )
}

add_cols(dat = df, a = x, b = y)
# [[1]]
# [1] 6
# [[2]]
# [1] 10

我在 select 里进行准引号,因为需要减少传递到 pmap 的列数。并且由于这些列有名称,内部函数里会有一些混乱,因此需要使用 unname(as.list(..))

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章