首页 > 解决方案 > 使用 `purrr::map` 和 compose 函数

问题描述

我想知道如何使用purrr::mapwhere.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

# 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"

我怎样才能做到这一点?

标签: rfunctional-programmingtidyversepurrr

解决方案


如果我们使用~,只需包装first就会得到预期的输出

library(purrr)
map(x, ~ first(class(.)))

推荐阅读