Search code examples
rdplyrtidyversemagrittr

Get second to last input from %>% pipe operator


I would like to make a factor out of a column I have just created within a pipeline. I can do this with the following code:

library("dplyr")
library("magrittr")
library("janitor")

iris <- iris %>% janitor::clean_names()    
iris %>% filter(species %in% c("setosa","versicolor")) %>% group_by(species) %>% 
             summarise(mean_sepal_length = mean(sepal_length)) %>% ungroup() %>%
             mutate(species = factor(species, levels = (iris %>% group_by(species) %>%  #<- works but messy
                                                            summarise(mean_sepal_length = mean(sepal_width)) %>% 
                                                            ungroup() %>% arrange(mean_sepal_length) %$% species))) %>% 
                    arrange(species)

I was wondering if there is "cleaner" way of doing this. Some thing like:

iris %>% filter(species %in% c("setosa","versicolor")) %>% group_by(species) %>% 
     summarise(mean_sepal_length = mean(sepal_length)) %>% ungroup() %>%
     mutate(species = factor(species, levels = (. %>% arrange(mean_sepal_length) %$% species))) %>% 
            arrange(species)

Where . is the second to last argument instead of the last argument given to the pipe?

This throws up an error because the last argument to the pipe is the mutate statement:

Error: Problem with `mutate()` input `species`. x 'match' requires vector arguments i Input `species` is `factor(...)`.

I think this is fundamentally not how the pipe operator works so this might not be possible.


Solution

  • For the second option to work, we can wrap the . inside {}

    library(dplyr)
    library(magrittr)
    iris %>% 
     filter(species %in% c("setosa","versicolor")) %>%
     group_by(species) %>% 
     summarise(mean_sepal_length = mean(sepal_length)) %>% 
     ungroup() %>%
     mutate(species = factor(species, 
          levels = ({.} %>%
                      arrange(mean_sepal_length) %$% species))) %>%
     arrange(species)
    # A tibble: 2 x 2
    #  species    mean_sepal_length
    #  <fct>                  <dbl>
    #1 setosa                  5.01
    #2 versicolor              5.94