Romain Francois, Professional R Enthusiast

To content | To menu | To search

Thursday, February 18 2010

raster images and RImageJ

The next version of R includes support for raster images in standard and grid graphics.

The RImageJ package uses ImageJ through rJava to read and manipulate images from various formats

Paul Murrell closed the gap and contributed code that allows using images from the RImageJ package as raster objects.

makes the graph :

Rplot001.png

This feature depends on R >= 2.11.0, so will only get available when this version becomes current, in the meantime, you can get the package from its rforge project page

Tuesday, September 8 2009

new R package : ant

The ant package has been released to CRAN yesterday. As discussed in previous posts in this blog (here and here), the ant R package provides an R-aware version of the ant build tool from the apache project.

The package contains an R script that can be used to invoke ant with enough plumbing so that it can use R code during the build process. Calling the script is further simplified with the ant function included in the package.

$ Rscript -e "ant::ant()"

The simplest way to take advantage of this package is to add it to the Depends list of yours, include a java source tree somewhere in your package tree (most likely somewhere in the inst tree) with a build.xml file, and include a configure and configure.win script at the root of the package that contains something like this:

#!/bin/sh

cd inst/java_src
"${R_HOME}/bin/Rscript" -e "ant::ant()"
cd ../..

This will be further illustrated with the demo package helloJavaWorld in future posts

Thursday, September 3 2009

update on the ant package

I have updated the ant package I described yesterday in this blog to add several things

  • Now the R code related to <r-set> and <r-run> tasks can either be given as the code attribute or as the text inside the task
  • The R code has access to special variables to manipulate the current project (project) and the current task (self) which can be used to set properties, get properties, ...
  • The package contains ant ant function so that ant can be invoked using a simple Rscript call, see below

The package now includes a demonstrative build.xml file in the examples directory

Here is the result

Wednesday, September 2 2009

R capable version of ant

ant is an amazing build tool. I have been using ant for some time to build the java code that lives inside the src directories of my R packages, see this post for example.

The drawbacks of this approach are :

  • that it assumes ant is available on the system that builds the package
  • You cannot use R code within the ant build script

The ant package for R is developed to solve these two issues. The package is source-controlled in r-forge as part of the orchestra project

Once installed, you find an ant.R script in the exec directory of the package. This script is pretty similar to the usual shell script that starts ant, but it sets it so that it can use R with the following additional tasks

  • <r-run> : to run arbitrary R code
  • <r-set> : to set a property of the current project with the result of an R expression

Here is an example build file that demonstrate how to use these tasks

Here is what happens when we call the R special version of ant with this build script

$ `Rscript -e "cat( system.file( 'exec', 'ant.R', package = 'ant') )"`
Buildfile: build.xml

test:
     [echo] 
     [echo]   	R home        : /usr/local/lib/R
     [echo]   	R version     : R version 2.10.0 Under development (unstable) (2009-08-05 r49067)
     [echo]   	rJava home    : /usr/local/lib/R/library/rJava
     [echo]   	rJava version : 0.7-1
     [echo]  

BUILD SUCCESSFUL
Total time: 1 second

Tip: get java home from R with rJava

Assuming rJava is installed and works, it is possible to take advantage of its magic to get the path where java is installed:

$ Rscript --default-packages="methods,rJava" -e ".jinit(); .jcall( 'java/lang/System', 'S', 'getProperty', 'java.home' ) "
[1] "/opt/jdk/jre"

This is useful when you develop scripts that need to call a java program without assuming that java is on the path, or the JAVA_HOME environment variable is set, etc ...

Friday, August 28 2009

Combine R CMD build and junit

This is a post in the series Mixing R CMD build and ant. Previous posts have shown how to compile the java code that lives in the src directory of a package and how to document this code using javadoc.

This post tackles the problem of unit testing of the java functionality that is shipped as part of an R package. Java has several unit test platforms, we will use junit here, but similar things could be done with other systems such as testng, ...

The helloJavaWorld package now looks like this :

