How to run R Scripts with NodeJs Rest API
This guide will show you how to integrate RScript with NodeJs. Finally, you will be able to create a simple rest API with r-script data.
You can integrate R script with NodeJs with simple steps.
First of all, you have to install
- NodeJs
- R
- R studio
1. Try this simple code in R Studio.
Open the file in R studio and press CTRL+ENTER in each line. Then you can see the result on the right side.
Horray…if you are just NodeJs developer, Now you know how to run an RScript.
2. Create Hello World Node API
Create a new folder. Then open it in a terminal then type following codes
npm initnpm install — save expresstouch index.js
index.js
var express = require('express');
var app = express(); app.get('/', function (req, res) { res.send('Hello World');
})
var server = app.listen(8081, function () { var port = server.address().port
console.log(`Example app listening at http://localhost:${port}`)})
in the terminal run `node index.js` then go to http://localhost:8081/
Horray…if you are just R Dev, Now you know how to run a NodeJs app with Rest API.
3. Now run R scripts in Node
If you go to this page, you can see 2 options. 1 — Async and 2 — sync. I don’t recommend to use sync functions because it blocks the NodeJs app. So no need to learn bad things. Let's try Asynchronous way to run R Script in NodeJs.
I am going to use the same example in this page https://www.npmjs.com/package/r-script with some changes.
npm install r-script --savecreate ex-async.R
create index.js
Use the this code and run npm start or node index.js
. Then Go to — http://localhost:8081/ex-async .Probably you will get an error message 😈
4. Did you get an error with 👆? that means the repo owner has not fixed a bug. But you can fix it.
If you get this error, you can fix it. https://github.com/joshkatz/r-script/issues/27
TypeError: Cannot read property 'data' of undefined
at executeExAsync (/Users/Admin/Desktop/r-node-example/index.js:13:17)
at /Users/Admin/Desktop/r-node-example/index.js:29:2
at Layer.handle [as handle_request] (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/layer.js:95:5)
at /Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/index.js:335:12)
at next (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/router/index.js:275:10)
at expressInit (/Users/Admin/Desktop/r-node-example/node_modules/express/lib/middleware/init.js:40:5)
The issue with the r-script library. That means you have to change the r-script library. Go to r-script library in node_modules folder then go to index.js. You can find the following code.
function init(path) { var obj = new R(path); return _.bindAll(obj, "data", "call", "callSync");}
Change it to
function init(path) {
var obj = new R(path);
_.bindAll(obj, "data", "call", "callSync");
return obj;
}
Then your code will work but it is not the correct way to do it. All you have to do is move r-script folder to the working folder and do that change.
You also have to change the import statement, remove `r-script` from package.json, etc. To minimize that, I published this source code to a git repo. You can download and try.
https://github.com/deshanm/r-node-example
For your information
- Limitation => You cannot pass a lot of data from NodeJs to RScript because of OS limitation.
- You can find answers for some issues in the git repo https://github.com/joshkatz/r-script/issues