2014-05-09 17 views
7

Tôi đang sử dụng JRI làm nô lệ tính toán cho các thống kê từ bên trong Java. R tính toán được yêu cầu theo thời gian, nhưng không quá thường xuyên. Do đó, tôi đã quyết định tạo ra một phương thức bao bọc cho phép tính tạo ra một cá thể REngine mới và cũng đóng nó lại vào cuối. Tất cả mọi thứ hoạt động như một say mê khi gọi phương thức lần đầu tiên. Thật không may, gọi nó lần thứ hai gây ra lỗi "R đã được khởi tạo".Lỗi Java-R cầu "JRI": R đã được khởi tạo

khởi:

private static Rengine createEngineInstance(){ 

     //Initialise R Engine. 
     Rengine re=new Rengine (new String [] {"--vanilla"}, false, new CallbackListener()); 

     //Wait until REngine-thread is ready 
     if (!re.waitForR()) 
     { 
      System.err.println ("Cannot load R. Is the environment variable R_HOME set correctly?"); 
      System.exit(1); 
     } 
     return re; 
} 

Wrapper phương pháp:

public static void performR(){ 

    //Create instance of R engine 
    Rengine re = createEngineInstance(); 

    //Perform some R operations 
    re.eval("..."); 

    re.end(); 

} 

Rõ ràng, ví dụ REngine không chấm dứt một cách chính xác. Vì vậy, tôi cần phải biết: 1) Có cơ hội để chấm dứt REngine và tạo một thể hiện mới sau này không? Cách này hoạt động chính xác? Tôi biết rằng không thể chạy nhiều chủ đề R cùng một lúc với JRI, nhưng đây không phải là những gì tôi đang nhắm tới. 2) Nếu đây không phải là trường hợp, tôi sẽ tạo một thể hiện bằng cách sử dụng mẫu Singleton. Làm thế nào tôi có thể đảm bảo trong trường hợp này là phiên R bị đóng khi chương trình chấm dứt?

Trợ giúp của bạn thực sự được đánh giá cao! Cảm ơn!

+0

Mặc dù đây không phải là câu trả lời bạn mong đợi, hãy thử sử dụng renjin http://www.renjin.org/, nó không sử dụng trình thông dịch R, vì vậy bạn sẽ không có loại vấn đề này (có những vấn đề khác với nó mặc dù ...) –

Trả lời

7

theo JRI Javadoc ....

Chỉ có một Rengine Instance có thể được sử dụng, và Rengine.end() chức năng có một số vấn đề ...

bạn không nên sử dụng mã như

này
Rengine engine = new Rengine(new String[] {"--vanilla"}, false, null); 

bạn có thể sử dụng Rengine với mã này

Rengine engine = Rengine.getMainEngine(); 
if(engine == null) 
    engine = new Rengine(new String[] {"--vanilla"}, false, null); 
2

câu hỏi rất cũ, nhưng tôi sẽ thêm việc xem xét RServe như một giải pháp thay thế thường hấp dẫn. Việc thiết lập là ít tham gia (theo ý kiến ​​của tôi) và giao diện gần như giống hệt nhau.

Hướng dẫn chi tiết được cung cấp here.

Điều này có các lợi ích bổ sung nếu bạn muốn thực hiện cuộc gọi đến R từ các luồng song song của Java, bạn có thể thực hiện việc này.

+0

Vẫn còn rất nhiều đánh giá cao. Cảm ơn! – Chris

Các vấn đề liên quan