.
|-- DESCRIPTION
|-- NAMESPACE
|-- R
|   |-- helloJavaWorld.R
|   `-- onLoad.R
|-- inst
|   |-- doc
|   |   |-- helloJavaWorld.Rnw
|   |   |-- helloJavaWorld.pdf
|   |   `-- helloJavaWorld.tex
|   `-- java
|       |-- hellojavaworld-tests.jar
|       `-- hellojavaworld.jar
|-- man
|   `-- helloJavaWorld.Rd
`-- src
    |-- Makevars
    |-- build.xml
    |-- junit
    |   `-- HelloJavaWorld_Test.java
    |-- lib
    |   `-- junit-4.7.jar
    `-- src
        `-- HelloJavaWorld.java

9 directories, 15 files

We have added the src/lib directory that contains the junit library and the HelloJavaWorld_Test.java that contain a simple class with a unit test

And the ant build file has been changed in order to

  • build the junit test cases, see the build-testcases target
  • run the unit tests, see the test target
  • create nice html reports, see the report target

The package can be downloaded here

Coming next, handling of dependencies between java code that lives in different R packages

Sunday, August 9 2009

Completion for java objects

As indicated in this thread, completion after the dollar operator can be customized by defining a custom names method. Here I am showing how to take advantage of this to display fields and methods of java references (jobjRef objects from the rJava package)

Here it is in action (I hit tab twice after the dollar sign)

Monday, June 22 2009

using ImageJ from R: the RImageJ package

I've pushed to CRAN the initial version of the RImageJ package. ImageJ is a java based image processing and analysis platform

This version of the package creates an instance of the IJ class as the IJ object in R, so that many methods of this class can be called using the dollar expansion of rJava.

Here is a simple example that uses the package:

download.file( "http://www.google.fr/intl/en_en/images/logo.gif", 
    dest = "google.gif" )

image = IJ$openImage( "google.gif" )
image$show()
IJ$run( "8-bit" )
IJ$run( "Invert" )
IJ$save( "bw-google.gif" )
image$close()


This downloads the google logo, convert it to black and white and inverts it

google logo bw-google.gif Future plans for this package contain:
  • integration of imagej and javagd
  • integration of the imagej macro recorder so that it creates R code instead of code in the imagej macro language

Wednesday, June 17 2009

with semantics for java objects in rJava

I've been playing with the rJava package recently. In a nutshell, rJava lets you create java objects and call methods on them from within the R console

col <- .jnew( "java/awt/Color", 255L, 0L, 0L )
.jcall( col, "I", "getRed" )
# [1] 255
col$getRed()
# [1] 255

The first call uses the regular function .jcall together with the JNI notation to call the getRed method of the created color, the second uses what rJava calls syntactic sugar, so that fields and methods of the object are accessed with the convenient R friendly dollar notation, great !!!

Here, I am just trying to add cream to make the coffee more tasty, by implementing the with method for java object

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

with.jobjRef <- function( data, expr, ...){
    
    env <- new.env( )
    clazz <- .jcall( data, "Ljava/lang/Class;", "getClass")
    fields <- .jcall( clazz, 
        "[Ljava/lang/reflect/Field;", "getFields" )
    lapply( fields, function(x ){
        n <- .jcall( x, "S", "getName" )
        makeActiveBinding( n, function(v){
            if( missing(v) ){
                # get 
                .jsimplify( .jcall( x, "Ljava/lang/Object;", "get", .jcast( data ) ) )
            } else {
                .jfield( data, n ) <- v
            }
        }, env ) 
    } )
    methods <- .jcall( clazz, 
        "[Ljava/lang/reflect/Method;", "getMethods" )
    lapply( methods, function(m){
        n <- .jcall( m, "S", "getName" )
        assign( n, function(...){
            .jrcall( data, n, ...) 
        }, env = env )
    } )
    assign( "this", data, env = env )
    eval( substitute( expr ), env = env )
}

This allows to call several methods on the same object, for example:

> with( col, {
+   cat( "red = ", getRed(), "\n" )
+   cat( "green = ", getGreen(), "\n" )
+   cat( "blue = ", getBlue(), "\n" )
+ })
red =  255 
green =  0 
blue =  0 
> p <- .jnew("java/awt/Point", 10L, 10L )
> with( p, {
+   move( 40L , 50L )
+   x <- y
+ } )
> p
[1] "Java-Object{java.awt.Point[x=50,y=50]}"

