R is a programming language for mathematics and statistics. There are several R libraries available to support web development, including rjson and RJSONIO (note case – R library names are case sensitive). RJSONIO is based on rjson, but with modifications to improve performance working with large JSON payloads.

The example below returns the data required to render a scatter chart with a best fit line like this:

This requires that you’ve already set up rApache. To install RJSONIO, check http://cran.r-project.org/src/contrib/ to find the latest version, and use that filename in the following. It appears that CRAN removes the old versions- unfortunately they don’t have an easy way to just pull the latest.

wget http://cran.r-project.org/src/contrib/RJSONIO_1.0-1.tar.gz R CMD INSTALL RJSONIO_1.0-1.tar.gz

The following code will pull JSON data from the URL, parse it, and return a linear model. This includes information for the graph, error bars, best fit line, axis intercepts, etc. For a charting package like ExtJS, the data may need to be re-formatted to render successfully, which fortunately R is quite good at.

```
setContentType("application/json")
library(RJSONIO)
library(utils)
cat(GET$data)
json <- fromJSON(URLdecode(GET$data))
fit <- lm(x ~ y)
cat(toJSON(fit))
```

Strictly speaking, this should be a POST, but this makes the example easier to read.

Some examples of this use the basicJSONHandler, like below. I found that this does not return numerics for JSON arrays, and opted not to use it.

h = basicJSONHandler() x = fromJSON("[1, 2, 3]", h)

If you've read this far, you may enjoy my review of the R Cookbook.

This URL accepts and returns JSON results:

http://localhost:8081/R/fit.R?data={%22x%22:[1.5,2,7,8,15],%22y%22:[1.5,2,7,8,15]}

Results:

{ "assign" : [ 0, 1 ], "call" : { "" : "lm", "formula" : [ "~", "x", "y" ] }, "coefficients" : { "(Intercept)" : 0.95408999999999999, "y" : 0.78297000000000005 }, "df.residual" : 3, "effects" : { "" : 0.23488999999999999, "(Intercept)" : -13.864000000000001, "y" : 8.5699000000000005 }, "fitted.values" : { "1" : 2.1284999999999998, "2" : 2.52, "3" : 6.4348999999999998, "4" : 7.2179000000000002, "5" : 12.699 }, "model" : { "x" : [ 1, 3, 6, 9, 12 ], "y" : [ 1.5, 2, 7, 8, 15 ] }, "qr" : { "pivot" : [ 1, 2 ], "qr" : [ { "(Intercept)" : -2.2361, "y" : -14.981999999999999 }, { "(Intercept)" : 0.44721, "y" : 10.945 }, { "(Intercept)" : 0.44721, "y" : -0.17422000000000001 }, { "(Intercept)" : 0.44721, "y" : -0.26557999999999998 }, { "(Intercept)" : 0.44721, "y" : -0.90512999999999999 } ], "qraux" : [ 1.4472, 1.2826 ], "rank" : 2, "tol" : 9.9999999999999995e-08 }, "rank" : 2, "residuals" : { "1" : -1.1285000000000001, "2" : 0.47997000000000001, "3" : -0.43489, "4" : 1.7821, "5" : -0.69865999999999995 }, "terms" : [ "~", "x", "y" ], "xlevels" : { } }