2013-09-02 3 views
2

Я пытаюсь вызвать некоторые г кода внутри Java, довольно много, как это:Заговор в R с помощью Java - работает, но не может найти участок

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()); 
    } 

} 

Ну, я получаю «Скрипт выполнен» печать ,

Мои (ну, на самом деле не моя, просто чтобы проверить) г-код достаточно прост, в значительной степени просто, чтобы увидеть это работает на всех:

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

Таким образом, он не должен делать гораздо больше, чем сюжет синус.

Однако не должно быть какого-то всплывающего окна, где вы можете увидеть сюжет? т.к. нет. Что я делаю не так?

Edit: В ответ на замечания, которые я получил здесь я редактировал г-файл, добавив:

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

к нему.

Однако, если я попытаюсь найти rplot.jpg на моей системе, ее просто нет.

+2

Возможно, вы должны явно объявить новое устройство для сюжета. В OSX функция 'quartz', в Windows это' windows', on * nix Я считаю, что вы хотите 'X11'. Возможно, имеет смысл сохранить график в файле, используя, например, 'png', а затем открыть файл с Java. –

+0

Вы также можете взглянуть на [rJava] (http: //www.rforge.net/rJava /) или [Rcaller] (http://www.mhsatman.com/rcaller.php), последний из которых имеет явную поддержку построения, а не ручное обращение к исполняемому файлу R. – chrylis

+0

Я посмотрел на них обоих. Проблема в том, что jar должен быть исполняемым на windows AND linux, и я просто не справился с этим. – newnewbie

ответ

2

Вы передали относительный каталог функции jpeg. Это делает его относительно текущего рабочего каталога R (значение возвращается getwd).

Попробуйте напечатать это значение, чтобы увидеть, где именно (на Windows, по умолчанию он находится в «Моих документах» для текущего пользователя)

print(getwd()) 

или пропускание абсолютного пути к jpeg.

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

Чтобы получить абсолютный путь, используйте pathological::standardize_path или R.utils::getAbsolutePath.

+0

Это, кажется, проблема. Однако как мне найти этот абсолютный путь (без повторного использования runtime.exec)? Я полагаю, в зависимости от компьютера, который пользователь использует, чтобы открыть банку, скрипт (в комплекте с банкой) также будет в другой папке, не так ли? – newnewbie

+0

У меня есть странная идея .... Я мог на самом деле, как только пользователь запустит программу, создайте эти r-скрипты на компьютере пользователя. Думаю, это сработает, но разумно ли это решение? – newnewbie

1

Вы можете ждать Process (exec возвращает Process объект), чтобы закончить с waitFor и проверить значение выхода: оно должно быть 0.

Если он не равен нулю, то, вероятно, нужно указать путь сценария.

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"); 
} 

Если значение выхода не 0, вы можете посмотреть на стандартный вывод и стандартный поток ошибок процесса, как предложено в комментарии Эндрю.

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"); 
} 

Как упоминалось в комментариях, вам нужно явно открыть устройство. Поскольку он закрыт, когда скрипт завершается, вам также необходимо добавить задержку.

x11() # Open a device (also works on Windows) 
plot(rnorm(10)) 
Sys.sleep(10) # Wait 10 seconds 
+0

Не было никакого преступления, но что это за «устройство»? – newnewbie

+0

'device' относится к типу графического вывода, например, к окну, PNG-файлу, PDF-файлу и т. Д.' X11() 'и' windows() 'эквивалентны и открывают окно для отображения графиков. Проверьте '? Устройство'. –

+0

Иногда я мог бы просто ..... Я знаю, что в моем r-skript нет ошибки, потому что тот же самый скрипт работает при использовании через командную строку. Я знаю, что абсолютный путь - это коррект, и я ВСЕГО начинаю/ошибаюсь. У кого-нибудь есть идея? – newnewbie