内容简介:提供一个在Nodejs中调用 R script 方法。我用的node框架是 eggjs,示例代码全是在Egg环境下实现的。你将会看到以前几个方面的内容。R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。简单一下,应该要坐这样操作的人都知道这种必备的背景知识。需要在调用 Node 中调用 R Script,是因为应用中需要对比较复杂的计算公式做翻译,其中会涉及到三角函数,开方或者求幂等数学运算。而直接用 Javascrip
提供一个在Nodejs中调用 R script 方法。我用的node框架是 eggjs,示例代码全是在Egg环境下实现的。你将会看到以前几个方面的内容。
- R 简介与在Node中调用R Script 的原因
- 相关环境的搭建与关键Node知识点
- 调用方式与相关代码
一、R 简介与在Node中调用R Script 的原因
R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。简单一下,应该要坐这样操作的人都知道这种必备的背景知识。
需要在调用 Node 中调用 R Script,是因为应用中需要对比较复杂的计算公式做翻译,其中会涉及到三角函数,开方或者求幂等数学运算。而直接用 Javascript 翻译后,在公式计算过程中会因为精度的问题导致整个计算结果异常。具体表现如,Math.tan 结果为0.000000000000001等此类计算结果。
大家搜索同类问题的时候,肯定看到排名靠前的r-script、 node-rscript 、 js-cal-r 、rscript这些packages。他们写的肯定是可以用的。燃鹅,具体实现的时候可能想到复杂,比如你的是一个长度在一万的Json数组,或者你的R Script在R studio中运行一切如常偏偏在node中调用就报错,甚至你用packeage page上的示例代码都报错。总之情况可能非常复杂。
二、相关环境的搭建与关键Node知识点
2.1 相关环境搭建
首先肯定机器上肯定需要搭建 Node 环境 和 R 的环境,node 环境就不给介绍了。如果你恰好也用的是Eggjs请参照官网。
R 环境则只需要安装最新的 R 安装包就可以了。目前最新的版本R version 3.5.1。官网 在官网如下位置。
安装好了之后需要配置系统环境变量,移动要配置。这一步非常重要。 在系统便利中将 bin
, include
两个路径加入到系统变量 Path 中,根据自己的安装路径,我是安装在C盘所以路径如下
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 命令行执行脚本是这样的
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
具体是什么,这里就不展开了,不然就模糊重点了。因为很多时候,我看别人的文章,作者很好心的把相关知识点都列出来了,讲的很细,很用心。但对我这种心急的 工具 党来,真的太花时间了,反而模糊了焦点。我想立刻解决的我的问题。 给代码作为参考,详细说明请看官网。
三、调用方式与相关代码
所以,下面直接提供代码。代码作为示例参考,并不十分规范,比如 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保存成文件并返回起绝对路径。
此外还有两点值得分享的
- R Script 中如何获取参数
args <- commandArgs(trailingOnly = TRUE) 复制代码
- 在 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 脚本的方法。
————————————————
第一次写技术类文章,如果对你有帮助的话,我会觉得高兴。如果看到有可以改进的地方,请给我一点建议。希望自己能坚持,以后分享更多自己收获的知识。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- MySQL使用UDF调用shell脚本
- 在新的,干净的PowerShell实例中调用PowerShell脚本(在另一个脚本中)
- Go调用企业微信API发送zabbix告警信息脚本
- 新姿势!Redis中调用Lua脚本以实现原子性操作
- 使用Python和Java调用Shell脚本时的死锁陷阱
- sysbench测试Oracle时写一个lua脚本调用sqlload快速造数据
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Learn Python the Hard Way
Zed A. Shaw / Addison-Wesley Professional / 2013-10-11 / USD 39.99
Master Python and become a programmer-even if you never thought you could! This breakthrough book and CD can help practically anyone get started in programming. It's called "The Hard Way," but it's re......一起来看看 《Learn Python the Hard Way》 这本书的介绍吧!