4

I'm using renjin and I'm trying to use values I generated in the java code with the r-code, for instance:

int x = 7;

try
{
   engine.eval("tmp<-c(x, 4)");
   engine.eval("print(tmp)");
}
catch (ScriptException ex) 
{
   ;
}

However, this does not work, as the engine apparently cannot work with x. Is there an easy way to solve this?

Yehoshaphat Schellekens
  • 2,305
  • 2
  • 22
  • 49
newnewbie
  • 993
  • 2
  • 11
  • 26
  • 1
    Can you concatenate x into the string as a literal value? ie, `engine.eval("tmp<-c(" + x + ", 4)");` – Kon Aug 15 '13 at 06:36
  • Yes that works fine, could you please write this as an answer so I can vote. But please, WHY does this work? – newnewbie Aug 15 '13 at 06:44
  • 1
    Basically, there is a difference between the _Java_ variable `x`, and an _R_ variable `x`. If you just `eval` a plain string, its contents are taken to be pure R code, so `x` will be interpreted as referring to an R object (which doesn't exist). You have to insert the contents of your Java object into the string, before eval'ing it. – Hong Ooi Aug 15 '13 at 07:00

2 Answers2

6

Renjin uses the javax.script interface, for which gives you a lot of power to interact with the R environment. See the documentation here: http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/

To set variables within R's global environment, you can use the put() method. Here are some examples:

engine.put("x", 4);
engine.put("y", new double[] { 1d, 2d, 3d, 4d });
engine.put("z", new org.renjin.sexp.DoubleArrayVector(1,2,3,4,5));
engine.put("obj", new HashMap());

Renjin will implicitly convert primitives, arrays of primitives, and java.lang.String instances to R objects. Java objects will be wrapped as R external objects.

From R code, Renjin allows you to manipulate Java objects using the $ operator, for example:

obj$put("a", 1)
obj$put("b", 2) 

print(obj$size())
print(obj$get("b"))

You can also provide your own implementations of R objects by extending the classes in the org.renjin.sexp package. For example:

public class MyDoubleVector extends DoubleVector {

  public double getElementAsDouble(int index) {
       // lookup value in database
       return index;
  }

  public int length() {
       // query length in database
       return length;
  }
}
akbertram
  • 1,330
  • 10
  • 16
3

You can concatenate the variable into the string as a literal, as I posted in the comment:

engine.eval("tmp<-c(" + x + ", 4)");

This works because (I'm assuming) the engine needs to evaluate literal expressions (with number values instead of variable), and the above expression essentially passes tmp<-c(7, 4) through concatenation (combination) of the strings and integer value. I would try also first running a command to store a variable and then reference it, ie:

engine.eval(x <- 7);

Then try your original expression. I'm not familiar with Renjin, though, so it's a bit of a shot in the dark.

Kon
  • 10,702
  • 6
  • 41
  • 58
  • Seems to have been a very good shot in the dark, one which I would not have made too, as it had escaped my notice that you can pass on literal expressions with the two plusses. THANK YOU.Really Saved me a lot of work. – newnewbie Aug 15 '13 at 07:05