0

私はPostgreSQLからデータを取得しようとしているJavaコードを書いており、その上で簡単な計算を行っています(中央値の計算)。まず、Java コード自体から RPostgreSQL ライブラリをロードし、次にドライバーをロードして、Java を介して R と PostgreSQL 間の接続を確立します。しかし、Java を介してクエリ コマンド (PostgreSQL から R にクエリを取得するために使用される) を起動しようとすると、次のようなエラーが発生します。

注: このエラーは解決されました。現在のエラー (スクリプト ファイル エラー) については、以下を参照してください。

org.rosuda.REngine.REngineException: eval failed, request status: R parser: syntax error
org.rosuda.REngine.Rserve.RConnection.parseAndEval(RConnection.java:454)
org.rosuda.REngine.REngine.parseAndEval(REngine.java:108)
Rtemp.main(Rtemp.java:40)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

私の現在のコードは次のとおりです。

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.*;

public class Rtemp {
  public static void main(String[] args) throws Exception {
    RConnection c = null;

    try {
      c = new RConnection();

      //Loading RPostgreSQL library
      REXP x = c.eval("library(RPostgreSQL)");

      //Loading PostgreSQL driver
      REXP drv = c.eval("dbDriver(\"PostgreSQL\")");

      // Establishing connection
      REXP r = c.parseAndEval("try(\"dbConnect(drv, host='localhost', port='5432',dbname='r1', user='postgres', password='pwd')\",silent=TRUE)");
      if (r.inherits("try-error")) System.err.println("Error: "+r.asString());
      else System.out.println("Success eval 1");


      REXP rs = c.parseAndEval("try(dbSendQuery(r,\"select colmn1 from host_brnd345633456_table1 limit 10 \"), silent=TRUE)");
      if (rs.inherits("try-error")) System.err.println("Error: "+rs.asString());
      else System.out.println("Success eval 2");



      REXP ftch = c.parseAndEval("try(ftch(rs,n=-1),silent=TRUE)");
      if (ftch.inherits("try-error")) System.err.println("Error: "+ftch.asString());
      else System.out.println("Success eval 3");

      REXP res = c.parseAndEval("try(median(ftch$colmn1),silent=TRUE)");
      if (res.inherits("try-error")) System.err.println("Error: "+res.asString());
      else {
        System.out.println("Success eval 4");
        System.out.println(res.asDouble());
      }
#The line 58 error mentioned below in the error section is coming at this line
      System.out.println(res.asDouble());
      //System.out.println(x.asString());
      System.out.println("Library loaded successfully");
    } catch(Exception e) {
      e.printStackTrace();
    } finally {
      if ( c != null )
        try {
          c.close();
        }
    }
  }
}

R のバージョンを表示するような単純なコードは正しく実行されているため、Rserve 接続に問題はないと思います。

また、dbSendQuery() などの R から PostgreSQL へのコマンドの書き込み構文にも問題はありません。R 内から直接コマンドを使用する場合と同様に、完全に正常に動作します。だから、私が思う問題は、Javaで同じことを書くことです(Javaの対応する構文)。

更新 1: エラー 2 (このエラーは解決済みです)

@ on_the_shores_of_linux_sea からの提案を受けて、コードを少し変更しましたが、次のような別のエラーが発生しています。

    Success eval 1
Error: Error in is(object, Cl) : 
  error in evaluating the argument 'conn' in selecting a method for function 'dbSendQuery': Error: object 'r' not found


Error: Error in is(object, Cl) : 
  error in evaluating the argument 'res' in selecting a method for function 'fetch': Error: object 'rs' not found


Error: Error in median(ftch$t31001400) : object 'ftch' not found

org.rosuda.REngine.REXPMismatchException: attempt to access org.rosuda.REngine.REXPString as double
    at org.rosuda.REngine.REXP.asDoubles(REXP.java:77)
    at org.rosuda.REngine.REXP.asDouble(REXP.java:103)
    at Rtemp.main(Rtemp.java:58)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Process finished with exit code 0

エラーの原因と解決方法がわかりません

二次的な質問: R クエリまたはステートメントをファイル (特別な R 形式のファイルまたはその他の形式のファイル) に記述し、Java にそのファイルを読み取らせてプッシュすることができるかどうかも知りたいので、これは二次的な質問です。それらを実行するためにRコマンドをRに入れますか?

更新 2: スクリプト ファイル エラー

以下で言及されている方法1@on_the_shores_of_linux_seaは現在正常に機能しています。私も方法 2 でやろうとしていますが、Java でスクリプトを管理するのが難しいです。私が使用しているJavaコードは次のとおりです。

public class Java_RScript {

    public static void main(String[] args) throws Exception {
        RConnection c = null;
        try {
            c = new RConnection();
            c.parseAndEval("try(source("script.R"),silent=TRUE)");
            REXP res = c.parseAndEval("try(\"do_operation()\", silent=TRUE)");
            System.out.println("Success:" + res.asDouble());
        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            if (c != null) {

                try {

                    c.close();

                } finally {
                }

            }

        }

    }
}

印刷されている出力コンソールのエラーは次のとおりです。

org.rosuda.REngine.REXPMismatchException: attempt to access org.rosuda.REngine.REXPString as double

私のスクリプトファイルの構文は次のとおりです。

do_operation <- function()
 {
 drv <- dbDriver("PostgreSQL")
   r <- dbConnect(drv, host='localhost', port='1234',dbname='db', user='user1', password='pswd')
   rs <-dbSendQuery(r,"select colmn1 from hostess_table limit 10")
   ftch <- fetch(rs,n=-1)
   res <- median(ftch$colmn1)
   return(res)
 }

エラーがスクリプト ファイルにあるのか、Java 構文にあるのかわかりません。

4

1 に答える 1