public static RResult[] kMeansClustering( String[] inputNames, Object[][] inputValues, boolean showWarnings, int numberOfClusters, int iterations)throws RemoteException
{
RResult [] kClusteringResult = null;
RConnection rConnection = null;
try
{
rConnection = getRConnection();
requestScriptAccess(rConnection); // doing this because the eval() call below is not safe
int []noOfClusters = new int [1];
noOfClusters[0] = numberOfClusters;
int[]iterationNumber = new int[1];
iterationNumber[0] = iterations;
rConnection.assign("clusternumber", noOfClusters);
//storing column length
int columnLength = inputValues[0].length;
//to check if columns are not empty and if all columns are of the same length
for (int j = 1; j < inputValues.length; j++)
{
if (columnLength == 0 || inputValues[j].length == 0)
throw new RemoteException("Unable to run computation on zero-length arrays.");
if (inputValues[j].length != columnLength)
throw new RemoteException("Unable to run computation on two arrays with different lengths (" + columnLength
+ " != " + inputValues[j].length + ").");
}
REXP evalValue;
String names = "";
// We have to send columns to R and receive them back to be sent once again to R
//enables 'n' number of columns to be sent
for (int i = 0; i < inputNames.length; i++)
{
String name = inputNames[i];
if(names.length() != 0){
names = names + "," + name;}
else{
names = name;
}
double[] value = ListUtils.copyDoubleArray(inputValues[i], new double[inputValues[i].length]);
rConnection.assign(name, value);
}
evalValue = rConnection.eval("data.frame(" + names + ")"); // NOT SAFE - script was built using user-specified strings
rConnection.assign("frame",evalValue);
rConnection.assign("clusternumber", noOfClusters);
rConnection.assign("iterations",iterationNumber);
//String script = "Clus <- kmeans(frame, "+numberOfClusters+","+iterations+")";
// String clusteringScript = "Clustering <- function(dframe, clusternumber, iterations)\n" +
// "{result1 <- kmeans(dframe, clusternumber, iterations)\n " +
// "result2 <- kmeans(dframe, clusternumber, (iterations - 1))\n " +
// "while(result1$totss != result2$totss)\n"+
// "{iterations <- iterations + 1 \n " +
// "result1 <- kmeans(dframe, clusternumber, iterations)\n " +
// "result2 <- kmeans(dframe, clusternumber, (iterations - 1))\n }" +
// "print(result1)" +
// "print(result2)" +
// "}" +
// "KCluResult <- Clustering(frame,clusternumber, iterations)";
String clusteringScript = "KClusResult <- kmeans(frame, clusternumber,iterations)";
int i = 0;
String[] outputNames = {"KClusResult$cluster", "KClusResult$centers"};
evalScript(rConnection, clusteringScript, showWarnings);
int iterationTimes = outputNames.length;
kClusteringResult = new RResult[outputNames.length];
for (; i < iterationTimes; i++)
{
String name;
// Boolean addedTolist = false;
if (iterationTimes == outputNames.length + 1){
name = outputNames[i - 1];
}
else{
name = outputNames[i];
}
// Script to get R - output
evalValue = evalScript(rConnection, name, showWarnings);
// System.out.println(evalValue);
if (evalValue.isVector()){
if (evalValue instanceof REXPString)
kClusteringResult[i] = new RResult(name, evalValue.asStrings());
else if (evalValue instanceof REXPInteger)
kClusteringResult[i] = new RResult(name, evalValue.asIntegers());
else if (evalValue instanceof REXPDouble){
if (evalValue.dim() == null)
kClusteringResult[i] = new RResult(name, evalValue.asDoubles());
else
kClusteringResult[i] = new RResult(name, evalValue.asDoubleMatrix());
}
else{
// if no previous cases were true, return debug String
kClusteringResult[i] = new RResult(name, evalValue.toDebugString());
}
}
else{
kClusteringResult[i] = new RResult(name, evalValue.toDebugString());
}
}
}
catch (Exception e)
{
e.printStackTrace();
throw new RemoteException("Unable to run R K-Means Clustering script", e);
}
finally
{
if (rConnection != null)
rConnection.close();
}
return kClusteringResult;
}