1. 程式人生 > >JRI方式實現Java和R連線--關鍵點在配置環境變數,重啟Eclipse

JRI方式實現Java和R連線--關鍵點在配置環境變數,重啟Eclipse

今天實現了JRI方式–Java呼叫R方法-不用預先在R客戶端啟動R就可以實現連線呼叫
JRI,全名是Java/R Interface,這是一種完全不同的方式,通過呼叫R的動態連結庫從而利用R中的函式等。
需要在install.packages(“rJava”)安裝rJava就行,在安裝資料夾中,可以看到一個jri的子資料夾,裡面有自帶的例子可以用來測試。

關鍵點在配置環境變數–我的如下:
這裡寫圖片描述

配置好之後呢,在library裡找到測試Java檔案,然後在eclipse裡建立一個Java工程,測一下,如下:

這裡寫圖片描述

eclipse程式碼測試結果如下:

這裡寫圖片描述

這裡寫圖片描述

如有錯誤,多是環境變數配置的問題;檢查jdk和r,,rJava環境變數;
修改後重啟eclipse再測;出錯如下,第一個是環境變數,第二個是Java,r,rJava要麼都是32位的,要麼都是64位的,須一致;

————————————–

Cannot find JRI native library!
Please make sure that the JRI native library is in a directory listed in java.library.path.

java.lang.UnsatisfiedLinkError: D:\software\myR\R-3.1.2\library\rJava\jri\jri.dll: Can’t find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1965)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1890)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1880)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at org.rosuda.JRI.Rengine.(Rengine.java:19)
at com.jri.testDemo.rtest.main(rtest.java:62)

————————————–

Cannot find JRI native library!
Please make sure that the JRI native library is in a directory listed in java.library.path.

java.lang.UnsatisfiedLinkError: D:\software\myR\R-3.1.2\library\rJava\jri\jri.dll: %1 不是有效的 Win32 應用程式。
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1965)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1890)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1880)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at org.rosuda.JRI.Rengine.(Rengine.java:19)
at com.jri.testDemo.rtest.main(rtest.java:62)

接下來附錄rtest.java檔案原始碼註釋,裡面提到了Java操作R的一些API

