2

I have been trying to execute an Rscript from my node.js server. tried to follow an example online, but i keep getting a null returned object or sometimes the process keeps running forever. I have mentioned the code snippet below. Thank you.

example.js ::

var R = require("r-script");


var out = R("scripts/testScript.R")
        .data("hello world", 20)
        .callSync(function(err,resp){
                      console.log(out);
                   });

testScript.R file :::

needs(magrittr)
set.seed(512)
do.call(rep, input) %>% 
strsplit(NULL) %>% 
sapply(sample) %>% 
apply(2, paste, collapse = "")
  • 1
    What if you use a trivial R program that just prints "hello"? – John Zwinck Jan 26 '17 at 08:29
  • Which process runs forever, the R process or the node process? Also I think it might be a problem that you try to log a variable in the callback of `.callSync` that is not definded before the function returns. – snaut Jan 26 '17 at 08:36
  • I have an example here, but not using `r-script`: https://github.com/stla/CallingRinNode – Stéphane Laurent Feb 08 '17 at 22:26

2 Answers2

3

For windows users:

You need to add the environment variable to Windows's %PATH% variable. R-script package needs to call "R" command from the CMD. If R.exe is not set as a environment vairable, then it will never be able to call the "R" command from anywhere.

Look up how to add environment variables to Windows, and remember: if the path to the folder containing the executables has a white space, it must be added between double quotes. "C:\Program Files\R\R-3.3.2\bin\x64"

If you have already done this but the problem persists, I can only think of two reasons:

  1. There's something wrong with your R method and it's giving an internal exception inside the R session.

  2. The system can't find the file. Maybe check the filepath.

AFP_555
  • 2,392
  • 4
  • 25
  • 45
3

You can use child processes in node to call other languages. I find it easiest to call Python from node, and use Python's subprocess module to then call R:

NODE

var spawn = require("child_process").spawn

var process = spawn('python',["call_r.py", script_choice, function_choice]);

This calls our call_r.py file passing along our script and function choices:

PYTHON (call_r.py)

import subprocess
import sys

script_choice = sys.argv[1]
function_choice = sys.argv[2]

call_script = 'R_Scripts/' + script_choice + '.R'
cmd = ['Rscript', call_script] + [function_choice]
result = subprocess.check_output(cmd, universal_newlines=True)

print(result)
sys.stdout.flush()

This parses the passed script and function choices, calling R via Python's subprocess module.

R (script that was chosen)

myArgs <- commandArgs(trailingOnly = TRUE)
function_choice <- myArgs[1]

# add your R functions here

eval(parse(text=function_choice))

Here, R parses the passed function choice and evaluates it. Note that arguments can be passed to the R function of choice by simply including them in the function argument (e.g. my_function('hey there'))

Cybernetic
  • 12,628
  • 16
  • 93
  • 132