Search code examples
rstring-interpolation

Better string interpolation in R


I need to build up long command lines in R and pass them to system(). I find it is very inconvenient to use paste0/paste function, or even sprintf function to build each command line. Is there a simpler way to do like this:

Instead of this hard-to-read-and-too-many-quotes:

cmd <- paste("command", "-a", line$elem1, "-b", line$elem3, "-f", df$Colum5[4])

or:

cmd <- sprintf("command -a %s -b %s -f %s", line$elem1, line$elem3, df$Colum5[4])

Can I have this:

cmd <- buildcommand("command -a %line$elem1 -b %line$elem3 -f %df$Colum5[4]")

Solution

  • This comes pretty close to what you are asking for. When any function f is prefaced with fn$, i.e. fn$f, character interpolation will be performed replacing ... with the result of running ... as an R expression.

    library(gsubfn)
    cmd <- fn$identity("command -a `line$elem1` -b `line$elem3` -f `df$Colum5[4]`")
    

    Here is a self contained reproducible example:

    library(gsubfn)
    
    # test inputs
    line <- list(elem1 = 10, elem3 = 30)
    df <- data.frame(Colum5 = 1:4)
    
    fn$identity("command -a `line$elem1` -b `line$elem3` -f `df$Colum5[4]`")
    ## [1] "command -a 10 -b 30 -f 4"
    

    system

    Since any function can be used we could operate directly on the system call like this. We have used echo here to make it executable but any command could be used.

    exitcode <- fn$system("echo -a `line$elem1` -b `line$elem3` -f `df$Colum5[4]`")
    ## -a 10 -b 30 -f 4
    

    Variation

    This variation would also work. fn$f also performs substitution of $whatever with the value of variable whatever. See ?fn for details.

    with(line, fn$identity("command -a $elem1 -b $elem3 -f `df$Colum5[4]`"))
    ## [1] "command -a 10 -b 30 -f 4"