Note in the last example that the x variable that is assigned is the "x" field of the object

Friday, May 29 2009

biocep's broken REPL

The REPL (Read Eval Print Loop) is the mechanism that R uses to (roughly):

  • get input from the console
  • send output to the console

JRI defines a mechanism for taking advantage of the REPL from java, through the RMainLoopCallbacks interface

biocep takes advantage of this infrastructure by implementing the interface within the DirectJNI class

To circumvent the fact that the REPL is basically an endless loop, gui front-ends usually let the loop run in its own thread, and set this thread to sleep whenever the user does something else than feeding the REPL. This is not quite the way it is done in biocep's implementation. In biocep, when there is no command to run, the REPL thread would wait a short amount of time and then send an empty string "" to the readConsole callback.

The reason why this is deficient is because R might not only use the REPL to ask for top-level command line commands, but also within the environment browser commonly used in R for debugging. Now feeding the browser prompt with an empty command has the effect of stepping out of it, making debugging impossible.

Here is patch against biocep that is a first attempt at solving this issue by implementing the REPL with a sleeping thread, inspired from the way the REPL is implemented in JGR. The patch has been made available to the author of biocep.

Friday, March 27 2009

Document java software with "R CMD build", ant, and javadoc

This is the sequel of this post where we look at ways to build javadoc documentation as part of an R package

Ant has the javadoc task which we will use to build html files from java sources, leading to this modified build script with the new javadoc target:

   1 <project name="Hello Java World" basedir="." default="build" >
   2 
   3   <property name="target.dir" value="../inst/java" />
   4   <property name="javadoc.dir" value="../inst/javadoc" />
   5   
   6   <target name="clean">
   7     <delete dir="bin" />
   8     <delete dir="${javadoc.dir}" />
   9   </target>
  10   
  11   <target name="compile">
  12     <mkdir dir="bin"/>
  13     <javac srcdir="src" destdir="bin" />
  14   </target>
  15   
  16   <target name="javadoc">
  17     <mkdir dir="${javadoc.dir}" />
  18     <javadoc access="public" destdir="${javadoc.dir}"
  19       author="true" version="true" use="true" 
  20       windowtitle="helloJavaWorld - Java API">
  21         
  22        <fileset dir="src" defaultexcludes="yes">
  23             <include name="**/*.java"/>
  24         </fileset>
  25           
  26     </javadoc>
  27   </target>
  28   
  29   <target name="build" depends="compile,javadoc">
  30     <jar jarfile="${target.dir}/hellojavaworld.jar">
  31       <fileset dir="bin" />
  32     </jar>
  33   </target>
  34   
  35 </project>
  36 

so that when we run "R CMD build", the directory inst/javadoc gets created and filled with documentation generated from the java sources

The next thing we need is a way to access this documentation from R documentation, so we will just add a link to it from the Rd file, I have added this into the helloJavaWorld.Rd file in the seealso section:

18 \seealso{\link[helloJavaWorld:../javadoc/index]{The Java API of the package}}

This is not a perfect solution but gives a starting point. Potential issues, things to improve :

  • It would be better to have a link in the 00Index.html file, but there currently is no way to do something like that
  • A way to jump back to the R documentation from the java documentation is needed

I have posted a copy of the built package here, and you can download the source of this version here

Next step, use the junitreport ant task to make a report of unit tests of the java code

Thursday, March 26 2009

Build java software with "R CMD build" and ant

The helloJavaWorld is a simple R package that shows how to distribute java software with an R package and communicate with it by means of the rJava package. helloJavaWorld has a vignette showing the different steps involved in making such a package.

Basically, helloJavaWorld uses the inst directory of an R package structure to ship the jar file in which the java software is packaged.

This post goes a bit further and shows how we can distribute the source of the java software and make R compile it when we run R CMD build. For that we are naturally going to use the src part of the R package, leading to this structure:

