Is if(interactive()) an R equivalent to the pythonic “if __name__ == ”__main__“: main()”?

Question:

I would like R scripts to have a main() function that gets executed while in interactive mode. But the main() function should not be executed while sourcing the file.

There is already a question about this and a very good answer suggests using the interactive() function. However this doesn’t work for me. I don’t have enough reputation points to comment or answer in that question. So I ask the question here again.

I write this in script_1.r

if(interactive()){
  your main code here
}

If I use knitr to waive a html or pdf document, sourcing the script. This code under if(interactive()) won’t be executed. This is good for me, that’s what I want.

My problem is that if I source("script_1.r") from script_2.r in interactive mode, it will still run the code under this if(interactive()) part.

Asked By: Paul Rougieux

||

Answers:

As you’ve noticed, no, it’s not the same thing. if(interactive()) does exactly what the name says – it tests whether the code is run in an interactive shell. No more, no less.

There’s no direct equivalent of if __name__ == '__main__' from Python in R, since R has no concept of modules in the same way as Python, and source’d code is just executed directly.

You could write your own source command to replace the default one and perform the necessary check, however.

That said, the question you’ve linked does contain an answer which presents a workaround and essentially replicates Python’s functionality. However, this doesn’t seem to be what you want since it won’t work as you expect when invoked by Knitr.

Answered By: Konrad Rudolph

The best way to get the kind of control you’re looking for is to use options.

For instance, ‘script.r’ would look like this:

main <- function() {
    message('main!')
}

if (getOption('run.main', default=TRUE)) {
   main()
}

If you are sourcing the file in interactive mode and don’t want main to execute, simply call options(run.main=FALSE) before you call source. If you are using the script with knitr and you want main to execute, don’t set the option, and it will default to TRUE. Or if you don’t want the main to run with knitr, call options(run.main=FALSE) before calling it.

Answered By: Matthew Plourde

Another way I have found that will work as you described without the need to use and change options is:

if (sys.nframe() == 0) {
    # ... do main stuff
}

sys.nframe() is equal to 0 when run from the interactive terminal or using Rscript.exe, in which case the main code will run. Otherwise when the code is sourced, sys.nframe() is equal to 4 (in my case, not sure how it works exactly) which will prevent the main code from running.

source

Answered By: user897506
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.