I would like to know how to use purrr::map where .f is a composition of two different functions.
First, let's create a list on which to map a composite function:
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"
Now let's say I want to extract the first element of the class of each element in the list:
# 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"
That works, but I want to avoid using map twice and would like to compose a function that can extract class and its first element in a single step. So I tried to compose such a function but it doesn't play nicely with 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"
How can I do this?
If we are using the ~, just wrapping the first would get the expected output
library(purrr)
map(x, ~ first(class(.)))
We can directly use compose() without the formula syntax:
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"
Created on 2021-06-30 by the reprex package (v2.0.0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With