Java-R-integration

1. Oversigt

R er et populært programmeringssprog, der bruges til statistik. Da det har en bred vifte af funktioner og pakker til rådighed, er det ikke et ualmindeligt krav at integrere R-kode på andre sprog.

I denne artikel vil vi se på nogle af de mest almindelige måder at integrere R-kode i Java på.

2. R script

For vores projekt starter vi med at implementere en meget enkel R-funktion, der tager en vektor som input og returnerer gennemsnittet af dens værdier. Vi definerer dette i en dedikeret fil:

customMean <- funktion (vektor) {middel (vektor)}

I hele denne tutorial bruger vi en Java-hjælpemetode til at læse denne fil og returnere dens indhold som en Snor:

String getMeanScriptContent () kaster IOException, URISyntaxException {URI rScriptUri = RUtils.class.getClassLoader (). GetResource ("script.R"). ToURI (); Sti inputScript = Paths.get (rScriptUri); returnere Files.lines (inputScript) .collect (Collectors.joining ()); }

Lad os nu se på de forskellige muligheder, vi har for at påkalde denne funktion fra Java.

3. RCaller

Det første bibliotek, vi skal overveje, er RCaller, som kan udføre kode ved at gyde en dedikeret R-proces på den lokale maskine.

Da RCaller er tilgængelig fra Maven Central, kan vi bare inkludere det i vores pom.xml:

 com.github.jbytecode RCaller 3.0 

Lad os derefter skrive en brugerdefineret metode, der returnerer gennemsnittet af vores værdier ved hjælp af vores originale R-script:

offentligt dobbelt gennemsnit (int [] værdier) kaster IOException, URISyntaxException {String fileContent = RUtils.getMeanScriptContent (); RCode kode = RCode.create (); code.addRCode (fileContent); code.addIntArray ("input", værdier); code.addRCode ("resultat <- customMean (input)"); RCaller-opkald = RCaller.create (kode, RCallerOptions.create ()); caller.runAndReturnResult ("resultat"); returner caller.getParser (). getAsDoubleArray ("resultat") [0]; }

I denne metode bruger vi hovedsageligt to objekter:

  • RCode, som repræsenterer vores kodekontekst, herunder vores funktion, dens input og en påkaldelseserklæring
  • RCaller, som lader os køre vores kode og få resultatet tilbage

Det er vigtigt at bemærke det RCaller er ikke egnet til små og hyppige beregninger på grund af den tid det tager at starte R-processen. Dette er en mærkbar ulempe.

Også, RCaller fungerer kun med R installeret på den lokale maskine.

4. Renjin

Renjin er en anden populær løsning til rådighed i R-integrationslandskabet. Det er mere bredt vedtaget, og det tilbyder også virksomhedsstøtte.

At tilføje Renjin til vores projekt er lidt mindre trivielt, da vi er nødt til at tilføje bedatadriven lager sammen med Maven afhængighed:

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

Lad os endnu en gang bygge en Java-indpakning til vores R-funktion:

offentligt dobbelt gennemsnit (int [] værdier) kaster IOException, URISyntaxException, ScriptException {RenjinScriptEngine motor = ny RenjinScriptEngine (); Streng meanScriptContent = RUtils.getMeanScriptContent (); engine.put ("input", værdier); engine.eval (meanScriptContent); DoubleArrayVector result = (DoubleArrayVector) engine.eval ("customMean (input)"); returneresultat.asReal (); }

Som vi kan se, konceptet er meget lig RCaller, selvom det er mindre detaljeret, da vi kan påkalde funktioner direkte ved navn ved hjælp af eval metode.

Den største fordel ved Renjin er, at den ikke kræver en R-installation, da den bruger en JVM-baseret tolk. Renjin er dog i øjeblikket ikke 100% kompatibel med GNU R.

5. Rserve

De biblioteker, vi hidtil har gennemgået, er gode valg til at køre kode lokalt. Men hvad nu hvis vi vil have flere klienter, der påberåber vores R-script? Det er her, Rserve kommer i spil, lade os køre R-kode på en ekstern maskine via en TCP-server.

Opsætning af Rserve indebærer installation af den relaterede pakke og start af serveren, der indlæser vores script gennem R-konsollen:

> install.packages ("Rserve") ...> bibliotek ("Rserve")> Rserve (args = "--RS-kilde ~ / script.R") Starter Rserve ...

Dernæst kan vi nu inkludere Rserve i vores projekt ved som normalt at tilføje Maven-afhængighed:

 org.rosuda.REngine Rserve 1.8.1 

Lad os endelig pakke vores R-script ind i en Java-metode. Her bruger vi en RCforbindelse objekt med vores serveradresse, som standard er 127.0.0.1:6311, hvis den ikke er angivet:

offentligt dobbelt gennemsnit (int [] værdier) kaster REngineException, REXPMismatchException {RConnection c = new RConnection (); c.assign ("input", værdier); returner c.eval ("customMean (input)"). asDouble (); }

6. FastR

Det sidste bibliotek, vi skal tale om, er FastR. en højtydende R-implementering bygget på GraalVM. På tidspunktet for denne skrivning FastR er kun tilgængelig på Linux- og Darwin x64-systemer.

For at kunne bruge det skal vi først installere GraalVM fra det officielle websted. Derefter skal vi installere FastR selv ved hjælp af Graal Component Updater og derefter køre det konfigurationsscript, der følger med det:

$ bin / gu installerer R ... $ sprog / R / bin / configure_fastr

Denne gang afhænger vores kode af Polyglot, GraalVM's interne API til indlejring af forskellige gæstesprog i Java. Da Polyglot er en generel API, specificerer vi sproget for den kode, vi vil køre. Vi bruger også c R-funktion til at konvertere vores input til en vektor:

offentligt dobbelt gennemsnit (int [] værdier) {Context polyglot = Context.newBuilder (). allowAllAccess (true) .build (); Streng meanScriptContent = RUtils.getMeanScriptContent (); polyglot.eval ("R", meanScriptContent); Værdi rBindings = polyglot.getBindings ("R"); Værdi rInput = rBindings.getMember ("c"). Execute (værdier); returner rBindings.getMember ("customMean"). udfør (rInput) .asDouble (); }

Når du følger denne tilgang, skal du huske på, at det gør vores kode tæt koblet til JVM. For at lære mere om GraalVM, se vores artikel om Graal Java JIT Compiler.

7. Konklusion

I denne artikel gennemgik vi nogle af de mest populære teknologier til integration af R i Java. At opsummere:

  • RCaller er lettere at integrere, da den er tilgængelig på Maven Central
  • Renjin tilbyder virksomhedsstøtte og kræver ikke, at R skal installeres på den lokale maskine, men det er ikke 100% kompatibelt med GNU R
  • Rserve kan bruges til at udføre R-kode på en ekstern server
  • FastR tillader problemfri integration med Java, men gør vores kode afhængig af VM og er ikke tilgængelig for alle operativsystemer

Som altid er al den kode, der bruges i denne tutorial, tilgængelig på GitHub.