3

I am writing a R script which I will be running as a script from the command line. I am passing command line arguments to the script using keywords as follows:

myscript.R --arg1=100 --arg2='hello' --arg3=3.14159

I want to write an R function that will return the command line values into a dictionary like object (i.e. a list of lists in R), filling unsupplied arguments with defaults.

for e.g.

parseArguments <- function() {
    options <- commandArgs(TRUE)

    # options now contains "--arg1=100 --arg2='hello' --arg3=3.14159"
    # parse string held in variable named options and stuff into a list 
    # .... Do some string manip ....

    args <- list()
    args['arg1'] <- 100
    args['arg2'] <- 'hello'
    args['arg3'] <- 3.14159
    args['arg4'] <- 123  # Not found in parsed line so we use a hard coded default

    return (args)
}

Can someone help fill in the blanks?

0

2 Answers 2

3
> parseArguments <- function() {
+     text1 = "--arg1=100 --arg2='hello' --arg3=3.14159" 
+     eval(parse( text= gsub("\\s", ";", gsub("--","", text1))))
+     args <- list()
+     args['arg1'] <- arg1
+     args['arg2'] <- arg2
+     args['arg3'] <- arg3
+     args['arg4'] <- 123  # Not found in parsed line so we use a hard coded default
+ 
+     return (args)
+ }
> argres <- parseArguments()
> argres
$arg1
[1] 100

$arg2
[1] "hello"

$arg3
[1] 3.14159

$arg4
[1] 123

To address the unkown number of arguments modification to the problem:

 parseArguments <- function() {
     text1 = "--arg1=100 --arg2='hello' --arg3=3.14159" 
     eval(parse(text=gsub("\\s", ";", gsub("--","", text1))))
     args <- list()
     for( ar in ls()[! ls() %in% c("text1", "args")] ) {args[ar] <- get(ar)}
     return (args)
 }
 argres <- parseArguments()
 argres
 #---------
$arg1
[1] 100

$arg2
[1] "hello"

$arg3
[1] 3.14159
Sign up to request clarification or add additional context in comments.

6 Comments

Ah, I'm glad I asked in here - it would have taken me forever to come up with that solution. One quick question - regarding default values for arguments not specified. The example I gave was a bit contrived. It is not clear from the snippet you provided, how to determine which arguments were not provided at the command line, so that default values could be substituted. Could you please clarify that?. Thanks!
Inside a function you can use ls() to find out what objects exist locally. You could loop over all of the local objects as names to the arg entries and use get() to supply the values. I will add code.
Thanks. Lots of interesting new stuff for me. Not sure I understand everything (lots of magic going on), but I hope to learn from the code.
DWIn: Could you please explain the meaning of this cryptic expression? for( ar in ls()[! ls() %in% c("text1", "args")] ) - its the list comprehension part that I don't get. Thanks!
I was just removing the other local named objects, text1 and args from the items added to the list, args. ls() returns a character vector of all the names of objects in the local environment, unless you point it at a different environment that is.
|
3

You can split each argument into the name and value parts, using strsplit or a regular expression. The following does not try to check the type of the arguments: everything will be returned as a string.

parseArgs <- function(...) {
  o <- commandArgs(TRUE)
  # The defaults arguments should be named
  defaults <- list(...)
  stopifnot( length(defaults) == length(names(defaults)) )
  stopifnot( all( names(defaults) != "" ) )
  # All the arguments should be of the form "--foo=bar"
  re <- "^--(.*?)=(.*)"
  stopifnot( all(grepl(re, o)) )
  # Extract the values and names
  r <- gsub(re, "\\2", o)
  names(r) <- gsub("^--(.*?)=(.*)", "\\1", o)
  r <- as.list(r)
  # Add the default values
  missing <- setdiff( names(defaults), names(r) )
  append(r, defaults[missing])
}
print( parseArgs() )
print( parseArgs(foo=1, bar=2) ) # With default values

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.