我想知道如何使用purrr::map
,其中.f
是两个不同功能的组合。
首先,让我们创建一个映射复合函数的列表:
library(tidyverse)
# create a list
x <- list(mtcars, tibble::as_tibble(iris), c("x", "y", "z"))
# extracting class of objects
purrr::map(.x = x, .f = class)
#> [[1]]
#> [1] "data.frame"
#>
#> [[2]]
#> [1] "tbl_df" "tbl" "data.frame"
#>
#> [[3]]
#> [1] "character"
现在让我们说我要提取列表中每个元素的class
的 first 元素:
# this works but uses `map` twice
purrr::map(.x = x, .f = class) %>%
purrr::map(.x = ., .f = `[[`, i = 1L)
#> [[1]]
#> [1] "data.frame"
#>
#> [[2]]
#> [1] "tbl_df"
#>
#> [[3]]
#> [1] "character"
那行得通,但是我想避免两次使用map
,而是想组成一个可以在一个步骤中提取类及其第一个元素的函数。因此,我尝试编写这样的函数,但它与map
# error
purrr::map(.x = x, .f = purrr::compose(class, `[[`, i = 1L))
#> Can't convert an integer vector to function
# no error but not the expected output
purrr::map(.x = x, .f = purrr::compose(class, `[[`), i = 1L)
#> [[1]]
#> [1] "numeric"
#>
#> [[2]]
#> [1] "numeric"
#>
#> [[3]]
#> [1] "character"
我该怎么做?
答案 0 :(得分:5)
如果我们使用~
,只需将first
包装起来即可获得预期的输出结果
library(purrr)
map(x, ~ first(class(.)))
答案 1 :(得分:1)
我们可以不用公式语法直接使用compose()
:
library(tidyverse)
x <- list(mtcars, tibble::as_tibble(iris), c("x", "y", "z"))
map(x, compose(first, class))
#> [[1]]
#> [1] "data.frame"
#>
#> [[2]]
#> [1] "tbl_df"
#>
#> [[3]]
#> [1] "character"
由 reprex package (v2.0.0) 于 2021 年 6 月 30 日创建
答案 2 :(得分:0)
来自?compose
compose(...,.dir = c(“后退”,“前进”))
... 要按顺序应用的功能(默认情况下从右到左)等...
.dir 如果为“ backward”(默认值),则按照数学中的常规从右到左的相反顺序调用函数。如果是“ forward”,则从左到右调用它们。
所以我们只需要反转函数顺序。另外,compose
不知道i=1L
属于哪个函数,因此在这种情况下,compose
会将它附加到最后一个函数class
,因此我们需要定义{{1} }专门用于预期的功能。
i=1L