京公网安备 11010802034615号
			经营许可证编号:京B2-20210330
		JAVA如何与R完美结合起来
	为什么要用java调用R?
     Java作为一个非常流行的编程语言,具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。但是Java缺乏数据分析以及可视化的能力。但是R语言却是专门为统计而生,R语言近年来发展迅速,可以用来进行机器学习,数据挖掘,数据可视化。 为了弥补这种差距, 我们可以将JAVA与R结合起来, 
今天我们来说两种方法,首先第一个,JAVA通过Rserve调用R语言。
一,环境
系统:win10
JDK:1.8
R:3.3.1
eclipse:luna
二.准备工作
在R软件里面安装Rserve包
install.packages("Rserve")
如果你已经安装了这个包就不需要这一步。如果安装过程没有报错就OK。接下来我们就要通过下面语句启动服务:
Rserve()
如果出现下面语句这表示服务已经启动好了:
Starting Rserve...
 "D:\PROGRA~1\R\R-33~1.1\library\Rserve\libs\x64\Rserve.exe"  
现在我们已经运行Rserve服务器,我们就可以在eclipse中创建一个Java程序,使用Rserve与R进行通信,并在Java代码中调用R的函数。 
我创建里一个RserveProject的java工程,然后右击工程名—properties—Java Build Path—Librares—Add External Jar...加载REngine.jar和Rserve.jar两个jar包,我把R装在了D:\Program Files\下,所以那两个包在D:\Program Files\R\R-3.3.1\library\Rserve\java。大家根据自己的实际情况找找。

