├── .github ├── ISSUE_TEMPLATE │ └── feature_request.md └── workflows │ ├── maven_build.yml │ └── maven_test.yml ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── RCaller ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pom.xml ├── settings.gradle └── src │ ├── main │ ├── java │ │ ├── benchmark │ │ │ └── PassingArraysAndMatrices.java │ │ ├── com │ │ │ └── github │ │ │ │ └── rcaller │ │ │ │ ├── EventHandler.java │ │ │ │ ├── FunctionCall.java │ │ │ │ ├── FunctionParameter.java │ │ │ │ ├── JavaObject.java │ │ │ │ ├── MessageSaver.java │ │ │ │ ├── TempFileService.java │ │ │ │ ├── datatypes │ │ │ │ ├── DataFrame.java │ │ │ │ ├── RealMatrix.java │ │ │ │ └── SVD.java │ │ │ │ ├── exception │ │ │ │ ├── ExecutionException.java │ │ │ │ ├── ParseException.java │ │ │ │ ├── RExecutableNotFoundException.java │ │ │ │ ├── RscriptExecutableNotFoundException.java │ │ │ │ └── XMLParseException.java │ │ │ │ ├── graphics │ │ │ │ ├── BlackTheme.java │ │ │ │ ├── DefaultTheme.java │ │ │ │ ├── GraphicsTheme.java │ │ │ │ ├── GraphicsType.java │ │ │ │ └── SkyTheme.java │ │ │ │ ├── io │ │ │ │ ├── ArrowBridge.java │ │ │ │ ├── CSVFileWriter.java │ │ │ │ ├── RCodeIO.java │ │ │ │ ├── ROutputParserArrow.java │ │ │ │ ├── ROutputParserXML.java │ │ │ │ ├── RSerializer.java │ │ │ │ └── arrow │ │ │ │ │ └── ArrowImpl.java │ │ │ │ ├── rstuff │ │ │ │ ├── FailurePolicy.java │ │ │ │ ├── RCaller.java │ │ │ │ ├── RCallerOptions.java │ │ │ │ ├── RCode.java │ │ │ │ ├── ROutputParser.java │ │ │ │ ├── RPlotViewer.java │ │ │ │ ├── RProcessStartUpOptions.java │ │ │ │ ├── RService.java │ │ │ │ └── RStreamHandler.java │ │ │ │ ├── scriptengine │ │ │ │ ├── LanguageElement.java │ │ │ │ ├── NamedArgument.java │ │ │ │ ├── RCallerScriptEngine.java │ │ │ │ └── RCallerScriptEngineFactory.java │ │ │ │ ├── statistics │ │ │ │ └── RandomNumberGenerator.java │ │ │ │ └── util │ │ │ │ ├── DataFrameUtil.java │ │ │ │ ├── FileStatusWatcher.java │ │ │ │ ├── Globals.java │ │ │ │ └── RCodeUtils.java │ │ └── examples │ │ │ ├── BasicGraphics.java │ │ │ ├── BasicScriptEngine.java │ │ │ ├── DescriptiveStatistics.java │ │ │ ├── EmptyArray.java │ │ │ ├── Forecasting.java │ │ │ ├── GraphicsWithThemes.java │ │ │ ├── GridCap.java │ │ │ ├── Main.java │ │ │ ├── ManualPaths.java │ │ │ ├── MultipleCalls.java │ │ │ ├── OrdinaryLeastSquares.java │ │ │ ├── PRandomNumberGenerator.java │ │ │ ├── RegressionWithRandomData.java │ │ │ ├── SampleGui.java │ │ │ ├── SampleRGui.form │ │ │ ├── SampleRGui.java │ │ │ ├── ScriptEngineInvocable.java │ │ │ ├── SimplePlot.java │ │ │ ├── UnitRoots.java │ │ │ └── WorkingWithData.java │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── javax.script.ScriptEngineFactory │ │ ├── arrow_bridge.R │ │ ├── runiversal.R │ │ └── xml_exporting.R │ └── test │ └── java │ └── com │ └── github │ └── rcaller │ ├── EventHandlerTest.java │ ├── FactorDataTypeTest.java │ ├── FileStatusWatcherTest.java │ ├── FunctionCallTest.java │ ├── GetMatrixDimensionsTest.java │ ├── GlobalsTest.java │ ├── GridCapTest.java │ ├── HandlingAllVariablesTest.java │ ├── JavaObjectTest.java │ ├── LargeDataTest.java │ ├── MatrixTest.java │ ├── ParserEmptyFileTest.java │ ├── PrimitiveDataTypes.java │ ├── RCallerTest.java │ ├── RServiceTest.java │ ├── RunOnlineTest.java │ ├── TestBugFixesStackOverflow.java │ ├── UTF8Test.java │ ├── datatypes │ ├── DataFrameTest.java │ └── RealMatrixTest.java │ ├── io │ └── RSerializerTest.java │ ├── rstuff │ └── RProcessStartUpOptionsTest.java │ └── scriptengine │ ├── InvokeTest.java │ ├── PutJavaObjectTest.java │ ├── ScriptEngineBasicsTest.java │ ├── TestClass1.java │ └── TestClass2.java ├── RCallerPhp ├── CodeUtils.php ├── Globals.php ├── RCaller.php ├── RCode.php ├── ROutputParser.php └── test │ ├── PlotTest.php │ ├── RCodeTest.php │ └── simpletest.php ├── README.md ├── bibtex.bib ├── doc ├── rcaller-url.txt └── rcaller3 │ ├── MatrixSendReceive.pdf │ ├── rcaller3.bib │ ├── rcaller3.pdf │ └── rcaller3.tex ├── markdown └── clojure.md └── paper ├── paper.bib └── paper.md /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this projectt 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/maven_build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java projectt with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: build 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 20 | uses: actions/setup-java@v1 21 | with: 22 | java-version: 17 23 | - name: Build with Maven 24 | run: cd RCaller && mvn compile 25 | -------------------------------------------------------------------------------- /.github/workflows/maven_test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java projectt with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: test 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | 14 | test: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Set up JDK 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: 17 24 | - name: Set up R 25 | run: | 26 | sudo apt-get update 27 | sudo apt-get -y install r-base 28 | sudo locale-gen "en_US.UTF-8" 29 | sudo bash -c 'echo "LANG=en_US.UTF-8" > /etc/default/locale' 30 | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV 31 | - name: Build with Maven 32 | run: cd RCaller && mvn test 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | before_script: 4 | - cd RCaller 5 | - sudo apt-get update 6 | - sudo apt-get -y install r-base 7 | - R --version 8 | 9 | script: mvn test 10 | 11 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our projectt and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | projectt maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | projectt maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within projectt spaces and in public spaces 49 | when an individual is representing the projectt or its community. Examples of 50 | representing a projectt or community include using an official projectt e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a projectt may be 53 | further defined and clarified by projectt maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the projectt team at mhsatman@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The projectt team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | projectt maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the projectt's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Welcome! 2 | 3 | Our contributors are mainly RCaller users in academia or software sector. They used to integrate RCaller in their projectts and they contributed to the projectt 4 | for supporting themself first and the whole users after. You can contribute by 5 | 6 | - sending pull requests (code is the king) 7 | - writing blogposts 8 | - making youtube videos 9 | - posting answers in stackoverflow. 10 | 11 | ## Sending pull requests 12 | If you added some functionality, tests, or examples in the projectt, first create a fork in Github and make the contribution public in your repo. 13 | Then send a pull request as described in [Creating pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request). 14 | 15 | ## Writing blogposts 16 | Many users have blogposts about RCaller. If you have one, tell us to be visible in this repo. Here is some blogposts: 17 | - [Practical code solutions](http://stdioe.blogspot.com/search/label/rcaller). 18 | - [Scott Hoover](https://scottdhoover.wordpress.com/2013/05/08/a-basic-rcaller-example/). 19 | - [Baeldung](https://www.baeldung.com/java-r-integration). 20 | - [Renjin](http://docs.renjin.org/en/latest/introduction.html). 21 | 22 | ## Making youtube videos 23 | Videos are perfect tools for tutorials. Here is some examples: 24 | - [video by Bryan Downing - 1](https://www.youtube.com/watch?v=hZDwuCV2fO8). 25 | - [video by Bryan Downing - 2](https://www.youtube.com/watch?v=fHt0cq-6BvM). 26 | 27 | ## Posting answers in stackoverflow 28 | Stackoverflow is the defacto forum for nearly all tools in area of software. RCaller questions can be found using the tag **rcaller**. 29 | - [Questions on stackoverflow](https://stackoverflow.com/questions/tagged/rcaller). 30 | 31 | 32 | ## Have problems? 33 | Please create an issue that addresses your problem. We will be happy to help to you. 34 | 35 | 36 | We are just here waiting to hear from you! 37 | -------------------------------------------------------------------------------- /RCaller/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | build/ 3 | .settings 4 | .idea 5 | .gradle 6 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 7 | !gradle-wrapper.jar 8 | .classpath 9 | RCaller.iml 10 | target.asc 11 | -------------------------------------------------------------------------------- /RCaller/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'maven-publish' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | group = 'com.github.jbytecode' 11 | version = '4.0.2' 12 | description = 'RCaller is a software library which simplifies performing data analysis and statistical calculations in Java using R. The details are hidden from users including transferring data between platforms, function calls, and retrieving results.' 13 | 14 | dependencies { 15 | implementation 'org.apache.commons:commons-lang3:3.12.0' 16 | compileOnly 'org.apache.arrow:arrow-vector:[5.0.0,)' 17 | 18 | testImplementation 'junit:junit:4.13.2' 19 | testImplementation 'org.apache.arrow:arrow-vector:[5.0.0,)' 20 | testImplementation 'org.apache.arrow:arrow-memory-netty:[5.0.0,)' 21 | } 22 | 23 | java.sourceCompatibility = JavaVersion.VERSION_11 24 | 25 | java { 26 | withSourcesJar() 27 | withJavadocJar() 28 | } 29 | 30 | publishing { 31 | publications { 32 | maven(MavenPublication) { 33 | from(components.java) 34 | } 35 | } 36 | } 37 | 38 | tasks.withType(JavaCompile) { 39 | options.encoding = 'UTF-8' 40 | } 41 | -------------------------------------------------------------------------------- /RCaller/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbytecode/rcaller/2c053c9e4cf2a123dfe379e6a8d7f29e283bac5c/RCaller/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /RCaller/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /RCaller/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /RCaller/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /RCaller/settings.gradle: -------------------------------------------------------------------------------- 1 | rootprojectt.name = 'RCaller' 2 | -------------------------------------------------------------------------------- /RCaller/src/main/java/benchmark/PassingArraysAndMatrices.java: -------------------------------------------------------------------------------- 1 | package benchmark; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | /** 7 | * Passing a double[] array (or matrix) to R, calculating a^2 (or transpose) 8 | * handling the result in Java. 9 | * 10 | * This benchmark reports the minimum, maximum median, average calculation times 11 | * with standard deviation and median absolute deviations scale measures. 12 | */ 13 | public class PassingArraysAndMatrices { 14 | 15 | private enum SimType { 16 | Vector, Matrix 17 | } 18 | 19 | /** 20 | * Random vector generator 21 | * 22 | * @param size Size of vector 23 | * @return Generated vector 24 | */ 25 | private final static double[] generateRandomVector(int size) { 26 | 27 | double[] d = new double[size]; 28 | for (int i = 0; i < size; i++) { 29 | d[i] = Math.random(); 30 | } 31 | 32 | return d; 33 | } 34 | 35 | /** 36 | * Generate random matrix 37 | * 38 | * @param n Number of rows 39 | * @param m Number of columns 40 | * @return Random matrix. 41 | */ 42 | private final static double[][] generateRandomMatrix(int n, int m) { 43 | 44 | double[][] d = new double[n][m]; 45 | for (int i = 0; i < n; i++) { 46 | for (int j = 0; j < m; j++) { 47 | d[i][j] = Math.random(); 48 | } 49 | } 50 | 51 | return d; 52 | } 53 | 54 | public static void main(String[] args) { 55 | 56 | performSimulation(/* size of vector */ 20000, 100 /* times */ , SimType.Vector); 57 | 58 | } 59 | 60 | public static void performSimulation(int VectorSize, int SimCount, SimType type) { 61 | 62 | RCaller caller = RCaller.create(); 63 | RCode code = RCode.create(); 64 | int[] elapsed = new int[SimCount]; 65 | 66 | System.out.println("- Simulations started."); 67 | 68 | for (int simulations = 0; simulations < SimCount; simulations++) { 69 | 70 | int timeStart = (int) System.currentTimeMillis(); 71 | code.clear(); 72 | if (type == SimType.Vector) { 73 | code.addDoubleArray("randomvector", generateRandomVector(VectorSize)); 74 | code.addRCode("result <- randomvector^2.0"); 75 | } else { 76 | code.addDoubleMatrix("randommatrix", generateRandomMatrix(VectorSize, VectorSize)); 77 | code.addRCode("result <- t(randommatrix)"); 78 | } 79 | caller.setRCode(code); 80 | caller.runAndReturnResultOnline("result", false); 81 | /* return variable is not handled */ caller.getParser().getAsDoubleArray("result"); 82 | elapsed[simulations] = (int) System.currentTimeMillis() - timeStart; 83 | 84 | } 85 | 86 | System.out.println("- Simulations finished. Calculating statistics:"); 87 | 88 | code.clear(); 89 | code.addIntArray("times", elapsed); 90 | code.addRCode("stats <- c(min(times), max(times), mean(times), sd(times), median(times), mad(times))"); 91 | caller.setRCode(code); 92 | caller.runAndReturnResultOnline("stats"); 93 | 94 | double[] stats = caller.getParser().getAsDoubleArray("stats"); 95 | 96 | System.out.printf("%10s %10s %10s %10s %10s %10s\n", "Min", "Max", "Mean", "Std.Dev.", "Median", "Mad"); 97 | System.out.printf("%10f %10f %10f %10f %10f %10f\n", stats[0], stats[1], stats[2], stats[3], stats[4], 98 | stats[5]); 99 | caller.stopRCallerOnline(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | public interface EventHandler { 4 | public void messageReceived(String senderName, String msg); 5 | } 6 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/FunctionCall.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class FunctionCall { 6 | 7 | private ArrayList parameters; 8 | private String fname; 9 | 10 | public FunctionCall() { 11 | this.fname = ""; 12 | this.parameters = new ArrayList<>(); 13 | } 14 | 15 | public FunctionCall(String functionName) { 16 | this.fname = functionName; 17 | this.parameters = new ArrayList<>(); 18 | } 19 | 20 | public FunctionCall(String functionName, ArrayList parameters) { 21 | this(functionName); 22 | this.parameters = parameters; 23 | } 24 | 25 | public void setFunctionName(String name) { 26 | this.fname = name; 27 | } 28 | 29 | public String getFunctionName() { 30 | return (this.fname); 31 | } 32 | 33 | public ArrayList getParameters() { 34 | return parameters; 35 | } 36 | 37 | public void setParameters(ArrayList parameters) { 38 | this.parameters = parameters; 39 | } 40 | 41 | public void addParameter(FunctionParameter fp) { 42 | this.parameters.add(fp); 43 | } 44 | 45 | public void addParameter(String name, String value, int type) { 46 | this.parameters.add(new FunctionParameter(name, value, type)); 47 | } 48 | 49 | public String generateCode(String returnVar) { 50 | StringBuilder builder = new StringBuilder(); 51 | builder.append(returnVar) 52 | .append(" <- ") 53 | .append(this.fname) 54 | .append("("); 55 | for (int i = 0; i < this.parameters.size(); i++) { 56 | builder.append(this.parameters.get(i)); 57 | if (i < (this.parameters.size() - 1)) { 58 | builder.append(", "); 59 | } 60 | } 61 | builder.append(")").append("\n"); 62 | return (builder.toString()); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/FunctionParameter.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | public class FunctionParameter { 4 | 5 | public final static int PARAM_LITERAL = 1; 6 | public final static int PARAM_OBJECT = 2; 7 | 8 | private String parameterName; 9 | private String value; 10 | private int type; 11 | 12 | public String getParameterName() { 13 | return parameterName; 14 | } 15 | 16 | public void setParameterName(String parameterName) { 17 | this.parameterName = parameterName; 18 | } 19 | 20 | public String getValue() { 21 | return value; 22 | } 23 | 24 | public void setValue(String value) { 25 | this.value = value; 26 | } 27 | 28 | public int getType() { 29 | return type; 30 | } 31 | 32 | public void setType(int type) { 33 | this.type = type; 34 | } 35 | 36 | public FunctionParameter(String parametername, String value, int type) { 37 | this.parameterName = parametername; 38 | this.value = value; 39 | this.type = type; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | if (this.type == PARAM_LITERAL) { 45 | return (this.parameterName + " = " + "\"" + this.value + "\""); 46 | } else if (this.type == PARAM_OBJECT) { 47 | return (this.parameterName + " = " + this.value); 48 | } else { 49 | throw new RuntimeException("FunctionParameter " + this.type + " is not defined"); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/JavaObject.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.util.RCodeUtils; 4 | 5 | import java.lang.reflect.Field; 6 | 7 | public class JavaObject { 8 | 9 | Object object; 10 | String name; 11 | 12 | public JavaObject(String name, Object o) { 13 | this.object = o; 14 | this.name = name; 15 | } 16 | 17 | public Object getObject() { 18 | return object; 19 | } 20 | 21 | public void setObject(Object object) { 22 | this.object = object; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public static String ConvertToRCode(String name, Object javaobject, boolean useList, boolean useEquals) throws IllegalAccessException { 34 | StringBuilder builder = new StringBuilder(); 35 | StringBuilder tempbuffer = new StringBuilder(); 36 | String className, varName; 37 | Object o; 38 | Field f; 39 | 40 | Field[] fields = javaobject.getClass().getFields(); 41 | if (useList) { 42 | if (useEquals) { 43 | builder.append(name).append(" = list("); 44 | } else { 45 | builder.append(name).append(" <- list("); 46 | } 47 | } 48 | for (int i = 0; i < fields.length; i++) { 49 | f = fields[i]; 50 | className = f.getType().getCanonicalName(); 51 | varName = f.getName(); 52 | o = f.get(javaobject); 53 | switch (className) { 54 | case "int": 55 | case "float": 56 | case "double": 57 | case "long": 58 | case "short": 59 | builder.append(varName).append("=").append(o); 60 | break; 61 | case "java.lang.String": 62 | builder.append(varName).append("=").append("\"").append(o).append("\""); 63 | break; 64 | case "boolean": 65 | builder.append(varName).append("=").append(o.toString().toUpperCase()); 66 | break; 67 | case "int[]": 68 | tempbuffer.setLength(0); 69 | RCodeUtils.addIntArray(tempbuffer, varName, (int[]) o, true); 70 | builder.append(tempbuffer.toString()); 71 | break; 72 | case "double[]": 73 | tempbuffer.setLength(0); 74 | RCodeUtils.addDoubleArray(tempbuffer, varName, (double[]) o, true); 75 | builder.append(tempbuffer.toString()); 76 | break; 77 | case "float[]": 78 | tempbuffer.setLength(0); 79 | RCodeUtils.addFloatArray(tempbuffer, varName, (float[]) o, true); 80 | builder.append(tempbuffer.toString()); 81 | break; 82 | case "short[]": 83 | tempbuffer.setLength(0); 84 | RCodeUtils.addShortArray(tempbuffer, varName, (short[]) o, true); 85 | builder.append(tempbuffer.toString()); 86 | break; 87 | case "long[]": 88 | tempbuffer.setLength(0); 89 | RCodeUtils.addLongArray(tempbuffer, varName, (long[]) o, true); 90 | builder.append(tempbuffer.toString()); 91 | break; 92 | case "boolean[]": 93 | tempbuffer.setLength(0); 94 | RCodeUtils.addLogicalArray(tempbuffer, varName, (boolean[]) o, true); 95 | builder.append(tempbuffer.toString()); 96 | break; 97 | case "java.lang.String[]": 98 | tempbuffer.setLength(0); 99 | RCodeUtils.addStringArray(tempbuffer, varName, (String[]) o, true); 100 | builder.append(tempbuffer.toString()); 101 | break; 102 | case "java.lang.Object": 103 | tempbuffer.setLength(0); 104 | //CodeUtils.addJavaObject(tempbuffer, o, true); 105 | tempbuffer.append(JavaObject.ConvertToRCode(name, o, useList, true)); 106 | builder.append(tempbuffer.toString()); 107 | break; 108 | default: 109 | builder.append(varName).append("=").append("\"").append("Unsupported data type: ").append(className).append(" in JavaObject").append("\""); 110 | break; 111 | } 112 | 113 | if (useList) { 114 | if (i < fields.length - 1) { 115 | builder.append(", "); 116 | } 117 | } else { 118 | builder.append(";"); 119 | } 120 | 121 | } 122 | 123 | if (useList) { 124 | builder.append(")\n"); 125 | } else { 126 | builder.append("\n"); 127 | } 128 | return (builder.toString()); 129 | } 130 | 131 | public String produceRCode(boolean useEquals) throws IllegalAccessException { 132 | return (JavaObject.ConvertToRCode(name, object, true, useEquals)); 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/MessageSaver.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | public class MessageSaver implements EventHandler { 4 | private final StringBuilder errorBuffer = new StringBuilder(); 5 | 6 | @Override 7 | public void messageReceived(String senderName, String msg) { 8 | errorBuffer.append(msg).append("\n"); 9 | } 10 | 11 | public String getMessage() { 12 | return errorBuffer.toString(); 13 | } 14 | 15 | public void resetMessage() { 16 | errorBuffer.setLength(0); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/TempFileService.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.exception.ExecutionException; 4 | import org.apache.commons.lang3.tuple.ImmutablePair; 5 | import org.apache.commons.lang3.tuple.Pair; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.nio.channels.FileChannel; 10 | import java.nio.file.StandardOpenOption; 11 | import java.util.ArrayList; 12 | import java.util.logging.Level; 13 | import java.util.logging.Logger; 14 | 15 | 16 | public class TempFileService { 17 | 18 | private static final Logger logger = Logger.getLogger(TempFileService.class.getName()); 19 | 20 | private final ArrayList> tempFiles; 21 | 22 | public TempFileService(){ 23 | tempFiles = new ArrayList<>(); 24 | } 25 | 26 | public File createTempFile(String prefix, String suffix) throws IOException { 27 | File f = File.createTempFile(prefix, suffix); 28 | FileChannel fileChannel = FileChannel.open( 29 | f.toPath(), 30 | StandardOpenOption.READ, 31 | StandardOpenOption.WRITE, 32 | StandardOpenOption.CREATE 33 | ); 34 | tempFiles.add(new ImmutablePair<>(f, fileChannel)); 35 | return(f); 36 | } 37 | 38 | public void deleteRCallerTempFiles(){ 39 | for (Pair tempFileAndChannel : tempFiles) { 40 | var fileChannel = tempFileAndChannel.getRight(); 41 | var tempFile = tempFileAndChannel.getLeft(); 42 | try { 43 | fileChannel.close(); 44 | } catch (IOException e) { 45 | logger.log(Level.WARNING, "Couldn't close file ".concat(tempFile.getName()), e); 46 | } 47 | if (!tempFile.delete()) { 48 | logger.log(Level.WARNING, "Couldn't delete file ".concat(tempFile.getName())); 49 | } 50 | } 51 | tempFiles.clear(); 52 | } 53 | 54 | public File createOutputFile() { 55 | try { 56 | return createTempFile("ROutput", ""); 57 | } catch (Exception e) { 58 | throw new ExecutionException("Can not create a temporary file for storing the R results: " + e.getMessage()); 59 | } 60 | } 61 | 62 | public File createControlFile() { 63 | try { 64 | return createTempFile("RControl", ""); 65 | } catch (Exception e) { 66 | throw new ExecutionException("Can not create a temporary file for storing the R results: " + e.getMessage()); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/datatypes/DataFrame.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.datatypes; 2 | 3 | import com.github.rcaller.util.DataFrameUtil; 4 | 5 | public class DataFrame { 6 | 7 | private Object[][] objects; 8 | private String[] names; 9 | 10 | private DataFrame(Object[][] objects, String[] names) { 11 | this.objects = objects; 12 | this.names = names; 13 | } 14 | 15 | /** 16 | * create an empty DataFrame with the dimensions of n*m 17 | * @param n is the number of columns 18 | * @param m is the number of rows 19 | * @return an empty data frame of the dimension n x m 20 | */ 21 | public static DataFrame create(int n, int m) { 22 | return new DataFrame(DataFrameUtil.createEmptyObjectsMatrix(n,m), DataFrameUtil.createDefaultNamesArray(n)); 23 | } 24 | 25 | public static DataFrame create(Object[][] objects, String[] names) { 26 | if (objects.length != names.length) { 27 | throw new IllegalArgumentException("The number of columns of the data frame is not equal with the number of names!"); 28 | } 29 | 30 | return new DataFrame(objects, names); 31 | } 32 | 33 | public Object[] getColumn(int i) { 34 | if (i >= getNumberOfColumns() || i < 0) { 35 | throw new IllegalArgumentException("Requested index is greater than the number of columns - 1!"); 36 | } 37 | 38 | return objects[i]; 39 | } 40 | 41 | public Object[] getRow(int i) { 42 | if (i >= getNumberOfRows() || i < 0) { 43 | throw new IllegalArgumentException("Requested index is greater than the number of rows - 1!"); 44 | } 45 | 46 | Object[] row = new Object[objects.length]; 47 | 48 | for (int j = 0; j < objects.length; j++) { 49 | row[j] = objects[j][i]; 50 | } 51 | 52 | return row; 53 | } 54 | 55 | public Object[][] getObjects() { 56 | return objects; 57 | } 58 | 59 | public String[] getNames() { 60 | return names; 61 | } 62 | 63 | public int getNumberOfColumns() { 64 | return objects.length; 65 | } 66 | 67 | public int getNumberOfRows() { 68 | return objects[0].length; 69 | } 70 | 71 | public Object getObject(int n, int m) { 72 | if (n >= getNumberOfColumns() || n < 0 && m > getNumberOfRows() || m < 0) { 73 | throw new IllegalArgumentException("Given indexes are greater than the dimensions of the data frame!"); 74 | } else if (n >= getNumberOfColumns() || n < 0) { 75 | throw new IllegalArgumentException("Requested index is greater than the number of columns - 1!"); 76 | } else if (m >= getNumberOfRows() || m < 0) { 77 | throw new IllegalArgumentException("Requested index is greater than the number of rows - 1!"); 78 | } 79 | 80 | return objects[n][m]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/datatypes/SVD.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.datatypes; 2 | 3 | public class SVD { 4 | 5 | private double[] d; 6 | private RealMatrix u; 7 | private RealMatrix v; 8 | 9 | public double[] getD() { 10 | return d; 11 | } 12 | 13 | public void setD(double[] d) { 14 | this.d = d; 15 | } 16 | 17 | public RealMatrix getU() { 18 | return u; 19 | } 20 | 21 | public void setU(RealMatrix u) { 22 | this.u = u; 23 | } 24 | 25 | public RealMatrix getV() { 26 | return v; 27 | } 28 | 29 | public void setV(RealMatrix v) { 30 | this.v = v; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/exception/ExecutionException.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.exception; 2 | 3 | /** 4 | * 5 | * @author Mehmet Hakan Satman 6 | */ 7 | public class ExecutionException extends RuntimeException { 8 | 9 | /** 10 | * Creates a new instance of RCallerExecutionException without detail message. 11 | */ 12 | public ExecutionException() { 13 | } 14 | 15 | /** 16 | * Constructs an instance of RCallerExecutionException with the specified detail message. 17 | * @param msg the detail message. 18 | */ 19 | public ExecutionException(String msg) { 20 | super(msg); 21 | } 22 | /** 23 | * Constructs an instance of RCallerExecutionException with the specified detail message and cause. 24 | * @param msg the detail message. 25 | * @param cause the cause exception. 26 | */ 27 | public ExecutionException(String msg, Throwable cause) { 28 | super(msg, cause); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/exception/ParseException.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.exception; 2 | 3 | /** 4 | * 5 | * @author Mehmet Hakan Satman 6 | */ 7 | public class ParseException extends ExecutionException { 8 | 9 | /** 10 | * Creates a new instance of RCallerParseException without detail message. 11 | */ 12 | public ParseException() { 13 | } 14 | 15 | /** 16 | * Constructs an instance of RCallerParseException with the specified detail message. 17 | * @param msg the detail message. 18 | */ 19 | public ParseException(String msg) { 20 | super(msg); 21 | } 22 | 23 | /** 24 | * Constructs an instance of RCallerParseException with the specified detail message and cause. 25 | * @param msg the detail message. 26 | * @param cause the cause exception. 27 | */ 28 | public ParseException(String msg, Throwable cause) { 29 | super(msg, cause); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/exception/RExecutableNotFoundException.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller.exception; 3 | 4 | public class RExecutableNotFoundException extends ExecutionException{ 5 | 6 | public RExecutableNotFoundException() { 7 | super(); 8 | } 9 | 10 | public RExecutableNotFoundException(String msg) { 11 | super(msg); 12 | } 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/exception/RscriptExecutableNotFoundException.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.github.rcaller.exception; 4 | 5 | public class RscriptExecutableNotFoundException extends ExecutionException{ 6 | 7 | public RscriptExecutableNotFoundException() { 8 | super(); 9 | } 10 | 11 | public RscriptExecutableNotFoundException(String msg) { 12 | super(msg); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/exception/XMLParseException.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.github.rcaller.exception; 4 | 5 | public class XMLParseException extends ParseException { 6 | 7 | public XMLParseException() { 8 | super(); 9 | } 10 | 11 | public XMLParseException(String msg) { 12 | super(msg); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/graphics/BlackTheme.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.graphics; 2 | 3 | import java.awt.Color; 4 | 5 | public class BlackTheme extends GraphicsTheme { 6 | 7 | public BlackTheme() { 8 | bgColor = Color.BLACK; 9 | plotColor = Color.WHITE; 10 | labelColor = Color.GREEN; 11 | headerColor = Color.RED; 12 | subheaderColor = Color.BLUE; 13 | axisColor = Color.RED; 14 | pointChar = "*"; 15 | lwd=3; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/graphics/DefaultTheme.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller.graphics; 3 | 4 | import java.awt.Color; 5 | 6 | public class DefaultTheme extends GraphicsTheme{ 7 | 8 | public DefaultTheme(){ 9 | bgColor = Color.WHITE; 10 | plotColor = Color.BLACK; 11 | labelColor = Color.BLACK; 12 | headerColor = Color.BLACK; 13 | subheaderColor = Color.BLACK; 14 | axisColor = Color.BLACK; 15 | pointChar = "o"; 16 | lwd=1; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/graphics/GraphicsTheme.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.graphics; 2 | 3 | import java.awt.Color; 4 | 5 | public abstract class GraphicsTheme { 6 | 7 | Color bgColor = Color.WHITE; 8 | Color plotColor = Color.BLACK; 9 | Color labelColor = Color.BLACK; 10 | Color headerColor = Color.BLACK; 11 | Color subheaderColor = Color.BLACK; 12 | Color axisColor = Color.BLACK; 13 | String pointChar = "o"; 14 | int lwd = 1; 15 | 16 | public int getLineWidth() { 17 | return lwd; 18 | } 19 | 20 | public void setLineWidth(int lwd) { 21 | this.lwd = lwd; 22 | } 23 | 24 | public Color getBackgroundColor() { 25 | return this.bgColor; 26 | } 27 | 28 | public void setBackgroundColor(Color col) { 29 | bgColor = col; 30 | } 31 | 32 | public Color getPlotColor() { 33 | return this.plotColor; 34 | } 35 | 36 | public void setPlotColor(Color col) { 37 | plotColor = col; 38 | } 39 | 40 | public Color getLabelColor() { 41 | return this.labelColor; 42 | } 43 | 44 | public void setLabelColor(Color col) { 45 | this.labelColor = col; 46 | } 47 | 48 | public Color getHeaderColor() { 49 | return this.headerColor; 50 | } 51 | 52 | public void setHeaderColor(Color col) { 53 | this.headerColor = col; 54 | } 55 | 56 | public Color getSubHeaderColor() { 57 | return this.subheaderColor; 58 | } 59 | 60 | public void setSubHeaderColor(Color col) { 61 | this.subheaderColor = col; 62 | } 63 | 64 | public String getPointChar() { 65 | return this.pointChar; 66 | } 67 | 68 | public Color getAxisColor() { 69 | return this.axisColor; 70 | } 71 | 72 | public void setAxisColor(Color col) { 73 | this.axisColor = col; 74 | } 75 | 76 | public void setPointChar(String pch) { 77 | this.pointChar = pch; 78 | } 79 | 80 | public String generateRCode() { 81 | StringBuffer buf = new StringBuffer(); 82 | buf.append("par(bg=").append("\"").append(getStringColor(bgColor)).append("\"").append(")").append("\n"); 83 | buf.append("par(col=").append("\"").append(getStringColor(plotColor)).append("\"").append(")").append("\n"); 84 | buf.append("par(col.lab=").append("\"").append(getStringColor(labelColor)).append("\"").append(")").append("\n"); 85 | buf.append("par(col.main=").append("\"").append(getStringColor(headerColor)).append("\"").append(")").append("\n"); 86 | buf.append("par(col.sub=").append("\"").append(getStringColor(subheaderColor)).append("\"").append(")").append("\n"); 87 | buf.append("par(col.axis=").append("\"").append(getStringColor(axisColor)).append("\"").append(")").append("\n"); 88 | buf.append("par(pch=").append("\"").append(this.pointChar).append("\"").append(")").append("\n"); 89 | buf.append("par(lwd=").append(this.lwd).append(")").append("\n"); 90 | return (buf.toString()); 91 | } 92 | 93 | private String getHex(int a) { 94 | String result = Integer.toHexString(a); 95 | if (result.length() == 2) { 96 | return (result); 97 | } else { 98 | return ("0" + result); 99 | } 100 | } 101 | 102 | public String getStringColor(Color col) { 103 | StringBuilder buf = new StringBuilder(7); 104 | buf.append("#"); 105 | buf.append(getHex(col.getRed())); 106 | buf.append(getHex(col.getGreen())); 107 | buf.append(getHex(col.getBlue())); 108 | return (buf.toString()); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/graphics/GraphicsType.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.graphics; 2 | 3 | public enum GraphicsType { 4 | 5 | bmp, 6 | jpeg, 7 | tiff, 8 | png 9 | } 10 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/graphics/SkyTheme.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller.graphics; 3 | 4 | import java.awt.Color; 5 | 6 | 7 | public class SkyTheme extends GraphicsTheme { 8 | public SkyTheme(){ 9 | bgColor = new Color(240,240,255); 10 | plotColor = new Color(0,200,255); 11 | labelColor = new Color(100,155,255); 12 | headerColor = new Color(0,0,255); 13 | subheaderColor = new Color(0,100,255); 14 | axisColor = new Color(10,0,255); 15 | pointChar = "*"; 16 | lwd=3; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/io/ArrowBridge.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCallerOptions; 5 | import com.github.rcaller.rstuff.RCode; 6 | 7 | import java.io.IOException; 8 | import java.net.URI; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | 13 | public abstract class ArrowBridge implements AutoCloseable { 14 | private static Boolean arrowAvailable = null; 15 | 16 | public static synchronized boolean isArrowAvailable(RCallerOptions rCallerOptions) { 17 | if (arrowAvailable == null) { 18 | arrowAvailable = isArrowAvailableInJava() && isArrowAvailableInR(rCallerOptions); 19 | } 20 | return arrowAvailable; 21 | } 22 | 23 | private static Boolean arrowAvailableInJava = null; 24 | 25 | private static synchronized boolean isArrowAvailableInJava() { 26 | if (arrowAvailableInJava == null) { 27 | try { 28 | org.apache.arrow.memory.RootAllocator rootAllocator = new org.apache.arrow.memory.RootAllocator(); 29 | org.apache.arrow.vector.VectorSchemaRoot vectorSchemaRoot = new org.apache.arrow.vector.VectorSchemaRoot(new ArrayList<>()); 30 | vectorSchemaRoot.close(); 31 | rootAllocator.close(); 32 | arrowAvailableInJava = true; 33 | } catch (NoClassDefFoundError e) { 34 | arrowAvailableInJava = false; 35 | } 36 | } 37 | return arrowAvailableInJava; 38 | } 39 | 40 | private static Boolean arrowAvailableInR = null; 41 | 42 | private static synchronized boolean isArrowAvailableInR(RCallerOptions rCallerOptions) { 43 | if (arrowAvailableInR == null) { 44 | var rCallerOptionsTemp = new RCallerOptions(rCallerOptions); 45 | rCallerOptionsTemp.setUseArrowIfAvailable(false); 46 | RCaller rCaller = RCaller.create(rCallerOptionsTemp); 47 | RCode rCode = rCaller.getRCode(); 48 | rCode.addRCode("available_arrow <- require(\"arrow\")"); 49 | rCaller.runAndReturnResult("available_arrow"); 50 | boolean[] availableArrow = rCaller.getParser().getAsLogicalArray("available_arrow"); 51 | rCaller.deleteTempFiles(); 52 | arrowAvailableInR = availableArrow.length == 1 && availableArrow[0]; 53 | } 54 | return arrowAvailableInR; 55 | } 56 | 57 | public static ArrowBridge newInstance() { 58 | return newInstance(RCallerOptions.create()); 59 | } 60 | 61 | public static ArrowBridge newInstance(RCallerOptions rCallerOptions) { 62 | if (!isArrowAvailable(rCallerOptions)) { 63 | StringJoiner details = new StringJoiner(", ", "(", ")"); 64 | if (!isArrowAvailableInJava()) { 65 | details.add("not linked to Java"); 66 | } 67 | if (!isArrowAvailableInR(rCallerOptions)) { 68 | details.add("not installed in R"); 69 | } 70 | throw new IllegalStateException("Arrow is not available in current context " + details); 71 | } 72 | return new com.github.rcaller.io.arrow.ArrowImpl(); 73 | } 74 | 75 | public abstract void loadArrowData(URI ipcResource) throws IOException; 76 | 77 | public abstract List getNames(); 78 | 79 | public abstract String getType(String name); 80 | 81 | public abstract int[] getDimensions(String name); 82 | 83 | public abstract String[] getAsStringArray(String name); 84 | 85 | public abstract double[] getAsDoubleArray(String name); 86 | 87 | public abstract float[] getAsFloatArray(String name); 88 | 89 | public abstract int[] getAsIntArray(String name); 90 | 91 | public abstract long[] getAsLongArray(String name); 92 | 93 | public abstract double[][] getAsDoubleMatrix(String name); 94 | 95 | //public abstract Object getUnwrappedField(String name); 96 | } 97 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/io/CSVFileWriter.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.datatypes.DataFrame; 4 | 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | 8 | public class CSVFileWriter extends FileWriter{ 9 | 10 | private CSVFileWriter(String filePath) throws IOException { 11 | super(filePath); 12 | } 13 | 14 | public static CSVFileWriter create(String filePath) throws IOException { 15 | return new CSVFileWriter(filePath); 16 | } 17 | 18 | public void writeDataFrameToFile(DataFrame dataFrame) throws IOException { 19 | appendArray(dataFrame.getNames()); 20 | for (int i = 0; i < dataFrame.getNumberOfRows(); i++) { 21 | appendArray(dataFrame.getRow(i)); 22 | } 23 | } 24 | 25 | private void appendArray(Object[] array) throws IOException { 26 | for (int i = 0; i < array.length; i++) { 27 | this.append(array[i].toString()); 28 | 29 | if (i == array.length - 1) { 30 | this.append('\n'); 31 | } else { 32 | this.append(','); 33 | } 34 | } 35 | this.flush(); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/io/RCodeIO.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.exception.ExecutionException; 4 | import com.github.rcaller.rstuff.RCallerOptions; 5 | import com.github.rcaller.util.RCodeUtils; 6 | import java.io.File; 7 | import java.net.URI; 8 | 9 | public class RCodeIO { 10 | 11 | private interface RCodeIOGenerator { 12 | String getInterprocessDependencies(); 13 | String getVariableExporting(String variableName, URI target); 14 | } 15 | 16 | private static class RCodeIOGeneratorArrow implements RCodeIOGenerator { 17 | @Override 18 | public String getInterprocessDependencies() { 19 | var generatingScript = new StringBuilder(); 20 | RCodeUtils.addResourceScript(generatingScript, "runiversal.R"); 21 | RCodeUtils.addResourceScript(generatingScript, "arrow_bridge.R"); 22 | return generatingScript.toString(); 23 | } 24 | 25 | @Override 26 | public String getVariableExporting(String variableName, URI target) { 27 | return "send_by_arrow(obj=" + variableName + ", name=\"" + variableName + 28 | "\", uri=\"" + new File(target).toString().replace("\\", "/") + "\")\n"; 29 | } 30 | } 31 | private static final RCodeIOGenerator rCodeIOGeneratorArrow = new RCodeIOGeneratorArrow(); 32 | 33 | private static class RCodeIOGeneratorXML implements RCodeIOGenerator { 34 | @Override 35 | public String getInterprocessDependencies() { 36 | var generatingScript = new StringBuilder(); 37 | RCodeUtils.addResourceScript(generatingScript, "runiversal.R"); 38 | RCodeUtils.addResourceScript(generatingScript, "xml_exporting.R"); 39 | return generatingScript.toString(); 40 | } 41 | 42 | @Override 43 | public String getVariableExporting(String variableName, URI target) { 44 | return "cat(makexml(obj=" + variableName + ", name=\"" + variableName + 45 | "\"), file=\"" + new File(target).toString().replace("\\", "/") + "\")\n"; 46 | } 47 | } 48 | private static final RCodeIOGenerator rCodeIOGeneratorXML = new RCodeIOGeneratorXML(); 49 | 50 | private static RCodeIOGenerator getRCodeIOGenerator(RCallerOptions rCallerOptions) { 51 | if (rCallerOptions.useArrowIfAvailable()) { 52 | if (ArrowBridge.isArrowAvailable(rCallerOptions)) { 53 | //Use Arrow by default if enabled 54 | return rCodeIOGeneratorArrow; 55 | } else { 56 | if (rCallerOptions.failIfArrowNotAvailable()) { 57 | throw new ExecutionException("Arrow is enabled but not available"); 58 | } else { 59 | //Use XML if Arrow is enabled but not available and we should not fail 60 | return rCodeIOGeneratorXML; 61 | } 62 | } 63 | } else { 64 | //Use XML if Arrow is disabled 65 | return rCodeIOGeneratorXML; 66 | } 67 | } 68 | 69 | /** 70 | * Prepare R script with functions or/and module loadings that would be used in following IPC 71 | * @param rCallerOptions Current parameters for selecting implementation 72 | * @return R script with functions or/and module loadings to be added to user's code 73 | */ 74 | public static String getInterprocessDependencies(RCallerOptions rCallerOptions) { 75 | return getRCodeIOGenerator(rCallerOptions).getInterprocessDependencies(); 76 | } 77 | 78 | /** 79 | * Prepare R script for exporting variable from top level R environment to file or another IPC channel 80 | * @param rCallerOptions Current parameters for selecting implementation 81 | * @param variableName R variable to be exported 82 | * @param target file or socket where export should be saved 83 | * @return R script for exporting variable to be added to user's code 84 | */ 85 | public static String getVariableExporting(RCallerOptions rCallerOptions, String variableName, URI target) { 86 | return getRCodeIOGenerator(rCallerOptions).getVariableExporting(variableName, target); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/io/ROutputParserArrow.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.exception.ParseException; 4 | import com.github.rcaller.rstuff.RCallerOptions; 5 | import com.github.rcaller.rstuff.ROutputParser; 6 | import org.apache.commons.lang3.NotImplementedException; 7 | import org.w3c.dom.Document; 8 | import org.w3c.dom.NodeList; 9 | import java.io.*; 10 | import java.net.URI; 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * 15 | * @author Kopilov Aleksandr 16 | */ 17 | public class ROutputParserArrow implements ROutputParser { 18 | ArrowBridge bridge; 19 | URI ipcResourceURI; 20 | 21 | public ROutputParserArrow() { 22 | this.bridge = ArrowBridge.newInstance(); 23 | } 24 | 25 | public ROutputParserArrow(RCallerOptions rCallerOptions) { 26 | this.bridge = ArrowBridge.newInstance(rCallerOptions); 27 | } 28 | 29 | @Override 30 | public Document getDocument() { 31 | throw new NotImplementedException("Not accessible in Arrow implementation"); 32 | } 33 | 34 | @Override 35 | public void setDocument(Document document) { 36 | throw new NotImplementedException("Not accessible in Arrow implementation"); 37 | } 38 | 39 | @Override 40 | public File getXMLFile() { 41 | throw new NotImplementedException("Not accessible in Arrow implementation"); 42 | } 43 | 44 | @Override 45 | public URI getIPCResource() { 46 | return ipcResourceURI; 47 | } 48 | 49 | @Override 50 | public void setIPCResource(URI ipcResourceURI) { 51 | this.ipcResourceURI = ipcResourceURI; 52 | } 53 | 54 | @Override 55 | public String getXMLFileAsString() throws IOException { 56 | throw new IOException(new NotImplementedException("Not accessible in Arrow implementation")); 57 | } 58 | 59 | @Override 60 | public void setXMLFile(File xmlFile) { 61 | throw new NotImplementedException("Not accessible in Arrow implementation"); 62 | } 63 | 64 | @Override 65 | public void parse() throws ParseException { 66 | try { 67 | bridge.loadArrowData(ipcResourceURI); 68 | } catch (IOException e) { 69 | throw new ParseException("Could not load Arrow data", e); 70 | } 71 | } 72 | 73 | @Override 74 | public ArrayList getNames() { 75 | var names = bridge.getNames(); 76 | if (names instanceof ArrayList) { 77 | return (ArrayList) names; 78 | } 79 | var castedNames = new ArrayList(names); 80 | return castedNames; 81 | } 82 | 83 | @Override 84 | public String getType(String variablename) { 85 | return bridge.getType(variablename); 86 | } 87 | 88 | @Override 89 | public int[] getDimensions(String name) { 90 | return bridge.getDimensions(name); 91 | } 92 | 93 | @Override 94 | public NodeList getValueNodes(String name) { 95 | throw new NotImplementedException("Not accessible in Arrow implementation"); 96 | } 97 | 98 | @Override 99 | public String[] getAsStringArray(String name) throws ParseException { 100 | return bridge.getAsStringArray(name); 101 | } 102 | 103 | @Override 104 | public double[] getAsDoubleArray(String name) throws ParseException { 105 | return bridge.getAsDoubleArray(name); 106 | } 107 | 108 | @Override 109 | public float[] getAsFloatArray(String name) throws ParseException { 110 | return bridge.getAsFloatArray(name); 111 | } 112 | 113 | @Override 114 | public int[] getAsIntArray(String name) throws ParseException { 115 | return bridge.getAsIntArray(name); 116 | } 117 | 118 | @Override 119 | public long[] getAsLongArray(String name) throws ParseException { 120 | return bridge.getAsLongArray(name); 121 | } 122 | 123 | @Override 124 | public double[][] getAsDoubleMatrix(String name, int n, int m) throws ParseException { 125 | int[] dimensions = getDimensions(name); 126 | if (dimensions[0] == n && dimensions[1] == m) { 127 | return bridge.getAsDoubleMatrix(name); 128 | } else { 129 | double[][] result = new double[n][m]; 130 | double[] arr = this.getAsDoubleArray(name); 131 | int c = 0; 132 | for (int i = 0; i < n; i++) { 133 | for (int j = 0; j < m; j++) { 134 | result[i][j] = arr[c]; 135 | c++; 136 | } 137 | } 138 | return (result); 139 | } 140 | } 141 | 142 | @Override 143 | public double[][] getAsDoubleMatrix(String name) throws ParseException { 144 | return bridge.getAsDoubleMatrix(name); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/io/RSerializer.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.util.Globals; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.DataOutputStream; 7 | import java.io.FileWriter; 8 | import java.io.IOException; 9 | 10 | public class RSerializer { 11 | 12 | ByteArrayOutputStream byteOut; 13 | DataOutputStream dataOut; 14 | 15 | public RSerializer() { 16 | byteOut = new ByteArrayOutputStream(); 17 | dataOut = new DataOutputStream(byteOut); 18 | } 19 | 20 | public void writeVector(double[] v) throws IOException { 21 | dataOut.write(getBytes("A")); 22 | /* version */ 23 | dataOut.write(getBytes("2")); 24 | dataOut.write(getBytes("197214")); 25 | dataOut.write(getBytes("131840")); 26 | dataOut.write(getBytes("14")); 27 | /* Vector Type */ 28 | dataOut.write(getBytes(v.length)); 29 | for (int i = 0; i < v.length; i++) { 30 | dataOut.write(getBytes(v[i])); 31 | } 32 | dataOut.flush(); 33 | byteOut.flush(); 34 | dataOut.close(); 35 | byteOut.close(); 36 | } 37 | 38 | public void writeDoubleMatrix(double[][] d) throws IOException { 39 | dataOut.write(getBytes("A")); 40 | dataOut.write(getBytes("2")); 41 | dataOut.write(getBytes("197214")); 42 | dataOut.write(getBytes("131840")); 43 | dataOut.write(getBytes("525")); 44 | dataOut.write(getBytes(d.length * d[0].length)); 45 | for (int i = 0; i < d.length; i++) { 46 | for (int j = 0; j < d[0].length; j++) { 47 | dataOut.write(getBytes(String.valueOf(d[i][j]))); 48 | } 49 | } 50 | dataOut.write(getBytes("1026")); 51 | dataOut.write(getBytes("1")); 52 | dataOut.write(getBytes("262153")); 53 | dataOut.write(getBytes("3")); 54 | dataOut.write(getBytes("dim")); 55 | dataOut.write(getBytes("13")); 56 | dataOut.write(getBytes("2")); 57 | dataOut.write(getBytes(d.length)); 58 | dataOut.write(getBytes(d[0].length)); 59 | dataOut.write(getBytes("254")); 60 | dataOut.flush(); 61 | byteOut.flush(); 62 | dataOut.close(); 63 | byteOut.close(); 64 | } 65 | 66 | byte[] getBytes(String s) { 67 | return ((s + "\n").getBytes(Globals.standardCharset)); 68 | } 69 | 70 | byte[] getBytes(double d) { 71 | return ((String.valueOf(d) + "\n").getBytes(Globals.standardCharset)); 72 | } 73 | 74 | public void save(String filename) throws IOException { 75 | FileWriter writer = new FileWriter(filename); 76 | writer.write(byteOut.toString()); 77 | writer.close(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/rstuff/FailurePolicy.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.rstuff; 2 | 3 | /** 4 | * Specifies the behaviour of the program in case of an exception 5 | */ 6 | public enum FailurePolicy { 7 | 8 | RETRY_1,//retry at most once 9 | RETRY_5, 10 | RETRY_10, //retry at most 10 times 11 | RETRY_FOREVER,//retry until success 12 | CONTINUE//ignore the error and continue 13 | } 14 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/rstuff/ROutputParser.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.rstuff; 2 | 3 | import com.github.rcaller.exception.ExecutionException; 4 | import com.github.rcaller.exception.ParseException; 5 | import com.github.rcaller.io.ArrowBridge; 6 | import com.github.rcaller.io.ROutputParserArrow; 7 | import com.github.rcaller.io.ROutputParserXML; 8 | import org.w3c.dom.Document; 9 | import org.w3c.dom.NodeList; 10 | import java.io.*; 11 | import java.net.URI; 12 | import java.util.ArrayList; 13 | 14 | /** 15 | * API for reading R IPC output. 16 | * @author Mehmet Hakan Satman 17 | */ 18 | public interface ROutputParser { 19 | 20 | /** 21 | * Static factory implementation creator with given options. 22 | * Returned implementation uses XML or Arrow IPC format. 23 | * @param rCallerOptions given options 24 | * @return ROutputParser implementing object 25 | */ 26 | static ROutputParser create(RCallerOptions rCallerOptions) { 27 | if (rCallerOptions.useArrowIfAvailable()) { 28 | if (ArrowBridge.isArrowAvailable(rCallerOptions)) { 29 | //Use Arrow by default if enabled 30 | return new ROutputParserArrow(rCallerOptions); 31 | } else { 32 | if (rCallerOptions.failIfArrowNotAvailable()) { 33 | throw new ExecutionException("Arrow is enabled but not available"); 34 | } else { 35 | //Use XML if Arrow is enabled but not available and we should not fail 36 | return new ROutputParserXML(); 37 | } 38 | } 39 | } else { 40 | //Use XML if Arrow is disabled 41 | return new ROutputParserXML(); 42 | } 43 | } 44 | 45 | /** 46 | * Returns parsed XML document. 47 | * @deprecated Do not use if you are not using XML consciously 48 | * @return parsed XML document 49 | * @throw NotImplementedException if Arrow implementation is used 50 | */ 51 | @Deprecated 52 | Document getDocument(); 53 | 54 | /** 55 | * Inits parsed XML document. 56 | * @deprecated Do not use if you are not using XML consciously 57 | * @throw NotImplementedException if Arrow implementation is used 58 | */ 59 | @Deprecated 60 | void setDocument(Document document); 61 | 62 | /** 63 | * Returns XML file. 64 | * @deprecated Do not use if you are not using XML consciously. Can be replaced with {@link #getIPCResource} 65 | * @return XML file 66 | * @throw NotImplementedException if Arrow implementation is used 67 | */ 68 | @Deprecated 69 | File getXMLFile(); 70 | 71 | URI getIPCResource(); 72 | 73 | /** 74 | * Returns raw XML document. 75 | * @deprecated Do not use if you are not using XML consciously 76 | * @return raw XML document 77 | * @throw NotImplementedException if Arrow implementation is used 78 | */ 79 | @Deprecated 80 | String getXMLFileAsString() throws IOException; 81 | 82 | /** 83 | * Inits XML file. 84 | * @deprecated Do not use if you are not using XML consciously. Can be replaced with {@link #setIPCResource} 85 | * @throw NotImplementedException if Arrow implementation is used 86 | */ 87 | @Deprecated 88 | void setXMLFile(File xmlFile); 89 | 90 | void setIPCResource(URI ipcResourceURI); 91 | 92 | void parse() throws ParseException; 93 | 94 | ArrayList getNames(); 95 | 96 | String getType(String variablename); 97 | 98 | int[] getDimensions(String name); 99 | 100 | /** 101 | * Returns nodes from parsed XML document. 102 | * @deprecated Do not use if you are not using XML consciously 103 | * @return nodes from parsed XML document 104 | * @throw NotImplementedException if Arrow implementation is used 105 | */ 106 | @Deprecated 107 | NodeList getValueNodes(String name); 108 | 109 | String[] getAsStringArray(String name) throws ParseException; 110 | 111 | double[] getAsDoubleArray(String name) throws ParseException; 112 | 113 | float[] getAsFloatArray(String name) throws ParseException; 114 | 115 | int[] getAsIntArray(String name) throws ParseException; 116 | 117 | long[] getAsLongArray(String name) throws ParseException; 118 | 119 | default boolean[] getAsLogicalArray(String name) throws ParseException { 120 | String[] strResults = getAsStringArray(name); 121 | boolean[] bools = new boolean[strResults.length]; 122 | for (int i = 0; i < strResults.length; i++) { 123 | try { 124 | bools[i] = Boolean.parseBoolean(strResults[i]); 125 | } catch (Exception e) { 126 | throw new ParseException("String value '" + strResults[i] + "' can not convert to boolean"); 127 | } 128 | } 129 | return (bools); 130 | } 131 | 132 | double[][] getAsDoubleMatrix(String name, int n, int m) throws ParseException; 133 | 134 | double[][] getAsDoubleMatrix(String name) throws ParseException; 135 | 136 | } 137 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/rstuff/RPlotViewer.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.rstuff; 2 | 3 | import com.github.rcaller.util.Globals; 4 | import javax.swing.*; 5 | import java.awt.*; 6 | 7 | /** 8 | * 9 | * @author Mehmet Hakan Satman 10 | */ 11 | public class RPlotViewer extends JFrame { 12 | 13 | private ImageIcon img; 14 | 15 | public ImageIcon getImg() { 16 | return img; 17 | } 18 | 19 | public void setImg(ImageIcon img) { 20 | this.img = img; 21 | } 22 | 23 | public RPlotViewer(ImageIcon img) { 24 | this.img = img; 25 | this.setSize(img.getIconWidth() + 20, img.getIconHeight() + 60); 26 | this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 27 | this.setTitle(Globals.version + " - Generated Plot"); 28 | repaint(); 29 | } 30 | 31 | @Override 32 | public void paint(Graphics g) { 33 | super.paint(g); 34 | if (img != null) { 35 | g.drawImage(this.img.getImage(), 10, 30, this); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/rstuff/RService.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.rstuff; 2 | 3 | 4 | public class RService { 5 | 6 | public static String type_String = "[Ljava.lang.String;"; 7 | public static String type_double = "[Ljava.lang.double;"; 8 | public static String type_Integer = "[Ljava.lang.Integer;"; 9 | private RCaller rcaller = null; 10 | private RCode rcode = null; 11 | 12 | public RService(){ 13 | rcaller = RCaller.create(); 14 | rcode = RCode.create(); 15 | rcaller.setRCode(rcode); 16 | } 17 | 18 | public RCaller getRCaller(){ 19 | return(this.rcaller); 20 | } 21 | 22 | public RCode getRCode(){ 23 | return(this.rcode); 24 | } 25 | 26 | public Object[] get(String var, String command, String type){ 27 | rcode.addRCode(var + " <- " +command); 28 | rcaller.runAndReturnResultOnline(var); 29 | if (type.equals(type_String)) { 30 | return(rcaller.getParser().getAsStringArray(var)); 31 | } else if (type.equals(type_Integer)) { 32 | int[] res = rcaller.getParser().getAsIntArray(var); 33 | Integer[] ints = new Integer[res.length]; 34 | for (int i=0;iMiroslav Batchkarov 17 | */ 18 | public class RStreamHandler implements Runnable { 19 | private AtomicBoolean stillReading = new AtomicBoolean(); 20 | private InputStream stream = null; 21 | private BufferedReader reader = null; 22 | private final Thread consumerThread; 23 | private String name = null; 24 | private ArrayList eventHandlers = null; 25 | private boolean OKAYdetected = false; 26 | 27 | public RStreamHandler(InputStream stream, String name) { 28 | this.stream = stream; 29 | this.name = name; 30 | consumerThread = new Thread(this, name + "ProcessorThread"); 31 | this.eventHandlers = new ArrayList<>(); 32 | } 33 | 34 | public boolean isOKAYdetected() { 35 | return OKAYdetected; 36 | } 37 | 38 | public void setOKAYdetected(boolean OKAYdetected) { 39 | this.OKAYdetected = OKAYdetected; 40 | } 41 | 42 | 43 | 44 | public void setStream(InputStream stream) { 45 | this.stream = stream; 46 | } 47 | 48 | public void addEventHandler(EventHandler eh) { 49 | this.eventHandlers.add(eh); 50 | } 51 | 52 | public void removeEventHandler(EventHandler eh) { 53 | this.eventHandlers.remove(eh); 54 | } 55 | 56 | public void start() { 57 | this.consumerThread.start(); 58 | } 59 | 60 | public void stop() { 61 | try { 62 | while (true) { 63 | stillReading.set(false); 64 | this.consumerThread.join(100); 65 | if (!this.consumerThread.isAlive()) { 66 | break; 67 | } else if (!stillReading.get()) { 68 | this.consumerThread.interrupt(); 69 | break; 70 | } 71 | } 72 | } catch (InterruptedException ex) { 73 | throw new RuntimeException(ex); 74 | } 75 | } 76 | 77 | public boolean isAlive() { 78 | return this.consumerThread.isAlive(); 79 | } 80 | 81 | public void run() { 82 | if (reader == null) { 83 | Charset charset = Charset.forName(System.getProperty("sun.jnu.encoding", Charset.defaultCharset().name())); 84 | reader = new BufferedReader(new InputStreamReader(stream, charset)); 85 | } 86 | try { 87 | while (true) { 88 | String s = reader.readLine(); 89 | //System.out.println(name+": "+s); 90 | OKAYdetected = false; 91 | stillReading.set(true); 92 | if (s == null){ 93 | break; 94 | } 95 | if(s.contains("OKAY!")){ 96 | this.OKAYdetected = true; 97 | } 98 | for (EventHandler eventHandler : eventHandlers) { 99 | eventHandler.messageReceived(name, s); 100 | } 101 | } 102 | } catch (IOException e) { 103 | e.printStackTrace(); 104 | } 105 | stillReading.set(false); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/scriptengine/LanguageElement.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller.scriptengine; 3 | 4 | 5 | public class LanguageElement { 6 | 7 | private String objectName; 8 | 9 | public String getObjectName() { 10 | return objectName; 11 | } 12 | 13 | public void setObjectName(String objectName) { 14 | this.objectName = objectName; 15 | } 16 | 17 | public LanguageElement(String objectName){ 18 | this.objectName = objectName; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/scriptengine/NamedArgument.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.scriptengine; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class NamedArgument { 6 | 7 | private String name = null; 8 | private Object obj = null; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public Object getObj() { 19 | return obj; 20 | } 21 | 22 | public void setObj(Object obj) { 23 | this.obj = obj; 24 | } 25 | 26 | public NamedArgument(String name, Object o) { 27 | this.name = name; 28 | this.obj = o; 29 | } 30 | 31 | public static NamedArgument Named(String name, Object o) { 32 | return (new NamedArgument(name, o)); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return (name + ": " + obj.getClass().getCanonicalName()); 38 | } 39 | 40 | public static Object find(ArrayList list, String name) { 41 | for (NamedArgument n : list) { 42 | if (n.getName().equals(name)) { 43 | return (n.getObj()); 44 | } 45 | } 46 | return (null); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/scriptengine/RCallerScriptEngineFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.scriptengine; 2 | 3 | import javax.script.ScriptEngine; 4 | import javax.script.ScriptEngineFactory; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class RCallerScriptEngineFactory implements ScriptEngineFactory { 9 | 10 | @Override 11 | public String getEngineName() { 12 | System.out.println("getEngineName() called"); 13 | return ("RCaller"); 14 | } 15 | 16 | @Override 17 | public String getEngineVersion() { 18 | return ("0.1"); 19 | } 20 | 21 | @Override 22 | public List getExtensions() { 23 | ArrayList ext = new ArrayList<>(); 24 | ext.add("R"); 25 | ext.add("RCaller"); 26 | return (ext); 27 | } 28 | 29 | @Override 30 | public List getMimeTypes() { 31 | ArrayList mimes = new ArrayList<>(); 32 | mimes.add("text/r"); 33 | return (mimes); 34 | } 35 | 36 | @Override 37 | public List getNames() { 38 | ArrayList names = new ArrayList<>(); 39 | names.add("RCallerScriptEngine"); 40 | names.add("RCaller"); 41 | names.add("R"); 42 | return (names); 43 | } 44 | 45 | @Override 46 | public String getLanguageName() { 47 | return ("R"); 48 | } 49 | 50 | @Override 51 | public String getLanguageVersion() { 52 | return ("3.2.4"); 53 | } 54 | 55 | @Override 56 | public Object getParameter(String key) { 57 | System.out.println("getParameter: "+key); 58 | if (null != key) { 59 | switch (key) { 60 | case ScriptEngine.ENGINE: 61 | return this.getEngineName(); 62 | case ScriptEngine.ENGINE_VERSION: 63 | return this.getEngineVersion(); 64 | case ScriptEngine.NAME: 65 | return this.getNames(); 66 | case ScriptEngine.LANGUAGE: 67 | return this.getLanguageName(); 68 | case ScriptEngine.LANGUAGE_VERSION: 69 | return this.getLanguageVersion(); 70 | default: 71 | return null; 72 | } 73 | } 74 | return("!"); 75 | } 76 | 77 | @Override 78 | public String getMethodCallSyntax(String string, String string1, String... strings) { 79 | StringBuilder buf = new StringBuilder(); 80 | buf.append(string); 81 | buf.append("("); 82 | buf.append(string1); 83 | if (strings.length == 0) { 84 | buf.append(")"); 85 | return (buf.toString()); 86 | } 87 | for (int i = 0; i < strings.length; i++) { 88 | buf.append(strings[i]); 89 | if (i < strings.length) { 90 | buf.append(","); 91 | } 92 | } 93 | buf.append(")"); 94 | return (buf.toString()); 95 | } 96 | 97 | @Override 98 | public String getOutputStatement(String string) { 99 | return ("print(" + string + ")"); 100 | } 101 | 102 | @Override 103 | public String getProgram(String... strings) { 104 | return ("Program"); 105 | } 106 | 107 | @Override 108 | public ScriptEngine getScriptEngine() { 109 | return (new RCallerScriptEngine()); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/statistics/RandomNumberGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.statistics; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | /** 7 | * 8 | * @author Mehmet Hakan Satman 9 | */ 10 | public class RandomNumberGenerator { 11 | 12 | private RCaller caller; 13 | private RCode code; 14 | 15 | public RandomNumberGenerator(RCaller rcaller) { 16 | this.caller = rcaller; 17 | this.code = RCode.create(); 18 | } 19 | 20 | private double[] generateRandom(String strcode) throws Exception { 21 | code.clear(); 22 | code.getCode().append(strcode).append("\n"); 23 | caller.setRCode(code); 24 | caller.runAndReturnResult("rcaller_data"); 25 | return (caller.getParser().getAsDoubleArray("rcaller_data")); 26 | } 27 | 28 | public double[] randomNormal(int n, double mean, double standardDeviation) throws Exception { 29 | return (generateRandom("rcaller_data<-rnorm(" + n + "," + mean + "," + standardDeviation + ")")); 30 | } 31 | 32 | public double[] randomLogNormal(int n, double logmean, double logStandardDeviation) throws Exception { 33 | return (generateRandom("rcaller_data<-rlnorm(" + n + "," + logmean + "," + logStandardDeviation + ")")); 34 | } 35 | 36 | public double[] randomUniform(int n, double min, double max) throws Exception { 37 | return (generateRandom("rcaller_data<-runif(" + n + "," + min + "," + max + ")")); 38 | } 39 | 40 | public double[] randomBeta(int n, double shape1, double shape2) throws Exception { 41 | return (generateRandom("rcaller_data<-rbeta(" + n + "," + shape1 + "," + shape2 + ")")); 42 | } 43 | 44 | public double[] randomCauchy(int n, double location, double scale) throws Exception { 45 | return (generateRandom("rcaller_data<-rcauchy(" + n + "," + location + "," + scale + ")")); 46 | } 47 | 48 | public double[] randomT(int n, int df) throws Exception { 49 | return (generateRandom("rcaller_data<-rt(" + n + "," + df + ")")); 50 | } 51 | 52 | public double[] randomChisqare(int n, int df) throws Exception { 53 | return (generateRandom("rcaller_data<-rchisq(" + n + "," + df + ")")); 54 | } 55 | 56 | public double[] randomF(int n, int df1, int df2) throws Exception { 57 | return (generateRandom("rcaller_data<-rf(" + n + "," + df1 + "," + df2 + ")")); 58 | } 59 | 60 | public double[] randomPoisson(int n, double lambda) throws Exception { 61 | return (generateRandom("rcaller_data<-rpois(" + n + "," + lambda + ")")); 62 | } 63 | 64 | public double[] randomBinom(int n, int size, double p) throws Exception { 65 | return (generateRandom("rcaller_data<-rbinom(" + n + "," + size + "," + p + ")")); 66 | } 67 | 68 | public double[] randomNegativeBinom(int n, int size, double p) throws Exception { 69 | return (generateRandom("rcaller_data<-rnbinom(" + n + "," + size + "," + p + ")")); 70 | } 71 | 72 | public double[] randomMultinomial(int n, int size, double p) throws Exception { 73 | return (generateRandom("rcaller_data<-rmultinom(" + n + "," + size + "," + p + ")")); 74 | } 75 | 76 | public double[] randomGeometric(int n, double p) throws Exception { 77 | return (generateRandom("rcaller_data<-rgeom(" + n + "," + p + ")")); 78 | } 79 | 80 | public double[] randomWeibull(int n, double shape, double scale) throws Exception { 81 | return (generateRandom("rcaller_data<-rweibull(" + n + "," + shape + "," + scale + ")")); 82 | } 83 | 84 | public double[] randomHyperGeometric(int amount, int n, int m, int k) throws Exception { 85 | return (generateRandom("rcaller_data<-rhyper(" + amount + "," + n + "," + m + "," + k + ")")); 86 | } 87 | 88 | public double[] randomExponential(int n, double theta) throws Exception { 89 | return (generateRandom("rcaller_data<-rexp(" + n + "," + theta + ")")); 90 | } 91 | 92 | public double[] randomGamma(int n, double shape, double rate, double scale) throws Exception { 93 | return (generateRandom("rcaller_data<-rgamma(" + n + "," + shape + "," + rate + "," + scale + ")")); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/util/DataFrameUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.util; 2 | 3 | public class DataFrameUtil { 4 | 5 | public static Object[][] createEmptyObjectsMatrix(int n, int m) { 6 | return new Object[n][m]; 7 | } 8 | 9 | public static Object[][] createObjectsMatrix(int n, int m, Object o) { 10 | Object[][] objects = new Object[n][m]; 11 | 12 | for (int i = 0; i < n; i++) { 13 | for (int j = 0; j < m; j++) { 14 | objects[i][j] = o; 15 | } 16 | } 17 | 18 | return objects; 19 | } 20 | 21 | public static String[] createDefaultNamesArray(int n) { 22 | String[] names = new String[n]; 23 | 24 | for (int i = 0; i < n; i++) { 25 | names[i] = "var" + i; 26 | } 27 | 28 | return names; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RCaller/src/main/java/com/github/rcaller/util/FileStatusWatcher.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.util; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.FileSystems; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.nio.file.StandardWatchEventKinds; 9 | import java.nio.file.WatchEvent; 10 | import java.nio.file.WatchKey; 11 | import java.nio.file.WatchService; 12 | 13 | public class FileStatusWatcher { 14 | 15 | public static void waitUntilFileChanged(File file) throws IOException,InterruptedException { 16 | WatchService watchService = FileSystems.getDefault().newWatchService(); 17 | Path folder = Paths.get(file.getParent()); 18 | folder.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); 19 | while (true) { 20 | WatchKey key = watchService.take(); 21 | for (WatchEvent watchEvent : key.pollEvents()) { 22 | final WatchEvent.Kind kind = watchEvent.kind(); 23 | // Entry_modify event 24 | if (StandardWatchEventKinds.ENTRY_MODIFY == kind) { 25 | if(watchEvent.context().toString().equals(file.getName())){ 26 | watchService.close(); 27 | return; 28 | } 29 | } 30 | } 31 | key.reset(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/BasicGraphics.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.graphics.SkyTheme; 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | 7 | import java.io.File; 8 | import java.util.logging.Level; 9 | import java.util.logging.Logger; 10 | 11 | /** 12 | * 13 | * @author Mehmet Hakan Satman 14 | * 15 | */ 16 | public class BasicGraphics { 17 | 18 | public BasicGraphics() { 19 | try { 20 | RCaller caller = RCaller.create(); 21 | RCode code = RCode.create(); 22 | 23 | code.addRCode("x <- rnorm(30)"); 24 | code.addRCode("y <- rnorm(30)"); 25 | code.addRCode("ols <- lm(y~x)"); 26 | 27 | caller.setGraphicsTheme(new SkyTheme()); 28 | 29 | File plt = code.startPlot(); 30 | code.addRCode("barplot(x,y)"); 31 | code.addRCode("abline(ols$coefficients[1], ols$coefficients[2])"); 32 | code.addRCode("abline(mean(y), 0)"); 33 | code.addRCode("abline(v = mean(x))"); 34 | code.endPlot(); 35 | 36 | caller.setRCode(code); 37 | caller.runAndReturnResult("ols"); 38 | 39 | code.showPlot(plt); 40 | } catch (Exception e) { 41 | Logger.getLogger(BasicGraphics.class.getName()).log(Level.SEVERE, e.getMessage()); 42 | } 43 | } 44 | 45 | public static void main(String[] args) { 46 | new BasicGraphics(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/BasicScriptEngine.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.scriptengine.RCallerScriptEngine; 4 | import com.github.rcaller.util.Globals; 5 | 6 | import javax.script.ScriptEngine; 7 | import javax.script.ScriptEngineManager; 8 | import javax.script.ScriptException; 9 | 10 | public class BasicScriptEngine { 11 | 12 | public static void main(String[] args) { 13 | try { 14 | new BasicScriptEngine(); 15 | } catch (ScriptException exception) { 16 | System.out.println("Error while scripting: " + exception.toString()); 17 | } 18 | } 19 | 20 | public BasicScriptEngine() throws ScriptException{ 21 | Example1(); 22 | Example2(); 23 | } 24 | 25 | public void Example1() throws ScriptException { 26 | 27 | Globals.R_current = "/usr/bin/R"; 28 | RCallerScriptEngine engine = new RCallerScriptEngine(); 29 | 30 | engine.put("mydata", new double[]{1, 2, 3, 4, 5}); 31 | engine.eval("mymean <- mean(mydata)"); 32 | 33 | double[] result = (double[]) engine.get("mymean"); 34 | System.out.println("Mean is " + result[0]); 35 | engine.close(); 36 | 37 | } 38 | 39 | 40 | 41 | public void Example2() throws ScriptException { 42 | 43 | ScriptEngineManager manager = new ScriptEngineManager(); 44 | ScriptEngine engine = manager.getEngineByName("RCaller"); 45 | 46 | engine.put("a", 25); 47 | 48 | engine.eval("b <- sqrt(a)"); 49 | 50 | double[] result = (double[]) engine.get("b"); 51 | 52 | System.out.println("b is " + result[0]); 53 | 54 | ((RCallerScriptEngine) engine).close(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/DescriptiveStatistics.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.util.Random; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | /** 11 | * 12 | * @author Mehmet Hakan Satman 13 | * @since 2.0 14 | * @version 2.0 15 | */ 16 | public class DescriptiveStatistics { 17 | 18 | /** 19 | * Standalone test application. 20 | * Calculates descriptive statistics of a random array using R 21 | * from Java. 22 | * 23 | */ 24 | public DescriptiveStatistics() { 25 | try { 26 | 27 | /** 28 | * Creating Java's random number generator 29 | */ 30 | Random random = new Random(); 31 | 32 | /** 33 | * Creating RCaller 34 | */ 35 | RCaller caller = RCaller.create(); 36 | RCode code = RCode.create(); 37 | 38 | /** 39 | * We are creating a random data from a normal distribution 40 | * with zero mean and unit variance with size of 100 41 | */ 42 | double[] data = new double[100]; 43 | 44 | for (int i = 0; i < data.length; i++) { 45 | data[i] = random.nextGaussian(); 46 | } 47 | 48 | /** 49 | * We are transferring the double array to R 50 | */ 51 | code.addDoubleArray("x", data); 52 | 53 | /** 54 | * Adding R Code 55 | */ 56 | code.addRCode("my.mean<-mean(x)"); 57 | code.addRCode("my.var<-var(x)"); 58 | code.addRCode("my.sd<-sd(x)"); 59 | code.addRCode("my.min<-min(x)"); 60 | code.addRCode("my.max<-max(x)"); 61 | code.addRCode("my.standardized<-scale(x)"); 62 | 63 | /** 64 | * Combining all of them in a single list() object 65 | */ 66 | code.addRCode( 67 | "my.all<-list(mean=my.mean, variance=my.var, sd=my.sd, min=my.min, max=my.max, std=my.standardized)"); 68 | 69 | /** 70 | * We want to handle the list 'my.all' 71 | */ 72 | caller.setRCode(code); 73 | caller.runAndReturnResult("my.all"); 74 | 75 | double[] results; 76 | 77 | /** 78 | * Retrieving the 'mean' element of list 'my.all' 79 | */ 80 | results = caller.getParser().getAsDoubleArray("mean"); 81 | System.out.println("Mean is " + results[0]); 82 | 83 | /** 84 | * Retrieving the 'variance' element of list 'my.all' 85 | */ 86 | results = caller.getParser().getAsDoubleArray("variance"); 87 | System.out.println("Variance is " + results[0]); 88 | 89 | /** 90 | * Retrieving the 'sd' element of list 'my.all' 91 | */ 92 | results = caller.getParser().getAsDoubleArray("sd"); 93 | System.out.println("Standard deviation is " + results[0]); 94 | 95 | /** 96 | * Retrieving the 'min' element of list 'my.all' 97 | */ 98 | results = caller.getParser().getAsDoubleArray("min"); 99 | System.out.println("Minimum is " + results[0]); 100 | 101 | /** 102 | * Retrieving the 'max' element of list 'my.all' 103 | */ 104 | results = caller.getParser().getAsDoubleArray("max"); 105 | System.out.println("Maximum is " + results[0]); 106 | 107 | /** 108 | * Retrieving the 'std' element of list 'my.all' 109 | */ 110 | results = caller.getParser().getAsDoubleArray("std"); 111 | 112 | /** 113 | * Now we are retrieving the standardized form of vector x 114 | */ 115 | System.out.println("Standardized x is "); 116 | 117 | for (double result : results) { 118 | System.out.print(result + ", "); 119 | } 120 | } catch (Exception e) { 121 | Logger.getLogger(DescriptiveStatistics.class.getName()).log(Level.SEVERE, e.getMessage()); 122 | } 123 | } 124 | 125 | public static void main(String[] args) { 126 | new DescriptiveStatistics(); 127 | } 128 | } 129 | 130 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/EmptyArray.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | 10 | /** 11 | * In this example, two String arrays are passed to R. 12 | * In R side, intersection of these non-overlapping arrays 13 | * are calculated. The result is an empty vector. 14 | */ 15 | public class EmptyArray { 16 | 17 | public EmptyArray() { 18 | try { 19 | RCaller caller = RCaller.create(); 20 | RCode code = RCode.create(); 21 | 22 | String[] str11 = new String[]{"a", "b", "c", "d", "e", "f", "g", "s", "c"}; 23 | String[] str22 = new String[]{"d", "b", "a", "l", "m", "a", "f", "r", "s"}; 24 | 25 | 26 | code.addStringArray("x", str11); 27 | code.addStringArray("y", str22); 28 | 29 | code.addRCode("result <- intersect(x, y);"); 30 | 31 | caller.setRCode(code); 32 | caller.runAndReturnResult("result"); 33 | 34 | String[] v = caller.getParser().getAsStringArray("result"); 35 | for (String aV : v) { 36 | System.out.println(aV); 37 | } 38 | 39 | } catch (Exception e) { 40 | Logger.getLogger(EmptyArray.class.getName()).log(Level.SEVERE, e.getMessage()); 41 | } 42 | } 43 | 44 | public static void main(String[] args) { 45 | new EmptyArray(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/Forecasting.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.util.Random; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | /** 11 | * In this example, an automatic ARIMA model 12 | * selection is performed using the R package forecast. 13 | */ 14 | public class Forecasting { 15 | 16 | public static void main(String[] args) { 17 | new Forecasting(); 18 | } 19 | 20 | public Forecasting() { 21 | Random random = new Random(12345); 22 | double[] stockClosePrices = new double[100]; 23 | stockClosePrices[0] = 0; 24 | for (int i = 1; i < stockClosePrices.length; i++) { 25 | stockClosePrices[i] = 0.5 + 1 * stockClosePrices[i - 1] + random.nextGaussian(); 26 | } 27 | RunRScript(stockClosePrices); 28 | } 29 | 30 | public void RunRScript(double[] stockClosePrices) { 31 | try { 32 | 33 | RCaller caller = RCaller.create(); 34 | 35 | RCode code = RCode.create(); 36 | 37 | code.addDoubleArray("x", stockClosePrices); 38 | code.R_require("forecast"); 39 | code.addRCode("ww <- auto.arima(x)"); 40 | code.addRCode("tt <- forecast(ww,h=20)"); 41 | 42 | code.addRCode("myResult <- list(upper=tt$upper, lower=tt$lower, fitted = as.double(tt$fitted))"); 43 | 44 | caller.setRCode(code); 45 | caller.runAndReturnResult("myResult"); 46 | 47 | /** 48 | * It is good to have a look at the XML file 49 | * for having info about which variables are passed to result 50 | */ 51 | System.out.println(caller.getParser().getXMLFileAsString()); 52 | 53 | double[] upValues = caller.getParser().getAsDoubleArray("upper"); 54 | double[] loValues = caller.getParser().getAsDoubleArray("lower"); 55 | double[] fitted = caller.getParser().getAsDoubleArray("fitted"); 56 | 57 | for (int i = 0; i < upValues.length; i++) { 58 | System.out.println(i + ": upValues: " + upValues[i] + ", fitted: " + fitted[i] + ", loValues: " + loValues[i]); 59 | } 60 | 61 | } catch (Exception e) { 62 | Logger.getLogger(Forecasting.class.getName()).log(Level.SEVERE, e.getMessage()); 63 | } 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/GraphicsWithThemes.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.graphics.BlackTheme; 6 | 7 | import javax.swing.*; 8 | import java.io.File; 9 | import java.util.logging.Level; 10 | import java.util.logging.Logger; 11 | 12 | /** 13 | * 14 | * @author Mehmet Hakan Satman 15 | */ 16 | public class GraphicsWithThemes { 17 | 18 | public static void main(String[] args) { 19 | new GraphicsWithThemes(); 20 | } 21 | 22 | public GraphicsWithThemes() { 23 | try { 24 | 25 | RCaller caller = RCaller.create(); 26 | 27 | /** 28 | * After version 2.0.6 29 | * Graphics themes change the theme for plots. 30 | * Themes: 31 | * BlackTheme 32 | * SkyTheme 33 | * DefaultTheme 34 | */ 35 | caller.setGraphicsTheme(new BlackTheme()); 36 | 37 | 38 | RCode code = RCode.create(); 39 | 40 | 41 | double[] numbers = new double[]{1, 4, 3, 5, 6, 10}; 42 | 43 | code.addDoubleArray("x", numbers); 44 | 45 | File file = code.startPlot(); 46 | code.addRCode("plot.ts(x)"); 47 | code.endPlot(); 48 | 49 | caller.setRCode(code); 50 | 51 | caller.runOnly(); 52 | 53 | /** 54 | * Handling generated plot as an ImageIcon 55 | */ 56 | ImageIcon ii = code.getPlot(file); 57 | 58 | code.showPlot(file); 59 | 60 | System.out.println("success"); 61 | } catch (Exception e) { 62 | Logger.getLogger(GraphicsWithThemes.class.getName()).log(Level.SEVERE, e.getMessage()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/GridCap.java: -------------------------------------------------------------------------------- 1 | 2 | package examples; 3 | 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | 7 | /** 8 | * This example installs the package grid 9 | * in R and produces some graphics. 10 | */ 11 | public class GridCap { 12 | 13 | public static void main(String[] args){ 14 | 15 | RCaller caller = RCaller.create(); 16 | RCode code = RCode.create(); 17 | 18 | code.R_require("grid"); 19 | 20 | code.addRCode("dev.new(width = 0.5, height = 0.5)"); 21 | code.addRCode("grid.rect()"); 22 | code.addRCode("grid.text(\"hi\")"); 23 | code.addRCode("cap <- grid.cap()"); 24 | code.addRCode("dev.off()"); 25 | 26 | caller.setRCode(code); 27 | caller.runAndReturnResult("cap"); 28 | 29 | 30 | int[] dims = caller.getParser().getDimensions("cap"); 31 | System.out.println("Returned matrix dimensions: "+dims[0]+" - "+dims[1]); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/Main.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.io.File; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | /** 11 | * 12 | * @author Mehmet Hakan Satman 13 | */ 14 | public class Main { 15 | 16 | public Main() { 17 | try { 18 | RCaller rCaller = RCaller.create(); 19 | RCode code = RCode.create(); 20 | 21 | double[] x = new double[]{1, 2, 3, 4, 5}; 22 | double[] y = new double[]{5, 7, 6, 10, 20}; 23 | code.addDoubleArray("x", x); 24 | code.addDoubleArray("y", y); 25 | code.addRCode("ols<-lm(y~x)"); 26 | code.addRCode("a<-ols$residuals"); 27 | 28 | double[] tt = new double[100]; 29 | for (int i = 0; i < tt.length; i++) { 30 | tt[i] = Math.random(); 31 | } 32 | code.addDoubleArray("tt", tt); 33 | File f = code.startPlot(); 34 | code.addRCode("pie(tt)"); 35 | code.endPlot(); 36 | 37 | rCaller.setRCode(code); 38 | rCaller.runAndReturnResult("ols"); 39 | 40 | System.out.println("Names : " + rCaller.getParser().getNames()); 41 | code.showPlot(f); 42 | double[] v = rCaller.getParser().getAsDoubleArray("fitted_values"); 43 | for (double aV : v) { 44 | System.out.println(aV); 45 | } 46 | } catch (Exception e) { 47 | Logger.getLogger(Main.class.getName()).log(Level.SEVERE, e.getMessage()); 48 | } 49 | } 50 | 51 | public static void main(String[] args) { 52 | new Main(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/ManualPaths.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.scriptengine.RCallerScriptEngine; 6 | import com.github.rcaller.util.Globals; 7 | 8 | import javax.script.ScriptException; 9 | 10 | /** 11 | * Examples showing how to set the path to the R executable manually 12 | */ 13 | public class ManualPaths { 14 | public static void main(String[] args) { 15 | try { 16 | RCallerScriptEngineExample(); 17 | RCallerExample(); 18 | } catch (ScriptException exception) { 19 | System.out.println("Error while scripting: " + exception.toString()); 20 | } 21 | } 22 | 23 | /** 24 | * Example using the scripting engine 25 | * 26 | * @throws ScriptException 27 | */ 28 | public static void RCallerScriptEngineExample() throws ScriptException { 29 | //Set the paths manually 30 | Globals.setRPaths("C:\\Program Files (x86)\\R\\R-2.11.1\\bin\\Rscript.exe", "C:\\Program Files (x86)\\R\\R-2.11.1\\bin\\R.exe"); 31 | //Get the engine 32 | RCallerScriptEngine engine = new RCallerScriptEngine(); 33 | //Add a variable 34 | engine.put("mydata", new double[]{1, 2, 3, 4, 5}); 35 | //Evaluate an expression 36 | engine.eval("mymean <- mean(mydata)"); 37 | //Get the value of a variable 38 | double[] result = (double[]) engine.get("mymean"); 39 | System.out.println("Mean is " + result[0]); 40 | engine.close(); 41 | } 42 | 43 | /** 44 | * Example using the RCaller object 45 | */ 46 | public static void RCallerExample() { 47 | //Set the paths manually 48 | Globals.setRPaths("C:\\Program Files (x86)\\R\\R-2.11.1\\bin\\Rscript.exe", "C:\\Program Files (x86)\\R\\R-2.11.1\\bin\\R.exe"); 49 | //Create a RCaller object 50 | RCaller rCaller = RCaller.create(); 51 | //Create a code object 52 | RCode code = RCode.create(); 53 | rCaller.setRCode(code); 54 | //Add a variable 55 | code.addDoubleArray("mydata", new double[]{1, 2, 3, 4, 5}); 56 | //Add an expression 57 | code.addRCode("mymean <- mean(mydata)"); 58 | //Evaluate code 59 | rCaller.runAndReturnResult("mymean"); 60 | //Parse result 61 | double[] result = rCaller.getParser().getAsDoubleArray("mymean"); 62 | System.out.println("Mean is " + result[0]); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/MultipleCalls.java: -------------------------------------------------------------------------------- 1 | // Fixes the bug reported in 2 | // http://stackoverflow.com/questions/24167677/rcaller-2-2-and-2-3-do-not-stop-in-sequential-command-mode-with-runandreturnresu/24170648#24170648 3 | // by the RCaller version 2.4 4 | 5 | 6 | package examples; 7 | 8 | import com.github.rcaller.rstuff.RCaller; 9 | import com.github.rcaller.rstuff.RCode; 10 | 11 | 12 | /** 13 | * This example shows how RCaller run multiple sequential commands 14 | * using a single R instance. 15 | */ 16 | public class MultipleCalls { 17 | 18 | public static void main(String[] args) { 19 | RCaller rcaller = RCaller.create(); 20 | RCode code = RCode.create(); 21 | 22 | code.addDoubleArray("x", new double[]{1.0, 2.0, 3.0, 4.0, 50.0}); 23 | code.addRCode("result <- mean(x)"); 24 | rcaller.setRCode(code); 25 | System.out.println("Running R"); 26 | 27 | rcaller.runAndReturnResultOnline("result"); 28 | 29 | double mean = rcaller.getParser().getAsDoubleArray("result")[0]; 30 | System.out.println("mean: " + mean); 31 | 32 | code.clear(); 33 | code.addRCode("result <- sd(x)"); 34 | rcaller.runAndReturnResultOnline("result"); 35 | 36 | double sd = rcaller.getParser().getAsDoubleArray("result")[0]; 37 | System.out.println("sd: " + sd); 38 | 39 | code.clear(); 40 | code.addRCode("result <- mad(x)"); 41 | rcaller.runAndReturnResultOnline("result"); 42 | 43 | double mad = rcaller.getParser().getAsDoubleArray("result")[0]; 44 | System.out.println("mad: " + mad); 45 | rcaller.stopStreamConsumers(); 46 | rcaller.stopRCallerOnline(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/OrdinaryLeastSquares.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | /** 10 | * 11 | * @author Mehmet Hakan Satman 12 | * @since 2.0 13 | * @version 2.0 14 | * 15 | */ 16 | public class OrdinaryLeastSquares { 17 | 18 | public static void main(String[] args) { 19 | new OrdinaryLeastSquares(); 20 | } 21 | 22 | /** 23 | * 24 | * Ordinary Least Squares with RCaller. 25 | * This class runs the lm() function of R 26 | * for regressing user defined vector y on vector x from java 27 | */ 28 | public OrdinaryLeastSquares() { 29 | 30 | try { 31 | /** 32 | * Creating an instance of RCaller class 33 | */ 34 | RCaller caller = RCaller.create(); 35 | RCode code = RCode.create(); 36 | 37 | /** 38 | * Creating vectors x and y 39 | */ 40 | double[] x = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 41 | double[] y = new double[]{2, 4, 6, 8, 10, 12, 14, 16, 18, 30}; 42 | 43 | /** 44 | * Converting Java arrays to R arrays 45 | */ 46 | code.addDoubleArray("x", x); 47 | code.addDoubleArray("y", y); 48 | 49 | /** 50 | * R code for regression of y on x 51 | */ 52 | code.addRCode("ols<-lm(y~x)"); 53 | 54 | /** 55 | * Run all! Our regression code returns something 56 | * and we want to handle the variable 'ols' 57 | */ 58 | caller.setRCode(code); 59 | caller.runAndReturnResult("ols"); 60 | 61 | /** 62 | * Getting names of components of the variable 'ols' 63 | */ 64 | System.out.println("Available results from lm() object:"); 65 | System.out.println(caller.getParser().getNames()); 66 | 67 | 68 | /** 69 | * Getting ols$residulas, ols$coefficients and ols$fitted.values 70 | * The names after '$' are components of the lm() object in R language 71 | */ 72 | double[] residuals = caller.getParser().getAsDoubleArray("residuals"); 73 | double[] coefficients = caller.getParser().getAsDoubleArray("coefficients"); 74 | double[] fitteds = caller.getParser().getAsDoubleArray("fitted_values"); 75 | 76 | /** 77 | * Printing results 78 | */ 79 | System.out.println("Coefficients:"); 80 | for (int i = 0; i < coefficients.length; i++) { 81 | System.out.println("Beta " + i + " = " + coefficients[i]); 82 | } 83 | 84 | System.out.println("Residuals:"); 85 | for (int i = 0; i < residuals.length; i++) { 86 | System.out.println(i + " = " + residuals[i]); 87 | } 88 | 89 | System.out.println("Fitted Values:"); 90 | for (int i = 0; i < fitteds.length; i++) { 91 | System.out.println(i + " = " + fitteds[i]); 92 | } 93 | 94 | } catch (Exception e) { 95 | /** 96 | * Note that, RCaller does some OS based works such as creating an external process and 97 | * reading files from temporary directories or creating images for plots. Those operations 98 | * may cause exceptions for those that user must handle the potential errors. 99 | */ 100 | Logger.getLogger(OrdinaryLeastSquares.class.getName()).log(Level.SEVERE, e.getMessage()); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/PRandomNumberGenerator.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.statistics.RandomNumberGenerator; 5 | 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | /** 10 | * 11 | * @author Mehmet Hakan Satman 12 | */ 13 | public class PRandomNumberGenerator { 14 | 15 | public static void main(String[] args) { 16 | new PRandomNumberGenerator(); 17 | } 18 | 19 | public PRandomNumberGenerator() { 20 | try { 21 | /** 22 | * RCaller instant 23 | */ 24 | RCaller caller = RCaller.create(); 25 | 26 | /** 27 | * Random Number Generator 28 | */ 29 | RandomNumberGenerator rng = new RandomNumberGenerator(caller); 30 | 31 | /** 32 | * Generating random numbers from a normal distribution with 33 | * zero mean and unit standard deviation 34 | */ 35 | double[] d = rng.randomNormal(10, 0, 1); 36 | 37 | /** 38 | * Printing generated content 39 | */ 40 | for (double aD : d) { 41 | System.out.println(aD); 42 | } 43 | } catch (Exception e) { 44 | Logger.getLogger(PRandomNumberGenerator.class.getName()).log(Level.SEVERE, e.getMessage()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/RegressionWithRandomData.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | /** 10 | * 11 | * @author Mehmet Hakan Satman 12 | */ 13 | public class RegressionWithRandomData { 14 | 15 | public static void main(String[] args) { 16 | new RegressionWithRandomData(); 17 | } 18 | 19 | public RegressionWithRandomData() { 20 | try { 21 | /** 22 | * Creating an instance of RCaller 23 | */ 24 | RCaller caller = RCaller.create(); 25 | RCode code = RCode.create(); 26 | 27 | /** 28 | * Generating random model with X ~ Normal(0,1), 29 | * e ~ Normal(0,1) and y = 5.0 + 5.0x + e 30 | */ 31 | code.addRCode("set.seed(123)"); 32 | code.addRCode("x <- rnorm(10)"); 33 | code.addRCode("e <- rnorm(10)"); 34 | code.addRCode("y <- 5.0 + 5.0 * x + e"); 35 | 36 | /** 37 | * Regression using simulated data 38 | */ 39 | code.addRCode("ols <- lm(y~x)"); 40 | 41 | /** 42 | * We want to handle the object 'ols' 43 | */ 44 | caller.setRCode(code); 45 | caller.runAndReturnResult("ols"); 46 | 47 | /** 48 | * Getting R results as XML 49 | * for debugging issues. 50 | */ 51 | System.out.println(caller.getParser().getXMLFileAsString()); 52 | } catch (Exception e) { 53 | Logger.getLogger(RegressionWithRandomData.class.getName()).log(Level.SEVERE, e.getMessage()); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/SampleGui.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.util.Globals; 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | 11 | /** 12 | * 13 | * @author Mehmet Hakan Satman 14 | */ 15 | public class SampleGui extends JFrame implements ActionListener { 16 | 17 | private JTextArea textArea; 18 | private JButton button; 19 | private JTextField textField; 20 | private JTextArea textResult; 21 | private JTextArea inputStreamResult; 22 | private JTextArea errorStreamResult; 23 | 24 | 25 | public SampleGui() { 26 | super("RCaller Sample GUI"); 27 | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 28 | this.setSize(640, 480); 29 | this.setLayout(null); 30 | 31 | Globals.detect_current_rscript(); 32 | 33 | textArea = new JTextArea("myvar<-c(1,2,3,4,5)\nothervar<-runif(10,0,1)\ncat(\"Hello World!\")\nfor(i in 1:5){\nprint(i)\n}\n"); 34 | textArea.setSize(350, 200); 35 | textArea.setLocation(10, 20); 36 | textArea.setBorder(new javax.swing.border.TitledBorder("R Code")); 37 | this.add(textArea); 38 | 39 | inputStreamResult = new JTextArea(); 40 | inputStreamResult.setSize(350,70); 41 | inputStreamResult.setLocation(10, 230); 42 | inputStreamResult.setBorder(new javax.swing.border.TitledBorder("Output by R")); 43 | this.add(inputStreamResult); 44 | 45 | errorStreamResult = new JTextArea(); 46 | errorStreamResult.setSize(350,70); 47 | errorStreamResult.setLocation(10, 310); 48 | errorStreamResult.setBorder(new javax.swing.border.TitledBorder("Error by R")); 49 | this.add(errorStreamResult); 50 | 51 | 52 | textField = new JTextField("othervar"); 53 | textField.setSize(200, 50); 54 | textField.setLocation(380, 20); 55 | textField.setBorder(new javax.swing.border.TitledBorder("Handle this by Java")); 56 | this.add(textField); 57 | 58 | button = new JButton("Run R Code"); 59 | button.setSize(150, 40); 60 | button.setLocation(380, 90); 61 | button.addActionListener(this); 62 | this.add(button); 63 | 64 | textResult = new JTextArea(); 65 | textResult.setSize(200, 250); 66 | textResult.setLocation(380, 140); 67 | textResult.setBorder(new javax.swing.border.TitledBorder("Result as Java object")); 68 | this.add(textResult); 69 | 70 | 71 | this.setVisible(true); 72 | } 73 | 74 | public static void main(String[] args) { 75 | new SampleGui(); 76 | } 77 | 78 | public void actionPerformed(ActionEvent e) { 79 | if (e.getActionCommand().equals("Run R Code")) { 80 | 81 | this.inputStreamResult.setText(""); 82 | this.errorStreamResult.setText(""); 83 | 84 | RCaller caller = RCaller.create(); 85 | 86 | RCode code = RCode.create(); 87 | code.addRCode(textArea.getText()); 88 | 89 | 90 | try { 91 | caller.setRCode(code); 92 | caller.runAndReturnResult(textField.getText()); 93 | double[] result = caller.getParser().getAsDoubleArray(textField.getText()); 94 | StringBuilder buf = new StringBuilder(); 95 | for (double aResult : result) { 96 | buf.append(aResult).append("\n"); 97 | } 98 | textResult.setText(buf.toString()); 99 | } catch (Exception ex) { 100 | JOptionPane.showMessageDialog(this, ex.toString()); 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/SampleRGui.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/SampleRGui.java: -------------------------------------------------------------------------------- 1 | 2 | package examples; 3 | 4 | 5 | import com.github.rcaller.rstuff.RCaller; 6 | import com.github.rcaller.rstuff.RCode; 7 | 8 | import java.awt.event.KeyEvent; 9 | import java.io.ByteArrayOutputStream; 10 | 11 | /** 12 | * A Swing interface for R using RCaller. 13 | */ 14 | public class SampleRGui extends javax.swing.JFrame { 15 | 16 | RCaller caller; 17 | RCode code; 18 | ByteArrayOutputStream byteOutput; 19 | /** 20 | * Creates new form SampleRGui 21 | */ 22 | public SampleRGui() { 23 | initComponents(); 24 | caller = RCaller.create(); 25 | code = RCode.create(); 26 | caller.setRCode(code); 27 | 28 | byteOutput = new ByteArrayOutputStream(); 29 | caller.redirectROutputToStream(byteOutput); 30 | 31 | code.addRCode("a<-1"); 32 | code.addRCode("version"); 33 | caller.runAndReturnResultOnline("a"); 34 | 35 | String result = byteOutput.toString(); 36 | jTextArea1.append(result); 37 | byteOutput.reset(); 38 | 39 | this.setVisible(true); 40 | jTextField1.requestFocus(); 41 | 42 | } 43 | 44 | /** 45 | * This method is called from within the constructor to initialize the form. 46 | * WARNING: Do NOT modify this code. The content of this method is always 47 | * regenerated by the Form Editor. 48 | */ 49 | @SuppressWarnings("unchecked") 50 | // //GEN-BEGIN:initComponents 51 | private void initComponents() { 52 | 53 | jScrollPane1 = new javax.swing.JScrollPane(); 54 | jTextArea1 = new javax.swing.JTextArea(); 55 | jTextField1 = new javax.swing.JTextField(); 56 | 57 | setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 58 | setTitle("R GUI - RCaller"); 59 | 60 | jTextArea1.setColumns(20); 61 | jTextArea1.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N 62 | jTextArea1.setRows(5); 63 | jScrollPane1.setViewportView(jTextArea1); 64 | 65 | jTextField1.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N 66 | jTextField1.addKeyListener(new java.awt.event.KeyAdapter() { 67 | public void keyPressed(java.awt.event.KeyEvent evt) { 68 | jTextField1KeyPressed(evt); 69 | } 70 | }); 71 | 72 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 73 | getContentPane().setLayout(layout); 74 | layout.setHorizontalGroup( 75 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 76 | .addGroup(layout.createSequentialGroup() 77 | .addContainerGap() 78 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 79 | .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 677, Short.MAX_VALUE) 80 | .addComponent(jTextField1)) 81 | .addContainerGap()) 82 | ); 83 | layout.setVerticalGroup( 84 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 85 | .addGroup(layout.createSequentialGroup() 86 | .addContainerGap() 87 | .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 372, Short.MAX_VALUE) 88 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 89 | .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 90 | ); 91 | 92 | pack(); 93 | }// //GEN-END:initComponents 94 | 95 | private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyPressed 96 | if(evt.getKeyCode() == KeyEvent.VK_ENTER){ 97 | code.clearOnline(); 98 | code.addRCode(jTextField1.getText()); 99 | caller.runAndReturnResultOnline("a"); 100 | jTextField1.setText(""); 101 | jTextArea1.append(byteOutput.toString()); 102 | byteOutput.reset(); 103 | } 104 | }//GEN-LAST:event_jTextField1KeyPressed 105 | 106 | /** 107 | * @param args the command line arguments 108 | */ 109 | public static void main(String args[]) { 110 | /* Set the Nimbus look and feel */ 111 | // 112 | /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 113 | * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 114 | */ 115 | try { 116 | for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 117 | if ("Nimbus".equals(info.getName())) { 118 | javax.swing.UIManager.setLookAndFeel(info.getClassName()); 119 | break; 120 | } 121 | } 122 | } catch (ClassNotFoundException ex) { 123 | java.util.logging.Logger.getLogger(SampleRGui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex.getMessage()); 124 | } catch (InstantiationException ex) { 125 | java.util.logging.Logger.getLogger(SampleRGui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex.getMessage()); 126 | } catch (IllegalAccessException ex) { 127 | java.util.logging.Logger.getLogger(SampleRGui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex.getMessage()); 128 | } catch (javax.swing.UnsupportedLookAndFeelException ex) { 129 | java.util.logging.Logger.getLogger(SampleRGui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex.getMessage()); 130 | } 131 | // 132 | 133 | /* Create and display the form */ 134 | java.awt.EventQueue.invokeLater(new Runnable() { 135 | public void run() { 136 | new SampleRGui().setVisible(true); 137 | } 138 | }); 139 | } 140 | 141 | // Variables declaration - do not modify//GEN-BEGIN:variables 142 | private javax.swing.JScrollPane jScrollPane1; 143 | private javax.swing.JTextArea jTextArea1; 144 | private javax.swing.JTextField jTextField1; 145 | // End of variables declaration//GEN-END:variables 146 | } 147 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/ScriptEngineInvocable.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.scriptengine.NamedArgument; 4 | import static com.github.rcaller.scriptengine.NamedArgument.*; 5 | import com.github.rcaller.scriptengine.RCallerScriptEngine; 6 | import com.github.rcaller.util.Globals; 7 | import java.util.ArrayList; 8 | import javax.script.Invocable; 9 | import javax.script.ScriptEngine; 10 | import javax.script.ScriptEngineManager; 11 | import javax.script.ScriptException; 12 | 13 | public class ScriptEngineInvocable { 14 | 15 | public static void main(String[] args) throws ScriptException, NoSuchMethodException{ 16 | new ScriptEngineInvocable(); 17 | } 18 | 19 | public ScriptEngineInvocable() throws ScriptException, NoSuchMethodException{ 20 | Globals.detect_current_rscript(); 21 | ScriptEngineManager manager = new ScriptEngineManager(); 22 | ScriptEngine engine = manager.getEngineByName("RCaller"); 23 | 24 | ArrayList results = (ArrayList) 25 | ((Invocable)engine).invokeFunction("sqrt", Named("",25.0)); 26 | 27 | double[] val = (double[])results.get(0).getObj(); 28 | System.out.println("Result is "+ val[0]); 29 | 30 | ((RCallerScriptEngine)engine).close(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/SimplePlot.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | 6 | import java.io.File; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | /** 11 | * 12 | * @author Mehmet Hakan Satman 13 | */ 14 | public class SimplePlot { 15 | 16 | public static void main(String[] args) { 17 | new SimplePlot(); 18 | } 19 | 20 | /** 21 | * Test for simple plots. 22 | * This class simply plots a time series array using plot.ts() 23 | * function of R. 24 | */ 25 | public SimplePlot() { 26 | try { 27 | RCaller caller = RCaller.create(); 28 | 29 | /** 30 | * One of the themes. 31 | */ 32 | 33 | RCode code = RCode.create(); 34 | 35 | 36 | double[] numbers = new double[]{1, 4, 3, 5, 6, 10}; 37 | 38 | code.addDoubleArray("x", numbers); 39 | File file = code.startPlot(); 40 | System.out.println("Plot will be saved to : " + file); 41 | code.addRCode("plot(x, pch=19)"); 42 | code.endPlot(); 43 | 44 | 45 | caller.setRCode(code); 46 | System.out.println(code.getCode().toString()); 47 | 48 | caller.runOnly(); 49 | code.showPlot(file); 50 | } catch (Exception e) { 51 | Logger.getLogger(SimplePlot.class.getName()).log(Level.SEVERE, e.getMessage()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/UnitRoots.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This example simply demonstrates calling S4 methods 3 | * using RCaller. 4 | */ 5 | package examples; 6 | 7 | import com.github.rcaller.rstuff.RCaller; 8 | import com.github.rcaller.rstuff.RCode; 9 | 10 | import java.util.Random; 11 | import java.util.logging.Level; 12 | import java.util.logging.Logger; 13 | 14 | /** 15 | * Finding unit roots using a package 16 | * which is not pre-installed. 17 | */ 18 | public class UnitRoots { 19 | 20 | public static void main(String[] args) { 21 | new UnitRoots(); 22 | } 23 | 24 | public UnitRoots() { 25 | try { 26 | /** 27 | * Creating a Random object 28 | */ 29 | Random random = new Random(12345); 30 | 31 | /** 32 | * Generating artificial data from 33 | * y[t] = 0.5 + 1* y[t-1] + epsilon 34 | * where epsilon ~ N(0,1) 35 | */ 36 | double[] stockClosePrices = new double[100]; 37 | stockClosePrices[0] = 0; 38 | for (int i = 1; i < stockClosePrices.length; i++) { 39 | stockClosePrices[i] = 0.5 + 1 * stockClosePrices[0] + random.nextGaussian(); 40 | } 41 | RCaller caller = RCaller.create(); 42 | 43 | RCode code = RCode.create(); 44 | 45 | code.addDoubleArray("x", stockClosePrices); 46 | 47 | code.R_require("fUnitRoots"); 48 | 49 | code.addRCode("ww <- diff(x, differences = 1)"); 50 | 51 | code.addRCode("tt <- unitrootTest(ww, lags=0)"); 52 | 53 | caller.setRCode(code); 54 | caller.runAndReturnResult("tt@test"); 55 | 56 | double[] res = caller.getParser().getAsDoubleArray("statistic"); 57 | System.out.println(res[0]); 58 | System.out.println("success"); 59 | } catch (Exception e) { 60 | Logger.getLogger(UnitRoots.class.getName()).log(Level.SEVERE, e.getMessage()); 61 | } 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /RCaller/src/main/java/examples/WorkingWithData.java: -------------------------------------------------------------------------------- 1 | 2 | package examples; 3 | 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | 7 | import java.io.File; 8 | import java.io.FileWriter; 9 | import java.io.PrintWriter; 10 | 11 | /** 12 | * This example shows how RCaller 13 | * handles data sent from R. The 14 | * data used is imported using 15 | * read.table() in R side. 16 | */ 17 | public class WorkingWithData { 18 | 19 | public WorkingWithData(){ 20 | 21 | /** 22 | * Creating an RCaller instance 23 | */ 24 | RCaller caller = RCaller.create(); 25 | 26 | /** 27 | * Creating a source code 28 | */ 29 | RCode code = RCode.create(); 30 | 31 | /** 32 | * Creating an external data file 33 | * Suppose that the data file is like 34 | * X Y Z 35 | * 1 2 3 36 | * 4 5 6 37 | * 7 8 9 38 | * 10 11 12 39 | */ 40 | File f = null; 41 | try{ 42 | f = File.createTempFile("rcallerexmp", ""); 43 | FileWriter writer = new FileWriter (f); 44 | PrintWriter pwriter = new PrintWriter(writer); 45 | pwriter.println("X Y Z"); 46 | pwriter.println("1 2 3"); 47 | pwriter.println("4 5 6"); 48 | pwriter.println("7 8 9"); 49 | pwriter.println("10 11 12"); 50 | pwriter.flush(); 51 | pwriter.close(); 52 | }catch(Exception e){ 53 | System.out.println("Error while writing to external data file"); 54 | } 55 | 56 | /** 57 | * Now, writing some R Code 58 | */ 59 | if (f != null) { 60 | code.addRCode("data <- read.table (\""+f.getAbsoluteFile()+"\", header=TRUE)"); 61 | } 62 | 63 | /** 64 | * Running the Code 65 | */ 66 | caller.setRCode(code); 67 | caller.runAndReturnResult("data"); 68 | 69 | /** 70 | * Getting Results 71 | */ 72 | double[] Z = caller.getParser().getAsDoubleArray("Z"); 73 | 74 | /** 75 | * Printing Z 76 | */ 77 | for (double aZ : Z) { 78 | System.out.println(aZ); 79 | } 80 | } 81 | 82 | public static void main(String[] args){ 83 | new WorkingWithData(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /RCaller/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory: -------------------------------------------------------------------------------- 1 | com.github.rcaller.scriptengine.RCallerScriptEngineFactory 2 | -------------------------------------------------------------------------------- /RCaller/src/main/resources/arrow_bridge.R: -------------------------------------------------------------------------------- 1 | require("arrow") 2 | 3 | send_element_by_arrow <- function(obj, name, stream) { 4 | if (is.data.frame(obj)) { 5 | #Export by Arrow as is 6 | arrow::write_ipc_stream(obj, stream, compression = "uncompressed") 7 | return() 8 | } 9 | if (is.array(obj)) { 10 | if (is.matrix(obj) && dim(obj)[1] > 0 && dim(obj)[2] > 0){ 11 | #Export filled matrix as Arrow table with one 'fixed-size-list' column 12 | #Convert flat matrix to jagged (list of vectors) that is supported by Arrow 13 | matrix_jagged_fixedsize <- list() 14 | rows <- dim(obj)[1] 15 | columns <- dim(obj)[2] 16 | for (i in 1:rows) { 17 | matrix_jagged_fixedsize[[i]] <- obj[i,] 18 | } 19 | #Create temporary redcord batch, rows type would be autodetected, matrix type would be 'list' 20 | batch_typedetect <- record_batch(matrix_column=matrix_jagged_fixedsize) 21 | #Convert 'list' type to 'fixed-size-list' 22 | schema_fixed_size <- schema(matrix_column=fixed_size_list_of(type = batch_typedetect$schema$fields[[1]]$type$value_type, columns)) 23 | batch <- record_batch(matrix_column=matrix_jagged_fixedsize, schema=schema_fixed_size) 24 | names(batch) <- name 25 | arrow::write_ipc_stream(batch, stream, compression = "uncompressed") 26 | return() 27 | } 28 | if (length(dim(obj)) > 2) { 29 | #3- and more-D arrays are not supported 30 | stop(paste(length(dim(obj)), "-D arrays are not supported")) 31 | } 32 | #1-D array and empty matrix can be converted to Vector 33 | dim(obj) <- c() 34 | } 35 | if (is.list(obj)){ 36 | if (length(obj) > 0 && length(names(obj)) == 0) { 37 | #Export as Arrow table with one 'list' column 38 | #Suppose that each element has the same type 39 | #Union typed and nested lists might not work 40 | batch <- record_batch(list_column=obj) 41 | names(batch) <- name 42 | arrow::write_ipc_stream(batch, stream, compression = "uncompressed") 43 | return() 44 | } else if (length(names(obj)) > 0) { 45 | #Export each field separately 46 | i <- 0 47 | for (subj_name in names(obj)) { 48 | i <- i + 1 49 | subj <- obj[[i]] 50 | send_element_by_arrow(subj, cleanNames(paste0(name, "$", subj_name)), stream) 51 | } 52 | } else { 53 | #Convert empty List to empty Vector 54 | obj <- unlist(obj) 55 | } 56 | } 57 | 58 | if (typeof(obj)=="language") { 59 | obj<-toString(obj) 60 | } else if(typeof(obj)=="logical") { 61 | obj<-as.character(obj) 62 | } else if(class(obj)=="factor") { 63 | obj<-as.vector(obj) 64 | } 65 | 66 | if (is.vector(obj) && length(obj) > 0) { 67 | #export filled vector with auto type detect 68 | batch <- record_batch(vector_column=obj) 69 | names(batch) <- name 70 | arrow::write_ipc_stream(batch, stream, compression = "uncompressed") 71 | return() 72 | } else if (length(obj) == 0) { 73 | #export empty element 74 | obj <- c(1) 75 | type_example_batch <- record_batch(empty_column=obj) 76 | length(obj) <- 0 77 | empty_batch <- record_batch(empty_column=obj, schema=type_example_batch$schema) 78 | arrow::write_ipc_stream(empty_batch, stream, compression = "uncompressed") 79 | return() 80 | # } else { 81 | # stop("Probably unsupported output") 82 | } 83 | } 84 | 85 | send_by_arrow <- function(obj, name, uri_result) { 86 | stream <- FileOutputStream$create(uri_result) 87 | if (is.list(obj) && length(names(obj)) > 0) { 88 | i <- 0 89 | for (subj_name in names(obj)) { 90 | i <- i + 1 91 | subj <- obj[[i]] 92 | send_element_by_arrow(subj, cleanNames(subj_name), stream) 93 | } 94 | } else { 95 | send_element_by_arrow(obj, cleanNames(name), stream) 96 | } 97 | stream$close() 98 | } 99 | -------------------------------------------------------------------------------- /RCaller/src/main/resources/runiversal.R: -------------------------------------------------------------------------------- 1 | cleanNames<-function(names){ 2 | cln<-paste(unlist(strsplit(names,"\\.")),collapse="_") 3 | cln<-paste(unlist(strsplit(cln,"<")),collapse="") 4 | cln<-paste(unlist(strsplit(cln,">")),collapse="") 5 | cln<-paste(unlist(strsplit(cln," ")),collapse="") 6 | cln<-paste(unlist(strsplit(cln,"\\(")),collapse="") 7 | cln<-paste(unlist(strsplit(cln,"\\)")),collapse="") 8 | cln<-paste(unlist(strsplit(cln,"\\[")),collapse="") 9 | cln<-paste(unlist(strsplit(cln,"\\]")),collapse="") 10 | cln<-paste(unlist(strsplit(cln,"\\*")),collapse="") 11 | cln<-paste(unlist(strsplit(cln,"&")),collapse="") 12 | return(cln) 13 | } 14 | -------------------------------------------------------------------------------- /RCaller/src/main/resources/xml_exporting.R: -------------------------------------------------------------------------------- 1 | replaceXMLchars <- function(aStr){ 2 | cln <-paste(unlist(strsplit(aStr,"&")),collapse="&") 3 | cln <-paste(unlist(strsplit(cln,"<")),collapse="<") 4 | cln <-paste(unlist(strsplit(cln,">")),collapse=">") 5 | cln <-paste(unlist(strsplit(cln,"'")),collapse="'") 6 | return(cln) 7 | } 8 | 9 | makevectorxml<-function(code,objt,name=""){ 10 | xmlcode<-code 11 | if(name==""){ 12 | varname<-cleanNames(deparse(substitute(obj))) 13 | }else{ 14 | varname<-name 15 | } 16 | obj<-objt 17 | n <- 0; m <- 0 18 | mydim <- dim(obj) 19 | if(!is.null(mydim)){ 20 | n <- mydim[1]; m <- mydim[2] 21 | }else{ 22 | n <- length(obj); m <- 1 23 | } 24 | if(is.matrix(obj)) { 25 | obj<-as.vector(obj) 26 | }else if(typeof(obj)=="language") { 27 | obj<-toString(obj) 28 | }else if(typeof(obj)=="logical") { 29 | obj<-as.character(obj) 30 | }else if(class(obj)=="factor") { 31 | obj<-as.vector(obj) 32 | } 33 | if(is.vector(obj) && is.numeric(obj)){ 34 | xmlcode<-paste(xmlcode,"",sep="") 35 | s <- sapply(X=obj, function(str){ 36 | return( 37 | paste("",iconv(replaceXMLchars(toString(str)), to="UTF-8"),"",sep="") 38 | )}) 39 | xmlcode<-paste(xmlcode,paste(s, collapse=""),"\n") 40 | } 41 | if(is.vector(obj) && is.character(obj)){ 42 | xmlcode<-paste(xmlcode,"\n",sep="") 43 | s <- sapply(X=obj, function(str){ 44 | return( 45 | paste("",iconv(replaceXMLchars(toString(str)), to="UTF-8"),"",sep="") 46 | )}) 47 | xmlcode<-paste(xmlcode,paste(s, collapse=""),"\n") 48 | } 49 | return(xmlcode) 50 | } 51 | 52 | 53 | makexml<-function(obj,name=""){ 54 | xmlcode<-"\n\n" 55 | if(!is.list(obj)){ 56 | xmlcode<-makevectorxml(xmlcode,obj,cleanNames(name)) 57 | }else{ 58 | objnames<-names(obj) 59 | for (i in 1:length(obj)){ 60 | name <- objnames[[i]] 61 | if (is.null(name)) { 62 | name <- paste(typeof(obj[[i]]), "-", i, sep='') 63 | } 64 | xmlcode<-makevectorxml(xmlcode,obj[[i]],cleanNames(name)) 65 | } 66 | } 67 | xmlcode<-paste(xmlcode,"\n",sep="") 68 | return(xmlcode) 69 | } 70 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/EventHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.util.Globals; 6 | import java.io.BufferedReader; 7 | import org.junit.*; 8 | import static org.junit.Assert.*; 9 | 10 | import java.io.File; 11 | import java.io.FileNotFoundException; 12 | import java.io.FileReader; 13 | import java.io.IOException; 14 | 15 | public class EventHandlerTest { 16 | 17 | private RCaller caller; 18 | private RCode code; 19 | 20 | @BeforeClass 21 | public static void setUpClass() throws Exception { 22 | Globals.detect_current_rscript(); 23 | } 24 | 25 | @AfterClass 26 | public static void tearDownClass() throws Exception { 27 | File f = new File("oneCopy.txt"); 28 | boolean result = f.delete(); 29 | } 30 | 31 | @Before 32 | public void setUp() { 33 | caller = RCaller.create(); 34 | code = RCode.create(); 35 | } 36 | 37 | @After 38 | public void tearDown() { 39 | caller = null; 40 | code = null; 41 | } 42 | 43 | @Test 44 | public void testEventHandler1() throws FileNotFoundException, IOException { 45 | caller.redirectROutputToFile("oneCopy.txt", false); 46 | 47 | code.clear(); 48 | code.addRCode("x<-1:1000"); 49 | code.addRCode("m<-median(x)"); 50 | caller.setRCode(code); 51 | 52 | caller.runAndReturnResultOnline("m"); 53 | 54 | code.clear(); 55 | code.addRCode("cat(\"This message might be caught by the event handler\")"); 56 | caller.runAndReturnResultOnline("m"); 57 | 58 | caller.stopStreamConsumers(); 59 | 60 | caller.deleteTempFiles(); 61 | caller.stopRCallerOnline(); 62 | 63 | BufferedReader reader = new BufferedReader(new FileReader("oneCopy.txt")); 64 | String s; 65 | boolean resultFound = false; 66 | 67 | while (true) { 68 | s = reader.readLine(); 69 | if (s == null) { 70 | break; 71 | } 72 | if (s.contains("This message might be caught by the event handler")) { 73 | resultFound = true; 74 | break; 75 | } 76 | } 77 | 78 | assertTrue(resultFound); 79 | 80 | reader.close(); 81 | 82 | File f = new File("oneCopy.txt"); 83 | f.delete(); 84 | 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/FactorDataTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import static org.junit.Assert.*; 5 | import org.junit.Test; 6 | 7 | public class FactorDataTypeTest { 8 | 9 | @Test 10 | public void FactorDataTypeAsStrings() { 11 | RCaller caller = RCaller.create(); 12 | caller.getRCode().addRCode("y <- factor(x=c(1,2,3))"); 13 | caller.runAndReturnResult("y"); 14 | String[] result = caller.getParser().getAsStringArray("y"); 15 | assertArrayEquals(new String[]{"1", "2", "3"}, result); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/FileStatusWatcherTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.util.FileStatusWatcher; 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | public class FileStatusWatcherTest { 13 | 14 | @Test 15 | public void testFileChanged() throws IOException, InterruptedException { 16 | TempFileService tmpFileService = new TempFileService(); 17 | final File testFile = tmpFileService.createOutputFile(); 18 | Thread th = new Thread(new Runnable() { 19 | @Override 20 | public void run() { 21 | FileWriter writer = null; 22 | try { 23 | writer = new FileWriter(testFile); 24 | writer.write("."); 25 | writer.flush(); 26 | writer.close(); 27 | } catch (IOException ex) { 28 | assertNull(ex); 29 | } 30 | while (true) { 31 | try { 32 | //This test does not work on some windows configuration without closing the FileWriter in this loop. 33 | writer = new FileWriter(testFile, true); 34 | writer.write("."); 35 | writer.flush(); 36 | writer.close(); 37 | } catch (IOException ex) { 38 | break; 39 | } 40 | } 41 | 42 | try { 43 | writer.close(); 44 | } catch (IOException ex) { 45 | 46 | } 47 | } 48 | }); 49 | th.start(); 50 | FileStatusWatcher.waitUntilFileChanged(testFile); 51 | assertTrue(testFile.length() > 0); 52 | testFile.delete(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/FunctionCallTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.util.Globals; 6 | import org.junit.Test; 7 | import org.junit.Assert; 8 | 9 | public class FunctionCallTest { 10 | 11 | private final static double delta = 1.0 / 1000.0; 12 | 13 | @Test 14 | public void LmCall() { 15 | RCaller caller = RCaller.create(); 16 | RCode code = RCode.create(); 17 | 18 | code.addDoubleArray("x", new double[]{1, 2, 3, 4, 5}); 19 | code.addDoubleArray("y", new double[]{2, 4, 6, 8, 10}); 20 | code.addRCode("mydata <- as.data.frame(cbind(x,y))"); 21 | 22 | FunctionCall fc = new FunctionCall(); 23 | fc.setFunctionName("lm"); 24 | fc.addParameter(new FunctionParameter("formula", "y~x", FunctionParameter.PARAM_OBJECT)); 25 | fc.addParameter(new FunctionParameter("data", "mydata", FunctionParameter.PARAM_OBJECT)); 26 | 27 | code.addFunctionCall("RegressResult", fc); 28 | caller.setRCode(code); 29 | 30 | caller.runAndReturnResult("RegressResult"); 31 | double[] coefs = caller.getParser().getAsDoubleArray("coefficients"); 32 | 33 | Assert.assertEquals(0.0, coefs[0], delta); 34 | Assert.assertEquals(2.0, coefs[1], delta); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/GetMatrixDimensionsTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller; 3 | 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | import com.github.rcaller.util.Globals; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | public class GetMatrixDimensionsTest { 11 | 12 | @Test 13 | public void testMatrixGetDimensions(){ 14 | int n = 21; 15 | int m = 23; 16 | double[][] data = new double[n][m]; 17 | for (int i=0;i names = caller.getParser().getNames(); 30 | 31 | assertEquals(caller.getParser().getAsDoubleArray("x")[0], 5.65, delta); 32 | assertEquals(caller.getParser().getAsDoubleArray("y")[0], 8.96, delta); 33 | } 34 | 35 | @Test 36 | public void GetAllVectorsInEnvironmentTest() { 37 | RCaller caller = RCaller.create(); 38 | RCode code = RCode.create(); 39 | 40 | code.addDoubleArray("x", new double[]{1,2,3,4,5}); 41 | code.addDoubleArray("y", new double[]{2,4,6,8,10}); 42 | code.addRCode("result <- as.list(.GlobalEnv)"); 43 | 44 | caller.setRCode(code); 45 | 46 | caller.runAndReturnResult("result"); 47 | 48 | ArrayList names = caller.getParser().getNames(); 49 | //System.out.println("Names : " + names); 50 | 51 | //System.out.println("x[4] is " + caller.getParser().getAsDoubleArray("x")[4]); 52 | //System.out.println("y[4] is " + caller.getParser().getAsDoubleArray("y")[4]); 53 | 54 | assertEquals(caller.getParser().getAsDoubleArray("x")[4], 5, delta); 55 | assertEquals(caller.getParser().getAsDoubleArray("y")[4], 10, delta); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/JavaObjectTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package com.github.rcaller; 6 | 7 | import com.github.rcaller.rstuff.RCaller; 8 | import com.github.rcaller.rstuff.RCode; 9 | import org.junit.*; 10 | 11 | import java.io.IOException; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | 15 | public class JavaObjectTest { 16 | 17 | double delta = 0.0000001; 18 | 19 | public JavaObjectTest() { 20 | } 21 | 22 | @BeforeClass 23 | public static void setUpClass() throws Exception { 24 | } 25 | 26 | @AfterClass 27 | public static void tearDownClass() throws Exception { 28 | } 29 | 30 | @Before 31 | public void setUp() { 32 | } 33 | 34 | @After 35 | public void tearDown() { 36 | } 37 | 38 | @Test 39 | public void simpleJavaObjectTest() throws IllegalAccessException { 40 | TestClass tc = new TestClass(); 41 | JavaObject t = new JavaObject("myObj", tc); 42 | assertEquals("myObj <- list(i=9, f=10.0, d=3.14, b=TRUE, l=567, s=\"test\")\n", t.produceRCode(false)); 43 | } 44 | 45 | @Test 46 | public void passJavaObjectToR() throws IllegalAccessException { 47 | TestClass tc = new TestClass(); 48 | tc.i = 999; 49 | tc.f = 2.71828f; 50 | tc.d = Math.PI; 51 | JavaObject jo = new JavaObject("myObj", tc); 52 | 53 | RCaller rcaller = RCaller.create(); 54 | RCode code = RCode.create(); 55 | 56 | code.addRCode(jo.produceRCode(false)); 57 | 58 | code.addRCode("myObj$i <- myObj$i + 1"); 59 | 60 | rcaller.setRCode(code); 61 | rcaller.runAndReturnResult("myObj"); 62 | 63 | int[] result = rcaller.getParser().getAsIntArray("i"); 64 | 65 | assertEquals(1000, result[0]); 66 | rcaller.deleteTempFiles(); 67 | } 68 | 69 | @Test 70 | public void TestClassWithArrays() throws IllegalAccessException, IOException { 71 | TestClassWithArrays tcwa = new TestClassWithArrays(); 72 | JavaObject jo = new JavaObject("tcwa", tcwa); 73 | 74 | RCaller rcaller = RCaller.create(); 75 | RCode code = RCode.create(); 76 | 77 | code.addRCode(jo.produceRCode(false)); 78 | 79 | rcaller.setRCode(code); 80 | rcaller.runAndReturnResult("tcwa"); 81 | 82 | int[] expectedIntArray = rcaller.getParser().getAsIntArray("ia"); 83 | for (int i = 0; i < tcwa.ia.length; i++) { 84 | assertEquals(expectedIntArray[i], tcwa.ia[i]); 85 | } 86 | 87 | double[] expectedDoubleArray = rcaller.getParser().getAsDoubleArray("da"); 88 | for (int i = 0; i < tcwa.da.length; i++) { 89 | assertEquals(expectedDoubleArray[i], tcwa.da[i], delta); 90 | } 91 | 92 | String[] expectedStringArray = rcaller.getParser().getAsStringArray("sa"); 93 | for (int i = 0; i < tcwa.sa.length; i++) { 94 | assertEquals(expectedStringArray[i], tcwa.sa[i]); 95 | } 96 | 97 | rcaller.deleteTempFiles(); 98 | } 99 | 100 | @Test 101 | public void TestClassWithArraysCalculations() throws IllegalAccessException, IOException { 102 | TestClassWithArrays tcwa = new TestClassWithArrays(); 103 | JavaObject jo = new JavaObject("tcwa", tcwa); 104 | 105 | RCaller rcaller = RCaller.create(); 106 | RCode code = RCode.create(); 107 | 108 | code.addRCode(jo.produceRCode(false)); 109 | code.addRCode("result <- quantile(tcwa$da, 0.95)"); 110 | rcaller.setRCode(code); 111 | 112 | rcaller.runAndReturnResult("result"); 113 | 114 | double mean = rcaller.getParser().getAsDoubleArray("result")[0]; 115 | assertEquals(mean, 10.05, delta); 116 | rcaller.deleteTempFiles(); 117 | } 118 | 119 | @Test 120 | public void ConvertJavaPlainObjectToRCode() throws IllegalAccessException { 121 | TestClass tc = new TestClass(); 122 | tc.b = true; 123 | tc.d = 6.789; 124 | tc.f = 4.5f; 125 | tc.i = 3; 126 | tc.l = 7L; 127 | tc.s = "s1"; 128 | String code = JavaObject.ConvertToRCode("Test", tc, true, true); 129 | assertEquals("Test = list(i=3, f=4.5, d=6.789, b=TRUE, l=7, s=\"s1\")\n", code); 130 | } 131 | 132 | @Test 133 | public void ConvertJavaPlainObjectToRCodeWithArrays() throws IllegalAccessException { 134 | TestClassWithArrays tc = new TestClassWithArrays(); 135 | tc.b = true; 136 | tc.ba = new boolean[]{true,false,true,true}; 137 | tc.d = 3.4; 138 | tc.da = new double[]{1.0,10.0,100.0}; 139 | tc.f = 5.6f; 140 | tc.i = 9; 141 | tc.ia = new int[]{1,2,3,4,5}; 142 | tc.l = 999L; 143 | tc.s = "H..."; 144 | tc.sa = new String[]{"One", "Two", "Three"}; 145 | String code = JavaObject.ConvertToRCode("Test", tc, true, true); 146 | assertEquals( 147 | "Test = list(ia=c(1, 2, 3, 4, 5), da=c(1.0, 10.0, 100.0), sa=c(\"One\", \"Two\", \"Three\"), ba=c(TRUE, FALSE, TRUE, TRUE), i=9, f=5.6, d=3.4, b=TRUE, l=999, s=\"H...\")\n", 148 | code); 149 | } 150 | 151 | }/* end of test class */ 152 | 153 | 154 | /** 155 | * 156 | * Simple Test Class Used for tests in passing simple Java objects to R as R 157 | * lists 158 | * 159 | */ 160 | class TestClass { 161 | 162 | public int i = 9; 163 | public float f = 10.0f; 164 | public double d = 3.14; 165 | public boolean b = true; 166 | public long l = 567; 167 | public String s = "test"; 168 | } 169 | 170 | class TestClassWithArrays extends TestClass { 171 | 172 | public int[] ia = new int[]{1, 2, 3, 4, 5}; 173 | public double[] da = new double[]{1.0, 2.0, 3.0, 4.0, 9.9, 10.1}; 174 | public String[] sa = new String[]{"One", "Two", "Three"}; 175 | public boolean[] ba = new boolean[]{true, true, false}; 176 | } 177 | 178 | class OtherClass { 179 | 180 | public String s = "This is a string in OtherClass"; 181 | } 182 | 183 | class TestClassWithObject { 184 | 185 | public JavaObject InnerObject = new JavaObject("anObject", new OtherClass()); 186 | public int[] ia = new int[]{1, 2, 3, 4, 5}; 187 | public int i = 90; 188 | } 189 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/LargeDataTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import static org.junit.Assert.*; 6 | import org.junit.Test; 7 | 8 | public class LargeDataTest { 9 | 10 | @Test 11 | public void testBigData_1000_10() { 12 | double delta = 1 / 100000; 13 | double[][] data = new double[1000][10]; 14 | for (int i = 0; i < data.length; i++) { 15 | for (int j = 0; j < data[0].length; j++) { 16 | data[i][j] = Math.random(); 17 | } 18 | } 19 | RCaller caller = RCaller.create(); 20 | RCode code = RCode.create(); 21 | 22 | code.addDoubleMatrix("x", data); 23 | code.addRCode("s <- dim(t(x) %*% x)"); 24 | caller.setRCode(code); 25 | 26 | caller.runAndReturnResult("s"); 27 | 28 | double[] result = caller.getParser().getAsDoubleArray("s"); 29 | 30 | assertEquals(result[0], 10.0, delta); 31 | assertEquals(result[1], 10.0, delta); 32 | caller.deleteTempFiles(); 33 | } 34 | 35 | @Test 36 | public void testReturnsBigData() { 37 | double delta = 0.5; 38 | RCaller caller = RCaller.create(); 39 | RCode code = RCode.create(); 40 | 41 | code.addRCode("s <- rnorm(1024 * 2)"); 42 | code.addRCode("m <- mean(s)"); 43 | code.addRCode("result <- list(arr=s, mean=m)"); 44 | caller.setRCode(code); 45 | caller.runAndReturnResult("result"); 46 | 47 | double m = caller.getParser().getAsDoubleArray("mean")[0]; 48 | int len = caller.getParser().getAsDoubleArray("arr").length; 49 | 50 | assertEquals(0.0, m, delta); 51 | assertEquals(2048l,(long) len); 52 | caller.deleteTempFiles(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/MatrixTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class MatrixTest { 10 | 11 | @Test 12 | public void simpleMatrixTest() { 13 | 14 | RCaller caller = RCaller.create(); 15 | RCode code = RCode.create(); 16 | 17 | double[][] matrix = new double[][]{{6, 4}, {9, 8}}; 18 | 19 | code.addDoubleMatrix("x", matrix); 20 | code.addRCode("s<-solve(x)"); 21 | 22 | caller.setRCode(code); 23 | 24 | caller.runAndReturnResult("s"); 25 | 26 | double[][] inverse = caller.getParser().getAsDoubleMatrix("s", matrix.length, matrix[0].length); 27 | 28 | double[][] expected = new double[][]{{0.6666667, -0.3333333}, {-0.7500000, 0.5000000}}; 29 | 30 | assertEquals(expected.length, inverse.length); 31 | for (int i = 0; i < expected.length; i++) { 32 | for (int j = 0; j < expected[0].length; j++) { 33 | double delta = 0.0001; 34 | assertEquals(expected[i][j], inverse[i][j], delta); 35 | } 36 | } 37 | 38 | caller.deleteTempFiles(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/ParserEmptyFileTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | import org.junit.Test; 7 | 8 | public class ParserEmptyFileTest { 9 | 10 | @Test(expected = Exception.class) 11 | public void EmptyOutputInParser(){ 12 | RCaller caller = RCaller.create(); 13 | RCode code = RCode.create(); 14 | 15 | code.addRCode("Some meaningless code"); 16 | caller.runAndReturnResult("requestedvar"); 17 | caller.deleteTempFiles(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/PrimitiveDataTypes.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller; 3 | 4 | 5 | import com.github.rcaller.rstuff.RCode; 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class PrimitiveDataTypes { 10 | 11 | @Test 12 | public void testDouble(){ 13 | RCode code = RCode.create(); 14 | code.addDouble("d", 3.141592); 15 | //System.out.println(code); 16 | assertEquals(true, code.toString().contains("d<-3.141592\n")); 17 | } 18 | 19 | @Test 20 | public void testInt(){ 21 | RCode code = RCode.create(); 22 | code.addInt("d", 3); 23 | //System.out.println(code); 24 | assertEquals(true, code.toString().contains("d<-3\n")); 25 | } 26 | 27 | @Test 28 | public void testLong(){ 29 | RCode code = RCode.create(); 30 | code.addLong("d", 3); 31 | //System.out.println(code); 32 | assertEquals(true, code.toString().contains("d<-3\n")); 33 | } 34 | 35 | @Test 36 | public void testFloat(){ 37 | RCode code = RCode.create(); 38 | code.addFloat("d", 3.141592f); 39 | //System.out.println(code); 40 | assertEquals(true, code.toString().contains("d<-3.141592\n")); 41 | } 42 | 43 | @Test 44 | public void testShort(){ 45 | RCode code = RCode.create(); 46 | code.addShort("d", (short)3); 47 | //System.out.println(code); 48 | assertEquals(true, code.toString().contains("d<-3\n")); 49 | } 50 | 51 | @Test 52 | public void testBoolean(){ 53 | RCode code = RCode.create(); 54 | code.addBoolean("d", true); 55 | //System.out.println(code); 56 | assertEquals(true, code.toString().contains("d<-TRUE\n")); 57 | } 58 | 59 | @Test 60 | public void testString(){ 61 | String msg = "Hello R!"; 62 | RCode code = RCode.create(); 63 | code.addString("s", msg); 64 | assertEquals(true, code.toString().contains("s<-\"Hello R!\"\n")); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/RServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RService; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class RServiceTest { 8 | 9 | private static RService service; 10 | 11 | public RServiceTest() { 12 | if (service == null) { 13 | service = new RService(); 14 | } 15 | } 16 | 17 | @Test 18 | public void TestVersion() { 19 | String version = service.version(); 20 | Assert.assertTrue(version.contains("R version")); 21 | } 22 | 23 | @Test 24 | public void TestMajorVersion() { 25 | String major = service.major(); 26 | Assert.assertTrue(Integer.parseInt(major) >= 2); 27 | } 28 | 29 | @Test 30 | public void TestGetVariableSequential() { 31 | service.getRCode().clear(); 32 | service.getRCode().addInt("x", 5); 33 | service.getRCode().addInt("y", 6); 34 | Object[] o = service.get("z", "list(z=x+y)", RService.type_Integer); 35 | Assert.assertEquals(11, ((Integer) o[0]).intValue()); 36 | 37 | service.getRCode().clear(); 38 | service.getRCode().addDoubleArray("x", new double[]{1, 2, 3}); 39 | service.getRCode().addDoubleArray("y", new double[]{2, 4, 6}); 40 | o = service.get("coefficients", "lm(y~x)", RService.type_double); 41 | 42 | double delta = 1.0 / 10000; 43 | Assert.assertEquals(0.0, ((Double) o[0]), delta); 44 | Assert.assertEquals(2.0, ((Double) o[1]), delta); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/TestBugFixesStackOverflow.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | public class TestBugFixesStackOverflow { 9 | 10 | 11 | @Test 12 | public void testStack1() { 13 | RCaller caller = RCaller.create(); 14 | RCode code = RCode.create(); 15 | 16 | String x = "is.installed <- function(mypkg){ \n" 17 | + "is.element(mypkg, installed.packages()[,1])\n" 18 | + "}\n" 19 | + "result <- is.installed(\"bbmle\")\n"; 20 | StringBuffer s = new StringBuffer(x); 21 | code.setCode(s); 22 | 23 | //System.out.println(x); 24 | caller.setRCode(code); 25 | //caller.redirectROutputToConsole(); 26 | //caller.runOnly(); 27 | caller.runAndReturnResult("result"); 28 | boolean result = caller.getParser().getAsLogicalArray("result")[0]; 29 | Assert.assertFalse(result); 30 | caller.deleteTempFiles(); 31 | } 32 | 33 | @Test 34 | public void testStack2() { 35 | double[][] data = new double[][]{ 36 | {197.136, 124.32, 63.492, 59.052}, 37 | {124.32, 78.4, 40.04, 37.24}, 38 | {63.492, 40.04, 20.449, 19.019}, 39 | {59.052, 37.24, 19.019, 17.689} 40 | }; 41 | RCaller caller = RCaller.create(); 42 | RCode code = RCode.create(); 43 | 44 | code.addDoubleMatrix("mydata", data); 45 | code.addRCode("result <- chisq.test(mydata)"); 46 | code.addRCode("mylist <- list(pval = result$p.value, df=result$parameter)"); 47 | 48 | caller.setRCode(code); 49 | caller.runAndReturnResult("mylist"); 50 | 51 | double pvalue = caller.getParser().getAsDoubleArray("pval")[0]; 52 | double df = caller.getParser().getAsDoubleArray("df")[0]; 53 | 54 | Assert.assertTrue(pvalue >=0 && pvalue <= 1.0); 55 | Assert.assertTrue(df >=0 && pvalue <= 100.0); 56 | caller.deleteTempFiles(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/UTF8Test.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.util.Globals; 6 | import org.junit.Test; 7 | 8 | import java.io.BufferedWriter; 9 | import java.io.File; 10 | import java.io.FileWriter; 11 | import java.io.IOException; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | import static org.junit.Assert.assertTrue; 15 | 16 | public class UTF8Test { 17 | 18 | public UTF8Test() { 19 | } 20 | 21 | /* 22 | @Test 23 | public void Utf8CharactersTest() { 24 | String s = "ǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦ"; 25 | RCode code = RCode.create(); 26 | RCaller caller = RCaller.create(); 27 | 28 | caller.setRCode(code); 29 | 30 | code.addRCode("rside <- list(s = intToUtf8(500:550))"); 31 | caller.runAndReturnResult("rside"); 32 | 33 | String[] result = caller.getParser().getAsStringArray("s"); 34 | assertTrue(result[0].equals(s)); 35 | } 36 | */ 37 | 38 | @Test 39 | public void VariableNameContainsAndCharacterTest() throws IOException{ 40 | RCode code = RCode.create(); 41 | RCaller caller = RCaller.create(); 42 | 43 | caller.setRCode(code); 44 | 45 | TempFileService tmpservice = new TempFileService(); 46 | File tmpfile = tmpservice.createTempFile("csv", ""); 47 | 48 | BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile)); 49 | writer.write("ID,Feature1,Feature2,Feature3\n"); 50 | writer.write("a&b,1,0.01,0.65\n"); 51 | writer.flush(); 52 | writer.close(); 53 | 54 | code.addRCode("predictions <- read.csv(\""+ Globals.getSystemSpecificRPathParameter(tmpfile)+"\",stringsAsFactors = FALSE)"); 55 | caller.runAndReturnResult("predictions"); 56 | 57 | String[] result = caller.getParser().getAsStringArray("ID"); 58 | assertEquals("a&b", result[0]); 59 | } 60 | 61 | @Test 62 | public void VariableNameContainsLessThanCharacterTest() throws IOException{ 63 | RCode code = RCode.create(); 64 | RCaller caller = RCaller.create(); 65 | 66 | caller.setRCode(code); 67 | 68 | TempFileService tmpservice = new TempFileService(); 69 | File tmpfile = tmpservice.createTempFile("csv", ""); 70 | 71 | BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile)); 72 | writer.write("ID,Feature1,Feature2,Feature3\n"); 73 | writer.write("ab,1,0.01,0.65\n"); 97 | writer.flush(); 98 | writer.close(); 99 | 100 | code.addRCode("predictions <- read.csv(\""+Globals.getSystemSpecificRPathParameter(tmpfile)+"\",stringsAsFactors = FALSE)"); 101 | caller.runAndReturnResult("predictions"); 102 | 103 | String[] result = caller.getParser().getAsStringArray("ID"); 104 | assertEquals("a>b", result[0]); 105 | } 106 | 107 | @Test 108 | public void VariableNameContainsApostropheCharacterTest() throws IOException{ 109 | RCode code = RCode.create(); 110 | RCaller caller = RCaller.create(); 111 | 112 | caller.setRCode(code); 113 | 114 | TempFileService tmpservice = new TempFileService(); 115 | File tmpfile = tmpservice.createTempFile("csv", ""); 116 | 117 | BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile)); 118 | writer.write("ID,Feature1,Feature2,Feature3\n"); 119 | writer.write("a'b,1,0.01,0.65\n"); 120 | writer.flush(); 121 | writer.close(); 122 | 123 | code.addRCode("predictions <- read.csv(\""+Globals.getSystemSpecificRPathParameter(tmpfile)+"\",stringsAsFactors = FALSE)"); 124 | caller.runAndReturnResult("predictions"); 125 | 126 | String[] result = caller.getParser().getAsStringArray("ID"); 127 | assertEquals("a'b", result[0]); 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/datatypes/DataFrameTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.datatypes; 2 | 3 | import com.github.rcaller.rstuff.RCaller; 4 | import com.github.rcaller.rstuff.RCode; 5 | import com.github.rcaller.util.DataFrameUtil; 6 | import org.junit.Test; 7 | 8 | import java.util.Arrays; 9 | 10 | import static junit.framework.Assert.assertEquals; 11 | import static junit.framework.Assert.assertTrue; 12 | 13 | public class DataFrameTest { 14 | 15 | @Test 16 | public void createDefaultDataFrameTest() { 17 | DataFrame dataFrame = DataFrame.create(4, 3); 18 | 19 | assertEquals(dataFrame.getNumberOfColumns(), 4); 20 | assertEquals(dataFrame.getNumberOfRows(), 3); 21 | assertEquals(dataFrame.getNames().length, 4); 22 | assertEquals(dataFrame.getNames()[0], "var0"); 23 | assertEquals(dataFrame.getNames()[1], "var1"); 24 | assertEquals(dataFrame.getNames()[2], "var2"); 25 | assertEquals(dataFrame.getNames()[3], "var3"); 26 | } 27 | 28 | @Test(expected = IllegalArgumentException.class) 29 | public void createDataFrameTest_shouldFail() { 30 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 31 | String[] names = new String[] {"numbers"}; 32 | 33 | DataFrame.create(objects, names); 34 | } 35 | 36 | @Test 37 | public void createDataFrameTest_shouldSucceed() { 38 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 39 | String[] names = new String[] {"numbers", "letters"}; 40 | 41 | DataFrame dataFrame = DataFrame.create(objects, names); 42 | 43 | assertTrue(Arrays.equals(dataFrame.getRow(0), new Object[]{1, "a"})); 44 | assertTrue(Arrays.equals(dataFrame.getColumn(1), new Object[]{"a", "b", "c"})); 45 | assertTrue(dataFrame.getObject(0,2).equals(3)); 46 | } 47 | 48 | @Test(expected = IllegalArgumentException.class) 49 | public void getRowTest_shouldFail_1() { 50 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 51 | String[] names = new String[] {"numbers", "letters"}; 52 | 53 | DataFrame dataFrame = DataFrame.create(objects, names); 54 | 55 | assertTrue(Arrays.equals(dataFrame.getRow(3), new Object[]{1, "a"})); 56 | } 57 | 58 | @Test(expected = IllegalArgumentException.class) 59 | public void getRowTest_shouldFail_2() { 60 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 61 | String[] names = new String[] {"numbers", "letters"}; 62 | 63 | DataFrame dataFrame = DataFrame.create(objects, names); 64 | 65 | assertTrue(Arrays.equals(dataFrame.getRow(-3), new Object[]{1, "a"})); 66 | } 67 | 68 | @Test(expected = IllegalArgumentException.class) 69 | public void getColumnTest_shouldFail_1() { 70 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 71 | String[] names = new String[] {"numbers", "letters"}; 72 | 73 | DataFrame dataFrame = DataFrame.create(objects, names); 74 | 75 | assertTrue(Arrays.equals(dataFrame.getColumn(7), new Object[]{"a", "b", "c"})); 76 | } 77 | 78 | @Test(expected = IllegalArgumentException.class) 79 | public void getColumnTest_shouldFail_2() { 80 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 81 | String[] names = new String[] {"numbers", "letters"}; 82 | 83 | DataFrame dataFrame = DataFrame.create(objects, names); 84 | 85 | assertTrue(Arrays.equals(dataFrame.getColumn(-7), new Object[]{"a", "b", "c"})); 86 | } 87 | 88 | @Test(expected = IllegalArgumentException.class) 89 | public void getObjectTest_shouldFail_1() { 90 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 91 | String[] names = new String[] {"numbers", "letters"}; 92 | 93 | DataFrame dataFrame = DataFrame.create(objects, names); 94 | 95 | assertTrue(dataFrame.getObject(-1,2).equals(3)); 96 | } 97 | 98 | @Test(expected = IllegalArgumentException.class) 99 | public void getObjectTest_shouldFail_2() { 100 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 101 | String[] names = new String[] {"numbers", "letters"}; 102 | 103 | DataFrame dataFrame = DataFrame.create(objects, names); 104 | 105 | assertTrue(dataFrame.getObject(0,-2).equals(3)); 106 | } 107 | 108 | @Test(expected = IllegalArgumentException.class) 109 | public void getObjectTest_shouldFail_3() { 110 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 111 | String[] names = new String[] {"numbers", "letters"}; 112 | 113 | DataFrame dataFrame = DataFrame.create(objects, names); 114 | 115 | assertTrue(dataFrame.getObject(-0,5).equals(3)); 116 | } 117 | 118 | @Test(expected = IllegalArgumentException.class) 119 | public void getObjectTest_shouldFail_4() { 120 | Object[][] objects = new Object[][]{{1,2,3}, {"a", "b", "c"}}; 121 | String[] names = new String[] {"numbers", "letters"}; 122 | 123 | DataFrame dataFrame = DataFrame.create(objects, names); 124 | 125 | assertTrue(dataFrame.getObject(8,2).equals(3)); 126 | } 127 | 128 | @Test 129 | public void writeDataFrameToRAndGetMean() { 130 | Object[][] objects = new Object[][]{{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}}; 131 | 132 | DataFrame dataFrame = DataFrame.create(objects, DataFrameUtil.createDefaultNamesArray(3)); 133 | 134 | RCaller rCaller = RCaller.create(); 135 | RCode rCode = RCode.create(); 136 | 137 | rCode.addDataFrame("df", dataFrame); 138 | rCode.addRCode("result <- c(colMeans(df), rowMeans(df))"); 139 | rCaller.setRCode(rCode); 140 | rCaller.runAndReturnResult("result"); 141 | 142 | double[] result = rCaller.getParser().getAsDoubleArray("result"); 143 | 144 | assertEquals(result[0], 2.5); 145 | assertEquals(result[1], 3.5); 146 | assertEquals(result[2], 4.5); 147 | assertEquals(result[3], 2.0); 148 | assertEquals(result[4], 3.0); 149 | assertEquals(result[5], 4.0); 150 | assertEquals(result[6], 5.0); 151 | } 152 | 153 | @Test 154 | public void writeBigDataFrame() { 155 | RCaller rCaller = RCaller.create(); 156 | RCode rCode = RCode.create(); 157 | 158 | rCode.addDataFrame("df", DataFrame.create(DataFrameUtil.createObjectsMatrix(2000, 3000, 2), DataFrameUtil.createDefaultNamesArray(2000))); 159 | rCode.addRCode("result <- c(nrow(df), ncol(df), df[2,2])"); 160 | rCaller.setRCode(rCode); 161 | rCaller.runAndReturnResult("result"); 162 | 163 | double[] result = rCaller.getParser().getAsDoubleArray("result"); 164 | assertEquals(result[0], 3000d); 165 | assertEquals(result[1], 2000d); 166 | assertEquals(result[2], 2d); 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/io/RSerializerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.io; 2 | 3 | import com.github.rcaller.TempFileService; 4 | import com.github.rcaller.rstuff.RCaller; 5 | import com.github.rcaller.rstuff.RCode; 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import com.github.rcaller.util.Globals; 10 | import org.junit.Test; 11 | 12 | import static org.junit.Assert.assertEquals; 13 | 14 | public class RSerializerTest { 15 | 16 | double delta = 1 / 100000; 17 | 18 | @Test 19 | public void WriteVectorTest() throws IOException { 20 | RSerializer rs = new RSerializer(); 21 | double[] v = new double[]{1.0, 2.0, 3.0}; 22 | rs.writeVector(v); 23 | 24 | TempFileService tmpServ = new TempFileService(); 25 | File tmpFile = tmpServ.createTempFile("RCaller", "Test"); 26 | 27 | rs.save(tmpFile.getCanonicalPath()); 28 | 29 | RCaller caller = RCaller.create(); 30 | RCode code = RCode.create(); 31 | 32 | code.addRCode("conn <- file(\"" + Globals.getSystemSpecificRPathParameter(tmpFile) + "\" , \"r\")"); 33 | code.addRCode("x <- unserialize(conn)"); 34 | caller.setRCode(code); 35 | 36 | caller.runAndReturnResult("x"); 37 | 38 | double[] x = caller.getParser().getAsDoubleArray("x"); 39 | assertEquals(1.0, x[0], delta); 40 | assertEquals(2.0, x[1], delta); 41 | assertEquals(3.0, x[2], delta); 42 | } 43 | 44 | @Test 45 | public void WriteMatrixTest() throws IOException { 46 | RSerializer rs = new RSerializer(); 47 | double[][] v = new double[][]{ 48 | {1.0, 2.0}, 49 | {3.0, 4.0}, 50 | {5.0, 6.0} 51 | }; 52 | 53 | rs.writeDoubleMatrix(v); 54 | 55 | TempFileService tmpServ = new TempFileService(); 56 | File tmpFile = tmpServ.createTempFile("RCaller", "Test"); 57 | 58 | rs.save(tmpFile.getCanonicalPath()); 59 | 60 | RCaller caller = RCaller.create(); 61 | RCode code = RCode.create(); 62 | 63 | code.addRCode("conn <- file(\"" + Globals.getSystemSpecificRPathParameter(tmpFile) + "\" , \"r\")"); 64 | code.addRCode("x <- unserialize(conn)"); 65 | caller.setRCode(code); 66 | 67 | caller.runAndReturnResult("x"); 68 | 69 | double[][] x = caller.getParser().getAsDoubleMatrix("x"); 70 | assertEquals(1.0, x[0][0], delta); 71 | assertEquals(2.0, x[1][0], delta); 72 | assertEquals(3.0, x[2][0], delta); 73 | assertEquals(4.0, x[0][1], delta); 74 | assertEquals(5.0, x[1][1], delta); 75 | assertEquals(6.0, x[2][1], delta); 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/rstuff/RProcessStartUpOptionsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.rstuff; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class RProcessStartUpOptionsTest { 8 | 9 | @Test 10 | public void startUpOptionsTest_1() { 11 | RProcessStartUpOptions rProcessStartUpOptions = RProcessStartUpOptions.create(); 12 | assertEquals(" --vanilla ", rProcessStartUpOptions.getStartUpOptionsAsCommand()); 13 | } 14 | 15 | @Test 16 | public void startUpOptionsTest_2() { 17 | RProcessStartUpOptions rProcessStartUpOptions = RProcessStartUpOptions.create(true, false, false, false, true, true, false, false, false, false, false, true, true, 18 | true, false, false, null, null, 10, null, null, "test", null, null, null); 19 | assertEquals(" --save --no-init-file --restore --quiet --silent --slave --min-vsize=10 --gui=test ", rProcessStartUpOptions.getStartUpOptionsAsCommand()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/scriptengine/PutJavaObjectTest.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.scriptengine; 2 | 3 | import com.github.rcaller.util.Globals; 4 | import javax.script.ScriptEngine; 5 | import javax.script.ScriptEngineManager; 6 | import org.junit.AfterClass; 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | public class PutJavaObjectTest { 12 | 13 | static ScriptEngine engine = null; 14 | double delta = 1 / 100000; 15 | 16 | public static void message(String text) { 17 | System.out.println("* " + text); 18 | } 19 | 20 | @BeforeClass 21 | public static void setUpClass() { 22 | Globals.detect_current_rscript(); 23 | ScriptEngineManager manager = new ScriptEngineManager(); 24 | engine = manager.getEngineByName("RCaller"); 25 | } 26 | 27 | @AfterClass 28 | public static void tearDownClass() { 29 | ((RCallerScriptEngine) engine).close(); 30 | } 31 | 32 | @Test 33 | public void passAsPlainJavaObjectToEngine() { 34 | TestClass1 tc1 = new TestClass1(); 35 | engine.put("tc1", tc1); 36 | double[] d1 = (double[]) engine.get("d1"); 37 | assertArrayEquals(new double[]{1.0, 2.0, 3.0}, d1, delta); 38 | double[] d2 = (double[]) engine.get("d2"); 39 | assertArrayEquals(new double[]{4.0, 5.0, 6.0}, d2, delta); 40 | } 41 | 42 | @Test 43 | public void passRichPlainJavaObjectToEngine() { 44 | TestClass2 tc2 = new TestClass2(); 45 | engine.put("tc2", tc2); 46 | double[] v1 = (double[]) engine.get("int_array"); 47 | assertArrayEquals(new double[]{1, 2, 3, 4, 5}, v1, delta); 48 | double[] v2 = (double[]) engine.get("double_array"); 49 | assertArrayEquals(new double[]{1.0, 2.0, 9.0}, v2, delta); 50 | String[] v3 = (String[]) engine.get("string_array"); 51 | assertArrayEquals(new String[]{"A", "Z", "X", "H", "h"}, v3); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/scriptengine/TestClass1.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.rcaller.scriptengine; 3 | 4 | 5 | public class TestClass1 { 6 | public double[] d1 = new double[]{1.0, 2.0, 3.0}; 7 | public double[] d2 = new double[]{4.0, 5.0, 6.0}; 8 | } 9 | -------------------------------------------------------------------------------- /RCaller/src/test/java/com/github/rcaller/scriptengine/TestClass2.java: -------------------------------------------------------------------------------- 1 | package com.github.rcaller.scriptengine; 2 | 3 | 4 | 5 | public class TestClass2 { 6 | 7 | public final int[] int_array = new int[]{1,2,3,4,5}; 8 | public final double[] double_array = new double[]{1.0, 2.0, 9.0}; 9 | public final String[] string_array = new String[]{"A","Z","X","H","h"}; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /RCallerPhp/CodeUtils.php: -------------------------------------------------------------------------------- 1 | . 20 | * 21 | * 22 | * Mehmet Hakan Satman - mhsatman@yahoo.com 23 | * http://www.mhsatman.com 24 | * Google code project: http://code.google.com/p/rcaller/ 25 | * 26 | */ 27 | 28 | class CodeUtils { 29 | 30 | public static function addNumericArray(&$sb, $name, $arr, $useEquals) { 31 | if ($useEquals) { 32 | //RCode.append(name).append("=").append("c("); 33 | $sb .= $name . "=" . "c("; 34 | } else { 35 | //RCode.append(name).append("<-").append("c("); 36 | $sb .= $name . "<-" . "c("; 37 | } 38 | for ($i = 0; $i < count($arr); $i++) { 39 | //RCode.append(String.valueOf(arr[i])); 40 | $sb .= $arr[$i]; 41 | if (i < arr . length - 1) { 42 | //RCode.append(", "); 43 | $sb .= ", "; 44 | } 45 | } 46 | if ($useEquals) { 47 | //RCode.append(")"); 48 | $sb .= ")"; 49 | } else { 50 | //RCode.append(");").append("\n"); 51 | $sb .= ");" . "\n"; 52 | } 53 | } 54 | 55 | public static function addStringArray(&$sb, $name, $arr, $useEquals) { 56 | if ($useEquals) { 57 | //RCode.append(name).append("=").append("c("); 58 | $sb .= $sb . $name . "=" . "c("; 59 | } else { 60 | //RCode.append(name).append("<-").append("c("); 61 | $sb .= $sb . $name . "<-" . "c("; 62 | } 63 | for ($i = 0; $i < count($arr); $i++) { 64 | //RCode.append("\"").append(arr[i]).append("\""); 65 | $sb .= "\"" . $arr[$i] . "\""; 66 | if (i < count($arr) - 1) { 67 | //RCode.append(", "); 68 | $sb .= ", "; 69 | } 70 | } 71 | if ($useEquals) { 72 | //RCode.append(")"); 73 | $sb .= ")"; 74 | } else { 75 | //RCode.append(");").append("\n"); 76 | $sb .= ");" . "\n"; 77 | } 78 | } 79 | 80 | public static function createTempFile($prefix) { 81 | $dir = sys_get_temp_dir(); 82 | //$sep = DIRECTORY_SEPARATOR; 83 | $name = tempnam($dir, $prefix); 84 | return ($name); 85 | } 86 | 87 | } 88 | 89 | ?> 90 | -------------------------------------------------------------------------------- /RCallerPhp/Globals.php: -------------------------------------------------------------------------------- 1 | . 20 | * 21 | * 22 | * Mehmet Hakan Satman - mhsatman@yahoo.com 23 | * http://www.mhsatman.com 24 | * Google code project: http://code.google.com/p/rcaller/ 25 | * 26 | */ 27 | 28 | class Globals { 29 | 30 | public static $cranRepos = "http://cran.r-projectt.org"; 31 | public static $RScript_Windows = "C:\\Program Files\\R\\R-2.13.0\\bin\\Rscript.exe"; 32 | public static $RScript_Linux = "/usr/bin/Rscript"; 33 | public static $Rscript_current; 34 | public static $R_Windows = "C:\\Program Files\\R\\R-2.13.0\\bin\\R.exe"; 35 | public static $R_Linux = "/usr/bin/R"; 36 | public static $R_current; 37 | //Theme Support did not implemented yet for php version 38 | //public static $theme = new DefaultTheme(); 39 | 40 | public static $version = "RCaller 2.0"; 41 | public static $about = "Author: Mehmet Hakan Satman - mhsatman@yahoo.com"; 42 | public static $licence = "LGPL v3.0"; 43 | 44 | public static function detect_current_rscript() { 45 | if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") { 46 | Globals::$Rscript_current = Globals::$RScript_Windows; 47 | Globals::$R_current = Globals::$R_Windows; 48 | } else { 49 | Globals::$Rscript_current = Globals::$RScript_Linux; 50 | Globals::$R_current = Globals::$R_Linux; 51 | } 52 | } 53 | 54 | } 55 | 56 | ?> 57 | -------------------------------------------------------------------------------- /RCallerPhp/RCode.php: -------------------------------------------------------------------------------- 1 | . 20 | * 21 | * 22 | * Mehmet Hakan Satman - mhsatman@yahoo.com 23 | * http://www.mhsatman.com 24 | * Google code project: http://code.google.com/p/rcaller/ 25 | * 26 | */ 27 | 28 | include_once ("Globals.php"); 29 | 30 | class RCode { 31 | 32 | private $code; 33 | 34 | function setCode($sb) { 35 | $this->code = $sb; 36 | } 37 | 38 | public function getCode() { 39 | return($this->code); 40 | } 41 | 42 | function __construct($sb) { 43 | $this->code = $sb; 44 | $this->clear(); 45 | } 46 | 47 | public function clear() { 48 | $this->code = ""; 49 | $this->addRCode("packageExist<-require(Runiversal)"); 50 | $this->addRCode("if(!packageExist){"); 51 | $this->addRCode("install.packages(\"Runiversal\", repos=\" " . Globals::$cranRepos . "\")"); 52 | $this->addRCode("}\n"); 53 | } 54 | 55 | public function prependRCode($code) { 56 | $this->code = $code . $this->code . "\n"; 57 | } 58 | 59 | public function addRCode($code) { 60 | $this->code .= $code . "\n"; 61 | } 62 | 63 | public function addStringArray($name, $arr) { 64 | //CodeUtils.addStringArray(code, name, arr, false); 65 | CodeUtils::addNumericArray($this->code, $name, $arr, false); 66 | } 67 | 68 | public function addNumericArray($name, $arr) { 69 | CodeUtils::addNumericArray($this->code, $name, $arr, false); 70 | } 71 | 72 | public function startPlot() { 73 | $f = CodeUtils::createTempFile("RcallerPlot"); 74 | //addRCode("png(\"" + f.toString().replace("\\", "/") + "\")"); 75 | /* 76 | * File path separator may be buggy in Windows. Look here again 77 | */ 78 | $this->addRCode("png(\"" . $f . "\")"); 79 | return ($f); 80 | } 81 | 82 | public function endPlot() { 83 | $this->addRCode("dev.off()"); 84 | } 85 | 86 | public function getPlot($f) { 87 | //data:image/png;base64 88 | $content = file_get_contents($f); 89 | $b = base64_encode($content); 90 | $html_text = ""; 91 | return $html_text; 92 | } 93 | 94 | public function showPlot($f) { 95 | /* 96 | ImageIcon plot = getPlot(f); 97 | RPlotViewer plotter = new RPlotViewer(plot); 98 | plotter.setVisible(true); 99 | */ 100 | throw new Exception("This is not implemented yet", "RCode.php", "showPlot()"); 101 | } 102 | 103 | public function R_require($pkg) { 104 | $this->code = "require(" . $pkg . ")\n" . $this->code; 105 | } 106 | 107 | public function R_source($sourceFile) { 108 | $this->addRCode("source(\"" + $sourceFile + "\")\n"); 109 | } 110 | 111 | public function toString() { 112 | return $this->code; 113 | } 114 | 115 | } 116 | 117 | ?> 118 | -------------------------------------------------------------------------------- /RCallerPhp/ROutputParser.php: -------------------------------------------------------------------------------- 1 | . 20 | * 21 | * 22 | * Mehmet Hakan Satman - mhsatman@yahoo.com 23 | * http://www.mhsatman.com 24 | * Google code project: http://code.google.com/p/rcaller/ 25 | * 26 | */ 27 | 28 | /** 29 | * 30 | * @author Mehmet Hakan Satman 31 | */ 32 | class ROutputParser { 33 | 34 | private $XMLFile = null; 35 | private $XMLContent = null; 36 | 37 | public function getXMLFile() { 38 | return $this->XMLFile; 39 | } 40 | 41 | public function getXMLFileAsString() { 42 | return file_get_contents($this->XMLFile); 43 | ; 44 | } 45 | 46 | public function setXMLFile($XMLFile) { 47 | $this->XMLFile = $XMLFile; 48 | } 49 | 50 | public function getXMLContent() { 51 | return ($this->XMLContent); 52 | } 53 | 54 | public function parse() { 55 | $this->XMLContent = simplexml_load_file($this->getXMLFile()); 56 | } 57 | 58 | function __construct() { 59 | 60 | } 61 | 62 | public function getNames() { 63 | $names = null; 64 | $i = 0; 65 | foreach ($this->XMLContent->variable as $v) { 66 | $names[$i] = (String) $v->attributes()->name; 67 | $i++; 68 | } 69 | return($names); 70 | } 71 | 72 | public function getAsStringArray($name) { 73 | $values = null; 74 | foreach ($this->XMLContent->variable as $v) { 75 | if ((String) $v->attributes()->name == $name) { 76 | for ($i = 0; $i < count($v->value); $i++) { 77 | $values[$i] = (String) $v->value[$i]; 78 | } 79 | } 80 | } 81 | return($values); 82 | } 83 | 84 | /* 85 | public double[][] getAsDoubleMatrix(String name, int n, int m) throws RCallerParseException { 86 | double[][] result = new double[n][m]; 87 | double[] arr = this.getAsDoubleArray(name); 88 | int c = 0; 89 | for (int i = 0; i < n; i++) { 90 | for (int j = 0; j < m; j++) { 91 | result[i][j] = arr[c]; 92 | c++; 93 | } 94 | } 95 | return (result); 96 | } 97 | */ 98 | } 99 | 100 | ?> -------------------------------------------------------------------------------- /RCallerPhp/test/PlotTest.php: -------------------------------------------------------------------------------- 1 | startPlot(); 11 | $code->addRCode("plot.ts(rnorm(10))"); 12 | $code->endPlot(); 13 | 14 | $caller->setRscriptExecutable("/usr/bin/Rscript"); 15 | $caller->setRCode($code); 16 | $caller->runOnly(); 17 | 18 | print($caller->getPlot($plot)); 19 | ?> 20 | -------------------------------------------------------------------------------- /RCallerPhp/test/RCodeTest.php: -------------------------------------------------------------------------------- 1 | 2 | . 20 | * 21 | * 22 | * Mehmet Hakan Satman - mhsatman@yahoo.com 23 | * http://www.mhsatman.com 24 | * Google code project: http://code.google.com/p/rcaller/ 25 | * 26 | */ 27 | 28 | require_once("../RCode.php"); 29 | require_once("../RCaller.php"); 30 | require_once("simpletest.php"); 31 | 32 | function TestRCode() { 33 | $rcode = new RCode(""); 34 | $rcode->clear(); 35 | $rcode->addRCode("a<-1:10"); 36 | $predicted = $rcode->toString(); 37 | print $predicted; 38 | } 39 | 40 | function TestRCaller1() { 41 | $rcaller = new RCaller(); 42 | $rcaller->setRscriptExecutable("/usr/bin/Rscript"); 43 | $rcode = new RCode(""); 44 | $rcode->clear(); 45 | $rcode->addRCode("mylist <- list(x=1:3, y=c(7,8,9))"); 46 | 47 | $rcaller->setRCode($rcode); 48 | $rcaller->runAndReturnResult("mylist"); 49 | 50 | $x = $rcaller->getParser()->getAsStringArray("x"); 51 | $y = $rcaller->getParser()->getAsStringArray("y"); 52 | 53 | test("getting x", $x, array(1, 2, 3)); 54 | test("getting y", $y, array(7, 8, 9)); 55 | } 56 | 57 | TestRCaller1(); 58 | ?> -------------------------------------------------------------------------------- /RCallerPhp/test/simpletest.php: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /bibtex.bib: -------------------------------------------------------------------------------- 1 | @article{satman2014rcaller, 2 | title={RCaller: A Software Library for Calling R from Java}, 3 | author={Satman, M Hakan}, 4 | journal={British Journal of Mathematics \& Computer Science}, 5 | volume={4}, 6 | number={15}, 7 | pages={2188--2196}, 8 | year={2014} 9 | } 10 | 11 | @article{SatmanKopilov2020, 12 | doi = {10.21105/joss.02722}, 13 | url = {https://doi.org/10.21105/joss.02722}, 14 | year = {2020}, 15 | publisher = {The Open Journal}, 16 | volume = {5}, 17 | number = {55}, 18 | pages = {2722}, 19 | author = {Mehmet Hakan Satman and Kopilov Aleksandr}, 20 | title = {RCaller: A Java package for interfacing R}, 21 | journal = {Journal of Open Source Software} 22 | } 23 | 24 | 25 | @misc{RCaller, 26 | title = {RCaller: A library for calling R from Java}, 27 | author = {{RCaller Development Team}}, 28 | year = 2011, 29 | URL = {https://github.com/jbytecode/rcaller}, 30 | } 31 | 32 | -------------------------------------------------------------------------------- /doc/rcaller-url.txt: -------------------------------------------------------------------------------- 1 | This is the official document for RCaller: 2 | http://www.sciencedomain.org/download.php?f=Satman4152014BJMCS10902_1.pdf&aid=4838&type=a 3 | 4 | 5 | -------------------------------------------------------------------------------- /doc/rcaller3/MatrixSendReceive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbytecode/rcaller/2c053c9e4cf2a123dfe379e6a8d7f29e283bac5c/doc/rcaller3/MatrixSendReceive.pdf -------------------------------------------------------------------------------- /doc/rcaller3/rcaller3.bib: -------------------------------------------------------------------------------- 1 | @article{satman2014rcaller, 2 | title={RCaller: A software library for calling R from Java}, 3 | author={Satman, M Hakan}, 4 | journal={British Journal of Mathematics \& Computer Science}, 5 | volume={4}, 6 | number={15}, 7 | pages={2188}, 8 | year={2014}, 9 | publisher={SCIENCEDOMAIN International} 10 | } 11 | 12 | 13 | @Manual{R, 14 | title = {R: A Language and Environment for Statistical Computing}, 15 | author = {{R Core Team}}, 16 | organization = {R Foundation for Statistical Computing}, 17 | address = {Vienna, Austria}, 18 | year = {2016}, 19 | url = {https://www.R-projectt.org/}, 20 | } 21 | 22 | 23 | @article{SLang, 24 | title={The new S language}, 25 | author={Becker, Richard A and Chambers, John M and Wilks, Allan R}, 26 | journal={Pacific Grove, Ca.: Wadsworth \& Brooks, 1988}, 27 | volume={1}, 28 | year={1988} 29 | } 30 | 31 | 32 | @article{eddelbuettel2011rcpp, 33 | title={Rcpp: Seamless R and C++ integration}, 34 | author={Eddelbuettel, Dirk and Fran{\c{c}}ois, Romain and Allaire, J and Chambers, John and Bates, Douglas and Ushey, Kevin}, 35 | journal={Journal of Statistical Software}, 36 | volume={40}, 37 | number={8}, 38 | pages={1--18}, 39 | year={2011} 40 | } 41 | 42 | @book{eddelbuettel2013seamless, 43 | title={Seamless R and C++ integration with Rcpp}, 44 | author={Eddelbuettel, Dirk}, 45 | year={2013}, 46 | publisher={Springer} 47 | } 48 | 49 | @article{hall2009weka, 50 | title={The WEKA data mining software: an update}, 51 | author={Hall, Mark and Frank, Eibe and Holmes, Geoffrey and Pfahringer, Bernhard and Reutemann, Peter and Witten, Ian H}, 52 | journal={ACM SIGKDD explorations newsletter}, 53 | volume={11}, 54 | number={1}, 55 | pages={10--18}, 56 | year={2009}, 57 | publisher={ACM} 58 | } 59 | 60 | @Article{RWeka1, 61 | title = {Open-Source Machine Learning: {R} Meets {Weka}}, 62 | author = {Kurt Hornik and Christian Buchta and Achim Zeileis}, 63 | journal = {Computational Statistics}, 64 | year = {2009}, 65 | volume = {24}, 66 | number = {2}, 67 | pages = {225--232}, 68 | doi = {10.1007/s00180-008-0119-7}, 69 | } 70 | 71 | @Book{RWeka2, 72 | title = {Data Mining: Practical Machine Learning Tools and 73 | Techniques}, 74 | author = {Ian H. Witten and Eibe Frank}, 75 | year = {2005}, 76 | edition = {2nd}, 77 | publisher = {Morgan Kaufmann}, 78 | address = {San Francisco}, 79 | } 80 | 81 | @article{urbanek2009talk, 82 | title={How to talk to strangers: ways to leverage connectivity between R, Java and Objective C}, 83 | author={Urbanek, Simon}, 84 | journal={Computational statistics}, 85 | volume={24}, 86 | number={2}, 87 | pages={303--311}, 88 | year={2009}, 89 | publisher={Springer} 90 | } 91 | 92 | @Manual{rJava, 93 | title = {rJava: Low-Level R to Java Interface}, 94 | author = {Simon Urbanek}, 95 | year = {2016}, 96 | note = {R package version 0.9-8}, 97 | url = {https://CRAN.R-projectt.org/package=rJava}, 98 | } 99 | 100 | @book{gordon1998essential, 101 | title={Essential JNI: Java Native Interface}, 102 | author={Gordon, Rob}, 103 | year={1998}, 104 | publisher={Prentice-Hall, Inc.} 105 | } 106 | 107 | 108 | @inproceedings{urbanek2003fast, 109 | title={A fast way to provide R functionality to applications}, 110 | author={Urbanek, Simon}, 111 | booktitle={Proceedings of DSC}, 112 | volume={2}, 113 | year={2003}, 114 | organization={Citeseer} 115 | } 116 | 117 | @Inbook{Friesen2007, 118 | author={Friesen, Jeff}, 119 | chapter="Scripting", 120 | title="Beginning Java{\texttrademark} SE 6 Platform: From Novice to Professional", 121 | year="2007", 122 | publisher="Apress", 123 | address="Berkeley, CA", 124 | pages="281--344", 125 | isbn="978-1-4302-0246-2", 126 | doi="10.1007/978-1-4302-0246-2_9", 127 | url="http://dx.doi.org/10.1007/978-1-4302-0246-2_9" 128 | } 129 | 130 | 131 | @book{lim2015r, 132 | title={R High Performance Programming}, 133 | author={Lim, Aloysius and Tjhi, William}, 134 | year={2015}, 135 | publisher={Packt Publishing Ltd} 136 | } 137 | 138 | @inproceedings{tierney2001compiling, 139 | title={Compiling R: A preliminary report}, 140 | author={Tierney, Luke}, 141 | booktitle={Proceedings of DSC}, 142 | volume={2}, 143 | pages={2}, 144 | year={2001} 145 | } 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /doc/rcaller3/rcaller3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbytecode/rcaller/2c053c9e4cf2a123dfe379e6a8d7f29e283bac5c/doc/rcaller3/rcaller3.pdf -------------------------------------------------------------------------------- /markdown/clojure.md: -------------------------------------------------------------------------------- 1 | # Calling R from within Clojure 2 | 3 | Clojure is one of the most popular JVM languages. RCaller can directly be used in a Clojure projectt. Firstly, add the RCaller dependency in your ```projectt.clj``` file: 4 | 5 | ```clojure 6 | :dependencies [[org.clojure/clojure "1.10.1"] 7 | [com.github.jbytecode/RCaller "3.0.2"]] 8 | ``` 9 | 10 | The primary Java classes ```RCaller``` and ```RCode``` can be included in the projectt using 11 | 12 | ```clojure 13 | (ns rcallertest.core 14 | (:import [com.github.rcaller.rstuff RCaller RCode]) 15 | (:gen-class)) 16 | ``` 17 | 18 | RCaller interacts with ```R``` interpreter in two ways. The first one simply passes the ```R``` code and gets back the calculated results. The ```R``` process is terminated after performing calculations. The second one hangs an ```R``` connection in the memory so sequential calls are faster using these pre-started ```R``` process. 19 | 20 | Here is a single pass example. In this example, an ```R``` process is created, calculations are performed, and the process is terminated: 21 | 22 | ```clojure 23 | (defn runAndResult [code x y] 24 | (let [rcaller (RCaller/create) 25 | rcode (RCode/create) 26 | parser (.getParser 27 | (do 28 | (.addRCode rcode code) 29 | (.setRCode rcaller rcode) 30 | (.runAndReturnResult rcaller x) 31 | rcaller)) 32 | result (.getAsDoubleArray parser y)] 33 | result)) 34 | ``` 35 | 36 | Now, we send an ```R``` code and get back the results: 37 | 38 | ```clojure 39 | (runAndResult 40 | " 41 | x <- rnorm(10) 42 | m = mean(x) 43 | s = sd(x) 44 | result <- list(m = m, s = s) 45 | " 46 | "result" "m") 47 | ``` 48 | 49 | ```x``` is an random vector drawn from a standard Normal distribution. ```m``` and ```s``` are arithmetic mean and standard deviation of ```x```, respectively. ```result``` is a ```list``` that holds these values. The ```runAndResult``` ```Clojure``` function extracts the value ```m``` from the returned list ```result```. 50 | -------------------------------------------------------------------------------- /paper/paper.bib: -------------------------------------------------------------------------------- 1 | @article{satman2014rcaller, 2 | title={RCaller: A software library for calling R from Java}, 3 | author={Satman, M Hakan}, 4 | journal={Journal of Advances in Mathematics and Computer Science}, 5 | pages={2188--2196}, 6 | doi={10.9734/bjmcs/2014/10902}, 7 | year={2014} 8 | } 9 | 10 | @Manual{rcoreteam, 11 | title = {R: A Language and Environment for Statistical Computing}, 12 | author = {{R Core Team}}, 13 | organization = {R Foundation for Statistical Computing}, 14 | address = {Vienna, Austria}, 15 | year = {2020}, 16 | url = {https://www.R-projectt.org/}, 17 | } 18 | @inproceedings{urbanek2003fast, 19 | title={A fast way to provide R functionality to applications}, 20 | author={Urbanek, Simon}, 21 | booktitle={Proceedings of DSC}, 22 | volume={2}, 23 | year={2003}, 24 | organization={Citeseer} 25 | } 26 | 27 | @article{urbanek2009talk, 28 | title={How to talk to strangers: ways to leverage connectivity between R, Java and Objective C}, 29 | author={Urbanek, Simon}, 30 | journal={Computational statistics}, 31 | volume={24}, 32 | number={2}, 33 | pages={303--311}, 34 | year={2009}, 35 | doi={10.1007/s00180-008-0132-x}, 36 | publisher={Springer} 37 | } 38 | 39 | @manual{satmancurcean2016, 40 | title={RCaller 3.0: An Easy Tool for Abstraction of Java and R Connectivity}, 41 | author={Satman, M.Hakan and Curcean, Paul}, 42 | year={2016}, 43 | url={https://github.com/jbytecode/rcaller/blob/master/doc/rcaller3/rcaller3.pdf} 44 | } 45 | 46 | @inproceedings{graalvm, 47 | title={Towards polyglot adapters for the graalvm}, 48 | author={Niephaus, Fabio and Felgentreff, Tim and Hirschfeld, Robert}, 49 | booktitle={Proceedings of the Conference Companion of the 3rd International Conference on Art, Science, and Engineering of Programming}, 50 | pages={1--3}, 51 | doi={10.1145/3328433.3328458}, 52 | year={2019} 53 | } 54 | 55 | @inproceedings{renjin, 56 | title={Renjin: A new R interpreter built on the JVM}, 57 | author={Bertram, Alexander}, 58 | booktitle={The R User Conference, useR! 2013 July 10-12 2013 University of Castilla-La Mancha, Albacete, Spain}, 59 | volume={10}, 60 | number={30}, 61 | pages={105}, 62 | year={2013} 63 | } 64 | 65 | @manual{rcallerservice, 66 | title={RCallerService — microservice for running R-scripts by HTTP}, 67 | author={Aleksandr Kopilov}, 68 | year={2020}, 69 | url={https://github.com/Kopilov/RCallerService} 70 | } 71 | -------------------------------------------------------------------------------- /paper/paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'RCaller: A Java package for interfacing R' 3 | tags: 4 | - R 5 | - Java 6 | - statistics 7 | - data science 8 | authors: 9 | - name: Mehmet Hakan Satman 10 | orcid: 0000-0002-9402-1982 11 | affiliation: 1 12 | - name: Kopilov Aleksandr 13 | orcid: 0000-0002-8223-2168 14 | affiliation: 2 15 | affiliations: 16 | - name: Department of Econometrics, Istanbul University, Istanbul, Turkey 17 | index: 1 18 | - name: Department of Mathematical Optimization and Modeling, BIA-Technologies, Saint Petersburg, Russian Federation 19 | index: 2 20 | date: 24 August 2020 21 | bibliography: paper.bib 22 | --- 23 | 24 | # Summary 25 | In this paper, version 3.0 of the open source library RCaller is introduced. RCaller is a software library which simplifies performing data analysis and statistical calculations in Java using R. The details are hidden from users including transferring data between platforms, function calls, and retrieving results. In addition to previous RCaller versions, RCaller 3.0 implements the scripting API of Java, ensuring R function calls and data transfers are performed in a standard way, as is usual for other scripting languages in Java. Besides implementation of new features, RCaller has many performance improvements in the new release of 3.0 [@satmancurcean2016]. 26 | 27 | # State of the field 28 | Nowadays, increased interest in statistical computation and data analysis has enhanced the popularity of some programming languages such as R, Python, and Julia. As a result of popularity, hundreds of packages are developed for these targeted languages. On the other side, many mainframe languages and their packages are adopted for general-purpose tasks in several platforms. Interaction between those languages became a major requirement due to the lack of modern statistical tools written in the general-purpose languages such as Java. Renjin [@renjin] is a great effort for interfacing R from within Java using a different perspective: Writing R from scratch in Java! GraalVM [@graalvm] is an other admirable attempt for interfacing Python and R in Java with its polyglot design. Many tools and software packages are developed for interfacing R and Java. Each one stands out with its different features including speed, installation procedures, learning speed, and ease of use. 29 | 30 | 31 | # Statement of need 32 | RCaller is a Java library for interfacing R from within Java [@satman2014rcaller]. R is a popular programming language and a programming environment with hundreds of packages written in C, C++, Fortran, and R itself [@rcoreteam]. This huge collection of computation tools is not directly accessible for the other languages, especially for Java. RCaller supplies a clean API for calling R functions, managing interactions, and transferring objects between languages. There are other options in the literature including Rserve [@urbanek2003fast] and rJava [@urbanek2009talk] which are based on TCP sockets and JNI (Java Native Interface), respectively. RCaller provides a set of easier calling schemes without any dependencies. Previous works showed that the performance of the library is suitable for more cases, and studies with moderate datasets can be handled in reasonable times [@satmancurcean2016]. Following its first publication [@satman2014rcaller], support for DataFrame objects, R start-up options, automatic Rscript executable locator, and Java Scripting API (JSR 223) have been implemented. 33 | 34 | 35 | R has many well-tested and mature packages including for automatic time series model selection, clustering, segmentation and classification, non-linear and robust regression estimations, data and text mining, linear and non-linear programming, generating plots, multivariate data analysis, and function optimization. RCaller brings all of the functionality that R provides in Java. RCaller is also used as a core of RCallerService [@rcallerservice], a free microservice solution for running R-scripts from any other languages using HTTP. 36 | 37 | 38 | # Java scripting interface 39 | RCaller also implements the scripting API of Java (JSR 223) after version 3 and above. In other words, the engine behaves like a Java implementation of R. With this feature of RCaller, calling R from Java is seemingly the same as in the other JSR 223 implementations such as JavaScript, Python, Groovy, and Ruby. However the performance is not directly comparable with native counterparts (Rhino, Jython, JGroovy, JRuby, etc.) since the target language is not reimplemented in Java. Here is an example of sorting a Java array in R side and handling the result in 40 | Java: 41 | 42 | ```Java 43 | ScriptEngineManager manager = new ScriptEngineManager(); 44 | ScriptEngine en = manager.getEngineByName("RCaller"); 45 | 46 | try { 47 | double[] a = new double[] {19.0, 17.0, 23.0}; 48 | en.put("a", a); 49 | en.eval("sortedA <- sort(a)"); 50 | double[] result = (double[])en.get("sortedA"); 51 | System.out.println(result[0]); 52 | } catch (ScriptException e) { 53 | // TODO Auto-generated catch block 54 | e.printStackTrace(); 55 | } 56 | ``` 57 | 58 | RCaller, as a scripting engine in Java, creates an R process, encodes Java objects to XML, runs commands in R side, gets back the results as XML, and parses the result to Java objects. Since a single R process is created and used for consecutive calls, XML parsing is the only calculation overhead. 59 | 60 | # Acknowledgements 61 | 62 | We acknowledge contributions from Paul Curcean, Miroslav Batchkarov, Joel Wong, Kejo Starosta, Steven Sotelo, Edinei Piovesan, Simon Carter, and others of this projectt. 63 | 64 | # References 65 | --------------------------------------------------------------------------------