Search code examples
rmagrittr

How to maintain defaults in a function when using the pipe in R?


I feel like this should be a really easy task, but I can't seem to find the answer online. I simply want to do something like this:

stringr::str_interp("x <- ${rnorm(1)}") %>% parse(text = .) %>% eval()

But that doesn't work; when I call x it tells me it cannot be found. I know it's a valid series of functions because this works:

eval(parse(text = stringr::str_interp("x <- ${rnorm(1)}")))

Any idea how to achieve this? Thanks!

NOTE: I'm using the github version of stringr, which is where the str_interp function comes from.


Solution

  • There are a couple of problems here. First, nested functions get evaluated from the inside out, so it should be

    str_interp --> parse --> eval
    

    since parse() goes inside eval(). String it, parse it, evaluate it. Next, you will need to evaluate it in an environment other than the default environment of eval(), which is the parent frame. I chose the global environment.

    library(magrittr)
    str_interp("x <- ${rnorm(1)}") %>% parse(text = .) %>% eval(globalenv())
    x
    # [1] 0.1542613
    

    Note: The necessary functions to reproduce this are in the stringr development version, found here: https://github.com/hadley/stringr/blob/master/R/interp.R