2014-05-09 2 views
7

Sto utilizzando JRI come slave di calcolo per le statistiche all'interno di Java. I calcoli R sono richiesti di volta in volta, ma non troppo frequentemente. Così, ho deciso di creare un metodo wrapper per il calcolo che crea una nuova istanza di REngine e la chiude anche alla fine. Tutto funziona come un fascino quando si chiama il metodo la prima volta. Sfortunatamente, chiamandolo una seconda volta si attiva l'errore "R è già inizializzato".Errore "JRI" ponte Java-R: R è già inizializzato

inizializzazione:

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; 
} 

metodo fascia:

public static void performR(){ 

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

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

    re.end(); 

} 

Ovviamente, l'istanza REngine non è terminato correttamente. Quindi, ho bisogno di sapere: 1) C'è la possibilità di chiudere il motore REngine e creare una nuova istanza più tardi? Come funziona correttamente? So che è impossibile eseguire più thread R allo stesso tempo con JRI, ma questo non è quello che sto puntando. 2) In caso contrario, creerei un'istanza utilizzando il modello Singleton. Come posso garantire in questo caso che la sessione R si chiuda quando il programma termina?

Il vostro aiuto è molto apprezzato! Grazie!

+0

Anche se questa non è la risposta che ci si aspettava, provare a utilizzare renjin http://www.renjin.org/, non usa l'interprete R, quindi non si ha questo tipo di problema (ci sono altri problemi con esso comunque ...) –

risposta

7

in base alle JRI Javadoc ....

solo Rengine grado può essere utilizzato, e Rengine.end() la funzione ha qualche problema ...

non si dovrebbe usare il codice come questo

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

è possibile utilizzare Rengine con questo codice

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

Molto vecchia questione, ma vorrei aggiungere che considerare RServe come un'alternativa è spesso attraente. Il set-up è meno coinvolto (secondo me) e l'interfaccia è quasi identica.

Tutorial dettagliato fornito here.

Questo ha i vantaggi aggiuntivi che se si desidera effettuare chiamate a R da thread paralleli di Java, è possibile farlo.

+0

Ancora molto apprezzato. Grazie! – Chris