내용 |
자바 웹어플리케이션에서 R이용하기
1. R을 설치하고 rJava 패키지를 설치해야 합니다.
install.packages("rJava")
-> C:\Program Files\R\R-3.3.1\library\rJava 에 패키지 설치됨
2. R_HOME과 PATH환경변수를 설정해야 합니다.
R_HOME
C:\Program Files\R\R-3.3.1
PATH
;C:\Program Files\R\R-3.3.1\bin\x64;C:\Program Files\R\R-3.3.1\library\rJava\jri\x64
3. C:\Program Files\R\R-3.3.1\library\rJava\jri\JRI.jar 파일을 WEB-INF\lib 폴더에 복사해주세요.
주의 : 이렇게 하면 컨텍스트 리로드 시 서버가 강제 종료됩니다. 그러므로 re-loadable 클래스들이 변경되었을 경우 서버를 다시 실행시켜 주세요.
* 참고할 자바 소스코드 위치
C:\Program Files\R\R-3.3.1\library\rJava\jri\examples
4. 예제 코드
package kr.co.javaspecialist.iris.model;
import java.util.ArrayList;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
public class IrisService {
//Rengine API : http://rforge.net/org/doc/org/rosuda/JRI/Rengine.html
private static final Rengine re = new Rengine(null, false, null);
public ArrayList<IrisVO> getAvgPetalBySpecies() {
ArrayList<IrisVO> irisList = new ArrayList<>();
try {
String[] species = {"setosa", "versicolor", "virginica"};
REXP result = re.eval("tapply(iris$Petal.Length, iris$Species, mean)");
REXP result2 = re.eval("tapply(iris$Petal.Width, iris$Species, mean)");
double resultList[] = result.asDoubleArray();
double resultList2[] = result2.asDoubleArray();
for(int i=0; i<resultList.length; i++) {
IrisVO iris = new IrisVO();
iris.setSpecies(species[i]);
iris.setPetalLength(resultList[i]);
iris.setPetalWidth(resultList2[i]);
irisList.add(iris);
}
} catch (Exception e) {
System.out.println("EX:"+e);
throw new RuntimeException(e);
}
return irisList;
}
@Override
protected void finalize() throws Throwable {
re.end();
}
}
5. Iris 데이터 분석하기 - VO 클래스
package kr.co.javaspecialist.iris.model;
public class IrisVO {
private String species;
private double sepalLength;
private double sepalWinth;
private double petalLength;
private double petalWidth;
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public double getSepalLength() {
return sepalLength;
}
public void setSepalLength(double sepalLength) {
this.sepalLength = sepalLength;
}
public double getSepalWinth() {
return sepalWinth;
}
public void setSepalWinth(double sepalWinth) {
this.sepalWinth = sepalWinth;
}
public double getPetalLength() {
return petalLength;
}
public void setPetalLength(double petalLength) {
this.petalLength = petalLength;
}
public double getPetalWidth() {
return petalWidth;
}
public void setPetalWidth(double petalWidth) {
this.petalWidth = petalWidth;
}
}
6. Iris 데이터 분석하기 - Service 클래스
package kr.co.javaspecialist.iris.model;
import java.util.ArrayList;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
public class IrisService {
// 1) we pass the arguments from the command line
// 2) we won't use the main loop at first, we'll start it later
// (that's the "false" as second argument)
// 3) the callbacks are null
// 4) Rengine API : http://rforge.net/org/doc/org/rosuda/JRI/Rengine.html
private static final Rengine re = new Rengine(null, false, null);
public ArrayList<IrisVO> getAvgPetalBySpecies() {
ArrayList<IrisVO> irisList = new ArrayList<>();
try {
String[] species = {"setosa", "versicolor", "virginica"};
REXP result = re.eval("tapply(iris$Petal.Length, iris$Species, mean)");
REXP result2 = re.eval("tapply(iris$Petal.Width, iris$Species, mean)");
double resultList[] = result.asDoubleArray();
double resultList2[] = result2.asDoubleArray();
for(int i=0; i<resultList.length; i++) {
IrisVO iris = new IrisVO();
iris.setSpecies(species[i]);
iris.setPetalLength(resultList[i]);
iris.setPetalWidth(resultList2[i]);
irisList.add(iris);
}
} catch (Exception e) {
System.out.println("EX:"+e);
throw new RuntimeException(e);
}
return irisList;
}
@Override
protected void finalize() throws Throwable {
re.end();
}
}
7. Iris 데이터 분석하기 - 컨트롤러
package kr.co.javaspecialist.iris.controller;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import kr.co.javaspecialist.common.controller.CommandHandler;
import kr.co.javaspecialist.iris.model.IrisService;
import kr.co.javaspecialist.iris.model.IrisVO;
public class IrisMeanController implements CommandHandler {
IrisService service = new IrisService();
@Override
public String process(HttpServletRequest request, HttpServletResponse response) {
ArrayList<IrisVO> irisList = service.getAvgPetalBySpecies();
Gson gson = new Gson();
String irisData = gson.toJson(irisList);
request.setAttribute("irisData", irisData);
String view = "/iris/iris_chart.jsp";
return view;
}
}
8. Iris 데이터 분석하기 - JSP 파일
<%@ page contentType="text/html; charset=UTF-8" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:setBundle basename="i18n/iris" />
<%@ taglib prefix="datatables" uri="http://github.com/dandelion/datatables" %>
<!DOCTYPE html>
<html>
<jsp:include page="/WEB-INF/view/include/staticFiles.jsp"/>
<style>
#chartdiv {
width: 100%;
height: 500px;
}
</style>
<!-- Resources -->
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
<link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<!-- Chart code -->
<script>
var chart = AmCharts.makeChart("chartdiv", {
"theme": "light",
"type": "serial",
"dataProvider": <%= request.getAttribute("irisData") %>,
"valueAxes": [{
"stackType": "3d",
"unit": "",
"position": "left",
"title": "Petal Average",
}],
"startDuration": 1,
"graphs": [{
"balloonText": "Average of Petal.Width [[category>: <b>[[value></b>",
"fillAlphas": 0.5,
"lineAlpha": 0.2,
"title": "Petal.Width",
"type": "column",
"valueField": "petalWidth"
}, {
"balloonText": "Average of Petal.Length [[category>: <b>[[value></b>",
"fillAlphas": 0.6,
"lineAlpha": 0.2,
"title": "Petal.Length",
"type": "column",
"valueField": "petalLength"
}],
"plotAreaFillAlphas": 0.1,
"depth3D": 60,
"angle": 30,
"categoryField": "species",
"categoryAxis": {
"gridPosition": "start"
},
"export": {
"enabled": true
}
});
jQuery('.chart-input').off().on('input change',function() {
var property = jQuery(this).data('property');
var target = chart;
chart.startDuration = 0;
if ( property == 'topRadius') {
target = chart.graphs[0];
if ( this.value == 0 ) {
this.value = undefined;
}
}
target[property] = this.value;
chart.validateNow();
});
</script>
<body>
<jsp:include page="/WEB-INF/view/include/bodyHeader.jsp"/>
<div class="container">
<div class="pg-opt">
<div class="row">
<div class="col-md-6 pc">
<h2><fmt:message key="IRIS"/></h2>
</div>
<div class="col-md-6">
<ol class="breadcrumb">
<li><fmt:message key="IRIS"/></li>
<li class="active"><fmt:message key="IRIS_CHART"/></li>
</ol>
</div>
</div>
</div>
<div class="content">
<div id="chartdiv"></div>
</div>
</div>
<jsp:include page="/WEB-INF/view/include/footer.jsp"/>
</body>
</html>
9. Iris 데이터 분석하기 - 실행 URL
http://localhost:8080/WebMVCProjectTemplate/iris/test.do
내 홈페이지 메뉴에 추가한 내용
<c:if test="${sessionScope.userid eq 'heojk' }">
<li class="dropdown">
<fmt:setBundle basename="i18n/iris" var="iris"/>
<a href='<c:url value="/"/>' class="dropdown-toggle" data-toggle="dropdown"><fmt:message bundle="${iris}" key="R_TEST"/></a>
<ul class="dropdown-menu">
<li><a href="<c:url value='/iris/test.do'/>"><fmt:message bundle="${iris}" key="IRIS"/></a>
</ul>
</li>
</c:if>
10. 자바에서 R 로 데이터 전달하기 예
double data[] = {1.2, 2.3, 4.5,5.5};
long xp = engine.rniPutDoubleArray(data);
engine.rniAssign("a", xp, 0);
REXP x;
x = engine.eval("a")
|