I would like the answer to contain information about:
-
What are mappers?
-
How to create a mapper in
R
? -
In what situations are mappers used (your role in functional programming)?
I would like the answer to contain information about:
What are mappers?
How to create a mapper in R
?
In what situations are mappers used (your role in functional programming)?
A mapper is a function that relates elements of a set with elements of the same or another set. This is a mathematical concept.
To better understand what a mapper in the programming context we need to first understand what a functional is.
A functional is a function that receives at least one function as an argument and returns a vector / list. There is a very important functional category that are the maps .
Essentially, a map is a hidden loop. They receive a vector and a function and apply this function to each element of the received vector. A simple implementation in R could be as follows:
meu_map <- function(x, f) {
out <- vector(mode = "list", length = length(x))
for (i in seq_along(x)) {
out[[i]] <- f(x[[i]])
}
out
}
meu_map(1:10, function(x) x^2)
mapper in programming is the name we give to the function we pass as an argument to the functionals of class map
.
Contrary to popular belief, using maps
in R is not related to performance, but to readability of the code. It's more or less the same idea of using for
instead of using while
. It is also worth noting that in R, we only use maps
when there is no vectorized option to do the same thing - in the above example the most certain would be to simply write x^2
.
In Base R, we create mappers
the same way we create functions, even though we can use them as anonymous functions. In the case of lapply
which is the most famous functional of R, mappers are the second argument in the calls below.
lapply(mtcars, mean)
lapply(mtcars, function(x) sum(x)/length(x))
The purrr
package implements a slightly different way of writing anonymous functions if you are going to use them as mappers.
library(purrr)
map(mtcars, ~sum(.x)/length(.x))
This new notation makes writing anonymous functions much less verbose, making the code simpler. In this case, writing ~sum(.x)/length(.x)
is equivalent to writing: function(.x) sum(.x)/length(.x)
. Note that it always assumes that the argument of the function has the name .x
.