.
|-- DESCRIPTION
|-- NAMESPACE
|-- R
|   |-- helloJavaWorld.R
|   `-- onLoad.R
|-- inst
|   |-- doc
|   |   |-- helloJavaWorld.Rnw
|   |   |-- helloJavaWorld.pdf
|   |   `-- helloJavaWorld.tex
|   `-- java
|       `-- hellojavaworld.jar
|-- man
|   `-- helloJavaWorld.Rd
`-- src
    |-- Makevars
    |-- build.xml
    `-- src
        `-- HelloJavaWorld.java

7 directories, 12 files

Only the src directory differs from the version of helloJavaWorld that is on cran. Let's have a look at the files that are in src:

helloJavaWorld.java is the same as the code we can read in helloJavaWorld's vignette

   1 public class HelloJavaWorld {
   2    
   3   public String sayHello() {
   4     String result = new String("Hello Java World!");
   5     return result;
   6   }
   7 
   8   public static void main(String[] args) {
   9   }
  10 
  11 } 

build.xml is a simple ant script. Ant is typically used to build java software. This build script is very simple. It defines the following targets:

  • clean: removes the bin directory we use to store compiled class files
  • compile: compiles all java classes found in src into bin
  • build: package the java classes into the hellojavaworld.jar file, that we store in the inst/java directory to comply with the initial package structure
   1 <project name="Hello Java World" basedir="." default="build" >
   2 
   3   <property name="target.dir" value="../inst/java" />
   4   
   5   <target name="clean">
   6     <delete dir="bin" />
   7   </target>
   8   
   9   <target name="compile">
  10     <mkdir dir="bin"/>
  11     <javac srcdir="src" destdir="bin" />
  12   </target>
  13   
  14   <target name="build" depends="compile">
  15     <jar jarfile="${target.dir}/hellojavaworld.jar">
  16       <fileset dir="bin" />
  17     </jar>
  18   </target>
  19   
  20   
  21 </project>

Next, is the Makevars file. When an R package is built, R looks into the src directory for a Makevars file, which would typically be used to indicate how to compile the source code that is in the package. We simply use the Makevars file to launch the building and cleaning with ant, so we have a simple Makevars file:

   1 .PHONY: all
   2 
   3 clean:
   4     ant clean
   5 
   6 all: clean
   7     ant build
   8 

See Writing R extensions for details on the Makevars file

And now we can R CMD build the package:

$ R CMD build helloJavaWorld
* checking for file 'helloJavaWorld/DESCRIPTION' ... OK
* preparing 'helloJavaWorld':                          
* checking DESCRIPTION meta-information ... OK         
* cleaning src                                         
ant clean                                              
Buildfile: build.xml                                   

clean:

BUILD SUCCESSFUL
Total time: 0 seconds
* installing the package to re-build vignettes
* Installing *source* package ‘helloJavaWorld’ ...
** libs                                           
ant clean                                         
Buildfile: build.xml

clean:

BUILD SUCCESSFUL
Total time: 0 seconds
ant build
Buildfile: build.xml

compile:
    [mkdir] Created dir: /home/romain/svn/helloJavaWorld/src/bin
    [javac] Compiling 1 source file to /home/romain/svn/helloJavaWorld/src/bin

build:
      [jar] Building jar: /home/romain/svn/helloJavaWorld/inst/java/hellojavaworld.jar

BUILD SUCCESSFUL
Total time: 1 second
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
 >>> Building/Updating help pages for package 'helloJavaWorld'
     Formats: text html latex example
  helloJavaWorld                    text    html    latex   example
** building package indices ...
* DONE (helloJavaWorld)
* creating vignettes ... OK
* cleaning src
ant clean
Buildfile: build.xml

clean:
   [delete] Deleting directory /home/romain/svn/helloJavaWorld/src/bin

BUILD SUCCESSFUL
Total time: 0 seconds
* removing junk files
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* building 'helloJavaWorld_0.0-7.tar.gz'

Download this version of helloJavaWorld: helloJavaWorld_0.0-7.tar.gz

This approach relies on ant being available, which we can specify in the SystemRequirements in the DESCRIPTION file

SystemRequirements: Java (>= 5.0), ant

Next time, we will see how to trick the documentation system so that it builds javadoc files