Skip to content

Corner cases

genmeblog edited this page Apr 14, 2020 · 1 revision

Sometimes interoperability between R and Clojure fails and we can face the case which can't be easily handled using clojisr DSL. Here is a collection of such cases and proposed solutions.

R symbols with forbidden chars

Normally Clojure symbol acts as R symbol, ie. 'x is the same as R x. However there are many examples where R symbols can't be easily represented on Clojure side. These can be defined in R packages as functions or appear as column names in dataframes after some data manipulation.

R symbol Clojure symbol Comment
: colon predefined in clojisr.v1.r namespace as function, also part of DSL
[ bra as above
[[ brabra as above
[<- bra<- as above
[[<- brabra<- as above
~ tilde or formula usually used in formulas, defined as DSL construct
symbol with spaces (symbol "`symbol with spaces`") construct artificial symbol
package::function (clojisr.v1.r/r "{package::function}") access via r call

with

Sometimes R functions acts as a macro which do not evaluate arguments but treat them as symbols. For example with is this kind of macro which evaluates an R expression in an environment constructed from data (as documentation describes).

> with(mtcars,lm(qsec ~ mpg))

Call:
lm(formula = qsec ~ mpg)

Coefficients:
(Intercept)          mpg  
    15.3548       0.1241  

Since expression is called after with is evaluated we can't do (r.base/with 'mtcars (r.stats/lm '(formula qsec mpg))), we have to call it:

(r.base/with 'mtcars '(lm (formula qsec mpg)))

;; Call:
;; lm(formula = (qsec ~ mpg))
;; 
;; Coefficients:
;; (Intercept)          mpg  
;;    15.3548       0.1241  

The same case is with r.dplyr/mutate function if you want to pass row_number call for example which should be passed as symbol, ie. '(row_number) not (r.dplyr/row_number)

Default function and data

When you start R, some packages are imported by default and are visible to the user. This is not a case in clojisr, you have to require all packages (even default) explicitly by calling (require-r '[base]). You learn quickly that you need also require utils, stats, datasets, graphics and grDevices to operate like in R.

Also by default all required R symbols land into dedicated namespace, for example (require '[base]) creates r.base namespace and puts there all functions and variables found in base package. To simulate R behaviour just add :refer :all to the require as you would normally do in Clojure.

What's also important, require-r calls library function, which loads this library also on the R side.

Clone this wiki locally