三.编写Java程序
在下面程序中,我分别直接调用了R中的函数,也调用自己的R脚本。
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
import org.rosuda.REngine.REXPMismatchException;;
public class Temp {
    public static void main(String[] args) throws REXPMismatchException {
        // TODO Auto-generated method stub
        RConnection connection = null;
        System.out.println("平均值");
        try {
            //创建对象
            connection = new RConnection();
            String vetor="c(1,2,3,4)";
            connection.eval("meanVal<-mean("+vetor+")");
    
            //System.out.println("the mean of given vector is="+mean);
            double mean=connection.eval("meanVal").asDouble();
            System.out.println("the mean of given vector is="+mean);
            //connection.eval(arg0)
            
        } catch (RserveException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("执行脚本");
        try {
            connection.eval("source('D:/myAdd.R')");
                 //此处路径也可以这样写D:\\\\myAdd.R
            int num1=20;
            int num2=10;
            int sum=connection.eval("myAdd("+num1+","+num2+")").asInteger();
            System.out.println("the sum="+sum);
        } catch (RserveException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        connection.close();
    }
}
结果为:
平均值
the mean of given vector is=2.5
执行脚本
the sum=30
其中myAdd.R代码如下:
myAdd<-function(x,y){
    sum=x+y
    return(sum)
}
四.Reserve的多线程
由于Rserve是以服务器的形式运行,那么它可以同时处理多个请求。 这也就意味着当我们使用命令启动Rserve的实例。
我们从R控制台启动Rserve实例,如下有三个实例。
Rserve(port=5011)
Rserve(port=5012)
Rserve(port=5013)
现在有了这3个独立的实例,这3个线程可以很容易地连接到这3个实例:
//线程1连接到在端口5011上运行的实例
RConnection connection = new RConnection("hostIP_or_hostName",5011);
//线程2连接到在端口5012上运行的实例
RConnection connection = new RConnection("hostIP_or_hostName",5012);
//线程3连接到在端口5013上运行的实例
RConnection connection = new RConnection("hostIP_or_hostName",5013);
第二种方法:
      这是一种比较简单方便的方法,这次我们需要写一个简单的R语言脚本,然后通过运行这个R脚本,来打开Rserve服务。这样的话,我们每次运行Java程序之前就不用先打开R,再输入程序打开Rserve服务。这样是不是很简单方便。今天我们要用这种方法,和R语言,画一个简单的词云出来。
首先,我们建一个R脚本:
library(Rserve)
Rserve()</span>
我将它保存成Rserve.R文件,放在了这个目录下(MyScript这是我自己新建的文件夹):    D:\Program Files\R\R-3.3.1\MyScript
提示:路径最后不要有中文字符,就是有的时候可能不识别,或包其他错误。
首先我们要导入  包,大家可以查看我的另一篇博文。我们新建一个类,用来初始化Rserve服务。代码如下
package rserve;
import javax.xml.transform.Source;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
/**
 * 启动Rserve服务
 * @author henry wang
 *
 */
public class Rservel {
  private  static String R_EXE_PATH="D:\\Program Files\\R\\R-3.3.1\\bin\\Rscript.exe";
  private static String R_SCRIPT_PATH="D:\\Program Files\\R\\R-3.3.1\\MyScript\\Rserve.R";
    public static RConnection getRConnection(){
        try {
            RConnection rConnection=new RConnection();
             return rConnection;
        } catch (RserveException e) {
            // TODO: handle exception
            System.out.println("正在启动Rserve服务......");
            try {
                Runtime rn=Runtime.getRuntime();            
                /*
                 * 不建议写成直接写成rn.exec("R_EXE_PATH R_SCRIPT_PATH"),
                                *如果这样学的画前面定义的R_EXE_PATH,R_SCRIPT_PATH会提示
                 * 这两个变量没有用到
                 * 运行也许会出错,提示错误如下:
         * java.io.IOException: Cannot run program "D:\Program": CreateProcess error=2, 
                                *系统找不到指定的文件。
                 */
                
                String[] commandArgs={R_EXE_PATH,R_SCRIPT_PATH}; 
               rn.exec(commandArgs); 
                Thread.sleep(5000);
            } catch (Exception e2) {
                // TODO: handle exception
                e2.printStackTrace();
            }
            return getRConnection();
        }        
    }
}
说明:R_EXE_PATH 是Rscript.exe或者R.exe的路径,这两个都可以。R_SCRIPT_PATH是R脚本的路径。
package rserve;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;
public class WordCloud extends JFrame{
private static final long serialVersionUID=1L;
static Image img;
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        WordCloud wc=new WordCloud();
        REXP xp=wc.getRobj();//获得R对象
        wc.PlotDemo(xp,wc);//错误
    }
    private REXP getRobj() throws Exception{
        RConnection c=Rserve.getRConnection();
        c.setStringEncoding("utf8");//设置字符编码
        //返回R的版本
        REXP Rservesion=c.eval("R.version.string");
        System.out.println(Rservesion.asString());
        System.out.println("\n----------绘图演示--------");
        System.out.println("");
        REXP xp=c.parseAndEval("jpeg('test.jpg',quality=90)");
        c.eval("library(wordcloud)");
        c.voidEval("colors=c('red','blue','green','yellow','purple')");
    c.parseAndEval(" data(SOTU);wordcloud(SOTU,min.freq=10,colors=colors);dev.off()");
    xp=c.parseAndEval("r=readBin('test.jpg','raw',3000*3000);unlink('test.jpg');r");
        return xp;
    }
    public void PlotDemo(REXP xp, JFrame f)throws Exception{
        img=Toolkit.getDefaultToolkit().createImage(xp.asBytes());
        MediaTracker mediaTracker=new MediaTracker(this);
        mediaTracker.addImage(img, 0);
        mediaTracker.waitForID(0);
        f.setTitle("Test Image");
        f.setSize(img.getWidth(null),img.getHeight(null));
        f.setDefaultCloseOperation(EXIT_ON_CLOSE);
        f.setVisible(true);
    }
    public void paint(Graphics g){
        g.drawImage(img, 0, 0, null);
    }    
}
c.parseAndEval(" data(SOTU);wordcloud(SOTU,min.freq=10,colors=colors);dev.off()");这个句子的冒号里面都是一些R语句,只不过每句话后面都有一个分号。
运行结果如下:

这样就好了,我们使用java调用R语言就绘制出了一个简单的词云。
                  数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
教材入口:https://edu.cda.cn/goods/show/3151 “纲举目张,执本末从。” 若想在数据分析领域有所收获,一套合适的学习教材至 ...
2025-11-04【2025最新版】CDA考试教材:CDA教材一级:商业数据分析(2025)__商业数据分析_cda教材_考试教材 (cdaglobal.com) ...
2025-11-04在数字化时代,数据挖掘不再是实验室里的技术探索,而是驱动商业决策的核心能力 —— 它能从海量数据中挖掘出 “降低成本、提升 ...
2025-11-04在 DDPM(Denoising Diffusion Probabilistic Models)训练过程中,开发者最常困惑的问题莫过于:“我的模型 loss 降到多少才算 ...
2025-11-04在 CDA(Certified Data Analyst)数据分析师的工作中,“无监督样本分组” 是高频需求 —— 例如 “将用户按行为特征分为高价值 ...
2025-11-04当沃尔玛数据分析师首次发现 “啤酒与尿布” 的高频共现规律时,他们揭开了数据挖掘最迷人的面纱 —— 那些隐藏在消费行为背后 ...
2025-11-03这个问题精准切中了配对样本统计检验的核心差异点,理解二者区别是避免统计方法误用的关键。核心结论是:stats.ttest_rel(配对 ...
2025-11-03在 CDA(Certified Data Analyst)数据分析师的工作中,“高维数据的潜在规律挖掘” 是进阶需求 —— 例如用户行为包含 “浏览次 ...
2025-11-03在 MySQL 数据查询中,“按顺序计数” 是高频需求 —— 例如 “统计近 7 天每日订单量”“按用户 ID 顺序展示消费记录”“按产品 ...
2025-10-31在数据分析中,“累计百分比” 是衡量 “部分与整体关系” 的核心指标 —— 它通过 “逐步累加的占比”,直观呈现数据的分布特征 ...
2025-10-31在 CDA(Certified Data Analyst)数据分析师的工作中,“二分类预测” 是高频需求 —— 例如 “预测用户是否会流失”“判断客户 ...
2025-10-31在 MySQL 实际应用中,“频繁写入同一表” 是常见场景 —— 如实时日志存储(用户操作日志、系统运行日志)、高频交易记录(支付 ...
2025-10-30为帮助教育工作者、研究者科学分析 “班级规模” 与 “平均成绩” 的关联关系,我将从相关系数的核心定义与类型切入,详解 “数 ...
2025-10-30对 CDA(Certified Data Analyst)数据分析师而言,“相关系数” 不是简单的数字计算,而是 “从业务问题出发,量化变量间关联强 ...
2025-10-30在构建前向神经网络(Feedforward Neural Network,简称 FNN)时,“隐藏层数目设多少?每个隐藏层该放多少个神经元?” 是每个 ...
2025-10-29这个问题切中了 Excel 用户的常见困惑 —— 将 “数据可视化工具” 与 “数据挖掘算法” 的功能边界混淆。核心结论是:Excel 透 ...
2025-10-29在 CDA(Certified Data Analyst)数据分析师的工作中,“多组数据差异验证” 是高频需求 —— 例如 “3 家门店的销售额是否有显 ...
2025-10-29在数据分析中,“正态分布” 是许多统计方法(如 t 检验、方差分析、线性回归)的核心假设 —— 数据符合正态分布时,统计检验的 ...
2025-10-28箱线图(Box Plot)作为展示数据分布的核心统计图表,能直观呈现数据的中位数、四分位数、离散程度与异常值,是质量控制、实验分 ...
2025-10-28在 CDA(Certified Data Analyst)数据分析师的工作中,“分类变量关联分析” 是高频需求 —— 例如 “用户性别是否影响支付方式 ...
2025-10-28