Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using `purrr::map` with compose functions

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?

like image 784
Indrajeet Patil Avatar asked Aug 09 '26 13:08

Indrajeet Patil


2 Answers

If we are using the ~, just wrapping the first would get the expected output

library(purrr)
map(x, ~ first(class(.)))
like image 109
akrun Avatar answered Aug 11 '26 07:08

akrun


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)

like image 32
jpdugo17 Avatar answered Aug 11 '26 06:08

jpdugo17



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!