public class rtest {
    public static void main(String[] args) {
        // just making sure we have the right version of everything
        //確定R的版本
        if (!Rengine.versionCheck()) {
            System.err.println("** Version mismatch - Java files don't match library version.");//
            System.exit(1);
        }
        System.out.println("Creating Rengine (with arguments)");
        // 1) we pass the arguments from the command line //命令列處理args
        // 2) we won't use the main loop at first, we'll start it later
        // (that's the "false" as second argument)//第二個引數是false表示不使用main迴圈
        // 3) the callbacks are implemented by the TextConsole class above
        //建立R引擎物件,看底層是通過反射方式建立的物件
        Rengine re = new Rengine(args, false, new TextConsole());
        //new TestConsole()成功會列印R歡迎資訊
        /**
         * R version 3.1.2 (2014-10-31) -- "Pumpkin Helmet"
            Copyright (C) 2014 The R Foundation for Statistical Computing
            R is free software and comes with ABSOLUTELY NO WARRANTY.
            ......
            Type 'q()' to quit R.
         */


        System.out.println("Rengine created, waiting for R");
        // the engine creates R is a new thread, so we should wait until it's ready
        // 新的執行緒,需要等等它準備好
        if (!re.waitForR()) {
            System.out.println("Cannot load R");//如果等待超時,報錯: 不能載入R
            return;
        }

        /*
         * High-level API - do not use RNI methods unless there is no other way
         * to accomplish what you want
         */
        try {
            REXP x;
            re.eval("data(iris)", false);
            System.out.println(x = re.eval("iris"));
            //鳶尾花資料集 x=iris
            // generic vectors are RVector to accomodate names 
            //產生R向量容納iris資料集的欄位名names 5列
            RVector v = x.asVector();
            if (v.getNames() != null) {
                System.out.println("has names:");
                for (Enumeration e = v.getNames().elements(); e.hasMoreElements();) {
                    System.out.println(e.nextElement());
                }
            }
            // for compatibility with Rserve we allow casting of vectors to lists
            // 通過 Rserve 把向量轉成list集合
            RList vl = x.asList();
            String[] k = vl.keys();//[Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]
            if (k != null) {
                //遍歷集合,輸出names
                System.out.println("and once again from the list:");
                int i = 0;
                while (i < k.length)
                    System.out.println(k[i++]);
            }

            // get boolean array
            //產生一個Boolean陣列
            System.out.println(x = re.eval("iris[[1]]>mean(iris[[1]])"));//[BOOLi* ]
            // R knows about TRUE/FALSE/NA, so we cannot use boolean[] this way
            // instead, we use int[] which is more convenient (and what R uses internally anyway)
            //將R布林陣列轉為int陣列?R底層處理布林用是的0,1?NA
            int[] bi = x.asIntArray();
            {
                int i = 0;
                while (i < bi.length) {
                    System.out.print(bi[i] == 0 ? "F " : (bi[i] == 1 ? "T " : "NA "));
                    i++;
                }
                System.out.println("");
            }

            // push a boolean array
            boolean by[] = { true, false, false };
            re.assign("bool", by);
            System.out.println(x = re.eval("bool"));//[BOOLi* ]
            // asBool returns the first element of the array as RBool //返回布林陣列的第一個元素作為RBool?
            // (mostly useful for boolean arrays of the length 1). is should
            // return true
            System.out.println("isTRUE? " + x.asBool().isTRUE());

            // now for a real dotted-pair list: 對於配對的資料,類似於key=value鍵值對形式資料
            System.out.println(x = re.eval("pairlist(a=1,b='foo',c=1:5)"));
            RList l = x.asList();
            if (l != null) {
                int i = 0;
                String[] a = l.keys();//[a, b, c]所有的鍵
                System.out.println("Keys:");
                while (i < a.length)
                    System.out.println(a[i++]);
                System.out.println("Contents:");//
                i = 0;
                while (i < a.length)
                    System.out.println(l.at(i++));//通過索引位置取值
                    //[REAL* (1.0)] 
                    //[STRING "foo"]
                    //[INT* (1, 2, 3, 4, 5)]
            }
            System.out.println(re.eval("sqrt(36)"));//[REAL* (6.0)]
        } catch (Exception e) {
            System.out.println("EX:" + e);
            e.printStackTrace();
        }

        // Part 2 - low-level API - for illustration purposes only!
        // System.exit(0);
        //第二部分--API -low level  

        // simple assignment like a<-"hello" (env=0 means use R_GlobalEnv)
        //引數0表示 use R_GlobalEnv  當前環境,即使用者環境,是使用者程式執行的環境空間。
        long xp1 = re.rniPutString("hello");
        re.rniAssign("a", xp1, 0);//賦值,定義變數a<-'hello'

        // Example: how to create a named list or data.frame建立list或資料框
        double da[] = { 1.2, 2.3, 4.5 };
        double db[] = { 1.4, 2.6, 4.2 };
        long xp3 = re.rniPutDoubleArray(da);
        long xp4 = re.rniPutDoubleArray(db);

        // now build a list (generic vector is how that's called in R)
        //R裡的向量,Java裡的list
        long la[] = { xp3, xp4 };
        long xp5 = re.rniPutVector(la);

        // now let's add names 新增names
        String sa[] = { "a", "b" };
        long xp2 = re.rniPutStringArray(sa);
        re.rniSetAttr(xp5, "names", xp2);

        // ok, we have a proper list now  帶屬性的list
        // we could use assign and then eval "b<-data.frame(b)", but for now
        // let's build it by hand:
        String rn[] = { "1", "2", "3" };
        long xp7 = re.rniPutStringArray(rn);
        re.rniSetAttr(xp5, "row.names", xp7);

        long xp6 = re.rniPutString("data.frame");
        re.rniSetAttr(xp5, "class", xp6);

        // assign the whole thing to the "b" variable
        re.rniAssign("b", xp5, 0);

        {
            System.out.println("Parsing");
            long e = re.rniParse("data(iris)", 1);
            System.out.println("Result = " + e + ", running eval");
            long r = re.rniEval(e, 0);
            System.out.println("Result = " + r + ", building REXP");//REXP result = [STRING "iris"]
            REXP x = new REXP(re, r);
            System.out.println("REXP result = " + x);
        }
        {
            System.out.println("Parsing");
            long e = re.rniParse("iris", 1);
            System.out.println("Result = " + e + ", running eval");
            long r = re.rniEval(e, 0);
            System.out.println("Result = " + r + ", building REXP");
            REXP x = new REXP(re, r);
            System.out.println("REXP result = " + x);//REXP result = [VECTOR ([REAL* (5.1, 4.9, 4.7, 4.6...
            double[] doubleArray = x.asDoubleArray();
        }
        {
            System.out.println("Parsing");
            long e = re.rniParse("names(iris)", 1);
            System.out.println("Result = " + e + ", running eval");
            long r = re.rniEval(e, 0);
            System.out.println("Result = " + r + ", building REXP");
            REXP x = new REXP(re, r);
            System.out.println("REXP result = " + x);//[STRING* ("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species")]
            String s[] = x.asStringArray();//[Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]
            if (s != null) {
                int i = 0;
                while (i < s.length) {
                    System.out.println("[" + i + "] \"" + s[i] + "\"");
                    i++;
                }
            }
        }
        {
            System.out.println("Parsing");
            long e = re.rniParse("rnorm(10)", 1);
            System.out.println("Result = " + e + ", running eval");
            long r = re.rniEval(e, 0);
            System.out.println("Result = " + r + ", building REXP");
            REXP x = new REXP(re, r);
            System.out.println("REXP result = " + x);
            double d[] = x.asDoubleArray();
            if (d != null) {
                int i = 0;
                while (i < d.length) {
                    System.out.print(((i == 0) ? "" : ", ") + d[i]);
                    i++;
                }
                System.out.println("");
            }
            System.out.println("");
        }
        {
            REXP x = re.eval("1:10");
            System.out.println("REXP result = " + x);
            int d[] = x.asIntArray();
            if (d != null) {
                int i = 0;
                while (i < d.length) {
                    System.out.print(((i == 0) ? "" : ", ") + d[i]);
                    i++;
                }
                System.out.println("");
            }
        }

        re.eval("print(1:10/3)");

        if (true) {
            // so far we used R as a computational slave without REPL
            // now we start the loop, so the user can use the console
            System.out.println("Now the console is yours ... have fun");
            re.startMainLoop();
        } else {
            re.end();
            System.out.println("end");
        }
    }