Wednesday, March 27, 2013

“Building ractives is so addictive it should be illegal!”

clickme is an amazing R package. I was not sure what to expect when I first saw Nacho Caballero's announcement. I actually was both skeptical and intimidated, but neither reaction was justified. The examples prove its power, and his wiki tutorials ease the noobie difficulties. Very similar to shiny, clickme serves as an integration point for html, javascript (especially d3), and R. While clickme does not allow the R websocket interactivity that shiny does, its more concentrated focus on quick reproducibility and sharing makes it a very useful tool. This is very much in the spirit of http://dexvis.wordpress.com/ Reusable Charts. ractives defined as

(short for interactives-a hat tip to Neal Stephenson), which are simple folder structures that contain a template file used to populate the JS code with R input data

provide the structure for clickme to produce an html file from

  1. a template in R markdown (template.rmd)
  2. a translator R script (translator.r)
  3. a data source
  4. external scripts (probably javascript) and styles (.css).

Inspired by the clickme longitudinal heatmap example, I just had to try to create my own ractive. I thought Mike Bostock's line chart example would serve as a nice template for my first ractive. The data not surprisingly will come from the R finance package PerformanceAnalytics dataset named managers. With very minor modifications to the Bostock source and a simple custom R script translator (translator.R shown below), we have everything we need for this ractive, which I will call multiline.

#' Translate the data object to the format expected by current template
#'
#' @param data input data object
#' @param opts options of current template
#' @return The opts variable with the opts$data variable filled in
translate <- function(data, opts = NULL) {
require(df2json)

# I would like to generalize this to handle both price and return right
# now just handles return clickme template.Rmd javascript can handle
# prices or cumulative so we will send cumulative which can serve as price

# remove na
data[is.na(data)] <- 0
# get cumulative growth
data <- cumprod(1 + data)


# convert to data frame
data.df <- data.frame(cbind(format(index(data), "%Y-%m-%d"), coredata(data)))
colnames(data.df)[1] = "date"
# melt the data frame so we have our data in long form
data.melt <- melt(data.df, id.vars = 1, stringsAsFactors = FALSE)
colnames(data.melt) <- c("date", "indexname", "price")
# remove periods from indexnames to prevent javascript confusion these .
# usually come from spaces in the colnames when melted
data.melt[, "indexname"] <- apply(matrix(data.melt[, "indexname"]), 2, gsub,
pattern = "[.]", replacement = "")
opts$data <- df2json(data.melt)
opts
}


Now to create our first clickme html page, we just need a couple lines of code in R.

# if not already installed, uncomment the tow lines below
# library(devtools) install_github('clickme', 'nachocab')

require(clickme)
# set location where you put your multiline ractive
set_root_path("your-path-goes-here/ractives")
require(PerformanceAnalytics)
data(managers) #although I use managers, really any xts series of returns will work
clickme(managers, "multiline")

Then, we have a web page that will create an interactive d3 line chart using the cumulative growth of the managers return series. If you do not see the embed below, then please follow the link.


Eventually, it will be very nice to have an entire gallery of amazing ractives.


git repo

4 comments:

  1. I see you've been busy. Nice work! I'm adding ractives to my list of technologies to explore. Currently I integrate with R via passing dataframes via RServer. This might be better.

    - Pat

    ReplyDelete
  2. d3.js is really awesome. I am still not totally sure where d3 and R pretty much intersect and where they are miles apart.

    d3.js is simply too slow for some graphical endeavours - the force-directed graph layout handles something like a hundred nodes, with R and iGraph I just composed an animation of a growing network arranged in a force-directed fashion involving 70'000 nodes.

    Then again even though you can create choropleth maps with R but then you can't check out individual regions anymore (name, value). For my artical on the ration of young women to men in EU I used R to preprocess the data from Eurostat then C&Ped it from R into a textarea. d3.js takes the TSV list and colors a regional map according to it.

    As far as I can tell from the Network-Tab in the Dev Tools Shiny web panels are fetching a new PNG for every interaction affecting the charting. So basically it pre-generates all possible outcomes and connects them with the HTML form state. Can you confirm that? Or does it's capabilites go beyond this?

    Cheers

    Raffael / www.joyofdata.de

    ReplyDelete
    Replies
    1. very much enjoyed the comment and liked your site. d3.js does have some performance issues for things like 70,000 nodes, but handles most of what I have thrown at it very quickly. Most of my delay come in the statistical computation and data collection. Integration with R drastically helps in these areas.

      Although most of the examples on shiny show passing a png over websocket to the html, I most like passing the data over the websocket and letting d3 update or recreate the graph. Some examples are http://timelyportfolio.blogspot.com/2012/12/shinyr-conversion-of-another-one-of-my.html and http://timelyportfolio.blogspot.com/2012/12/d3-shiny-and-r-reporting-performance.html.

      Delete
  3. You're Shiny examples look very interesting. I am curious to figure out where Shiny might be useful in a business context. Will have to take a closer look at it.

    ReplyDelete