Nodejs 調用 R 腳本 / Nodejs Call R Script

提供一個在Nodejs中調用 R script 方法。我用的node框架是 eggjs,示例代碼全是在Egg環境下實現的。你將會看到之前幾個方面的內容。html

  • R 簡介與在Node中調用R Script 的緣由
  • 相關環境的搭建與關鍵Node知識點
  • 調用方式與相關代碼

1、R 簡介與在Node中調用R Script 的緣由

R是用於統計分析、繪圖的語言和操做環境。R是屬於GNU系統的一個自由、免費、源代碼開放的軟件,它是一個用於統計計算和統計製圖的優秀工具。簡單一下,應該要坐這樣操做的人都知道這種必備的背景知識。node

須要在調用 Node 中調用 R Script,是由於應用中須要對比較複雜的計算公式作翻譯,其中會涉及到三角函數,開方或者求冪等數學運算。而直接用 Javascript 翻譯後,在公式計算過程當中會由於精度的問題致使整個計算結果異常。具體表現如,Math.tan 結果爲0.000000000000001等此類計算結果。npm

你們搜索同類問題的時候,確定看到排名靠前的 r-scriptnode-rscriptjs-cal-rrscript這些packages。他們寫的確定是能夠用的。燃鵝,具體實現的時候可能想到複雜,好比你的是一個長度在一萬的Json數組,或者你的R Script在R studio中運行一切如常恰恰在node中調用就報錯,甚至你用packeage page上的示例代碼都報錯。總之狀況可能很是複雜。json

2、相關環境的搭建與關鍵Node知識點

2.1 相關環境搭建

首先確定機器上確定須要搭建 Node 環境 和 R 的環境,node 環境就不給介紹了。若是你剛好也用的是Eggjs請參照官網api

R 環境則只須要安裝最新的 R 安裝包就能夠了。目前最新的版本R version 3.5.1。官網 在官網以下位置。數組

R 官網

安裝好了以後須要配置系統環境變量,移動要配置。這一步很是重要。 在系統便利中將bin,include兩個路徑加入到系統變量 Path 中,根據本身的安裝路徑,我是安裝在C盤因此路徑以下bash

C:\Program Files\R\R-3.5.1\bin
C:\Program Files\R\R-3.5.1\include
複製代碼

系統環境便利

2.2 Nodejs 知識點

其實,在 node 中調用 R script 的實現思路其實只有一個那就是 經過命令行來執行 R Script。我很粗略的查看了以前提到的Package 源碼。很是不嚴謹的下結論,他們的實現思路實際上是同樣的,不同的是在參數處理,已經返回值的處理。框架

R Script 命令行執行腳本是這樣的async

Rscript R_File_Path Parameter

R_File_Path: .R 文件的據對路徑
Parameter: 參數 類型爲字符串
複製代碼

因此關鍵問題 「Node 調用R Script」 就成了如何在 "Node中運行命令行"。解決這個問題用的方法就是使用調用Node模塊中子進程child_process 中的 exec函數

var child_process = require('child_process');
var exec = child_process.exec;
複製代碼

child_process 具體是什麼,這裏就不展開了,否則就模糊重點了。由於不少時候,我看別人的文章,做者很好心的把相關知識點都列出來了,講的很細,很用心。但對我這種心急的工具黨來,真的太花時間了,反而模糊了焦點。我想馬上解決的個人問題。 給代碼做爲參考,詳細說明請看官網

3、調用方式與相關代碼

因此,下面直接提供代碼。代碼做爲示例參考,並不十分規範,好比egg中獲取數據的操做最好放在service裏面。

'use strict';

const path = require("path")
const child_process = require('child_process');
const exec = child_process.exec;

const Controller = require('egg').Controller;

class TestRController extends Controller {
  async echo() {
    let Parameter = path.join(__dirname, "./../public/assets/csv/tilt.csv");
    let R_File_Path = path.join(__dirname, "./../public/assets/r/tilt.R");
    let cmd = 'Rscript' + ' "' + R_File_Path + '" ' + Parameter;
    
    exec(cmd, (error, stdout, stderr) => {
        if (error) {
            consle.log(stderr);
        } else {
            console.log(stdout);
        }
    });
  }
}
module.exports = TestRController;

複製代碼

其中比較重要的exec方法的回調結果,每一個參數什麼意思,就看上圖須要解釋一下或者官網。解釋下若是執行後的返回結果,參數傳遞的小技巧。 若是數據量比較小那麼,直接放放在參數中

'Rscript R_File_Path "{a:1,b:'p1'}"; 複製代碼

這樣R Script 能夠直接接受的參數字符串,而且也能序列化成JSON後完成進一步的處理。

可是當參數太大的時候,直接這樣傳參是會出問題的。處理大量數據參數的技巧則是將在參數數據存放在.txt, .json, .csv文件中,直接將參數文件的絕對路徑傳遞R Script 來完成處理。 一樣的道理,在數據返回時也同樣會有數據量的限制,數據量較小時可直接返回爲JSON字符串,若是過大,則由R保存成文件並返回起絕對路徑。

此外還有兩點值得分享的

  1. R Script 中如何獲取參數
args <- commandArgs(trailingOnly = TRUE)
複製代碼
  1. 在 Nodejs 中 exec 方法參數都對,代碼拼好的cmd命令在cmd.exe能正常執行。但在Node中執行時,就是報 R Script 中用到的Pakckage這個沒安裝那個沒安裝。而且在R Studio中不管重裝多少次都重複報錯。解決辦法:

檢查 library路徑,如C:\Program Files\R\R-3.5.1\library裏面到底有沒有這樣Package。沒有則,下載到引用的Package,而後後手動拷貝到這個路徑下。

以上是我解決在Nodejs 中Nodejs 調用 R 腳本的方法。

————————————————

第一次寫技術類文章,若是對你有幫助的話,我會以爲高興。若是看到有能夠改進的地方,請給我一點建議。但願本身能堅持,之後分享更多本身收穫的知識。

相關文章
相關標籤/搜索