User Tools

Site Tools


Sidebar

  • Learn about Wiki
  • Lectures
  • Study
  • Tips
    • study:data_analysis:clojure_mathematica_r

      <markdown> # 08. Working with Mathematica and R

      Clojure가 어떻게 “Mathmetica와 R과 연동”하는가에 대해 설명함.

      ### [Mathematica](http://www.wolfram.com/mathematica/)란? - http://mirror.enha.kr/wiki/매스매티카 - 개발자인 스티븐 울프램은 신동이다. 영국 상류층에서 태어나서 이튼 칼리지를 다니다가 자기 수준에 안 맞는다고 생각해서 자퇴하고, 옥스포드 대학에 들어갔는데 강의가 수준이 낮다고 생각하고 2년도 못 버티고 또 자퇴하고 칼텍으로 건너가서 2년이 채 안 지난 20살때 박사학위를 받는다. - 입자물리를 연구하면서 연구할때 쓸 컴퓨터 프로그램을 짜다가 물리학 때려치우고 이길로 나섰다. 그래서 자기가 짠 컴퓨터 프로그램을 팔기 시작했는데 그것이 바로 매스매티카.

      ### [R](http://www.r-project.org/)이란? - R은 통계 계산 및 그래픽을 위한 언어이자 free 소프트웨어 환경. - KRUG 한국R사용자모임: http://r-project.kr/ - 2013.11 세미나: http://r-project.kr/content/r-manuals-11%EC%9B%94-%EC%84%B8%EB%AF%B8%EB%82%98-%EC%9D%BC%EC%A0%95%EC%9E%85%EB%8B%88%EB%8B%A4

      ### [Rserve](http://rforge.net/Rserve/) - Rserve는 다른 프로그램이 R의 기능을 활용할 수 있도록 도와주는 TCP/IP서버. - Java에서 클라이언트/서버개념 없이 R의 활용하려면, JRI라는 것도 있음. - http://rforge.net/JRI/

      ### LocalRepo - https://github.com/kumarshantanu/lein-localrepo - leiningen의 의존성을 해결하는데 있어, jar파일가지고, 로컬에 저장소를 만드는것. - 원레는 maven이 해줘야 하는 일이지만.. 간편하게 `lein localrepo install foo-1.0.6.jar com.example/foo 1.0.6`

      ### 8장에서 쓰는 예제 데이터 - http://www.ericrochester.com/clj-data-analysis/data/all_160.P3.csv

      ## Setting up Mathematica to talk to Clojuratica for Linux 참고: http://drcabana.org/2012/10/23/installation-and-configuration-of-clojuratica/

      환경: Ubuntu 12.04 LTS - 64-bit

      * mathmatica 다운로드. - http://www.wolfram.com/mathematica/trial/ - 가입필(email인증) - 1.75GB - 7시간동안 다운받아야함.

      </markdown>

      $ sudo sh Mathematica_9.0.1_LINUX.sh
       
      Enter the installation directory, or press ENTER to select /usr/local/Wolfram/Mathematica/9.0:
      >
       
      Type the directory path in which the Wolfram Mathematica script(s) will be created, or press ENTER to select /usr/local/bin
      >
       
      $ sudo mathematica
       
       
      ~$ mkdir ~/clj-interop && cd ~/clj-interop
      clj-interop$ wget http://mirror.apache-kr.org/ant/binaries/apache-ant-1.9.2-bin.zip
      clj-interop$ unzip apache-ant-1.9.2-bin.zip
      clj-interop$ wget https://github.com/stuarthalloway/Clojuratica/archive/master.zip
      clj-interop$ unzip master.zip
       
      clj-interop$ ls
      apache-ant-1.9.2-bin.zip master.zip
      apache-ant-1.9.2  Clojuratica-master
       
      clj-interop$ cd Clojuratica-master
      Clojuratica-master$ ../apache-ant-1.9.2/bin/ant
      Clojuratica-master$ sudo cp src/mma/*.m /usr/local/Wolfram/Mathematica/9.0/SystemFiles/Autoload/
       
      $ lein localrepo install ~/clj-interop/Clojuratica-master/clojuratica.jar local.repo/clojuratica 2.0.0
      $ lein localrepo install /usr/local/Wolfram/Mathematica/9.0/SystemFiles/Links/JLink/JLink.jar local.repo/JLink 9.0.0
       
       
      $ vi ~/.lein/profiles.clj:
       
          {:user {:plugins [[lein-localrepo "0.5.2"]]}}
       
      $ export LD_LIBRARY_PATH=/usr/local/Wolfram/Mathematica/9.0/SystemFiles/Links/JLink/SystemFiles/Libraries/Linux-x86-64

      <markdown>

      ## Setting up Mathematica to talk to Clojuratica for Windows

      * mathmatica 다운로드. - http://www.wolfram.com/mathematica/trial/ - 가입필(email인증) - 1.3GB - 6시간동안 다운받아야함. - 체험판인 경우 1PC에서만 activate됨. (하나의 activate key로, Windows, Linux 동시에 할 수 없음.)

      * Ant 다운로드 - http://ant.apache.org/bindownload.cgi - http://mirror.apache-kr.org/ant/binaries/apache-ant-1.9.2-bin.zip

      * JDK 다운로드 - http://www.oracle.com/technetwork/java/javase/downloads/index.html - http://download.oracle.com/otn-pub/java/jdk/7u45-b18/jdk-7u45-windows-x64.exe

      * Clojuratica 다운로드 - https://github.com/stuarthalloway/Clojuratica/archive/master.zip

      </markdown>

      C:\clj-interop>ls
      apache-ant-1.9.2  Clojuratica-master
       
      C:\clj-interop\Clojuratica-master>..\apache-ant-1.9.2\bin\ant.bat
      C:\clj-interop\Clojuratica-master>cp src/mma/*.m "C:\Program Files\Wolfram Research\Mathematica\9.0\SystemFiles\Autoload\"
       
      C:\clj-interop>notepad C:\Users\<USERNAME>\.lein\profiles.clj
       
          {:user {:plugins [[lein-localrepo "0.5.2"]]}}
       
      C:\clj-interop> lein localrepo install C:\clj-interop\Clojuratica-master\clojuratica.jar local.repo/clojuratica 2.0.0
      C:\clj-interop> lein localrepo install "C:\Program Files\Wolfram Research\Mathematica\9.0\SystemFiles\Links\JLink\JLink.jar" local.repo/JLink 9.0.0

      <markdown>

      ### ERROR java.lang.UnsatisfiedLinkError: com.wolfram.jlink.NativeLink.MLOpenString(Ljava/lang/String;[Ljava/lang/String;)

      - http://forums.wolfram.com/mathgroup/archive/2008/Aug/msg00664.html

      JLINK_LIB_DIR 를 설정하라고 하는데, 그냥 JLinkNativeLibrary.dll을 project폴더에 복사하고 실행시키는 방향으로 감.

      JLinkNativeLibrary.dll위치

      C:\Program Files\Wolfram Research\Mathematica\9.0\SystemFiles\Links\JLink\SystemFiles\Libraries\Windows\
      C:\Program Files\Wolfram Research\Mathematica\9.0\SystemFiles\Links\JLink\SystemFiles\Libraries\Windows-x86-64

      ## Calling Mathematica functions from Clojuratica

      lein new mm

      project.clj

      </markdown>

      (defproject mm "0.1.0-SNAPSHOT"
        :dependencies [[org.clojure/clojure "1.5.1"]
                       [local.repo/JLink "9.0.0"]
                       [local.repo/clojuratica "2.0.0"]
                       [incanter "1.5.4"]])

      <markdown>

      src/mm/core.clj

      </markdown>

      (ns mm.core)
       
      (use 'clojuratica)
      (import [com.wolfram.jlink MathLinkFactory])
       
      ;; J/Link
      ;; Mathematica에서 Java 메소드를 호출 할 수 있음.
      ;; Mathematica 서비스를 할용가능한  Java프로램을 작성할 수 있음.
       
      (defn init-mma [mma-command]
        (defonce math-evaluate
          (math-evaluator
           (doto
               (MathLinkFactory/createKernelLink mma-command)
             (.discardAnswer)))))
       
       
      (init-mma
       (str "-linkmode launch -linkname "
           "/usr/local/Wolfram/Mathematica/9.0/Executables/MathKernel"))
       
      (def-math-macro math math-evaluate)

      <markdown>

      src/mm/clojuratica.clj

      </markdown>

      (ns mm.clojuratica
        (:use mm.core)
        (:require [incanter.core :as i]
                  incanter.stats
                  incanter.io))
       
       
      ;; FindRoot
      ;; 근 찾기
      ;; http://reference.wolfram.com/mathematica/ref/FindRoot.html
       
      (math (FindRoot [(== (Exp (- x 2)) y) (== (Power y 2) x)]
                      [[x 1] [y 1]]))
      ;=> [(-> x 0.019026016103714054) (-> y 0.13793482556524314)]
       
      (def data-file "data/all_160.P3.csv")
       
      (def data (incanter.io/read-dataset data-file :header true))
       
      (defn mma-mean
        ([dataset col]
           (math (Mean ~(i/sel dataset :cols col)))))
       
      (defn mma-median
        ([dataset col]
           (math (Median ~(i/sel dataset :cols col)))))
       
      (mma-mean data :POP100)
      ;=> 230766493/29439
       
      (mma-median data :POP100)
      ;=> 1081
       
      (incanter.stats/mean [1 2 3 4 5])
      ;=> 3.0
       
      (incanter.stats/median [1 2 3 4 5])
      ;=> 3.0
       
      (incanter.stats/median [1 2 10])
      ;=> 2.0
       
      (incanter.stats/median [1 10 90 200])
      ;=> 50.0
       
       
      (math (Get "mma/line-integral.m"))
      ;=> (* 2 Pi)
       
      ;; FactorInteger
      ;; 소인수분해
      ;; http://reference.wolfram.com/mathematica/ref/FactorInteger.html
      (math (FactorInteger 1234567890))
      ;=> [[2 1] [3 2] [5 1] [3607 1] [3803 1]]
       
       
       
      ;; ======================================
      ;; Mathematica Function
       
      (def factor-int
        (math
         (Function [x] (FactorInteger x))))
       
      (factor-int 1234567890)
      ;=> [[2 1] [3 2] [5 1] [3607 1] [3803 1]]
       
       
      ;; ======================================
      ;; Parallel
      (math (LaunchKernels))
       
      (math (ParallelMap #'(Plus % 1) [1 2 3 4 5]))
      ;=> [2 3 4 5 6]
      ;=> [2 3 4 5 6]
       
       
      (let [f (math :parallel (Function [x] (Fibonacci x)
                                        $KernelID))
            agents (map (fn [_] (agent nil)) (range 10))]
        (dorun (map #(send-off % f) agents))
        (dorun (map await agents))
        (map deref agents))
      ;=> (4 3 2 1 4 4 4 3 2 3)
      ;=> (4 2 4 4 1 3 2 4 3 4)
      ;=> (3 4 1 4 2 2 1 3 4 3)

      <markdown>

      mma/line-integral.m

      </markdown>

      SyntaxInformation[lineIntegrate] =
          {"LocalVariables" -> {"Plot", {3, 3}},
           "ArgumentsPattern" -> {_, _, _}};
       
      lineIntegrate[r_?VectorQ, f_Function, {t_, tMin_, tMax_}] :=
      	Module[{param, localR}, localR = r /. t -> param;
                 Integrate[(f[localR, #] Sqrt[#.#]) &@D[localR, param], {param, tMin, tMax}]]
       
      lineIntegrate[{Cos[t], Sin[t]}, 1 &, {t, 0, 2 Pi}]

      <markdown>

      ## Setting up R to talk to Clojure R은 무료 통계 프로그램.

      http://craig-russell.co.uk/2012/05/08/install-r-on-ubuntu.html

      ### Ubuntu 12.04 LTS

      </markdown>

      $ sudo vi /etc/apt/sources/list
       
      	deb http://cran.ma.imperial.ac.uk/bin/linux/ubuntu precise/
       
      $ sudo apt-get update
      $ sudo apt-get install r-base
       
      $ R
      > install.packages("Rserve")
      ~/R/x86_64-pc-linux-gnu-library/3.0
       
      $ cd ~/clj-interop
      clj-interop$ mkdir Rserve && cd Rserve
       
      Rserve$ wget http://www.rforge.net/Rserve/files/REngine.jar
      Rserve$ wget http://www.rforge.net/Rserve/files/RserveEngine.jar
      Rserve$ lein localrepo install ~/clj-interop/Rserve/REngine.jar local.repo/REngine 1.8.0
      Rserve$ lein localrepo install ~/clj-interop/Rserve/RserveEngine.jar local.repo/RserveEngine 1.8.0
       
      $ export R_HOME=/usr/lib/R
      $ export PATH=$PATH:~/R/x86_64-pc-linux-gnu-library/3.0/Rserve/libs
      $ Rserve

      <markdown>

      ### Windows

      * R 다운로드: http://cran.nexr.com/bin/windows/base/ * Rserve 다운로드: http://www.rforge.net/Rserve/files/

      </markdown>

      C:\clj-interop>R.exe
      > install.packages("Rserve")
       
      C:\clj-interop\Rserve> wget http://www.rforge.net/Rserve/files/REngine.jar
      C:\clj-interop\Rserve> wget http://www.rforge.net/Rserve/files/RserveEngine.jar
       
       
      lein localrepo install lein localrepo install C:\clj-interop\Rserve\REngine.jar local.repo/REngine 1.8.0
      lein localrepo install lein localrepo install C:\clj-interop\Rserve\RserveEngine.jar local.repo/RserveEngine 1.8.0
       
       
      https://rforge.net/bin/windows/contrib/3.0/Rserve_1.8-0.zip을 다운받고,
      압축풀어, Rserve\libs\x64\에 있는 Rserve.*파일들을
      R이 설치된 폴더(C:\Program Files\R\R-3.0.2\bin\x64\)에 복사시켜준다.
      Rserve.exe 실행

      <markdown>

      ## Calling R functions from Clojure

      project.clj

      </markdown>

      (defproject rr "0.1.0-SNAPSHOT"
        :dependencies [[org.clojure/clojure "1.5.1"]
                       [local.repo/REngine "1.8.0"]
                       [local.repo/RserveEngine "1.8.0"]])

      <markdown>

      src/rr/core.clj

      </markdown>

      (ns rr.core)
       
      ;; ===================
      ;; Rserve를 이용. R과 연결.
       
      (import '[org.rosuda.REngine REngine]
              '[org.rosuda.REngine.Rserve RConnection])
       
      (def ^:dynamic *r-cxn* (RConnection.))
       
       
      ;; 연결 되었는지 테스트.
      (map #(.asDouble %)
           (.. *r-cxn* (eval "qr(c(1,2,3,4,5,6,7))") asList))
       
      ;; > qr(c(1,2,3,4,5,6,7))
      ;; $qr
      ;;             [,1]
      ;; [1,] -11.8321596
      ;; [2,]   0.1690309
      ;; [3,]   0.2535463
      ;; [4,]   0.3380617
      ;; [5,]   0.4225771
      ;; [6,]   0.5070926
      ;; [7,]   0.5916080
      ;; 
      ;; $rank
      ;; [1] 1
      ;; 
      ;; $qraux
      ;; qraux is a REAL vector of length P and Qraux is a REAL n by p matrix, as computed by Linpack subroutine dqrdc.
      ;; [1] 1.084515
      ;; 
      ;; $pivot
      ;; Pivot is a vector of length p containing the column numbers in x corresponding to the successive columns of q and r.
      ;; [1] 1
      ;; 
      ;; attr(,"class")
      ;; [1] "qr"
       
      ;=> (-11.832159566199232 1.0 1.0845154254728517 1.0)
       
       
      (map #(.asDouble %)
           (.. *r-cxn* (eval "qr(c(-3,-9,-6,-39,-2,8))") asList))
      ;=> (41.41255848169731 1.0 1.0724417932624444 1.0)
       
      ;; ===================
      ;; Vector를 R로 넘겨주기.
       
      (require '[clojure.string :as str])
       
      (defprotocol ToR
        (->r [x] "Convert an item to R."))
       
      (extend-protocol ToR
        clojure.lang.ISeq
        (->r [coll] (str "c(" (str/join \, (map ->r coll)) ")"))
       
        clojure.lang.PersistentVector
        (->r [coll] (->r (seq coll)))
       
        java.lang.Integer
        (->r [i] (str i))
        java.lang.Long
        (->r [l] (str l))
        java.lang.Float
        (->r [f] (str f))
        java.lang.Double
        (->r [d] (str d)))
       
      (defn r-mean
        ([coll] (r-mean coll *r-cxn*))
        ([coll r-cxn]
           (.. r-cxn
               (eval (str "mean(" (->r coll) ")"))
               asDouble)))
       
      (->r [1.0 2.0 3.0])
      ;=> "c(1.0,2.0,3.0)"
       
      (r-mean [1.0 2.0 3.0])
      ;=> 2.0
       
      (r-mean (map (fn [_] (rand))
                   (range 5)))
      ;=> 0.46599524431898004
       
       
      ;; ===================
      ;; R파일 읽어오기.
       
      (import '[java.io File])
       
      ;; 카이자승 검증
      ;; 카이제곱 검정
       
      (defn win-to-xnix-path [winpath]
        (str/replace winpath #"\\" "/"))
       
      (defn r-source
        ([filename] (r-source filename *r-cxn*))
        ([filename r-cxn]
           (.eval r-cxn
                   (str "source(\""
                        (win-to-xnix-path (.getAbsolutePath (File. filename)))
                        "\")"))))
       
      (def x-sqr (.asList (r-source "r/chisqr-example.R")))
       
      (.. x-sqr (at 0) asList (at "statistic") asDouble)
      ;=> 1.1581311830842826
       
      (.. x-sqr (at 0) asList (at "parameter") asInteger)
      ;=> 2
       
      (.. x-sqr (at 0) asList (at "p.value") asDouble)
      ;=> 0.5604217848398094
       
      (.. x-sqr (at 0) asList names)
      ;=> ["statistic" "parameter" "p.value" "method" "data.name" "observed" "expected" "residuals" "stdres"]
       
       
       
      ;; ===================
      ;; Plotting
       
      (defn r-plot
        ([data filename] (r-plot data filename *r-cxn*))
        ([data filename r-cxn]
           (.. r-cxn
               (eval (str "png(filename=\""
                          (win-to-xnix-path
                           (.getAbsolutePath (File. filename)))
                          "\", height=300, width=250, bg=\"white\")\n"
                          "plot(" (->r data) ")\n"
                          "dev.off()\n")))))
       
      (r-plot [1.0 1.0 2.0 3.0 5.0 8.0 11.0] "fib.png")
      ;; png(filename="fib.png", height=300, width=250, bg="white")
      ;; plot(c(1,1,2,3,5,8,11))
      ;; dev.off()

      <markdown>

      r/chisqr-example.R

      </markdown>

      dat <- data.frame(q1=sample(c("A","B","C"),size=1000,replace=TRUE),
                        sex=sample(c("M","F"),size=1000,replace=TRUE))
      # > dat
      #      q1 sex
      # 1     C   F
      # 2     A   F
      # 3     A   F
      # 4     B   F
      # 5     B   F
      # 6     B   M
      # ...
       
      dtab <- with(dat,table(q1,sex))
      # > dtab
      #    sex
      # q1    F   M
      #   A 149 180
      #   B 169 180
      #   C 154 168
       
      (Xsq <- chisq.test(dtab))
      # > (Xsq <- chisq.test(dtab))
      #
      #         Pearson's Chi-squared test
      #
      # data:  dtab
      # X-squared = 0.7427, df = 2, p-value = 0.6898

      <markdown>

      ## 기타 * programming-in-r: http://manuals.bioinformatics.ucr.edu/home/programming-in-r * rexamples: http://www.rexamples.com/ * J/Link without Java: http://www.youtube.com/watch?v=g9KdQbq_JLE </markdown>

      study/data_analysis/clojure_mathematica_r.txt · Last modified: 2019/02/04 14:26 (external edit)