1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package ubic.basecode.util.r;
20
21 import org.apache.commons.collections4.Transformer;
22 import org.apache.commons.collections4.functors.StringValueTransformer;
23 import org.apache.commons.lang3.ArrayUtils;
24 import org.apache.commons.lang3.RandomStringUtils;
25 import org.apache.commons.lang3.StringUtils;
26 import org.rosuda.REngine.*;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import ubic.basecode.dataStructure.matrix.DoubleMatrix;
30 import ubic.basecode.dataStructure.matrix.ObjectMatrix;
31 import ubic.basecode.dataStructure.matrix.ObjectMatrixImpl;
32 import ubic.basecode.math.linearmodels.LinearModelSummary;
33 import ubic.basecode.math.linearmodels.OneWayAnovaResult;
34 import ubic.basecode.math.linearmodels.TwoWayAnovaResult;
35 import ubic.basecode.util.Configuration;
36
37 import java.io.BufferedReader;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.util.*;
42
43
44
45
46
47
48
49 public abstract class AbstractRClient implements RClient {
50
51 protected static Logger log = LoggerFactory.getLogger( AbstractRClient.class );
52
53
54
55
56
57 public static String variableIdentityNumber( Object ob ) {
58 return Integer.toString( Math.abs( ob.hashCode() + 1 ) ) + RandomStringUtils.insecure().nextAlphabetic( 6 );
59 }
60
61
62
63
64
65
66
67
68 private static double[] unrollMatrix( double[][] matrix ) {
69 int rows = matrix.length;
70 int cols = matrix[0].length;
71 double[] unrolledMatrix = new double[rows * cols];
72
73 int k = 0;
74 for ( int i = 0; i < rows; i++ ) {
75 for ( int j = 0; j < cols; j++ ) {
76 unrolledMatrix[k] = matrix[i][j];
77 k++;
78 }
79 }
80 return unrolledMatrix;
81 }
82
83
84
85
86
87
88
89
90 private static double[] unrollMatrix( DoubleMatrix<?, ?> matrix ) {
91
92
93
94
95 int rows = matrix.rows();
96 int cols = matrix.columns();
97 double[] unrolledMatrix = new double[rows * cols];
98
99 int k = 0;
100 for ( int i = 0; i < rows; i++ ) {
101 for ( int j = 0; j < cols; j++ ) {
102 unrolledMatrix[k] = matrix.get( i, j );
103 k++;
104 }
105 }
106 return unrolledMatrix;
107 }
108
109
110
111
112
113
114 @Override
115 public String assignFactor( List<String> strings ) {
116 String variableName = "f." + variableIdentityNumber( strings );
117 return assignFactor( variableName, strings );
118 }
119
120
121
122
123
124
125 @Override
126 public String assignFactor( String factorName, List<String> list ) {
127 String l = assignStringList( list );
128 this.voidEval( factorName + "<-factor(" + l + ")" );
129 return factorName;
130 }
131
132
133
134
135
136
137 @Override
138 public String assignMatrix( double[][] matrix ) {
139 String matrixVarName = "Matrix_" + variableIdentityNumber( matrix );
140 log.debug( "Assigning matrix with variable name " + matrixVarName );
141 int rows = matrix.length;
142 int cols = matrix[0].length;
143 if ( rows == 0 || cols == 0 ) throw new IllegalArgumentException( "Empty matrix?" );
144 double[] unrolledMatrix = unrollMatrix( matrix );
145 this.assign( "U" + matrixVarName, unrolledMatrix );
146 this.voidEval( matrixVarName + "<-matrix(" + "U" + matrixVarName + ", nrow=" + rows + " , ncol=" + cols
147 + ", byrow=TRUE)" );
148 this.voidEval( "rm(U" + matrixVarName + ")" );
149
150 return matrixVarName;
151 }
152
153
154
155
156
157
158 @Override
159 public String assignMatrix( DoubleMatrix<?, ?> matrix ) {
160 return assignMatrix( matrix, StringValueTransformer.stringValueTransformer() );
161 }
162
163
164
165
166
167
168
169 @Override
170 public String assignMatrix( DoubleMatrix<?, ?> matrix, Transformer rowNameExtractor ) {
171 String matrixVarName = "Matrix_" + variableIdentityNumber( matrix );
172 log.debug( "Assigning matrix with variable name " + matrixVarName );
173 int rows = matrix.rows();
174 int cols = matrix.columns();
175 if ( rows == 0 || cols == 0 ) throw new IllegalArgumentException( "Empty matrix?" );
176 double[] unrolledMatrix = unrollMatrix( matrix );
177 assert ( unrolledMatrix != null );
178 this.assign( "U" + matrixVarName, unrolledMatrix );
179 this.voidEval( matrixVarName + "<-matrix(" + "U" + matrixVarName + ", nrow=" + rows + ", ncol=" + cols
180 + ", byrow=TRUE)" );
181 this.voidEval( "rm(U" + matrixVarName + ")" );
182
183 if ( matrix.hasColNames() && matrix.hasRowNames() )
184 assignRowAndColumnNames( matrix, matrixVarName, rowNameExtractor );
185 return matrixVarName;
186 }
187
188
189
190
191
192
193 @Override
194 public String assignStringList( List<?> strings ) {
195 String variableName = "stringList." + variableIdentityNumber( strings );
196
197 Object[] array = strings.toArray();
198 String[] sa = new String[array.length];
199 for ( int i = 0; i < array.length; i++ ) {
200 sa[i] = array[i].toString();
201 }
202
203 assign( variableName, sa );
204 return variableName;
205 }
206
207
208
209
210
211
212 @Override
213 public boolean booleanDoubleArrayEval( String command, String argName, double[] arg ) {
214 this.assign( argName, arg );
215 REXP x = this.eval( command );
216 if ( x.isLogical() ) {
217 try {
218 REXPLogical b = new REXPLogical( new boolean[1], new REXPList( x.asList() ) );
219 return b.isTRUE()[0];
220 } catch ( REXPMismatchException e ) {
221 throw new RuntimeException( e );
222 }
223 }
224 return false;
225 }
226
227
228
229
230
231
232 @Override
233 public String dataFrame( ObjectMatrix<String, String, Object> matrix ) {
234
235
236
237
238
239 List<String> colNames = matrix.getColNames();
240 List<String> rowNames = matrix.getRowNames();
241
242 assert colNames.size() == matrix.columns();
243
244 String colV = assignStringList( colNames );
245 String rowV = assignStringList( rowNames );
246
247 List<String> terms = new ArrayList<String>();
248 for ( int j = 0; j < colNames.size(); j++ ) {
249
250 Object[] column;
251
252 Object v = matrix.getEntry( 0, j );
253
254 if ( v instanceof Number ) {
255 column = new Double[matrix.rows()];
256 } else if ( v instanceof Boolean ) {
257 column = new String[matrix.rows()];
258 } else if ( v instanceof String ) {
259 column = new String[matrix.rows()];
260 } else {
261 throw new IllegalArgumentException( "Sorry, can't make data frame from values of type "
262 + v.getClass().getName() );
263 }
264
265 for ( int i = 0; i < matrix.rows(); i++ ) {
266
267 Object value = matrix.getEntry( i, j );
268
269 if ( matrix.isMissing( i, j ) ) {
270 column[i] = null;
271 } else if ( value instanceof Number ) {
272 column[i] = ( ( Number ) value ).doubleValue();
273 } else if ( value instanceof Boolean ) {
274 column[i] = ( ( Boolean ) value ) ? "T" : "F";
275 } else if ( value instanceof String ) {
276 column[i] = value;
277 }
278 }
279
280 if ( v instanceof Number ) {
281 assign( colNames.get( j ), ArrayUtils.toPrimitive( ( Double[] ) column ) );
282 terms.add( colNames.get( j ) );
283 } else if ( v instanceof Boolean ) {
284 assignFactor( colNames.get( j ), Arrays.asList( ( String[] ) column ) );
285 terms.add( colNames.get( j ) );
286 } else if ( v instanceof String ) {
287 assignFactor( colNames.get( j ), Arrays.asList( ( String[] ) column ) );
288 terms.add( colNames.get( j ) );
289 }
290
291 }
292
293 String varName = "df." + variableIdentityNumber( matrix );
294
295 String command = varName + "<-data.frame(" + StringUtils.join( terms, "," ) + ", row.names=" + rowV + " )";
296 log.debug( command );
297 eval( command );
298 eval( "names(" + varName + ")<-" + colV );
299
300 return varName;
301
302 }
303
304 @Override
305 public ObjectMatrix<String, String, Object> dataFrameEval( String command ) {
306
307 REXP df = eval( command );
308
309 try {
310
311 RList dfl = df.asList();
312
313 if ( !df.getAttribute( "class" ).asString().equals( "data.frame" ) ) {
314 throw new IllegalArgumentException( "Command did not return a dataframe" );
315 }
316
317 String[] rowNames = df.getAttribute( "row.names" ).asStrings();
318 String[] colNames = df.getAttribute( "names" ).asStrings();
319
320 assert dfl.size() == colNames.length;
321
322 ObjectMatrix<String, String, Object> result = new ObjectMatrixImpl<String, String, Object>(
323 rowNames.length, colNames.length );
324
325 result.setRowNames( Arrays.asList( rowNames ) );
326 result.setColumnNames( Arrays.asList( colNames ) );
327
328 for ( int i = 0; i < dfl.size(); i++ ) {
329 REXP column = ( REXP ) dfl.get( i );
330
331 if ( column.isNumeric() ) {
332 double[] asDoubles = column.asDoubles();
333
334 for ( int j = 0; j < rowNames.length; j++ ) {
335 result.set( j, i, asDoubles[j] );
336 }
337
338 } else {
339 String[] asStrings = column.asStrings();
340
341 for ( int j = 0; j < rowNames.length; j++ ) {
342 result.set( j, i, asStrings[j] );
343 }
344
345 }
346
347 }
348
349 return result;
350 } catch ( REXPMismatchException e ) {
351
352 throw new RuntimeException( e );
353
354 }
355
356 }
357
358 public abstract void disconnect();
359
360
361
362
363
364
365 @Override
366 public double[] doubleArrayDoubleArrayEval( String command, String argName, double[] arg ) {
367 try {
368 this.assign( argName, arg );
369 RList l = this.eval( command ).asList();
370 return l.at( argName ).asDoubles();
371 } catch ( REXPMismatchException e ) {
372 throw new RuntimeException( e );
373 }
374 }
375
376
377
378
379
380
381 @Override
382 public double[] doubleArrayEval( String command ) {
383 REXP r = this.eval( command );
384 if ( r == null ) {
385 return null;
386 }
387
388 if ( !r.isNumeric() ) {
389 throw new RuntimeException( "Command did not return numbers: " + command + ", result was: " + r );
390 }
391
392 try {
393 return r.asDoubles();
394 } catch ( REXPMismatchException e ) {
395 throw new RuntimeException( e );
396 }
397 }
398
399
400
401
402
403
404
405 @Override
406 public double[] doubleArrayTwoDoubleArrayEval( String command, String argName, double[] arg, String argName2,
407 double[] arg2 ) {
408 this.assign( argName, arg );
409 this.assign( argName2, arg2 );
410 try {
411 return this.eval( command ).asDoubles();
412 } catch ( REXPMismatchException e ) {
413 throw new RuntimeException( e );
414 }
415 }
416
417
418
419
420
421
422
423 @Override
424 public double doubleTwoDoubleArrayEval( String command, String argName, double[] arg, String argName2, double[] arg2 ) {
425 this.assign( argName, arg );
426 this.assign( argName2, arg2 );
427 REXP x = this.eval( command );
428 try {
429 return x.asDouble();
430 } catch ( REXPMismatchException e ) {
431 throw new RuntimeException( e );
432 }
433 }
434
435
436
437
438
439
440 @Override
441 public int[] intArrayEval( String command ) {
442 try {
443 return eval( command ).asIntegers();
444 } catch ( REXPMismatchException e ) {
445 throw new RuntimeException( e );
446 }
447 }
448
449
450
451
452
453
454 @Override
455 @SuppressWarnings({ "unchecked" })
456 public LinearModelSummary linearModel( double[] data, Map<String, List<?>> factors ) {
457
458 String datName = RandomStringUtils.insecure().nextAlphabetic( 10 );
459 assign( datName, data );
460
461 for ( String factorName : factors.keySet() ) {
462 List<?> list = factors.get( factorName );
463 if ( list.iterator().next() instanceof String ) {
464 assignFactor( factorName, ( List<String> ) list );
465 } else {
466
467 List<Double> d = new ArrayList<Double>();
468 for ( Object object : list ) {
469 d.add( ( Double ) object );
470 }
471
472 assign( factorName, ArrayUtils.toPrimitive( d.toArray( new Double[] {} ) ) );
473 }
474 }
475
476 String modelDeclaration = datName + " ~ " + StringUtils.join( factors.keySet(), "+" );
477
478 String lmName = RandomStringUtils.insecure().nextAlphabetic( 10 );
479 String command = lmName + "<-lm(" + modelDeclaration + ", na.action=na.exclude)";
480 log.debug( command );
481 voidEval( command );
482
483 REXP lmsum = eval( "summary(" + lmName + ")" );
484 REXP anova = eval( "anova(" + lmName + ")" );
485
486 try {
487 return new LinearModelSummaryImpl( datName, lmsum, anova, factors.keySet().toArray( new String[] {} ) );
488 } catch ( REXPMismatchException e ) {
489 throw new RuntimeException( e );
490 }
491 }
492
493
494
495
496
497
498 @Override
499 public LinearModelSummary linearModel( double[] data, ObjectMatrix<String, String, Object> d ) {
500
501 String datName = RandomStringUtils.insecure().nextAlphabetic( 10 );
502 assign( datName, data );
503
504 String df = dataFrame( d );
505
506 String varNames = StringUtils.join( d.getColNames(), "+" );
507
508 String lmName = RandomStringUtils.insecure().nextAlphabetic( 10 );
509 String command = lmName + "<-lm(" + datName + " ~ " + varNames + ", data=" + df + ", na.action=na.exclude)";
510 voidEval( command );
511
512 REXP lmsum = eval( "summary(" + lmName + ")" );
513 REXP anova = eval( "anova(" + lmName + ")" );
514
515 try {
516 return new LinearModelSummaryImpl( datName, lmsum, anova, d.getColNames().toArray( new String[] {} ) );
517 } catch ( REXPMismatchException e ) {
518 throw new RuntimeException( e );
519 }
520 }
521
522
523
524
525 @Override
526 public List<?> listEval( Class<?> listEntryType, String command ) {
527
528 REXP rexp = this.eval( command );
529
530 List<Object> result = new ArrayList<Object>();
531 try {
532 if ( !rexp.isVector() ) {
533 throw new IllegalArgumentException( "Command did not return some kind of vector" );
534 }
535
536 if ( rexp instanceof REXPInteger ) {
537 log.debug( "integer" );
538 double[][] asDoubleMatrix = rexp.asDoubleMatrix();
539 for ( double[] ds : asDoubleMatrix ) {
540 result.add( ds );
541 }
542
543 if ( rexp instanceof REXPFactor ) {
544 log.info( "factor" );
545
546 }
547 } else if ( rexp instanceof REXPGenericVector ) {
548 log.debug( "generic" );
549 REXPGenericVector v = ( REXPGenericVector ) rexp;
550 List<?> tmp = new ArrayList<Object>( v.asList().values() );
551
552 if ( tmp.size() == 0 ) return tmp;
553
554 for ( Object t : tmp ) {
555 String clazz = ( ( REXP ) t ).getAttribute( "class" ).asString();
556
557
558
559 if ( clazz.equals( "htest" ) ) {
560 try {
561 result.add( new HTest( ( ( REXP ) t ).asList() ) );
562 } catch ( REXPMismatchException e ) {
563 result.add( new HTest() );
564 }
565 } else if ( clazz.equals( "lm" ) ) {
566 throw new UnsupportedOperationException();
567 } else {
568 result.add( new HTest() );
569 }
570
571
572
573 }
574
575 } else if ( rexp instanceof REXPDouble ) {
576 log.debug( "double" );
577 double[][] asDoubleMatrix = rexp.asDoubleMatrix();
578 for ( double[] ds : asDoubleMatrix ) {
579 result.add( ds );
580 }
581
582 } else if ( rexp instanceof REXPList ) {
583 log.debug( "list" );
584 if ( rexp.isPairList() ) {
585
586 }
587
588 if ( rexp.isLanguage() ) {
589 throw new UnsupportedOperationException( "Don't know how to deal with vector type of "
590 + rexp.getClass().getName() );
591 }
592 log.debug( rexp.getClass().getName() );
593 result = new ArrayList<Object>( rexp.asList().values() );
594 } else {
595 throw new UnsupportedOperationException( "Don't know how to deal with vector type of "
596 + rexp.getClass().getName() );
597 }
598
599 return result;
600 } catch ( REXPMismatchException e ) {
601 throw new RuntimeException( e );
602 }
603
604 }
605
606
607
608
609
610
611 @Override
612 public boolean loadLibrary( String libraryName ) {
613 try {
614
615 String userLibPath = Configuration.getString( "rlibpath" );
616 if ( StringUtils.isNotBlank( userLibPath ) ) {
617 voidEval( ".libPaths(" + userLibPath + ")" );
618 }
619
620
621 List<String> libraries = stringListEval( "installed.packages()[,1]" );
622 if ( !libraries.contains( libraryName ) ) {
623 return false;
624 }
625 } catch ( Exception e ) {
626
627
628
629 log.warn( "Was unable to check for installed library before attempting to load it." );
630 }
631
632 try {
633 voidEval( "library(" + libraryName + ")" );
634 return true;
635 } catch ( Exception e ) {
636 return false;
637 }
638 }
639
640
641
642
643
644
645 @Override
646 public OneWayAnovaResult oneWayAnova( double[] data, List<String> factor ) {
647 String f = assignFactor( factor );
648 StringBuffer command = new StringBuffer();
649
650 assign( "foo", data );
651
652 String modelDeclaration;
653
654 modelDeclaration = "foo ~ " + f;
655
656 command.append( "anova(aov(" + modelDeclaration + "))" );
657
658 REXP eval = eval( command.toString() );
659
660 try {
661 return new OneWayAnovaResultImpl( "foo", eval );
662 } catch ( REXPMismatchException e ) {
663 throw new RuntimeException( e );
664 }
665 }
666
667
668
669
670
671
672 @Override
673 public Map<String, OneWayAnovaResult> oneWayAnovaEval( String command ) {
674 REXP rawResult = this.eval( command );
675
676 if ( rawResult == null ) {
677 return null;
678 }
679
680 Map<String, OneWayAnovaResult> result = new HashMap<String, OneWayAnovaResult>();
681 try {
682 RList mainList = rawResult.asList();
683 if ( mainList == null ) {
684 return null;
685 }
686
687 log.debug( mainList.size() + " results." );
688
689 for ( int i = 0; i < mainList.size(); i++ ) {
690
691 REXP anovaTable = mainList.at( i );
692
693 String elementIdentifier = mainList.keyAt( i );
694
695 assert elementIdentifier != null;
696
697 if ( log.isDebugEnabled() ) log.debug( "Key: " + elementIdentifier );
698
699 if ( !anovaTable.isList() || !anovaTable.hasAttribute( "row.names" ) ) {
700 log.debug( "No anovaresult for " + elementIdentifier );
701 result.put( elementIdentifier, new OneWayAnovaResultImpl( elementIdentifier ) );
702 continue;
703 }
704
705 result.put( elementIdentifier, new OneWayAnovaResultImpl( elementIdentifier, anovaTable ) );
706
707 }
708 } catch ( REXPMismatchException e ) {
709 throw new RuntimeException( e );
710 }
711
712 return result;
713
714 }
715
716
717
718
719
720
721 @Override
722 public void remove( String variableName ) {
723 this.voidEval( "rm(" + variableName + ")" );
724 }
725
726
727
728
729
730
731 @Override
732 public Map<String, LinearModelSummary> rowApplyLinearModel( String dataMatrixVarName, String modelFormula,
733 String[] factorNames ) {
734
735 String lmres = "lmlist." + RandomStringUtils.insecure().nextAlphanumeric( 10 );
736
737 log.info( "Starting model fitting ..." );
738
739 loadScript( this.getClass().getResourceAsStream( "/ubic/basecode/util/r/linearModels.R" ) );
740
741 String command = lmres + "<-rowlm(" + modelFormula + ", data.frame(" + dataMatrixVarName + ") )";
742
743 log.debug( command );
744 this.voidEval( command );
745
746 log.info( "Model fits complete, summarizing ..." );
747 REXP rawLmSummaries = this.eval( "lapply(" + lmres + ", function(x){ try(summary(x), silent=T)})" );
748
749 if ( rawLmSummaries == null ) {
750 log.warn( "No results from apply(... lm)" );
751 return null;
752 }
753
754 log.info( "Summaries done, doing hypothesis tests ..." );
755
756 REXP rawAnova = this.eval( "lapply(" + lmres + ", function(x){ try(anova(x), silent=T)})" );
757
758 Map<String, LinearModelSummary> result = new HashMap<String, LinearModelSummary>();
759 try {
760 log.info( "Processing the results ..." );
761
762 RList rawLmList = rawLmSummaries.asList();
763 if ( rawLmList == null ) {
764 log.warn( "Raw lm summary results were null" );
765 return null;
766 }
767
768 RList rawAnovaList = rawAnova.asList();
769 if ( rawAnovaList == null ) {
770 return null;
771 }
772
773 log.debug( rawLmList.size() + " results." );
774
775 assert rawLmList.size() == rawAnovaList.size();
776
777 for ( int i = 0; i < rawLmList.size(); i++ ) {
778
779 REXP lmSummary = rawLmList.at( i );
780 REXP anova = rawAnovaList.at( i );
781
782 String elementIdentifier = rawLmList.keyAt( i );
783
784 assert elementIdentifier != null;
785 assert elementIdentifier.equals( rawAnovaList.keyAt( i ) );
786
787 if ( log.isDebugEnabled() ) log.debug( "Key: " + elementIdentifier );
788
789 if ( !lmSummary.isList() || !lmSummary.getAttribute( "class" ).asString().equals( "summary.lm" ) ) {
790 log.debug( "No lm for " + elementIdentifier );
791 result.put( elementIdentifier, new LinearModelSummaryImpl( elementIdentifier ) );
792 } else {
793 LinearModelSummary linearModelSummary = new LinearModelSummaryImpl( elementIdentifier, lmSummary, anova, factorNames );
794 result.put( elementIdentifier, linearModelSummary );
795 }
796
797 }
798 } catch ( REXPMismatchException e ) {
799 throw new RuntimeException( e );
800 }
801
802 return result;
803 }
804
805
806
807
808
809
810 @Override
811 public String stringEval( String command ) {
812 try {
813 return this.eval( command ).asString();
814 } catch ( REXPMismatchException e ) {
815 throw new RuntimeException( e );
816 }
817 }
818
819
820
821
822
823
824 @Override
825 public List<String> stringListEval( String command ) {
826 try {
827 REXP eval = this.eval( command );
828
829 RList v;
830 List<String> results = new ArrayList<String>();
831 if ( eval instanceof REXPString ) {
832 String[] strs = ( ( REXPString ) eval ).asStrings();
833 for ( String string : strs ) {
834 results.add( string );
835 }
836 } else {
837 v = eval.asList();
838 for ( Iterator<?> it = v.iterator(); it.hasNext(); ) {
839 results.add( ( ( REXPString ) it.next() ).asString() );
840 }
841 }
842
843 return results;
844 } catch ( REXPMismatchException e ) {
845 throw new RuntimeException( e );
846 }
847 }
848
849
850
851
852
853
854 @Override
855 public TwoWayAnovaResult twoWayAnova( double[] data, List<String> factor1, List<String> factor2,
856 boolean includeInteraction ) {
857
858 String factorA = assignFactor( factor1 );
859 String factorB = assignFactor( factor2 );
860 StringBuffer command = new StringBuffer();
861
862 assign( "foo", data );
863
864 String modelDeclaration;
865
866 if ( includeInteraction ) {
867 modelDeclaration = "foo ~ " + factorA + "*" + factorB;
868 } else {
869 modelDeclaration = "foo ~ " + factorA + "+" + factorB;
870 }
871
872 command.append( "anova(aov(" + modelDeclaration + "))" );
873
874 REXP eval = eval( command.toString() );
875
876 try {
877 return new TwoWayAnovaResultImpl( "foo", eval );
878 } catch ( REXPMismatchException e ) {
879 throw new RuntimeException( e );
880 }
881 }
882
883
884
885
886
887
888 @Override
889 public Map<String, TwoWayAnovaResult> twoWayAnovaEval( String command, boolean withInteractions ) {
890 REXP rawResult = this.eval( command );
891
892 if ( rawResult == null ) {
893 return null;
894 }
895
896 Map<String, TwoWayAnovaResult> result = new HashMap<String, TwoWayAnovaResult>();
897 try {
898 RList mainList = rawResult.asList();
899 if ( mainList == null ) {
900 return null;
901 }
902
903 log.debug( mainList.size() + " results." );
904
905 for ( int i = 0; i < mainList.size(); i++ ) {
906
907 REXP anovaTable = mainList.at( i );
908
909 String elementIdentifier = mainList.keyAt( i );
910
911 assert elementIdentifier != null;
912
913 if ( log.isDebugEnabled() ) log.debug( "Key: " + elementIdentifier );
914
915 if ( !anovaTable.isList() || !anovaTable.hasAttribute( "row.names" ) ) {
916 log.debug( "No anovaresult for " + elementIdentifier );
917 result.put( elementIdentifier, new TwoWayAnovaResultImpl( elementIdentifier ) );
918 continue;
919 }
920
921 result.put( elementIdentifier, new TwoWayAnovaResultImpl( elementIdentifier, anovaTable ) );
922
923 }
924 } catch ( REXPMismatchException e ) {
925 throw new RuntimeException( e );
926 }
927
928 return result;
929
930 }
931
932
933
934
935
936
937
938 protected void loadScript( InputStream is ) {
939 try {
940
941 BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
942 String line = null;
943 StringBuilder buf = new StringBuilder();
944 while ( ( line = reader.readLine() ) != null ) {
945 if ( line.startsWith( "#" ) || StringUtils.isBlank( line ) ) {
946 continue;
947 }
948 buf.append( StringUtils.trim( line ) + "\n" );
949 }
950 is.close();
951 log.debug( buf.toString() );
952 this.voidEval( buf.toString() );
953
954 } catch ( IOException e ) {
955 throw new RuntimeException( e );
956 }
957 }
958
959
960
961
962
963
964
965 private void assignRowAndColumnNames( DoubleMatrix<?, ?> matrix, String matrixVarName, Transformer rowNameExtractor ) {
966
967 List<Object> rown = new ArrayList<Object>();
968 for ( Object o : matrix.getRowNames() ) {
969 rown.add( rowNameExtractor.transform( o ) );
970 }
971
972 String rowNameVar = assignStringList( rown );
973 String colNameVar = assignStringList( matrix.getColNames() );
974
975 String dimcmd = "dimnames(" + matrixVarName + ")<-list(" + rowNameVar + ", " + colNameVar + ")";
976 this.voidEval( dimcmd );
977 }
978
979 }