Java-R integráció

1. Áttekintés

R egy népszerű programozási nyelv, amelyet statisztikákhoz használnak. Mivel sokféle funkció és csomag áll rendelkezésre, nem ritka követelmény az R kód beágyazása más nyelvekre.

Ebben a cikkben megnézzük az R kód Java-ba történő integrálásának leggyakoribb módszereit.

2. R szkript

A projektünknél egy nagyon egyszerű R függvény végrehajtásával kezdjük, amely egy vektort vesz be bemenetként, és visszaadja az értéke átlagát. Ezt egy külön fájlban definiáljuk:

customMean <- függvény (vektor) {közép (vektor)}

A bemutató során egy Java segítő módszert használunk a fájl elolvasására és tartalmának a-ként történő visszaadására Húr:

A getMeanScriptContent () karakterlánc eldobja az IOException, URISyntaxException {URI rScriptUri = RUtils.class.getClassLoader (). GetResource ("script.R"). ToURI (); Path inputScript = Paths.get (rScriptUri); return Files.lines (inputScript) .collect (Collectors.joining ()); }

Most nézzük meg azokat a különféle lehetőségeket, amelyekkel ezt a függvényt meg kell hívnunk a Java-ból.

3. RCaller

Az első könyvtár, amelyet figyelembe veszünk, az RCaller, amely a helyi gépen egy dedikált R folyamat létrehozásával képes végrehajtani a kódot.

Mivel az RCaller elérhető a Maven Central-tól, egyszerűen felvehetjük a mi termékünkbe pom.xml:

 com.github.jbytecode RCaller 3.0 

Ezután írjunk egy egyéni metódust, amely az eredeti R szkript használatával adja vissza értékeink átlagát:

nyilvános kettős átlag (int [] értékek) dobja az IOException, URISyntaxException {String fileContent = RUtils.getMeanScriptContent (); RCode kód = RCode.create (); code.addRCode (fileContent); code.addIntArray ("input", értékek); code.addRCode ("eredmény <- customMean (input)"); RCaller caller = RCaller.create (kód, RCallerOptions.create ()); caller.runAndReturnResult ("eredmény"); return caller.getParser (). getAsDoubleArray ("eredmény") [0]; }

Ebben a módszerben főleg két objektumot használunk:

  • RCode, amely a kódkörnyezetünket képviseli, beleértve a függvényünket, annak bevitelét és egy meghívási utasítást
  • RCaller, amely lehetővé teszi számunkra a kód futtatását és az eredmény visszaszerzését

Fontos ezt észrevenni Az RCaller nem alkalmas kicsi és gyakori számításokra az R folyamat elindításához szükséges idő miatt. Ez észrevehető hátrány.

Is, Az RCaller csak akkor működik, ha R telepítve van a helyi gépre.

4. Renjin

A Renjin egy másik népszerű megoldás, amely elérhető az R integrációs tájon. Szélesebb körben elfogadott, és vállalati támogatást is kínál.

Renjin hozzáadása a projektünkhöz kissé kevésbé triviális, mivel hozzá kell adnunk a bedatadriven adattár a Maven-függőséggel együtt:

  bedatadriven bedatadriven public repo //nexus.bedatadriven.com/content/groups/public/ org.renjin renjin-script-engine RELEASE 

Még egyszer hozzunk létre egy Java csomagolást az R függvényünkhöz:

nyilvános kettős középérték (int [] értékek) dobja az IOException, URISyntaxException, ScriptException {RenjinScriptEngine engine = new RenjinScriptEngine (); String meanScriptContent = RUtils.getMeanScriptContent (); motor.put ("input", értékek); motor.eval (meanScriptContent); DoubleArrayVector eredmény = (DoubleArrayVector) motor.eval ("customMean (input)"); visszatérési eredmény.asReal (); }

Ahogy látjuk, a koncepció nagyon hasonlít az RCaller-re, bár kevésbé bőbeszédű, mivel a függvényekkel közvetlenül név szerint hívhatjuk meg a eval módszer.

