שילוב Java-R

1. סקירה כללית

R היא שפת תכנות פופולרית המשמשת לסטטיסטיקה. מכיוון שיש לו מגוון רחב של פונקציות וחבילות זמינים, זה לא דרישה נדירה להטמיע קוד R לשפות אחרות.

במאמר זה נבחן כמה מהדרכים הנפוצות ביותר לשילוב קוד R ב- Java.

2. תסריט R

עבור הפרויקט שלנו, נתחיל ביישום פונקציית R פשוטה מאוד שלוקחת וקטור כקלט ומחזירה את ממוצע הערכים שלה. נגדיר זאת בקובץ ייעודי:

customMean <- פונקציה (וקטור) {ממוצע (וקטור)}

במהלך הדרכה זו נשתמש בשיטת עוזר Java לקרוא את הקובץ ולהחזיר את תוכנו כ- חוּט:

מחרוזת getMeanScriptContent () זורקת IOException, URISyntaxException {URI rScriptUri = RUtils.class.getClassLoader (). GetResource ("script.R"). ToURI (); נתיב inputScript = Paths.get (rScriptUri); להחזיר Files.lines (inputScript) .collect (Collectors.joining ()); }

עכשיו, בואו נסתכל על האפשרויות השונות שיש לנו להפעיל פונקציה זו מג'אווה.

3. RCaller

הספרייה הראשונה שנשקול היא RCaller שיכולה לבצע קוד על ידי השרצת תהליך R ייעודי במכונה המקומית.

מכיוון ש- RCaller זמין מ Maven Central, אנחנו יכולים פשוט לכלול אותו ב- pom.xml:

 com.github.jbytecode RCaller 3.0 

לאחר מכן, בוא נכתוב שיטה מותאמת אישית שתחזיר את ממוצע הערכים שלנו באמצעות סקריפט R המקורי שלנו:

ממוצע כפול ציבורי (int [] ערכים) זורק IOException, URISyntaxException {String fileContent = RUtils.getMeanScriptContent (); קוד RCode = RCode.create (); code.addRCode (fileContent); code.addIntArray ("קלט", ערכים); code.addRCode ("תוצאה <- customMean (קלט)"); מתקשר RCaller = RCaller.create (קוד, RCallerOptions.create ()); caller.runAndReturnResult ("תוצאה"); החזר caller.getParser (). getAsDoubleArray ("תוצאה") [0]; }

בשיטה זו אנו משתמשים בעיקר בשני אובייקטים:

  • RCode, המייצג את הקשר הקוד שלנו, כולל הפונקציה שלנו, הקלט שלו והצהרת קריאה
  • RCaller, המאפשר לנו להריץ את הקוד ולקבל את התוצאה בחזרה

חשוב לשים לב לכך RCaller אינו מתאים לחישובים קטנים ותכופים בגלל הזמן שלוקח להתחיל בתהליך R. זהו חסרון מורגש.

גַם, RCaller עובד רק עם R המותקן במחשב המקומי.

4. רנג'ין

Renjin הוא פיתרון פופולרי נוסף הזמין בנוף האינטגרציה של R. זה מאומץ יותר, והוא גם מציע תמיכה ארגונית.

הוספת Renjin לפרויקט שלנו היא קצת פחות טריוויאלית מכיוון שעלינו להוסיף את bedatadriven מאגר יחד עם התלות של Maven:

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

שוב, בואו נבנה מעטפת Java לפונקציית R שלנו:

ממוצע כפול ציבורי (int [] ערכים) זורק IOException, URISyntaxException, ScriptException {RenjinScriptEngine engine = RenjinScriptEngine חדש (); מחרוזת meanScriptContent = RUtils.getMeanScriptContent (); engine.put ("קלט", ערכים); engine.eval (meanScriptContent); DoubleArrayVector result = (DoubleArrayVector) engine.eval ("customMean (input)"); return result.asReal (); }

כמו שאנו יכולים לראות, הרעיון דומה מאוד ל- RCaller, אם כי פחות מילולי, מכיוון שנוכל להפעיל פונקציות ישירות בשם באמצעות הערכה שיטה.

