-
Notifications
You must be signed in to change notification settings - Fork 10
Corner cases
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.
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 |
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 , we have to call it:(r.base/with 'mtcars (r.stats/lm '(formula qsec mpg)))
(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)
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.