Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional convert options for r->clj functions #105

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ pom.xml.asc
.clay*
*qmd
.clerk
.calva
1 change: 1 addition & 0 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
:test {:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.0" :git/sha "b3fd0d2"}}
:jvm-opts ["-Djava.awt.headless=true"]
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}}}
68 changes: 45 additions & 23 deletions src/clojisr/v1/impl/java_to_clj.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
(:require [tech.v3.dataset :as ds]
[tech.v3.dataset.column :as col]
[tech.v3.datatype :refer [->reader]]

[tech.v3.tensor :as dtt]
[clojisr.v1.impl.protocols :as prot]
[clojisr.v1.impl.common :refer [tsp->reader first-step->java java->column cartesian-product]]))
[clojisr.v1.impl.common :refer [tsp->reader first-step->java java->column cartesian-product]]
[tech.v3.datatype :as dtype]
[ tech.v3.tensor.dimensions :as tdim]))

(set! *unchecked-math* :warn-on-boxed)

Expand Down Expand Up @@ -92,20 +94,36 @@
(apply ds/concat)))))

(defn multidim? [obj] (prot/attribute obj "dim"))
(defn multidim->dataset
([exp] (multidim->dataset exp nil))
([exp extra]
(let [dims (fix-dims (prot/attribute exp "dim"))
dimnames (fix-dimnames dims (prot/attribute exp "dimnames"))]
(make-nd exp extra dims dimnames))))

(defn- make-tensor [exp dims]

(def exp exp)
(def dims dims)

(dtt/construct-tensor (prot/->clj exp)
(tdim/dimensions dims)))
;; (dtt/->tensor [[7 4 6 8 8 7 5 9 7 8]
;; [4 1 3 6 5 2 3 5 4 2]
;; [3 8 5 1 7 9 3 8 5 2]] :datatype :float64))
(defn multidim->dataset-or-tensor
([exp] (multidim->dataset-or-tensor exp nil nil))
([exp extra] (multidim->dataset-or-tensor exp extra nil))
([exp extra options]


(let [dims (fix-dims (prot/attribute exp "dim"))
dimnames (fix-dimnames dims (prot/attribute exp "dimnames"))]
(if (:as-tensor options)
(make-tensor exp dims)
(make-nd exp extra dims dimnames)))))

(defn mts? [obj] (prot/inherits? obj "mts"))
(defn mts->dataset
[exp]
(let [tsp (-> exp
(prot/attribute "tsp")
(tsp->reader))]
(multidim->dataset exp [tsp :$time])))
(multidim->dataset-or-tensor exp [tsp :$time])))


;; table
Expand Down Expand Up @@ -153,18 +171,22 @@

(defn java->clj
"Perform high level data conversion"
[exp]
(let [exp (first-step->java exp)]
(cond
(data-frame? exp) (data-frame->dataset exp)
(mts? exp) (mts->dataset exp)
(timeseries? exp) (timeseries->dataset exp)
(dist? exp) (dist->dataset exp)
(table? exp) (table->dataset exp)
(multidim? exp) (multidim->dataset exp)
:else (prot/->clj exp))))

(defn java->native
[exp]
(prot/->native exp))

([exp options]
;(println :options options)
(def options options)
(let [exp (first-step->java exp)]
(cond
(data-frame? exp) (data-frame->dataset exp)
(mts? exp) (mts->dataset exp)
(timeseries? exp) (timeseries->dataset exp)
(dist? exp) (dist->dataset exp)
(table? exp) (table->dataset exp)
(multidim? exp) (multidim->dataset-or-tensor exp nil options)
:else (prot/->clj exp))))
( [exp] (java->clj exp nil)))

(defn java->native
[exp]
(prot/->native exp))

6 changes: 6 additions & 0 deletions src/clojisr/v1/impl/rserve/call.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@

(defn try-eval-catching-errors [expression ^RConnection r-connection]
;; Using the technique of https://stackoverflow.com/a/40447542/1723677, the way it is used in Rojure.
(def expression expression)
(try
(let [expression-str (-> expression
(string/escape char-escape-string)
(->> (format "try(eval(parse(text=\"%s\")),silent=TRUE)")))
^REXP rexp (locking r-connection
(.parseAndEval r-connection expression-str))]
(def rexp rexp)

(clojure.reflect/reflect rexp)
(.asIntegers rexp)

(if (.inherits rexp "try-error")
(do (log/error [::try-eval-catching-errors {:message (format "Error in R evaluating expression: %s. R exception: %s"
expression (.asString rexp))}])
Expand Down
55 changes: 52 additions & 3 deletions src/clojisr/v1/r.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
[clojure.string :as string]
[clojisr.v1.util :refer [bracket-data maybe-wrap-backtick]]
[clojisr.v1.require :refer [require-r-package]]
[clojisr.v1.engines :refer [engines]])
[clojisr.v1.engines :refer [engines]]
[tech.v3.tensor :as dtt])
(:import clojisr.v1.robject.RObject))

(defn init [& {:keys [session-args]}]
Expand Down Expand Up @@ -40,7 +41,7 @@
(defn java->native-clj [java-object]
(java2clj/java->native java-object))

(defn java->clj [java-object] (java2clj/java->clj java-object))
(defn java->clj [java-object & options] (java2clj/java->clj java-object options))

(defn clj->java [clj-object & {:keys [session-args]}]
(let [session (session/fetch-or-make session-args)]
Expand All @@ -49,7 +50,13 @@
(def clj->java->r (comp java->r clj->java))
(def clj->r clj->java->r)

(defn r->java->clj [r-object] (-> r-object r r->java java2clj/java->clj))
(defn r->java->clj
([r-object options]
(-> r-object
(r)
(r->java)
(java2clj/java->clj options)))
( [r-object] (r->java->clj r-object nil)))
(def r->clj r->java->clj)

(defn r->java->native-clj [r-object] (-> r r-object r->java java2clj/java->native))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not change this function to take options.
Could not find any usage, neither sucessfully call it myself.

Expand Down Expand Up @@ -222,3 +229,45 @@
"Prints help for an R object or function"
([r-object] (println (help r-object)))
([function package] (println (help function package))))

(comment
(require-r '[datasets])

(require-r '[base])

(r "m <- array(seq(1, 10*5*4*7), dim=c(10, 5, 4,7))")


( r)

(def m (-> (r "m")
( r->clj {:as-tensor true})))

(r "dim(m)")

)

(require '[tech.v3.tensor :as dtt])

(r "m[10,5,4,7]")
;;=> [1] 1400
(dtt/mget m 9 4 3 6)
;;=> 1400


(r "m[1,1,1,1]")
;;=> [1] 1
(dtt/mget m 0 0 0 0)
;;=> 1

(r "m[3,3,3,3]")
;;=> [1] 523
;;

;;
(dtt/mget m 2 2 2 2)
;;=> 353

(r "print(.MEM$xe6ab3051a83d48f3)")

(r "capture.output(print(.MEM$x9cd80e7a0ca4471b))")
24 changes: 24 additions & 0 deletions test/clojisr/v1/matrix_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(ns clojisr.v1.matrix-test
(:require
[clojure.test :refer [deftest is]]
[clojisr.v1.r :as r]))

(r/require-r '[base])

(deftest options-are-optional-without

(is (= (range 5)
(->
(r.base/matrix (range 5))
(r/r->clj)
(get 1)))))


(deftest options-are-optional-wit
;; does not crash
(is (= (range 5)
(->
(r.base/matrix (range 5))
(r/r->clj {:some-option true})
(get 1)))))

Loading