A Renjin fő előnye, hogy nem igényel R telepítést, mivel JVM-alapú tolmácsot használ. Renjin azonban jelenleg nem 100% -ban kompatibilis a GNU R-vel.

5. Tartalék

Az eddig áttekintett könyvtárak jó választás a kód helyi futtatására. De mi van, ha azt akarjuk, hogy több kliens hívja meg az R szkriptünket? Itt játszik szerepet Rserve, lehetővé téve az R kód futtatását egy távoli gépen egy TCP szerveren keresztül.

Az Rserve beállítása magában foglalja a kapcsolódó csomag telepítését és a kiszolgáló elindítását a szkriptünk betöltése során az R konzolon keresztül:

> install.packages ("Rserve") ...> library ("Rserve")> Rserve (args = "--RS-source ~ / script.R") Az Rserve indítása ...

Ezután most be tudjuk vonni az Rserve-t a projektünkbe, a szokásos módon hozzáadva a Maven-függőséget:

 org.rosuda.Motor Rserve 1.8.1 

Végül csomagoljuk be az R szkriptünket egy Java módszerbe. Itt egy RC csatlakozás objektum a szerver címünkkel, alapértelmezés szerint 127.0.0.1:6311, ha nincs megadva:

nyilvános kettős átlag (int [] értékek) dobja a REngineException, REXPMismatchException {RConnection c = new RConnection (); c. kiosztás ("input", értékek); return c.eval ("customMean (input)"). asDouble (); }

6. FastR

Az utolsó könyvtár, amelyről beszélni fogunk, a FastR. nagy teljesítményű R megvalósítás, amely a GraalVM-re épült. Az írás idején A FastR csak Linux és Darwin x64 rendszereken érhető el.

Használatához először telepítenünk kell a GraalVM-et a hivatalos webhelyről. Ezt követően magát a FastR-t kell telepítenünk a Graal Component Updater segítségével, majd futtatnunk kell a hozzá tartozó konfigurációs szkriptet:

$ bin / gu telepíti az R ... $ languages ​​/ R / bin / configure_fastr fájlt

Ezúttal a kódunk a Polyglot-tól, a GraalVM belső API-tól függ, amely lehetővé teszi a különböző vendégnyelvek Java beágyazását. Mivel a Polyglot egy általános API, megadjuk a futtatni kívánt kód nyelvét. Ezenkívül a c R függvény a bemenetünk vektorokká alakításához:

nyilvános kettős középérték (int [] értékek) {Context polyglot = Context.newBuilder (). allowAllAccess (true) .build (); String meanScriptContent = RUtils.getMeanScriptContent (); polyglot.eval ("R", meanScriptContent); RBindings = polyglot.getBindings ("R") érték; RInput = rBindings.getMember ("c") .érték (értékek); return rBindings.getMember ("customMean"). végrehajtani (rInput) .asDouble (); }

Ha ezt a megközelítést követi, ne feledje, hogy ez kódunkat szorosan összekapcsolja a JVM-mel. Ha többet szeretne megtudni a GraalVM-ről, olvassa el a Graal Java JIT Compiler cikkünket.

7. Következtetés

Ebben a cikkben áttekintettük az R Java integrálásának legnépszerűbb technológiáit. Összefoglalva:

  • Az RCaller könnyebben integrálható, mivel a Maven Centralon elérhető
  • A Renjin vállalati támogatást kínál, és nem igényli az R telepítését a helyi gépre, de nem 100% -ban kompatibilis a GNU R-vel
  • Az Rserve használható az R kód távoli kiszolgálón történő végrehajtására
  • A FastR lehetővé teszi a zökkenőmentes integrációt a Java-val, de kódunkat a virtuális géptől teszi függővé, és nem minden operációs rendszerhez érhető el

Mint mindig, az oktatóanyagban használt összes kód elérhető a GitHubon.