3

I am running a scala application and would like to call a R file using Renjin and pass values to the R file from scala. When I load the R file from scala i get error on laply package not found. It would be great if some one could tell me how to load R packages into scala using Renjin.

Below is the code i used in scala to call R file using Renjin

  1. Copied the jar file with dependencies using the following command

    scala -cp renjin-script-engine-0.7.0-RC6-jar-with-dependencies.jar

  2. Now the scala interpreter started.

    import javax.script.; import org.renjin.sexp.;

    val factory = new ScriptEngineManager();

// create an R engine

val engine = factory.getEngineByName("Renjin");

// evaluate R script on disk

engine.eval(new java.io.FileReader("myscript.R"));

At this step it error cont not find function 'lapply'

How do i add packages to Renjin. Where do i add the class path.

Below is code for R file

score.sentiment = function (sentences, pos.words,neg.words, .progress='none')
{
  require(plyr)
  require(stringr)

  scores =  laply(sentences, function(sentence,pos.words,neg.words){

    sentence = gsub('[[:punct:]]','',sentence)
    sentence = gsub('[[:cntrl:]]','',sentence)
    sentence = gsub('\\d+','',sentence)
    sentence = tolower(sentence)

    word.list = str_split(sentence, '\\s+')
    words = unlist(word.list)

    pos.matches = match(words, pos.words)

    neg.matches = match(words, neg.words)

    pos.matches = !is.na(pos.matches)

    neg.matches = !is.na(neg.matches)

    score = sum(pos.matches) - sum (neg.matches)

    return(score)

  },pos.words, neg.words, .progress = .progress)

  scores.df = data.frame(score=scores, text=sentences)

  return(scores.df)

}

Second part of the question is how do I pass parameter from scala console to this R file.

For Example the Sentence here is a tweet. I would like to send it to R function from scala.

mjkallen
  • 468
  • 3
  • 12
Pawan
  • 1,954
  • 4
  • 21
  • 27

3 Answers3

1

I don't believe that plyr or stringr will work out of the box with Renjin. I haven't checked, but I think plyr works quite a bit of magic with GNU R's C Api, and Renjin seems to choke on some of stringr's test functions.

However, I don't think you'll need either package in the function above, just replace laply and str_split with sapply and strsplit respectively from the base package.

Once you've evaluated your function definition as you've done above, you can invoke this function from Scala/Java using the [invokeFunction](http://docs.oracle.com/javase/7/docs/api/javax/script/Invocable.html#invokeFunction(java.lang.String, java.lang.Object...)) method:

((Invocable)engine).invokeFunction("score.sentiment", 
       "Best pizza EVER!",
       new String[] { "best", "cool" },
       new String[] { "sucks", "awful" });

Renjin will convert the string arrays to StringVector objects (R character objects) but you can also create the StringVector objects yourself.

http://docs.oracle.com/javase/7/docs/api/javax/script/Invocable.html#invokeFunction(java.lang.String, java.lang.Object...)

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
akbertram
  • 1,330
  • 10
  • 16
0

I was able to use r packages in scala using jvmr. Below is a sample code.

package org.scala.rtest

import org.ddahl.jvmr.RInScala

object RIntegration {
    def main(args: Array[String]) {
       val R = RInScala()
       R>"""
            require(sparkR)

            score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
                {
                  require(plyr)
                  require(stringr)


                  scores = laply(sentences, function(sentence, pos.words, neg.words) {

                    # clean up sentences with R's regex-driven global substitute, gsub():

                    sentence = gsub('[[:punct:]]', '', sentence, ignore.case=T)

                    sentence = gsub('[[:cntrl:]]', '', sentence, ignore.case=T)

                    sentence = gsub('\\d+', '', sentence, ignore.case=T)

                    # and convert to lower case:

                    sentence = tolower(sentence)

                    # split into words. str_split is in the stringr package

                    word.list = str_split(sentence, '\\s+')

                    # sometimes a list() is one level of hierarchy too much

                    words = unlist(word.list)

                    # compare our words to the dictionaries of positive & negative terms

                    pos.matches = match(words, pos.words)
                    neg.matches = match(words, neg.words)

                    # match() returns the position of the matched term or NA
                    # we just want a TRUE/FALSE:

                    pos.matches = !is.na(pos.matches)

                    neg.matches = !is.na(neg.matches)

                    # and conveniently enough, TRUE/FALSE will be treated as 1/0 by sum():

                    score = sum(pos.matches) - sum(neg.matches)

                    return(score)

                  }, pos.words, neg.words, .progress=.progress )
                  scores.df = data.frame(score=scores, text=sentences)
                  return(scores.df)
                } 


       """

        R(" x <- scan('positive-words.txt',what='character',comment.char=';')")
        R(" y <- scan('negative-words.txt',what='character',comment.char=';')")
        R(" z <- scan('twitterstream1.txt', what='character' )")

        R.eval("df <- score.sentiment(z,x,y)")  
        println(R.capture("df"))

        }
}

Hope this helps some one.

Pawan
  • 1,954
  • 4
  • 21
  • 27
0

Java:

Build a version of the package specifically compiled for renjin. Then add it to your classpath using maven or another build tool.

Check out the Introduction at Renjin documentation for more information:

http://docs.renjin.org/en/latest/introduction.html#using-cran-packages-in-renjin

hilzj
  • 68
  • 10