I'm learning the map function in purrr package and have the following code not working:
library(purrr)
library(dplyr)
df1 = data.frame(type1 = c(rep('a',5),rep('b',5)),
             x = 1:10,
             y = 11:20) 
df1 %>% 
  group_by(type1) %>% 
  nest() %>% 
  map(.$data,with(.x, x + y))
df1 %>% 
  group_by(type1) %>% 
  nest() %>% 
  map(.$data,function(df) df$x + df$y)
For the last two block of code, the errors return as:
Error: Index 1 must have length 1
By contrary, the following two blocks of code work well,
df1 %>% 
  group_by(type1) %>% 
  nest() %>% .$data %>% 
  map(.,~with(.x, .x$x + .x$y))
df1 %>% 
  group_by(type1) %>% 
  nest() %>% .$data %>% 
  map(.,~with(.x, .x$x + .x$y))
Can anyone help me to understand the errors and how to fix them?
You need to add braces around the map expression, since . doesn't appear as a separate argument placeholder in the function so magrittr pipe is applying the first-argument rule which you can read more about here; and also use ~ to construct a function which is what map is expecting:
df1 %>% 
    group_by(type1) %>% 
    nest() %>% 
    { map(.$data, ~ with(.x, x + y)) }
#[[1]]
#[1] 12 14 16 18 20
#[[2]]
#[1] 22 24 26 28 30
Similarly for the second method:
df1 %>% 
    group_by(type1) %>% 
    nest() %>% 
    { map(.$data,function(df) df$x + df$y) }
#[[1]]
#[1] 12 14 16 18 20
#[[2]]
#[1] 22 24 26 28 30
                        If you wanted to use split(), I usually split on my grouping factor and then just map an anonymous function for what I want to do for a single tibble/dataframe in the newly created list:
df1 %>% 
    split(.$type1) %>% 
    map(~ mutate(., z = x + y) %>% # chain like you would a single tib
        select(z) %>%
        unlist(T,F))
$a
[1] 12 14 16 18 20
$b
[1] 22 24 26 28 30
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With