Question

I am trying to invoke some r code from within Java,pretty much like this:

private void makeMatrix() throws ScriptException {
    try {
        Runtime.getRuntime().exec(" Rscript firstscript.r");
        System.out.println("Script executed");
         } catch (IOException ex) {
       System.out.println("Exception");
       System.out.println(ex.getMessage());
    }

}

Well, I get the "Script executed" print.

My (well, not really mine, just to test) r-Code is fairly simple, pretty much just to see it works at all:

x=seq(0,2,by=0.01)
y=2*sin(2*pi*(x-1/4))
plot(x,y)

So, it should not do much more than plot a sinus.

However, should not there be some kind of popup where you can actually see the plot? because there is none. What am I doing wrong?

Edit: In response to the comments I got here I edited the r-file, adding:

jpeg('rplot.jpg')
plot(x,y)
dev.off()

to it.

However, If I then try to find rplot.jpg on my system it simply is not there.

Was it helpful?

Solution

You passed a relative directory to the jpeg function . This makes it relative to R's current working directory (the value returned by getwd).

Try printing this value to see where that is (on Windows, by default it's in "My Documents" for the current user)

print(getwd())

or passing an absolute path to jpeg.

jpeg('c:/rplot.jpg')
plot(x,y)
dev.off()

To get an absolute path, use pathological::standardize_path or R.utils::getAbsolutePath.

OTHER TIPS

You can wait for the Process (exec returns a Process object) to finish with waitFor, and check the exit value: it should be 0.

If it is not zero, you probably need to specify the path of the script.

public static void main( String[] args ) throws IOException, InterruptedException {
    Process p = Runtime.getRuntime().exec("Rscript /tmp/test.R");
    System.out.println("Started");
    p.waitFor();
    if( p.exitValue() != 0 )
        System.out.println("Something went wrong");
    else 
        System.out.println("Finished");
}

If the exit value is not 0, you can look at the stdout and stderr of the process, as suggested in Andrew's comment.

public static void main(String[] args) throws IOException, InterruptedException {
    System.out.println("test...");
    Process p = Runtime.getRuntime().exec(new String[] {
        "Rscript",
        "-e",
        "print(rnorm(5)))" // Intentional error, to produce an error message
    } );
    System.out.println("Started");

    String line = null;

    System.out.println("Stdout:");
    BufferedReader stdout = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
    while ( (line = stdout.readLine()) != null)
        System.out.println(line);

    System.out.println("Stderr:");
    BufferedReader stderr = new BufferedReader( new InputStreamReader( p.getErrorStream() ) );
    while ( (line = stderr.readLine()) != null)
        System.out.println(line);

    p.waitFor();
    if( p.exitValue() != 0 )
        System.out.println("Something went wrong, exit value=" + p.exitValue());
    else 
        System.out.println("Finished");
}

As mentionned in the comments, you need to explicitly open the device. Since it is closed when the script terminates, you also need to add a delay.

x11() # Open a device (also works on Windows)
plot( rnorm(10) )
Sys.sleep(10) # Wait 10 seconds
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top