In one R file, I plan to source another R file that supports reading two command-line arguments. This sounds like a trivial task but I couldn't find a solution online. Any help is appreciated.
6 Answers
I assume the sourced script accesses the command line arguments with commandArgs? If so, you can override commandArgs in the parent script to return what you want when it is called in the script you're sourcing. To see how this would work:
file_to_source.R
print(commandArgs())
main_script.R
commandArgs <- function(...) 1:3
source('file_to_source.R')
outputs [1] 1 2 3
If your main script doesn't take any command line arguments itself, you could also just supply the arguments to this script instead.
6 Comments
commandArgs from file to source uses the trailingOnly argument. To fix this I found this is more useful in general: commandArgs <- function(...) 1:3 where ... absorbs any unused arguments.commandArgs() function.The simplest solution is to replace source() with system() and paste. Try
arg1 <- 1
arg2 <- 2
system(paste("Rscript file_to_source.R", arg1, arg2))
4 Comments
file_to_source.R produces into globalenv(). For that, it seems to me, you need Matthew Plourde's hack -- redefine commandArgs, and maybe rm() your version immediately after calling source().If you have one script that sources another script, you can define variables in the first one that can be used by the sourced script.
> tmpfile <- tempfile()
> cat("print(a)", file=tmpfile)
> a <- 5
> source(tmpfile)
[1] 5
1 Comment
An extended version of @Matthew Plourde's answer. What I usually do is to have an if statement to check if the command line arguments have been defined, and read them otherwise.
In addition I try to use the argparse library to read command line arguments, as it provides a tidier syntax and better documentation.
file to be sourced
if (!exists("args")) {
suppressPackageStartupMessages(library("argparse"))
parser <- ArgumentParser()
parser$add_argument("-a", "--arg1", type="character", defalt="a",
help="First parameter [default %(defult)s]")
parser$add_argument("-b", "--arg2", type="character", defalt="b",
help="Second parameter [default %(defult)s]")
args <- parser$parse_args()
}
print (args)
file calling source()
args$arg1 = "c"
args$arg2 = "d"
source ("file_to_be_sourced.R")
c, d
1 Comment
args <- parser$parse_args(); if (exists('myargs')) { args <- purrr::list_modify(args, !!!myargs) }This works:
# source another script with arguments
source_with_args <- function(file, ...){
commandArgs <<- function(trailingOnly){
list(...)
}
source(file)
}
source_with_args("sourcefile.R", "first_argument", "second_argument")
Note that the built in commandArgs function has to be redefined with <<- instead of <-.
As I understand it, this makes its scope extend beyond the function source_with_args() where it is defined.
3 Comments
I've tested some of the alternatives here and I end up with this:
File calling the source:
source_with_args <- function(file, ...){
system(paste("Rscript", file, ...))
}
source_with_args(
script_file,
paste0("--data=", data_processed_file),
paste0("--output=", output_file)
)
File to be sourced:
library(optparse)
option_list = list(
make_option(
c("--data"),
type="character",
default=NULL,
help="input file",
metavar="filename"
),
make_option(
c("--output"),
type="character",
default=NULL,
help="output file [default= %default]",
metavar="filename"
)
)
opt_parser = OptionParser(option_list=option_list)
data_processed_file <- opt$data
oputput_file <- opt$output
if(is.null(data_processed_file) || is.null(oputput_file)){
stop("Required information is missing")
}
source(file)is to load things into your workspace. If you want to execute the sourced object, better to do so in the next command.