The objective is to have two simple ways to source some code, say func.R, containing a function. Calling R CMD BATCH func.R
initializes the function and evaluates is. Within a session, issuing source("func.R")
simply initializes the function.
Any idea?

- 64,767
- 30
- 146
- 239

- 10,095
- 14
- 54
- 73
-
Can you clarify the question? The title question is different from the ideas in the actual body of the question – Chris_Rands May 08 '18 at 09:33
6 Answers
I think that the interactive()
function might work.
This function returns TRUE
when R is being used interactively and FALSE
otherwise. So just use if (interactive())
i.e. the equivalent is
if (!interactive()) {
main()
}

- 18,883
- 8
- 47
- 56
-
Excellent, I had no idea this existed. I think this will change the way I write R. – Vince Jun 03 '10 at 17:46
-
3With the Rscript shebang line and this our R scripts will be more pythonic than ever before! – Michael Dunn Jun 20 '10 at 11:25
-
3@gappy Can you update this answer? I feel like this answer doesn't answer your question in the title. It mainly tells you whether the R file is being sourced on commandline or using Rscript. – Navneet Aug 17 '15 at 15:42
-
6This doesn't work if you're calling the main script with `rscript` and other files are `source`d. – JAD Jul 22 '19 at 07:18
-
2`Interactive()` does not behave exactly like `__name__ == '__main__'`. Sourcing file `a.R` from `b.R` where file `a.R` has `print(interactive())` will return `True`. As @JAD mentioned. – cach1 Nov 21 '22 at 20:24
Another option is:
#!/usr/bin/Rscript
# runs only when script is run by itself
if (sys.nframe() == 0){
# ... do main stuff
}

- 926
- 7
- 5
-
16This is better than the accepted answer as it allows for a script to be sourced and the snippet within the if block not executed. – Wei Oct 01 '18 at 14:56
-
would you know why on my end if I position sys.nframe() where you did it shows value equal to 4 and not 0 ? – Angelo Aug 13 '21 at 13:41
-
Works like intended. But this doesn't include any automatization in RStudio (e.g. clicking "Source") which calls the script internally. – CodePrinz Aug 11 '22 at 13:52
You could pass arguments into R, and if an argument is present run main(). More on arguments here: http://yangfeng.wordpress.com/2009/09/03/including-arguments-in-r-cmd-batch-mode/

- 7,608
- 3
- 41
- 46
-
I voted the other answer, but I didn't know you could pass arguments from the command line either. That's helpful. – gappy Jun 06 '10 at 02:28
-
1Since about the beginning of 2009 it's been possible to run R scripts with a shebang line, e.g. `#!/usr/bin/Rscript --vanilla` directly from the command line: e.g. run `chmod 700 my_script.r` to make it executable, and then you can run the script with `./my_script.r` (within the script you read arguments the same way as in the link above, by `args=(commandArgs(TRUE))` – Michael Dunn Jun 20 '10 at 11:24
It's a lot of work, but I finally got it (and posted at Rosetta Code).
This example exports a function called meaningOfLife
. When the script is run by itself, it runs main
. When imported by another R file, it does not run main
.
#!/usr/bin/Rscript
meaningOfLife <- function() {
42
}
main <- function(program, args) {
cat("Main: The meaning of life is", meaningOfLife(), "\n")
}
getProgram <- function(args) {
sub("--file=", "", args[grep("--file=", args)])
}
args <- commandArgs(trailingOnly = FALSE)
program <- getProgram(args)
if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) {
main(program, args)
q("no")
}

- 22,868
- 20
- 88
- 147
I asked a similar question, in an answer, Matthew Plourde suggested using getOption('run.main', default=TRUE)
in the main script and then setting options(run.main=FALSE)
before calling source()
. This worked in my case.
Otherwise a simpler pattern when you have an R script creating a bunch of functions and you want to write a few lines at the end of the script to experiment with the use of a function: place these extra lines in an if(FALSE){}
block.

- 1
- 1

- 10,289
- 4
- 68
- 110
This works fairly well for my use. If you have two files and want to source one with the other while only running a certain part of the file.
parent file: parent.R
print("Running Parent File")
`__name__` <- "__main__"
print(paste0("This file is : ", `__name__`))
`__src__` <- "__not.main__"
source("child.R")
rm(`__src__`)
child file: child.R
print("Running Child File")
`__name__` <- "__main__"
if (exists("__src__")){`__name__` <- `__src__`}
if (`__name__` == "__main__"){
print(paste0("This file is : ", `__name__`))
} else {
print(paste0("This file is : ", `__name__`))
}
Output when running Rscript parent.R
[1] "Running Parent File"
[1] "This file is : __main__"
[1] "Running Child File"
[1] "This file is : __not.main__"
Output when running Rscript child.R
[1] "Running Child File"
[1] "This file is : __main__"
A more robust method would be to write a custom source function where a list of arguments can be included.
source2 <- function(file, args = list()){
tryCatch(
expr = {
assign("__src__", "__not.main__", envir = globalenv())
assign("__src.args__", args, envir = globalenv())
source(file)
},
error = function(e){
message("File could not be sourced")
},
finally = {
rm(list = c("__src__", "__src.args__"), envir = globalenv());
assign("__name__", "__main__", envir = globalenv())
})
}
source2("child.R", args = list("list", "of", "arguments"))

- 83
- 1
- 6