היתרון העיקרי של רנג'ין הוא שהוא אינו דורש התקנת R מכיוון שהוא משתמש במתורגמן מבוסס JVM. עם זאת, כרגע Renjin אינו תואם 100% ל- GNU R.

5. שרת

הספריות שבדקנו עד כה הן אפשרויות טובות להפעלת קוד באופן מקומי. אבל מה אם נרצה שיהיו מספר לקוחות המפעילים את תסריט ה- R שלנו? זה המקום בו Rserve נכנס לשחק, מאפשר לנו להפעיל קוד R במחשב מרוחק דרך שרת TCP.

הגדרת Rserve כוללת התקנת החבילה הקשורה והפעלת השרת עם טעינת הסקריפט שלנו דרך מסוף R:

> install.packages ("Rserve") ...> ספרייה ("Rserve")> Rserve (args = "--RS-source ~ / script.R") מתחיל Rserve ...

בשלב הבא נוכל לכלול את Rserve בפרויקט שלנו על ידי הוספת התלות של Maven, כרגיל:

 org.rosuda.REngine Rserve 1.8.1 

לבסוף, בואו נעטוף את סקריפט ה- R שלנו לשיטת Java. כאן נשתמש ב- חיבור RC התנגד עם כתובת השרת שלנו, ברירת המחדל היא 127.0.0.1:6311 אם לא מסופק:

ממוצע כפול פומבי (int [] ערכים) זורק REngineException, REXPMismatchException {RConnection c = RCNection new (); c.assign ("קלט", ערכים); החזר c.eval ("customMean (קלט)"). asDouble (); }

6. FastR

הספרייה האחרונה שעליה נדבר היא FastR. יישום R ביצועים גבוהים שנבנה על GraalVM. בזמן כתיבת שורות אלה, FastR זמין רק במערכות לינוקס ו- Darwin x64.

על מנת להשתמש בו, ראשית עלינו להתקין את GraalVM מהאתר הרשמי. לאחר מכן, עלינו להתקין את FastR עצמו באמצעות Upal Component Updater ולאחר מכן להריץ את סקריפט התצורה המצורף אליו:

$ bin / gu להתקין R ... $ שפות / R / bin / configure_fastr

הפעם הקוד שלנו יהיה תלוי ב- Polyglot, ה- API הפנימי של GraalVM להטמעת שפות אורח שונות ב- Java. מכיוון ש- Polyglot הוא ממשק API כללי, אנו מציינים את שפת הקוד שאנו רוצים להריץ. כמו כן, נשתמש ב- ג פונקציית R כדי להמיר את הקלט שלנו לווקטור:

ממוצע כפול ציבורי (int [] ערכים) {Context polyglot = Context.newBuilder (). allowAllAccess (true) .build (); מחרוזת meanScriptContent = RUtils.getMeanScriptContent (); polyglot.eval ("R", meanScriptContent); ערך rBindings = polyglot.getBindings ("R"); ערך rInput = rBindings.getMember ("c"). Execute (ערכים); החזר rBindings.getMember ("customMean"). execute (rInput) .asDouble (); }

כשאתה מבצע גישה זו, זכור שהוא הופך את הקוד שלנו לצמוד היטב עם ה- JVM. למידע נוסף על GraalVM עיין במאמר שלנו על מהדר Java JIT של Graal.

7. מסקנה

במאמר זה עברנו על כמה מהטכנולוגיות הפופולריות ביותר לשילוב R ב- Java. לסיכום:

  • קל יותר לשלב את RCaller מכיוון שהוא זמין ב- Maven Central
  • Renjin מציעה תמיכה ארגונית ואינה דורשת התקנת R במחשב המקומי אך היא אינה תואמת 100% ל- GNU R
  • ניתן להשתמש ב- Rserve לצורך ביצוע קוד R בשרת מרוחק
  • FastR מאפשר שילוב חלק עם Java אך הופך את הקוד שלנו לתלוי ב- VM ואינו זמין לכל מערכת הפעלה

כמו תמיד, כל הקוד המשמש במדריך זה זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found