如何减少 purrr::map 中的参数冗余

问题描述 投票:0回答:1

Map 语句非常棒,但它们的输入常常让人感觉不必要的冗余。例如,在下面的块中,必须重新列出我已经从

tibble
请求的变量似乎很愚蠢。简而言之,我希望我可以为匿名函数添加
\()
。有谁有办法减少冗余吗?当然,我可以使用
mutate
完成下面的任务,但我只是想展示我正在寻找的内容。

library(tidyverse)

mtcars |> 
  as_tibble() |> 
  mutate(
    test = pmap_chr(
      .l = list(mpg,cyl),
      .f = \(mpg,cyl){ #Ahhhh! So redundant!!!
        str_glue("{mpg}_{cyl}")
      }
    )
  )

PS:“~”不再是最佳实践,尽管这对我有帮助。

PPS:这不是问题的正式部分,因为它是基于意见的,但是您是否更喜欢在

mutate
中使用地图与直接在列表上使用地图?我发现将它们与
mutate
一起使用可以更有组织性并且需要更少的设置,但我一直想知道这是否是一个好主意。我不经常看到人们只是设置列表并将其输入到
purrr::map

r purrr
1个回答
0
投票

正如评论中所指出的,我们实际上并不需要

pmap_*
,但为了回答这个问题,我们必须使用它。

然后我们可以使用

with(list(...) ..whatever..)
来避免重复论证。在此代码中,为了简洁起见,我们使用了点 (.),但如果我们使用 |> 或者
mutate
位于
group_by
中,则使用更详细的
pick(everything())

library(dplyr)
library(purrr)
library(stringr)

mtcars[1:3, 1:3] %>%
  mutate(test = pmap(., ~ with(list(...), str_glue("{mpg}_{cyl}"))))
##                mpg cyl disp   test
## Mazda RX4     21.0   6  160   21_6
## Mazda RX4 Wag 21.0   6  160   21_6
## Datsun 710    22.8   4  108 22.8_4

如果可以使用

str_glue_data
我们可以稍微简化一下。

mtcars[1:3, 1:3] %>%
  mutate(test = pmap(., ~ str_glue_data(list(...), "{mpg}_{cyl}")))

如果

paste
没问题,那么对于这个例子

mtcars[1:3, 1:3] %>%
  mutate(test = pmap_chr(., paste, sep = "_"))

这是一个不同的示例,表明

with/list
也适用于其他情况:

dat <- data.frame(a = 11:13, b = 21:23, c = 0)
dat %>%
  mutate(p.value = pmap_dbl(., ~ with(list(...), prop.test(a, b)$p.value)))
##    a  b c   p.value
## 1 11 21 0 1.0000000
## 2 12 22 0 0.8311704
## 3 13 23 0 0.6766573
© www.soinside.com 2019 - 2024. All rights reserved.