RSRuby and Rails revisited

A couple of months ago, I wrote a brief guide to displaying R plots in a Rails application using RSRuby.

It worked at the time – really it did – but since then, I’ve encountered problems. One is that despite sending the plot output to a PNG file, R X11 windows started to pop up on loading the web page containing the plot. Another is the appearance of long error messages related to “stack smashing” on terminating Mongrel server.

Fortunately, I read an excellent guide by Ana Nelson, R on Rails with RSRuby, which convinced me that I was doing things all wrong. So here is an amended version of my R + RSRuby + Rails “Hello World” application.

We start as usual with “rails Plotter”. Next, I like to delete the public/index.html file and generate a controller named “home” with a single action, “index”.

rails Plotter
cd Plotter
rm public/index.html
./script generate controller Home index

Edit config/routes.rb so as root points to this controller and action:

ActionController::Routing::Routes.draw do |map|
  map.root  :controller => "home"
end

Right, let’s get on with the R integration. Create two new directories, lib/R and public/images/R. Edit a file in lib/R named “plot.R”:

myplot = function() {
  png(filename = "public/images/R/plot.png")
  boxplot(c(1,2,3,4),c(5,6,7,8))
  dev.off()
}

This defines a function, myplot(), which generates a toy boxplot from two sets of values and writes it to the file public/images/R/plot.png.

The file helpers/application_helper.rb, as before, defines the environment variable R_HOME, required for RSRuby to work:

module ApplicationHelper
# set R_HOME if not set
  if ENV['R_HOME'].nil?
    ENV['R_HOME'] = "/usr/lib/R"
  end
end

The file controllers/application_controller.rb defines a method named “get_r”. This method initiates an instance of RSRuby, reads the R script lib/R/plot.R and returns the instance variable:

class ApplicationController < ActionController::Base
  def get_r
    require 'rsruby'
    @@r = RSRuby.instance
    @@r.eval_R("source('lib/R/plot.R')")
    return @@r
  end
end
&#91;/sourcecode&#93;

We're all set.  In the Home controller, controllers/home_controller.rb, we can call the get_r method and then, call the R function, myplot(), on the RSRuby instance:
&#91;sourcecode language="ruby"&#93;
class HomeController < ApplicationController
  before_filter :get_r

  def index
    @@r.myplot.call
  end
end
&#91;/sourcecode&#93;

This writes the R boxplot to a PNG file.  The view, views/home/index.html.erb, is simple:
&#91;sourcecode language="ruby"&#93;
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>

<%= image_tag("R/plot.png") %>

Fire up Rails with “./script/server”, open “http://localhost:3000&#8221; in a browser and you should see a view like the one shown to the right.

R boxplot in Rails via RSRuby

R boxplot in Rails via RSRuby


Much better than before, I think you’ll agree. Head over to Ana’s blog post and scroll down to the paragraph that begins: “My workflow for using RSRuby and R to produce dynamic graphs goes something like this”, where a better programmer than I explains the advantages of this approach.

Next steps: get some variables from Rails into the R plotting function and do something real.