{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Calling R, Python and C++ from Julia\n", "\n", "\n", "- Douglas Bates\n", "- U. of Wisconsin - Madison\n", "- github: dmbates\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## In 2012 I started using Julia\n", "\n", "### Good things\n", "- What Viral said: multiple dispatch, JIT method compilation, extensible type system, interesting language constructs.\n", "\n", "### Bad things\n", "- Many things I knew how to do in `R` were not available or needed to be relearned.\n", "- Re-learning takes a while for things like data visualization systems\n", "- `R` packages often provide data sets for illustration/experimentation. As a rule `Julia` packages don't." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## The `RCall` package (JuliaStats/RCall.jl)\n", "\n", "- Julia has the `ccall` function. Steven Johnson had written `PyCall`. Avik created `JavaCall`\n", "- So I started writing `RCall`. Most of the recent work has been done by Randy Lai and Simon Byrne.\n", "- Basic approach\n", " - Create Julia immutables to mirror `R`'s `SEXPREC` struct (see [`types.jl`](https://github.com/JuliaStats/RCall.jl/blob/master/src/types.jl) )\n", " - Locate and dlopen `libR` (see [`setup.jl`](https://github.com/JuliaStats/RCall.jl/blob/master/src/setup.jl) )\n", " - Start an embedded `R` process\n", " - Call `R`'s API\n", "- Functions of interest are `reval`, `rcall`, `rcopy`, etc." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " @R_str 2163 bytes Function\n", " @rget 1576 bytes Function\n", " @rimport 1860 bytes Function\n", " @rlibrary 1296 bytes Function\n", " @rput 1542 bytes Function\n", " @rusing 452 bytes Function\n", " @var_str 259 bytes Function\n", " CharSxp 136 bytes DataType\n", " ClosSxp 148 bytes DataType\n", " CplxSxp 136 bytes DataType\n", " IntSxp 136 bytes DataType\n", " LglSxp 136 bytes DataType\n", " NilSxp 112 bytes DataType\n", " RCall 566 KB Module\n", " RObject 168 bytes DataType\n", " RealSxp 136 bytes DataType\n", " StrSxp 136 bytes DataType\n", " Sxp 92 bytes DataType\n", " anyNA 1377 bytes Function\n", " getAttrib 2722 bytes Function\n", " getNames 978 bytes Function\n", " globalEnv 8 bytes RCall.RObject{RCall.EnvSxp}\n", " isFactor 1066 bytes Function\n", " isNA 4223 bytes Function\n", " isOrdered 1067 bytes Function\n", " rcall 3149 bytes Function\n", " rcopy 39 KB Function\n", " reval 6289 bytes Function\n", " rlang 2229 bytes Function\n", " rparse 829 bytes Function\n", " rprint 4106 bytes Function\n", " setAttrib! 4453 bytes Function\n", " setNames! 1054 bytes Function\n" ] } ], "source": [ "using RCall # make the package available\n", "whos(RCall)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "search: rcall RCall remotecall remotecall_wait remotecall_fetch UniformScaling\n", "\n" ] }, { "data": { "text/latex": [ "Evaluate a function in the global environment. The first argument corresponds to the function to be called. It can be either a FunctionSxp type, a SymSxp or a Symbol.\n" ], "text/markdown": [ "Evaluate a function in the global environment. The first argument corresponds to the function to be called. It can be either a FunctionSxp type, a SymSxp or a Symbol.\n" ], "text/plain": [ "Evaluate a function in the global environment. The first argument corresponds to the function to be called. It can be either a FunctionSxp type, a SymSxp or a Symbol.\n" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "?rcall" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "search: rcopy precompile __precompile__ readchomp ProcessGroup\n", "\n" ] }, { "data": { "text/latex": [ "Evaluate and convert the result of a string as an R expression.\n", "\\texttt{rcopy} copies the contents of an R object into a corresponding canonical Julia type.\n", "\\texttt{rcopy(T,p)} converts a pointer \\texttt{p} to a Sxp object to a native Julia object of type T.\n", "\\texttt{rcopy(p)} performs a default conversion.\n" ], "text/markdown": [ "Evaluate and convert the result of a string as an R expression.\n", "\n", "`rcopy` copies the contents of an R object into a corresponding canonical Julia type.\n", "\n", "`rcopy(T,p)` converts a pointer `p` to a Sxp object to a native Julia object of type T.\n", "\n", "`rcopy(p)` performs a default conversion.\n" ], "text/plain": [ "Evaluate and convert the result of a string as an R expression.\n", "\n", "`rcopy` copies the contents of an R object into a corresponding canonical Julia type.\n", "\n", "`rcopy(T,p)` converts a pointer `p` to a Sxp object to a native Julia object of type T.\n", "\n", "`rcopy(p)` performs a default conversion.\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "?rcopy" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "text/html": [ "
mpgcyldisphpdratwtqsecvsamgearcarb
121.06.0160.0110.03.92.6216.460.01.04.04.0
221.06.0160.0110.03.92.87517.020.01.04.04.0
322.84.0108.093.03.852.3218.611.01.04.01.0
421.46.0258.0110.03.083.21519.441.00.03.01.0
518.78.0360.0175.03.153.4417.020.00.03.02.0
618.16.0225.0105.02.763.4620.221.00.03.01.0
714.38.0360.0245.03.213.5715.840.00.03.04.0
824.44.0146.762.03.693.1920.01.00.04.02.0
922.84.0140.895.03.923.1522.91.00.04.02.0
1019.26.0167.6123.03.923.4418.31.00.04.04.0
1117.86.0167.6123.03.923.4418.91.00.04.04.0
1216.48.0275.8180.03.074.0717.40.00.03.03.0
1317.38.0275.8180.03.073.7317.60.00.03.03.0
1415.28.0275.8180.03.073.7818.00.00.03.03.0
1510.48.0472.0205.02.935.2517.980.00.03.04.0
1610.48.0460.0215.03.05.42417.820.00.03.04.0
1714.78.0440.0230.03.235.34517.420.00.03.04.0
1832.44.078.766.04.082.219.471.01.04.01.0
1930.44.075.752.04.931.61518.521.01.04.02.0
2033.94.071.165.04.221.83519.91.01.04.01.0
2121.54.0120.197.03.72.46520.011.00.03.01.0
2215.58.0318.0150.02.763.5216.870.00.03.02.0
2315.28.0304.0150.03.153.43517.30.00.03.02.0
2413.38.0350.0245.03.733.8415.410.00.03.04.0
2519.28.0400.0175.03.083.84517.050.00.03.02.0
2627.34.079.066.04.081.93518.91.01.04.01.0
2726.04.0120.391.04.432.1416.70.01.05.02.0
2830.44.095.1113.03.771.51316.91.01.05.02.0
2915.88.0351.0264.04.223.1714.50.01.05.04.0
3019.76.0145.0175.03.622.7715.50.01.05.06.0
" ], "text/plain": [ "32×11 DataFrames.DataFrame\n", "│ Row │ mpg │ cyl │ disp │ hp │ drat │ wt │ qsec │ vs │ am │ gear │\n", "├─────┼──────┼─────┼───────┼───────┼──────┼───────┼───────┼─────┼─────┼──────┤\n", "│ 1 │ 21.0 │ 6.0 │ 160.0 │ 110.0 │ 3.9 │ 2.62 │ 16.46 │ 0.0 │ 1.0 │ 4.0 │\n", "│ 2 │ 21.0 │ 6.0 │ 160.0 │ 110.0 │ 3.9 │ 2.875 │ 17.02 │ 0.0 │ 1.0 │ 4.0 │\n", "│ 3 │ 22.8 │ 4.0 │ 108.0 │ 93.0 │ 3.85 │ 2.32 │ 18.61 │ 1.0 │ 1.0 │ 4.0 │\n", "│ 4 │ 21.4 │ 6.0 │ 258.0 │ 110.0 │ 3.08 │ 3.215 │ 19.44 │ 1.0 │ 0.0 │ 3.0 │\n", "│ 5 │ 18.7 │ 8.0 │ 360.0 │ 175.0 │ 3.15 │ 3.44 │ 17.02 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 6 │ 18.1 │ 6.0 │ 225.0 │ 105.0 │ 2.76 │ 3.46 │ 20.22 │ 1.0 │ 0.0 │ 3.0 │\n", "│ 7 │ 14.3 │ 8.0 │ 360.0 │ 245.0 │ 3.21 │ 3.57 │ 15.84 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 8 │ 24.4 │ 4.0 │ 146.7 │ 62.0 │ 3.69 │ 3.19 │ 20.0 │ 1.0 │ 0.0 │ 4.0 │\n", "│ 9 │ 22.8 │ 4.0 │ 140.8 │ 95.0 │ 3.92 │ 3.15 │ 22.9 │ 1.0 │ 0.0 │ 4.0 │\n", "│ 10 │ 19.2 │ 6.0 │ 167.6 │ 123.0 │ 3.92 │ 3.44 │ 18.3 │ 1.0 │ 0.0 │ 4.0 │\n", "│ 11 │ 17.8 │ 6.0 │ 167.6 │ 123.0 │ 3.92 │ 3.44 │ 18.9 │ 1.0 │ 0.0 │ 4.0 │\n", "⋮\n", "│ 21 │ 21.5 │ 4.0 │ 120.1 │ 97.0 │ 3.7 │ 2.465 │ 20.01 │ 1.0 │ 0.0 │ 3.0 │\n", "│ 22 │ 15.5 │ 8.0 │ 318.0 │ 150.0 │ 2.76 │ 3.52 │ 16.87 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 23 │ 15.2 │ 8.0 │ 304.0 │ 150.0 │ 3.15 │ 3.435 │ 17.3 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 24 │ 13.3 │ 8.0 │ 350.0 │ 245.0 │ 3.73 │ 3.84 │ 15.41 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 25 │ 19.2 │ 8.0 │ 400.0 │ 175.0 │ 3.08 │ 3.845 │ 17.05 │ 0.0 │ 0.0 │ 3.0 │\n", "│ 26 │ 27.3 │ 4.0 │ 79.0 │ 66.0 │ 4.08 │ 1.935 │ 18.9 │ 1.0 │ 1.0 │ 4.0 │\n", "│ 27 │ 26.0 │ 4.0 │ 120.3 │ 91.0 │ 4.43 │ 2.14 │ 16.7 │ 0.0 │ 1.0 │ 5.0 │\n", "│ 28 │ 30.4 │ 4.0 │ 95.1 │ 113.0 │ 3.77 │ 1.513 │ 16.9 │ 1.0 │ 1.0 │ 5.0 │\n", "│ 29 │ 15.8 │ 8.0 │ 351.0 │ 264.0 │ 4.22 │ 3.17 │ 14.5 │ 0.0 │ 1.0 │ 5.0 │\n", "│ 30 │ 19.7 │ 6.0 │ 145.0 │ 175.0 │ 3.62 │ 2.77 │ 15.5 │ 0.0 │ 1.0 │ 5.0 │\n", "│ 31 │ 15.0 │ 8.0 │ 301.0 │ 335.0 │ 3.54 │ 3.57 │ 14.6 │ 0.0 │ 1.0 │ 5.0 │\n", "│ 32 │ 21.4 │ 4.0 │ 121.0 │ 109.0 │ 4.11 │ 2.78 │ 18.6 │ 1.0 │ 1.0 │ 4.0 │\n", "\n", "│ Row │ carb │\n", "├─────┼──────┤\n", "│ 1 │ 4.0 │\n", "│ 2 │ 4.0 │\n", "│ 3 │ 1.0 │\n", "│ 4 │ 1.0 │\n", "│ 5 │ 2.0 │\n", "│ 6 │ 1.0 │\n", "│ 7 │ 4.0 │\n", "│ 8 │ 2.0 │\n", "│ 9 │ 2.0 │\n", "│ 10 │ 4.0 │\n", "│ 11 │ 4.0 │\n", "⋮\n", "│ 21 │ 1.0 │\n", "│ 22 │ 2.0 │\n", "│ 23 │ 2.0 │\n", "│ 24 │ 4.0 │\n", "│ 25 │ 2.0 │\n", "│ 26 │ 1.0 │\n", "│ 27 │ 2.0 │\n", "│ 28 │ 2.0 │\n", "│ 29 │ 4.0 │\n", "│ 30 │ 6.0 │\n", "│ 31 │ 8.0 │\n", "│ 32 │ 2.0 │" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mtcars = rcopy(\"mtcars\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## A simpler interface\n", "- the character `R` followed by a string evaluates the string as an `R` expression. The behavior is defined in `@R_str`. See [`rstr.jl`](https://github.com/JuliaStats/RCall.jl/blob/master/src/rstr.jl).\n", "- Julia allows multiline strings using triple quotes\n", "- string interpolation of Julia objects is allowed using `$`, only when it is not used as valid `R` syntax.\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "0.7525806925786059" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R\"\"\"\n", "suppressMessages(library(lme4))\n", "fm1 <- lmer(Yield ~ 1 + (1 | Batch), Dyestuff, REML = FALSE)\n", "getME(fm1, \"theta\")\n", "\"\"\"[1]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "image/png": "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" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "RCall.RObject{RCall.VecSxp}\n" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using DataFrames\n", "brownian(N) = DataFrame(x = 1:N, y = cumsum(randn(N)))\n", "srand(1234321) # set random number seed\n", "br = brownian(10_000);\n", "R\"\"\"\n", "suppressMessages(library(ggplot2))\n", "ggplot($br, aes(x = x, y = y)) + geom_line()\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## An even simpler interface\n", "\n", "- Most of base Julia, including the REPL, is written in Julia\n", "- The REPL allows for different, user-extensible, modes: julia, shell, help, ..\n", "- Modes can be switched by the first character you type at the prompt (`?` for help; `;` for shell)\n", "- `RCall` adds an R REPL mode (magic char is `$`). `Cxx` adds a `C++` REPL mode (magic is `<`). " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## RCall summary\n", "\n", "- There is no \"glue\" code written in a compiled language. The whole package is written in Julia.\n", "- It is feasible to emulate the internal R structures in Julia. The other direction would be very difficult.\n", "- `ccall`, `cglobal`, `cfunction`, `Libdl.dlopen` allow low-level access to a C API.\n", "- String macros and REPL modes allow for a familiar interface." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## PyCall (stevengj/PyCall.jl)\n", "\n", "- the `@pyimport` macro functions like `import` in Python." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "using PyCall\n", "@pyimport numpy as np\n", "@pyimport pandas as pd\n", "@pyimport feather" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Categorical 8 bytes PyCall.PyObject\n", " CategoricalIndex 8 bytes PyCall.PyObject\n", " DataFrame 8 bytes PyCall.PyObject\n", " DateOffset 8 bytes PyCall.PyObject\n", " DatetimeIndex 8 bytes PyCall.PyObject\n", " ExcelFile 8 bytes PyCall.PyObject\n", " ExcelWriter 8 bytes PyCall.PyObject\n", " Expr 8 bytes PyCall.PyObject\n", " Float64Index 8 bytes PyCall.PyObject\n", " Grouper 8 bytes PyCall.PyObject\n", " HDFStore 8 bytes PyCall.PyObject\n", " Index 8 bytes PyCall.PyObject\n", " IndexSlice 8 bytes PyCall.PyObject\n", " Int64Index 8 bytes PyCall.PyObject\n", " MultiIndex 8 bytes PyCall.PyObject\n", " NaT 8 bytes PyCall.PyObject\n", " Panel 8 bytes PyCall.PyObject\n", " Panel4D 8 bytes PyCall.PyObject\n", " Period 8 bytes PyCall.PyObject\n", " PeriodIndex 8 bytes PyCall.PyObject\n", " RangeIndex 8 bytes PyCall.PyObject\n", " Series 8 bytes PyCall.PyObject\n", " SparseArray 8 bytes PyCall.PyObject\n", " SparseDataFrame 8 bytes PyCall.PyObject\n", " SparseList 8 bytes PyCall.PyObject\n", " SparsePanel 8 bytes PyCall.PyObject\n", " SparseSeries 8 bytes PyCall.PyObject\n", " SparseTimeSeries 8 bytes PyCall.PyObject\n", " Term 8 bytes PyCall.PyObject\n", " TimeGrouper 8 bytes PyCall.PyObject\n", " TimeSeries 8 bytes PyCall.PyObject\n", " Timedelta 8 bytes PyCall.PyObject\n", " TimedeltaIndex 8 bytes PyCall.PyObject\n", " Timestamp 8 bytes PyCall.PyObject\n", " WidePanel 8 bytes PyCall.PyObject\n", " __anon__ 10 KB Module\n", " algos 8 bytes PyCall.PyObject\n", " bdate_range 8 bytes PyCall.PyObject\n", " compat 8 bytes PyCall.PyObject\n", " computation 8 bytes PyCall.PyObject\n", " concat 8 bytes PyCall.PyObject\n", " core 8 bytes PyCall.PyObject\n", " crosstab 8 bytes PyCall.PyObject\n", " cut 8 bytes PyCall.PyObject\n", " date_range 8 bytes PyCall.PyObject\n", " datetime 8 bytes PyCall.PyObject\n", " datetools 8 bytes PyCall.PyObject\n", " dependency 16 bytes ASCIIString\n", " describe_option 8 bytes PyCall.PyObject\n", " eval 8 bytes PyCall.PyObject\n", " ewma 8 bytes PyCall.PyObject\n", " ewmcorr 8 bytes PyCall.PyObject\n", " ewmcov 8 bytes PyCall.PyObject\n", " ewmstd 8 bytes PyCall.PyObject\n", " ewmvar 8 bytes PyCall.PyObject\n", " ewmvol 8 bytes PyCall.PyObject\n", " expanding_apply 8 bytes PyCall.PyObject\n", " expanding_corr 8 bytes PyCall.PyObject\n", " expanding_count 8 bytes PyCall.PyObject\n", " expanding_cov 8 bytes PyCall.PyObject\n", " expanding_kurt 8 bytes PyCall.PyObject\n", " expanding_max 8 bytes PyCall.PyObject\n", " expanding_mean 8 bytes PyCall.PyObject\n", " expanding_median 8 bytes PyCall.PyObject\n", " expanding_min 8 bytes PyCall.PyObject\n", " expanding_quantile 8 bytes PyCall.PyObject\n", " expanding_skew 8 bytes PyCall.PyObject\n", " expanding_std 8 bytes PyCall.PyObject\n", " expanding_sum 8 bytes PyCall.PyObject\n", " expanding_var 8 bytes PyCall.PyObject\n", " factorize 8 bytes PyCall.PyObject\n", " fama_macbeth 8 bytes PyCall.PyObject\n", " formats 8 bytes PyCall.PyObject\n", " get_dummies 8 bytes PyCall.PyObject\n", " get_option 8 bytes PyCall.PyObject\n", " get_store 8 bytes PyCall.PyObject\n", " groupby 8 bytes PyCall.PyObject\n", " hard_dependencies 65 bytes Tuple{ASCIIString,ASCIIString,ASCI…\n", " hashtable 8 bytes PyCall.PyObject\n", " index 8 bytes PyCall.PyObject\n", " indexes 8 bytes PyCall.PyObject\n", " infer_freq 8 bytes PyCall.PyObject\n", " info 8 bytes PyCall.PyObject\n", " io 8 bytes PyCall.PyObject\n", " isnull 8 bytes PyCall.PyObject\n", " json 8 bytes PyCall.PyObject\n", " lib 8 bytes PyCall.PyObject\n", " lreshape 8 bytes PyCall.PyObject\n", " match 8 bytes PyCall.PyObject\n", " melt 8 bytes PyCall.PyObject\n", " merge 8 bytes PyCall.PyObject\n", " missing_dependencies 0 bytes 0-element Array{Any,1}\n", " msgpack 8 bytes PyCall.PyObject\n", " notnull 8 bytes PyCall.PyObject\n", " np 8 bytes PyCall.PyObject\n", " offsets 8 bytes PyCall.PyObject\n", " ols 8 bytes PyCall.PyObject\n", " option_context 8 bytes PyCall.PyObject\n", " options 8 bytes PyCall.PyObject\n", " ordered_merge 8 bytes PyCall.PyObject\n", " pandas 8 bytes PyCall.PyObject\n", " parser 8 bytes PyCall.PyObject\n", " period_range 8 bytes PyCall.PyObject\n", " pivot 8 bytes PyCall.PyObject\n", " pivot_table 8 bytes PyCall.PyObject\n", " plot_params 357 bytes Dict{Any,Any} with 1 entry\n", " pnow 8 bytes PyCall.PyObject\n", " qcut 8 bytes PyCall.PyObject\n", " read_clipboard 8 bytes PyCall.PyObject\n", " read_csv 8 bytes PyCall.PyObject\n", " read_excel 8 bytes PyCall.PyObject\n", " read_fwf 8 bytes PyCall.PyObject\n", " read_gbq 8 bytes PyCall.PyObject\n", " read_hdf 8 bytes PyCall.PyObject\n", " read_html 8 bytes PyCall.PyObject\n", " read_json 8 bytes PyCall.PyObject\n", " read_msgpack 8 bytes PyCall.PyObject\n", " read_pickle 8 bytes PyCall.PyObject\n", " read_sas 8 bytes PyCall.PyObject\n", " read_sql 8 bytes PyCall.PyObject\n", " read_sql_query 8 bytes PyCall.PyObject\n", " read_sql_table 8 bytes PyCall.PyObject\n", " read_stata 8 bytes PyCall.PyObject\n", " read_table 8 bytes PyCall.PyObject\n", " reset_option 8 bytes PyCall.PyObject\n", " rolling_apply 8 bytes PyCall.PyObject\n", " rolling_corr 8 bytes PyCall.PyObject\n", " rolling_count 8 bytes PyCall.PyObject\n", " rolling_cov 8 bytes PyCall.PyObject\n", " rolling_kurt 8 bytes PyCall.PyObject\n", " rolling_max 8 bytes PyCall.PyObject\n", " rolling_mean 8 bytes PyCall.PyObject\n", " rolling_median 8 bytes PyCall.PyObject\n", " rolling_min 8 bytes PyCall.PyObject\n", " rolling_quantile 8 bytes PyCall.PyObject\n", " rolling_skew 8 bytes PyCall.PyObject\n", " rolling_std 8 bytes PyCall.PyObject\n", " rolling_sum 8 bytes PyCall.PyObject\n", " rolling_var 8 bytes PyCall.PyObject\n", " rolling_window 8 bytes PyCall.PyObject\n", " scatter_matrix 8 bytes PyCall.PyObject\n", " set_eng_float_format 8 bytes PyCall.PyObject\n", " set_option 8 bytes PyCall.PyObject\n", " show_versions 8 bytes PyCall.PyObject\n", " sparse 8 bytes PyCall.PyObject\n", " stats 8 bytes PyCall.PyObject\n", " test 8 bytes PyCall.PyObject\n", " timedelta_range 8 bytes PyCall.PyObject\n", " to_datetime 8 bytes PyCall.PyObject\n", " to_msgpack 8 bytes PyCall.PyObject\n", " to_numeric 8 bytes PyCall.PyObject\n", " to_pickle 8 bytes PyCall.PyObject\n", " to_timedelta 8 bytes PyCall.PyObject\n", " tools 8 bytes PyCall.PyObject\n", " tseries 8 bytes PyCall.PyObject\n", " tslib 8 bytes PyCall.PyObject\n", " types 8 bytes PyCall.PyObject\n", " unique 8 bytes PyCall.PyObject\n", " util 8 bytes PyCall.PyObject\n", " value_counts 8 bytes PyCall.PyObject\n", " wide_to_long 8 bytes PyCall.PyObject\n" ] } ], "source": [ "whos(pd)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "text/plain": [ "brown (generic function with 1 method)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function brown(N::Number)\n", " v = zeros(N + 1)\n", " for i in 1:N\n", " v[i + 1] = v[i] + randn()\n", " end\n", " v\n", "end\n", " " ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
br1br2
00.0000000.000000
1-0.773834-0.006075
2-0.537581-0.281177
30.0702390.989620
40.9139220.272461
50.7832530.943957
61.8471610.796048
70.4481321.478668
8-2.3587310.106409
9-3.037559-0.322209
10-0.647172-0.024637
11-0.3244460.887330
12-1.0873910.764816
13-0.0925981.635592
140.2703251.103798
150.0267710.601902
16-1.4699821.815822
17-2.1443280.957945
18-3.3442901.105669
19-2.1127581.303400
20-3.0720210.911289
21-2.2438481.488212
22-1.2762591.990742
23-2.1050552.864032
24-1.9098554.591759
25-2.2415744.498321
26-2.7128884.342676
27-2.5015684.245411
28-2.7375413.471929
29-1.6668903.263433
.........
9971-67.201469-37.090684
9972-68.372847-37.603236
9973-69.053534-37.842471
9974-67.648497-38.373551
9975-65.773006-39.242039
9976-66.520155-39.173315
9977-66.774692-40.773012
9978-67.839113-39.828624
9979-68.676012-40.120377
9980-68.364612-38.445496
9981-66.843212-38.913253
9982-66.390980-38.201632
9983-65.733951-37.470297
9984-65.099306-38.119241
9985-66.354152-37.442763
9986-68.651218-38.013503
9987-67.823224-37.741410
9988-68.053629-38.639877
9989-67.943860-36.262430
9990-66.721974-35.792575
9991-67.957720-35.626207
9992-68.531987-34.892304
9993-68.036708-34.475120
9994-69.109629-34.392904
9995-69.369302-34.677581
9996-69.953834-36.628048
9997-69.380250-37.220133
9998-69.382725-36.422765
9999-69.528264-35.077929
10000-68.787819-35.410307
\n", "

10001 rows × 2 columns

\n", "
" ], "text/plain": [ "PyObject br1 br2\n", "0 0.000000 0.000000\n", "1 -0.773834 -0.006075\n", "2 -0.537581 -0.281177\n", "3 0.070239 0.989620\n", "4 0.913922 0.272461\n", "5 0.783253 0.943957\n", "6 1.847161 0.796048\n", "7 0.448132 1.478668\n", "8 -2.358731 0.106409\n", "9 -3.037559 -0.322209\n", "10 -0.647172 -0.024637\n", "11 -0.324446 0.887330\n", "12 -1.087391 0.764816\n", "13 -0.092598 1.635592\n", "14 0.270325 1.103798\n", "15 0.026771 0.601902\n", "16 -1.469982 1.815822\n", "17 -2.144328 0.957945\n", "18 -3.344290 1.105669\n", "19 -2.112758 1.303400\n", "20 -3.072021 0.911289\n", "21 -2.243848 1.488212\n", "22 -1.276259 1.990742\n", "23 -2.105055 2.864032\n", "24 -1.909855 4.591759\n", "25 -2.241574 4.498321\n", "26 -2.712888 4.342676\n", "27 -2.501568 4.245411\n", "28 -2.737541 3.471929\n", "29 -1.666890 3.263433\n", "... ... ...\n", "9971 -67.201469 -37.090684\n", "9972 -68.372847 -37.603236\n", "9973 -69.053534 -37.842471\n", "9974 -67.648497 -38.373551\n", "9975 -65.773006 -39.242039\n", "9976 -66.520155 -39.173315\n", "9977 -66.774692 -40.773012\n", "9978 -67.839113 -39.828624\n", "9979 -68.676012 -40.120377\n", "9980 -68.364612 -38.445496\n", "9981 -66.843212 -38.913253\n", "9982 -66.390980 -38.201632\n", "9983 -65.733951 -37.470297\n", "9984 -65.099306 -38.119241\n", "9985 -66.354152 -37.442763\n", "9986 -68.651218 -38.013503\n", "9987 -67.823224 -37.741410\n", "9988 -68.053629 -38.639877\n", "9989 -67.943860 -36.262430\n", "9990 -66.721974 -35.792575\n", "9991 -67.957720 -35.626207\n", "9992 -68.531987 -34.892304\n", "9993 -68.036708 -34.475120\n", "9994 -69.109629 -34.392904\n", "9995 -69.369302 -34.677581\n", "9996 -69.953834 -36.628048\n", "9997 -69.380250 -37.220133\n", "9998 -69.382725 -36.422765\n", "9999 -69.528264 -35.077929\n", "10000 -68.787819 -35.410307\n", "\n", "[10001 rows x 2 columns]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(Dict(\"br1\" => pd.Series(brown(10_000)), \"br2\" => pd.Series(brown(10_000))))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "feather.write_dataframe(df, \"/tmp/br.feather\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "RCall.RObject{RCall.VecSxp}\n", "Source: local data frame [10,001 x 2]\n", "\n", " br1 br2\n", " \n", "1 0.00000000 0.000000000\n", "2 -0.77383429 -0.006074936\n", "3 -0.53758071 -0.281177366\n", "4 0.07023901 0.989619762\n", "5 0.91392200 0.272461480\n", "6 0.78325339 0.943957326\n", "7 1.84716072 0.796047645\n", "8 0.44813220 1.478668055\n", "9 -2.35873065 0.106408928\n", "10 -3.03755867 -0.322209156\n", ".. ... ...\n" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R\"\"\"\n", "library(feather)\n", "read_feather(\"/tmp/br.feather\")\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Julia 1.1.0", "language": "julia", "name": "julia-1.1" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "0.4.6" } }, "nbformat": 4, "nbformat_minor": 2 }