## 7.2 Producing atomic vectors

# map_chr() always returns a character vector
mtcars %>%
map_chr(typeof)
#>      mpg      cyl     disp       hp     drat       wt     qsec       vs
#> "double" "double" "double" "double" "double" "double" "double" "double"
#>       am     gear     carb
#> "double" "double" "double"
# map_lgl() always returns a logical vector
mtcars %>%
map_lgl(is.double)
#>  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
#> TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# map_int() always returns a integer vector
mtcars %>%
map_int(function(x) length(unique(x)))
#>  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
#>   25    3   27   22   22   29   30    2    2    3    6
# map_dbl() always returns a double vector
mtcars %>%
map_dbl(mean)
#>     mpg     cyl    disp      hp    drat      wt    qsec      vs      am    gear
#>  20.091   6.188 230.722 146.688   3.597   3.217  17.849   0.438   0.406   3.688
#>    carb
#>   2.812

pair <- function(x) c(x, x)
map_dbl(1:2, pair)
#> Error: Result 1 must be a single double, not an integer vector of length 2
1:2 %>%
map(pair)
#> [[1]]
#> [1] 1 1
#>
#> [[2]]
#> [1] 2 2
1:2 %>%
map_dbl(as.character)
#> Error: Can't coerce element 1 from a character to a double
1:2 %>%
map_chr(as.character)
#> [1] "1" "2"

### 7.2.1 purrr-style anonymous functions

mtcars %>%
map_dbl(function(x) length(unique(x)))
#>  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
#>   25    3   27   22   22   29   30    2    2    3    6
mtcars %>%
map_dbl(~ length(unique(.x)))
#>  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
#>   25    3   27   22   22   29   30    2    2    3    6
mtcars %>%
map_dbl(~ length(unique(.)))
#>  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb
#>   25    3   27   22   22   29   30    2    2    3    6

This shortcut is particularly useful for generating random data:

1:5 %>%
map(~ rnorm(mean = .x, n = 5)) %>%
str()
#> List of 5
#>  $: num [1:5] 1.788 0.578 1.057 1.711 -0.587 #>$ : num [1:5] 2.6 3.22 1.69 1.79 1.63
#>  $: num [1:5] 3.33 4.88 2.52 4.74 3.32 #>$ : num [1:5] 3.9 3.22 4.1 3.95 3.73
#>  \$ : num [1:5] 5.65 3.43 2.95 6.02 5.6
x <- list(
list(-1, x = 1, y = c(2), z = "a"),
list(-2, x = 4, y = c(5, 6), z = "b"),
list(-3, x = 8, y = c(9, 10, 11))
)

# select by position
x %>%
map(2)
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 4
#>
#> [[3]]
#> [1] 8
# select by name
x %>%
map("x")
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 4
#>
#> [[3]]
#> [1] 8
# select by both position and name
x %>%
map(list("y", 2))
#> [[1]]
#> NULL
#>
#> [[2]]
#> [1] 6
#>
#> [[3]]
#> [1] 10