Search code examples
rpipetidyversepipelinemagrittr

How do you call a function that takes no inputs within a pipeline?


I tried searching for this but couldn't find any similar questions. Let's say, for the sake of a simple example, I want to do the following using dplyr's pipe %>%.

c(1,3,5) %>% ls() %>% mean()

Setting aside what the use case would be for a pipeline like this, how can I call a function "mid-pipeline" that doesn't need any inputs coming from the left-hand side and just pass them along to the next function in the pipeline? Basically, I want to put an "intermission" or "interruption" of sorts into my pipeline, let that function do its thing, and then continue on my merry way. Obviously, the above doesn't actually work, and I know the T pipe %T>% also won't be of use here because it still expects the middle function to need inputs coming from the lhs. Are there options here shy of assigning intermediate objects and restarting the pipeline?


Solution

  • With the ‘magrittr’ pipe operator you can put an operand inside {…} to prevent automatic argument substitution:

    c(1,3,5) %>% {ls()} %>% mean()
    # NA
    # Warning message:
    # In mean.default(.) : argument is not numeric or logical: returning NA
    

    … but of course this serves no useful purpose.

    Incidentally, ls() inside a pipeline is executed in its own environment rather than the calling environment so its use here is even less useful. But a different function that returned a sensible value could be used, e.g.:

    c(1,3,5) %>% {rnorm(10)} %>% mean()
    # [1] -0.01068046
    

    Or, if you intended for the left-hand side to be passed on, skipping the intermediate ls(), you could do the following:

    c(1,3,5) %>% {ls(); .} %>% mean()
    # [1] 3
    

    … again, using ls() here won’t be meaningful but some other function that has a side-effect would work.