Search code examples
rpipetidyversemagrittr

`magrittr` pipe into apply


How do you pipe an object into a specific place in an apply call, that isn't the first input? The magrittr dot placeholder does not seem to work for this.

  dat <- 1:10 
  locs <- list(c(1, 2),
               c(3, 4),
               c(5, 6))
  
  foo <- function(x, y, z) {
    out <- mean(c(x[y], x[z]))
    return(out)
  }
  
  # works
  lapply(locs, function(z) foo(dat, z[1], z[2]))
  
  # none of these work 
  dat %>%
    lapply(locs, function(z) foo(., z[1], z[2]))
    
  dat %>%
    lapply(locs, function(z) foo((.), z[1], z[2]))
    
  dat %>%
    lapply(locs, function(z) {. %>% foo(z[1], z[2])})
    
  
  # New native pipe and placeholder also do not work
  dat |>
    lapply(locs, function(z) foo(_, z[1], z[2]))  

Solution

  • Here are two ways, with the magrittr and native pipes.

    suppressPackageStartupMessages(library(magrittr))
    dat <- 1:10 
    locs <- list(c(1, 2),
                 c(3, 4),
                 c(5, 6))
    
    foo <- function(x, y, z) {
      out <- mean(c(x[y], x[z]))
      return(out)
    }
    
    # wrap the function around parenthesis
    dat %>%
      (\(d) lapply(locs, \(z) foo(., z[1], z[2])))()
    #> [[1]]
    #> [1] 1.5
    #> 
    #> [[2]]
    #> [1] 3.5
    #> 
    #> [[3]]
    #> [1] 5.5
    
    # New native pipe with anonymous function
    dat |>
      {\(d) lapply(locs, \(z) foo(x = d, z[1], z[2]))}()
    #> [[1]]
    #> [1] 1.5
    #> 
    #> [[2]]
    #> [1] 3.5
    #> 
    #> [[3]]
    #> [1] 5.5
    

    Created on 2022-05-18 by the reprex package (v2.0.1)