Giter Club home page Giter Club logo

opencpu-clj's Introduction

Clojars Project

opencpu-clj

A Clojure library designed to use the OpenCPU API from Clojure.

Usage

The purpose of this library is to allow Clojure applications to call arbitrary R functions and access data from R packages via a remote opencpu server. For the current list of supported API methods see [here] (doc/endpoints.md)

To use this library, just add

[opencpu-clj "0.3.1"]

to you project.clj

Low level API

The low-level package contains four methods, which match the names of the API endpoints:

  • object
  • library
  • package
  • session

Low-level general call of an R function

To call R, there are low-level methods (in ocpu.clj), which just call the OpenCPU endpoints. They require parameter to be encoded in JSON or to be the keys coming from previous calls. The parameters must be named always.

A general call to an R method looks like this:

(use '[opencpu-clj.ocpu])


(object "https://cloud.opencpu.org" :library "stats" :R "rnorm" {:n 10})
=> {:result ["/ocpu/tmp/x047c97a725/R/.val" "/ocpu/tmp/x047c97a725/stdout" "/ocpu/tmp/x047c97a725/source" "/ocpu/tmp/x047c97a725/console" "/ocpu/tmp/x047c97a725/info" "/ocpu/tmp/x047c97a725/files/DESCRIPTION"], :status 201}
1f6261fc3/info" "/ocpu/tmp/x01f6261fc3/files/DESCRIPTION"]
(session "https://cloud.opencpu.org" "/ocpu/tmp/x047c97a725/R/.val" :json )
=>{:result (1.0304 -1.2131 1.1241 -0.2802 0.0636 -0.2377 0.8318 1.5895 1.9314 0.2717), :status 200}

This calls the R function "rnorm" from package "stats" with parameter (n=10) on the OpenCPU server at url "http://cloud.opencpu.org".

It returns a session key. (In the form of a list of session key links). Further data of the call result can be obtained by accessing the different links via the "session" method.

These links give access to different data from the call, like:

  • the result of the call
  • the stdout of the call
  • the parameters the function was called with
  • the sessionInfo() of the call ...

So to access the return value of a function, two calls are required.

Low-level call of R function - JSON-RPC style

An example usage to call R function "seq", with named parameters "from" and "to". It gets called in "json-rpc style", so returns Json, which gets coerced to a Clojure data structure (in this case a vector)

Attention: This is not possible to do with all R functions. Most function results cannot be converted to Json by the OpenCPU server, and some json coming back cannot be converted to a Clojure datastructure.

So in contrary to the "general" style, which always succeeds (given the parameter are ok, so R can do the call successfully), the Json style might fail to marshall the result back from the server.

So the following will work, because the "seq" function returns a vector of numeric type, which can be marshalled to Json by R and unnmarshelled by Clojure.

(object "https://cloud.opencpu.org" :library "base" :R "seq" {:from 1 :to 5} :json)
=>{:result (1 2 3 4 5), :status 200}

To call the "lm" method like this, will fail, as it returns the R class "lm", which cannot be marshalled to Json by the JSONlite library used by the opencpu server.

(object "https://cloud.opencpu.org" :library "stats" :R "lm" {:formula "dist ~ speed" :data "cars"} :json)
=> {:result "No method asJSON S3 class: lm\n", :status 400}

So this method can only be called without :json. And the resulting session objects can then be used as parameters in further calls.

An other example is some matrix calculations done in R:

(require '[clojure.core.matrix :as m])
(require '[cheshire.core :as json])

(def m (m/matrix [[13 2][5 4]]))
(object "https://cloud.opencpu.org" :library "base" :R "eigen" {:x (json/encode m)} :json {:force true})

=> {:result {:values [14 3], :vectors [[0.8944 -0.1961] [0.4472 0.9806]]}, :status 201}

Parameter format for function calls

The "parameter" map passed to the 'object' need to have the values either as:

  • valid R expressions
  • session keys
  • Json syntax.

See the tests in ocpu_test.clj for examples.

Json Syntax

Json encoded parameters need to be in a Json format which is understood by the R function jsonlite::fromJSON and get converted in the correct R type. So the "params" parameter of function 'object' is a map from Keywords to (Json-encoded) Strings, like

{:a 10   b: [1 2 3 4 5]   c: "[\"a\",\"b\",\"c\"]}

Examples:

 R type         | R code                            | Clojure Type        | Json representation as Clojure String literal
----------------|-----------------------------------|-------------------- |-----------------------
                |                                   |primitive            | 1  or "1"
 numeric vector |                                   |integer vector       | "[1,2,3]"
 char vector    |                                   |String vector        | "[\"a\",\"b\",\"c\"
 matrix         | matrix(1:4,nrow=2)                |                     | "[[1,3],[2,4]]"
 dataframe      | data.frame(x=c(1,2),y=c("a","b")  |                     | "[{\"x\":1,\"y\":\"a\"},{\"x\":2,\"y\":\"b\"}]"
 list           | list(1,2)                         |                     | "[[1],[2]]"
 named list     | list(a=1,b=2)                     |                     | "{\"a\":[1],\"b\":[2]} "

See here for further information: http://arxiv.org/pdf/1403.2805v1.pdf

The return values for the R function calls via 'object' which requests "json" as output format, get encoded appropriately. So the function 'object' returns a Json encoded value following the upper encodings

High level API

Calling an R function

Evaluating an R expression

Accessing data from an R package

To access a dataset from inside an R package, the get-dataset method can be used like this.

(get-dataset "https://cloud.opencpu.org" "MASS" "Boston")

It returns a class of the type 'clojure.core.matrix.impl.dataset' which is used as well by Incanter. So all methods from Incanter, which take a dataset should work with it.

License

Copyright © 2014 Carsten Behring

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

opencpu-clj's People

Contributors

behrica avatar jonyepsilon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

daslu

opencpu-clj's Issues

possibly improve performance of json API

(require '[opencpu-clj.core :refer :all]
                '[clojure.core.matrix.dataset :as ds :refer [dataset]]
                '[opencpu-clj.test-support :refer [j]])

 (let [server-url "http://localhost:1723"
      rows (->> {:x (vec (range 9999))} 
                ds/dataset
                ds/row-maps)]
    (time (call-function-json-RPC server-url "base" "dim" {:x (j rows)})))

(Replace sever-url with your local opencpu sever url.)

Here is the output at my machine:

   11562.178474 msecs
   {:result (9999 1), :status 200}

This kind of performance requires some investigation. One suspect for time waste is the need to pass the whole dataset as a json string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.