Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use main function in R

I've been using R for 4 months now, and I really hope there is a way to use main function as in other languages (C++, Python...)

The main reason I want to do this is that all the variables I use in a R script are global variables that can potentially pollute the namespace of the functions I defined in the same script:

f <- function(x) {
  x + a
}
a <- 50
f(5)

For me, this is just a personal preference. I'm a sloppy programmer and I want to prevent myself from making silly mistakes.

I can surely define main <- function() {}, but I want to know if there is anything similar to this:

if __name__ == "__main__": 
    main()

(In this Python script, if the function name is main, then run main() to call the main function.)

like image 255
BlueFeet Avatar asked Oct 28 '15 19:10

BlueFeet


3 Answers

but is there anything similar to

if __name__ == "__main__": 
    main()

in python?

There is indeed!

But you need to use the package ‘box’ instead of source/packages. Then, inside your module, you can write

if (is.null(box::name())) …

… which is equivalent to Python’s if __name__ == '__main__'.

Or you can even use the klmr/sys module. Then you can write the following:

box::use(klmr/sys)

f = function(x) {
    x + a
}

sys$run({
    a = 50
    sys$print(f(5))
})

If you execute this script on the command line (via Rscript or R CMD BATCH), it will execute the main function specified by sys$run. Conversely, if you import this script as a module into another script, the main function won’t be executed, but f will still be defined and exported.

like image 144
Konrad Rudolph Avatar answered Nov 08 '22 21:11

Konrad Rudolph


So, it's not quite the same as __name__ == "__main__", but you might find the interactive function interesting here. Which returns TRUE if you are in an interactive mode.

So you can do something like this:

main <- function() {
    ....
}

if(!interactive()) {
    main()
}

This is a bit different though because it will always run if it's required from a script.

like image 12
Leif Andersen Avatar answered Nov 08 '22 20:11

Leif Andersen


Answering your exact question (I'm not addressing whether it makes sense in the context of R. I'm only starting to dig deeper into R and finding it ill suited to write non-interactive programs so I'm blaming it on me). You can create a main function and pass to it the input arguments. However, note that for this work you don't call it via R. It seems that you need to use Rscript instead.

main <-function (argv)
{
  if (length (argv) < 3)
    {
      cat ('usage error: requires at least 3 arguments\n',
           file=stderr ());
      return (1);
    }

  cat (sprintf ('This program was called with %d arguments\n',
                length (argv)));

  return (0);
}

if (identical (environment (), globalenv ()))
  quit (status=main (commandArgs (trailingOnly = TRUE)));
like image 4
carandraug Avatar answered Nov 08 '22 22:11

carandraug