---
title: "2.5 `map(.x, .f)`"
format:
  html:
    self-contained: TRUE
---

<iframe width="565" height="393" src="https://www.youtube.com/embed/F0uhYZPh7mk" title="2.6.1 map()" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

`map(.x, .f)` is a fundamental tidyverse function that applies function `.f` to each element of input vector `.x` and outputs a list. Let's explore how it works through examples and practice.

![](https://d33wubrfki0l68.cloudfront.net/f0494d020aa517ae7b1011cea4c4a9f21702df8b/2577b/diagrams/functionals/map.png){width=50%}

## Understanding `map(.x, .f)`

Consider this basic string manipulation that gets the first 3 characters of the character string:

```{r}
substr("apple", start = 1, stop = 3)
# Output: "app"
```

When working with vectors:

```{r}
substr(c("apple", "banana", "cherry"), start = 1, stop = 3)
# Output: "app" "ban" "che"
```

Here's how we achieve the same thing using `map(.x, .f)`:

<div style="background-color:#d2ff96; border-width:3px; border-style:solid; border-color:#d2ff96; padding: 1em;">

### a) Fill in the blanks to complete this code chunk:

```{r, message = F}
library(tidyverse)

# Fill in the arguments to map() to get the first 3 letters of each word
# map(
# .x = ___________, 
# .f = function(x) substr(x, start = ___, stop = ___)
# )
```
</div>

Notice that map() outputs a list. To get a character vector instead, use `map_chr()`.

- `map_dbl()` outputs a numeric vector
- `map_lgl()` outputs a logical vector
- `map_chr()` outputs a character vector

## Three ways to write `.f`

1. Write `.f` as a named function:

```{r}
map_chr(c("apple", "banana", "cherry"), substr, start = 1, stop = 3)
```

2. Write `.f` as an anonymous function:

```{r}
map_chr(c("apple", "banana", "cherry"), function(x) substr(x, start = 1, stop = 3))
```

3. Write `.f` as a formula, using `~` and referring to `.x` directly:

```{r}
map_chr(c("apple", "banana", "cherry"), ~ substr(.x, start = 1, stop = 3))
```


## Practice Questions

For each question, provide three solutions using a:

- Named function
- Anonymous function
- Formula syntax

<div style="background-color:#d2ff96; border-width:3px; border-style:solid; border-color:#d2ff96; padding: 1em;">
### b) Round these numbers to the nearest whole number:

```{r}
# Using round() as a vectorized function: 
round(c(1.234, 2.345, 3.456))

# Using map() to vectorize round():
# a) Named function:
# map_dbl(_______)

# b) Anonymous function:
# map_dbl(_______)

# c) Formula:
# map_dbl(_______)
```
</div>

<div style="background-color:#d2ff96; border-width:3px; border-style:solid; border-color:#d2ff96; padding: 1em;">
### c) Round these numbers to 2 decimal places:

```{r}
# Using round() as a vectorized functtion: 
round(c(1.234, 2.345, 3.456), digits = 2)

# Using map() to vectorize round():
# a) Named function:
# map_dbl(_______)

# b) Anonymous function:
# map_dbl(_______)

# c) Formula:
# map_dbl(_______)
```
</div>

<div style="background-color:#d2ff96; border-width:3px; border-style:solid; border-color:#d2ff96; padding: 1em;">
### d) Split these strings at the hyphen:

```{r}
# Original vector: c("a-b", "c-d", "e-f")
# Desired output: A list where each element is a character vector of length 2
# Complete all three approaches using strsplit()
```
</div>

