3

I have the following R script (myscript.r)

#!/usr/bin/env Rscript
dat <- read.table(file('stdin'), sep=" ",header=FALSE)
# do something with dat
# later with user given "param_1" 

With that script we can run it the following way;

$ cat data_no_*.txt | ./myscript.r

What I want to do is to make the script takes additional parameter from user:

$ cat data_no_*.txt | ./myscript.r param_1

What should I do to modify the myscript.r to accommodate that?

neversaint
  • 60,904
  • 137
  • 310
  • 477

2 Answers2

2

We built littler to support just that via its r executable.

Have a look at its examples, it may fit your bill.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
2

For very basic usage, have a look at ?commandArgs.

For more complex usage, two popular packages for command-line arguments and options parsing are getopt and optparse. I use them all the time, they get the job done. I also see argparse, argparser, and GetoptLong but have never used them before. One I missed: Dirk recommended that you look at docopt which does seem very nice and easy to use.

Finally, since you seem to be passing arguments via pipes you might find this OpenRead() function useful for generalizing your code and allowing your arguments to be pipes or files.


I wanted to test docopt so putting it all together, your script could look like this:

#!/usr/bin/env Rscript

## Command-line parsing ##

'usage: my_prog.R [-v -m <msg>] <param> <file_arg> 

options:
 -v        verbose
 -m <msg>  Message' -> doc

library(docopt)
opts <- docopt(doc)

if (opts$v) print(str(opts)) 
if (!is.null(opts$message)) cat("MESSAGE: ", opts$m)

## File Read ##

OpenRead <- function(arg) {
   if (arg %in% c("-", "/dev/stdin")) {
      file("stdin", open = "r")
   } else if (grepl("^/dev/fd/", arg)) {
      fifo(arg, open = "r")
   } else {
      file(arg, open = "r")
   }
}

dat.con <- OpenRead(opts$file_arg)
dat <- read.table(dat.con, sep = " ", header = FALSE)

# do something with dat and opts$param

And you can test running:

echo "1 2 3" | ./test.R -v -m HI param_1 -

or

./test.R -v -m HI param_1 some_file.txt
Community
  • 1
  • 1
flodel
  • 87,577
  • 21
  • 185
  • 223
  • 1
    What you *really* want to look at is the much smarter [dococt](http://cran.r-project.org/package=doctopt) package --- but then you *still* need a program to read them with, and `r` beats `Rscript` in my book ... – Dirk Eddelbuettel Oct 02 '14 at 02:02
  • Fixed link: [docopt](http://cran.r-project.org/web/packages/docopt/index.html). Interesting indeed, mostly from an ease-of-use. But at a glance, I feel it doesn't have as many bells and whistles. – flodel Oct 02 '14 at 02:12
  • Thanks for catching the typo. I luuuv docopt after years of getopt (and related C/C++ libs). – Dirk Eddelbuettel Oct 02 '14 at 02:13