I am following an issue posted on github, https://github.com/tidyverse/purrr/issues/179 and found that there is a map inside a map. Can any one explain, what the outer map is doing. Or can we write the . %>% pipe like map(~mean(.x). Any help?
suppressWarnings(library(purrr))
suppressWarnings(library(purrrlyr))
alist <- list(
data.frame(a = 1:2, b = 6:7),
data.frame(a = 3:5, b = 8:10)
)
# using purrr
alist %>% map(. %>% map_dbl(mean)) %>% dplyr::bind_rows()
#> # A tibble: 2 x 2
#> a b
#> <dbl> <dbl>
#> 1 1.5 6.5
#> 2 4 9
## using dmap
alist %>% map_df(. %>% dmap(mean))
#> # A tibble: 2 x 2
#> a b
#> <dbl> <dbl>
#> 1 1.5 6.5
#> 2 4 9
alist contains a list of data frames. The first map() loops on the list and returns a list, the inside map_dbl() loops on the columns of the data frame and returns a double for each vector.
If you typed what you suggest, map(alist, ~mean(.x)) this means the map() loops on the list, and gives a whole dataframe to mean() in the variable .x. So it is equivalent to such a loop:
for(i in 1:length(alist)){
.x <- alist[[i]]
mean(.x)
}
In the example, alist %>% map(. %>% map_dbl(mean)) is equivalent to map(alist, ~ map_dbl(.x, mean)) and would be equivalent to such a structure:
for(i in 1:length(alist)){
my_df <- alist[[i]]
for(j in 1:length(names(my_df))){
my_col <- my_df[[j]]
mean(my_col)
}
}
PS: Just note that the for loops here are for illustration. In real life i and j have no reason to be numerical and could contain the whole dataframe and the name of the column, for example. Also, you'd have to package the means back into a dataframe to return them, which map_dbl() is taking care of here.