galaaz 2.1.7 → 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/Rakefile +20 -2
- data/bin/check_gemfile_lock_version +46 -0
- data/bin/release_bump +26 -0
- data/blogs/README.md +4 -0
- data/blogs/galaaz_2_0/galaaz_2_0.Rmd +385 -0
- data/blogs/galaaz_2_0/galaaz_2_0.md +409 -0
- data/blogs/galaaz_2_0/galaaz_2_0.tex +756 -0
- data/blogs/galaaz_2_0/images/galaaz-header.png +0 -0
- data/blogs/galaaz_2_0/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +76 -58
- data/blogs/galaaz_ggplot/galaaz_ggplot.md +188 -161
- data/blogs/galaaz_ggplot/galaaz_ggplot.tex +185 -117
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/gknit/gknit.Rmd +48 -28
- data/blogs/gknit/gknit.md +60 -43
- data/blogs/gknit/gknit.tex +1409 -0
- data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
- data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
- data/blogs/gknit/gknit_files/figure-latex/bubble-1.png +0 -0
- data/blogs/gknit/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/manual/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/manual/manual.Rmd +161 -71
- data/blogs/manual/manual.md +573 -482
- data/blogs/manual/manual.tex +1113 -517
- data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-markdown_github/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-markdown_github/diverging_bar.png +0 -0
- data/blogs/nse_dplyr/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/nse_dplyr/nse_dplyr.Rmd +42 -8
- data/blogs/nse_dplyr/nse_dplyr.md +69 -50
- data/blogs/nse_dplyr/nse_dplyr.tex +1626 -0
- data/blogs/oh_my/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/oh_my/oh_my.Rmd +206 -55
- data/blogs/oh_my/oh_my.md +247 -96
- data/blogs/oh_my/oh_my.tex +2038 -93
- data/blogs/r_on_rails_ledger/images/00_portfolio_page.png +0 -0
- data/blogs/r_on_rails_ledger/images/01_results_panel.png +0 -0
- data/blogs/r_on_rails_ledger/images/02_density_tail_risk.png +0 -0
- data/blogs/r_on_rails_ledger/images/03_mc_cone.png +0 -0
- data/blogs/r_on_rails_ledger/images/04_rolling_var.png +0 -0
- data/blogs/r_on_rails_ledger/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/r_on_rails_ledger/r_on_rails_ledger.Rmd +354 -0
- data/blogs/r_on_rails_ledger/r_on_rails_ledger.md +365 -0
- data/blogs/r_on_rails_ledger/r_on_rails_ledger.tex +670 -0
- data/blogs/ruby_plot/images/galaaz-lockup-stacked.png +0 -0
- data/blogs/ruby_plot/ruby_plot.Rmd +56 -35
- data/blogs/ruby_plot/ruby_plot.md +63 -47
- data/blogs/ruby_plot/ruby_plot.tex +194 -125
- data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
- data/lib/galaaz/cli.rb +98 -13
- data/logos/icon-font/README.md +27 -0
- data/logos/icon-font/build_font.py +130 -0
- data/logos/icon-font/galaaz-mark.svg +34 -0
- data/script/omarchy/README.md +9 -2
- data/script/omarchy/fonts/galaaz.ttf +0 -0
- data/script/omarchy/galaaz-guide.sh +1 -1
- data/script/omarchy/install-galaaz.sh +8 -1
- data/script/omarchy/omarchy-menu.jsonc +21 -9
- data/sty/galaaz-header.png +0 -0
- data/sty/galaaz-headers-from-p3.tex +4 -0
- data/sty/galaaz.sty +76 -23
- data/version.rb +1 -1
- metadata +46 -7
- data/blogs/galaaz_ggplot/galaaz_ggplot.log +0 -754
- data/blogs/manual/manual.log +0 -1786
- data/blogs/nse_dplyr/nse_dplyr.log +0 -928
- data/blogs/oh_my/oh_my.log +0 -804
- data/blogs/ruby_plot/ruby_plot.log +0 -885
data/blogs/manual/manual.md
CHANGED
|
@@ -10,11 +10,16 @@ output:
|
|
|
10
10
|
self_contained: true
|
|
11
11
|
keep_md: true
|
|
12
12
|
toc: true
|
|
13
|
+
toc_float: true
|
|
13
14
|
toc_depth: 3
|
|
14
15
|
number_sections: true
|
|
16
|
+
includes:
|
|
17
|
+
before_body: _logo_before_body.html
|
|
15
18
|
pdf_document:
|
|
16
19
|
includes:
|
|
17
|
-
in_header:
|
|
20
|
+
in_header:
|
|
21
|
+
- "../../sty/galaaz.sty"
|
|
22
|
+
- "../../sty/galaaz-headers-from-p3.tex"
|
|
18
23
|
keep_tex: yes
|
|
19
24
|
number_sections: yes
|
|
20
25
|
toc: true
|
|
@@ -26,68 +31,70 @@ fontsize: 11pt
|
|
|
26
31
|
|
|
27
32
|
|
|
28
33
|
|
|
29
|
-
# Introduction
|
|
30
|
-
|
|
31
|
-
**Galaaz is R-on-Rails:** keep **GNU R** for statistics, graphics, and the CRAN /
|
|
32
|
-
Bioconductor ecosystem, and use **Ruby** (with **Rails** when you need a web app) for
|
|
33
|
-
everything R was never meant to own—HTTP, auth, databases, background jobs, HTML, APIs.
|
|
34
|
-
|
|
35
|
-
The primary audience is the **R scientist** who already has models, dplyr/ggplot pipelines,
|
|
36
|
-
and domain knowledge, and wants a **one-person path to production on the web**. Learning
|
|
37
|
-
enough Ruby and Rails to ship an app is usually easier than hiring (or becoming) a dedicated
|
|
38
|
-
web-and-stats dual specialist. Ruby developers gain full access to R libraries as a
|
|
39
|
-
secondary benefit; the design priority is **R workflow first, web second**.
|
|
40
34
|
|
|
41
|
-
Galaaz does **not** re-implement scientific libraries in Ruby. Ruby and R run in **separate
|
|
42
|
-
processes**; the **Galaaz bridge** sends requests to standard **GNU R** and returns typed
|
|
43
|
-
results. You keep calling familiar ideas from Ruby (`R.c(...)`, `R.library('ggplot2')`,
|
|
44
|
-
`~R[:mtcars]`, dplyr-style chains) while Rails (or plain Ruby) owns the application shell.
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
SciPy, scikit-learn, Django/Flask). Galaaz’s bet is different: if your science already lives
|
|
48
|
-
in **R**, do not rewrite it in Python to get a website—**put R on Rails**.
|
|
36
|
+
# Introduction
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
Galaaz is a system for tightly coupling Ruby and R. Ruby is a powerful language, with a large
|
|
39
|
+
community, a very large set of libraries and great for web development. However, it lacks
|
|
40
|
+
libraries for data science, statistics, scientific plotting and machine learning. On the
|
|
41
|
+
other hand, R is considered one of the most powerful languages for solving all of the above
|
|
42
|
+
problems. **Python** is a strong competitor: NumPy, pandas, SciPy, and scikit-learn are
|
|
43
|
+
widely used building blocks, and **PyPI** hosts many thousands of other packages for
|
|
44
|
+
numerical work, machine learning, and beyond.
|
|
45
|
+
|
|
46
|
+
With Galaaz we do not intend to re-implement any of the scientific libraries in R, we allow
|
|
47
|
+
for very tight coupling between the two languages to the point that the Ruby developer does
|
|
48
|
+
not need to know that there is an R engine running.
|
|
49
|
+
|
|
50
|
+
According to Wikipedia "Ruby is a dynamic, interpreted, reflective, object-oriented,
|
|
51
|
+
general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro
|
|
52
|
+
"Matz" Matsumoto in Japan." It reached high popularity with the development of Ruby on Rails
|
|
53
|
+
(RoR) by David Heinemeier Hansson. RoR is a web application framework first released
|
|
54
|
+
around 2005. It makes extensive use of Ruby's metaprogramming features. With RoR,
|
|
55
|
+
Ruby became very popular. According to [Ruby’s place in the TIOBE index](https://www.tiobe.com/tiobe-index/ruby/)
|
|
56
|
+
it peaked in popularity around 2008, then declined until 2015 when it started picking up again.
|
|
57
|
+
Ruby remains a significant language in web development and general-purpose scripting.
|
|
58
|
+
|
|
59
|
+
Python, a language similar to Ruby, ranks 4th in the index. Java, C and C++ take the
|
|
60
|
+
first three positions. Ruby is often criticized for its focus on web applications.
|
|
61
|
+
But Ruby can do [much more](https://github.com/markets/awesome-ruby) than just web applications.
|
|
62
|
+
Yet, for scientific computing, Ruby lags behind Python and R. Python offers Django and
|
|
63
|
+
similar frameworks for the web, plus NumPy, pandas, and a deep catalog of science and ML libraries.
|
|
64
|
+
R is a free software environment for statistical computing and graphics with thousands
|
|
65
|
+
of libraries for data analysis.
|
|
66
|
+
|
|
67
|
+
Until recently, there was no real perspective for Ruby to bridge this gap.
|
|
68
|
+
Implementing a complete scientific computing infrastructure would take too long.
|
|
55
69
|
|
|
56
70
|
**Galaaz 2.0** supports **JRuby** and **CRuby** equally for the same NewBridge protocol.
|
|
57
71
|
Pick the Ruby that fits your app: JRuby when you want real multithreading for web and I/O;
|
|
58
72
|
CRuby when you prefer MRI. R remains the same **GNU R** you use interactively—including
|
|
59
|
-
compiled extensions and Bioconductor.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- Scale for many users: more **R worker processes/containers** behind the app (R is single-threaded
|
|
85
|
-
per process); the Ruby web tier scales separately (JRuby threads or a multi-process CRuby
|
|
86
|
-
setup). Galaaz’s instance manager is the starting point for that pattern—not a rewrite of
|
|
87
|
-
every algorithm à la enterprise ScaleR.
|
|
88
|
-
|
|
89
|
-
Rubyists are welcome: the same bridge exposes CRAN to application code. The **intended** on-ramp,
|
|
90
|
-
though, is **R scientist → small Rails app**, not “hire a stats team to teach Rails developers R.”
|
|
73
|
+
compiled extensions and Bioconductor. Ruby and R run in **separate processes**; the
|
|
74
|
+
**Galaaz bridge** sends requests to R and returns results to Ruby. From your point of view
|
|
75
|
+
you still write Ruby: `R.c(...)`, `R.library('ggplot2')`, `~R[:mtcars]`, and dplyr-style
|
|
76
|
+
chains on R objects. You do not need to learn R syntax to get a lot done, though reading R
|
|
77
|
+
documentation for individual packages remains useful.
|
|
78
|
+
|
|
79
|
+
Earlier experiments with Galaaz used Oracle’s **GraalVM** with TruffleRuby and FastR so that
|
|
80
|
+
Ruby and R could share one runtime. That path is no longer the focus: **standard GNU R**
|
|
81
|
+
gives full compatibility with the R package ecosystem (including compiled extensions and
|
|
82
|
+
Bioconductor) while either Ruby engine talks to R over NewBridge (JRuby for mature
|
|
83
|
+
multithreading on the application side; CRuby when you prefer MRI).
|
|
84
|
+
|
|
85
|
+
The bridge handles **communication and typing** between the two worlds; large tables can
|
|
86
|
+
also flow through **Apache Arrow** on the R side when you use the optional helpers described
|
|
87
|
+
later in this manual.
|
|
88
|
+
|
|
89
|
+
Library wrapping is a common way to bring features from one language into another.
|
|
90
|
+
To improve performance, Python often wraps more efficient C libraries. For the
|
|
91
|
+
Python developer, the existence of such C libraries is hidden. The problem with
|
|
92
|
+
library wrapping is that for any new library, there is the need to handcraft a new
|
|
93
|
+
wrapper.
|
|
94
|
+
|
|
95
|
+
Galaaz, instead of wrapping a single C or R library, wraps the whole R language
|
|
96
|
+
in Ruby. Doing so, all thousands of R libraries are available immediately
|
|
97
|
+
to Ruby developers without any new wrapping effort.
|
|
91
98
|
|
|
92
99
|
## What does Galaaz mean
|
|
93
100
|
|
|
@@ -131,27 +138,17 @@ JRuby (`bin/galaaz_jruby_env.inc.sh` / `lib/galaaz_jruby.rb`). **`bin/galaaz-jru
|
|
|
131
138
|
<tbody>
|
|
132
139
|
<tr>
|
|
133
140
|
<td style="text-align:left;"> galaaz-bootstrap </td>
|
|
134
|
-
<td style="text-align:left;"> WSL2 helper: Docker checks; optional TinyTeX
|
|
141
|
+
<td style="text-align:left;"> WSL2 helper: Docker checks; optional TinyTeX/poppler. </td>
|
|
135
142
|
<td style="text-align:left;"> Yes* </td>
|
|
136
143
|
</tr>
|
|
137
|
-
<tr>
|
|
138
|
-
<td style="text-align:left;"> galaaz-ruby </td>
|
|
139
|
-
<td style="text-align:left;"> Selected Ruby (default: ruby on PATH) with repo lib/ on LOAD_PATH; JVM flags only on JRuby. </td>
|
|
140
|
-
<td style="text-align:left;"> Yes </td>
|
|
141
|
-
</tr>
|
|
142
144
|
<tr>
|
|
143
145
|
<td style="text-align:left;"> galaaz-jruby </td>
|
|
144
|
-
<td style="text-align:left;">
|
|
146
|
+
<td style="text-align:left;"> JRuby with repo lib/ on LOAD_PATH and JVM flags. </td>
|
|
145
147
|
<td style="text-align:left;"> Yes </td>
|
|
146
148
|
</tr>
|
|
147
|
-
<tr>
|
|
148
|
-
<td style="text-align:left;"> galaaz_ruby_env.inc.sh </td>
|
|
149
|
-
<td style="text-align:left;"> Sourced by bash wrappers; sets GALAAZ_RUBY_BIN and optional JVM args. </td>
|
|
150
|
-
<td style="text-align:left;"> Yes† </td>
|
|
151
|
-
</tr>
|
|
152
149
|
<tr>
|
|
153
150
|
<td style="text-align:left;"> galaaz_jruby_env.inc.sh </td>
|
|
154
|
-
<td style="text-align:left;"> Sourced
|
|
151
|
+
<td style="text-align:left;"> Sourced by bash wrappers; sets JRUBY_J_ARGS. </td>
|
|
155
152
|
<td style="text-align:left;"> Yes† </td>
|
|
156
153
|
</tr>
|
|
157
154
|
<tr>
|
|
@@ -166,13 +163,11 @@ JRuby (`bin/galaaz_jruby_env.inc.sh` / `lib/galaaz_jruby.rb`). **`bin/galaaz-jru
|
|
|
166
163
|
|
|
167
164
|
† Not run directly.
|
|
168
165
|
|
|
169
|
-
**`galaaz-
|
|
166
|
+
**`galaaz-jruby` examples** (from repo root):
|
|
170
167
|
|
|
171
168
|
```text
|
|
172
|
-
bin/galaaz-ruby my_script.rb
|
|
173
|
-
GALAAZ_RUBY=jruby bin/galaaz-ruby my_script.rb
|
|
174
169
|
bin/galaaz-jruby my_script.rb
|
|
175
|
-
bin/galaaz-
|
|
170
|
+
bin/galaaz-jruby -S rspec
|
|
176
171
|
```
|
|
177
172
|
|
|
178
173
|
## Interactive use, examples, and Rake
|
|
@@ -188,17 +183,17 @@ bin/galaaz-ruby -S rspec
|
|
|
188
183
|
<tbody>
|
|
189
184
|
<tr>
|
|
190
185
|
<td style="text-align:left;"> gstudio </td>
|
|
191
|
-
<td style="text-align:left;"> IRB or Pry with Galaaz preloaded (
|
|
186
|
+
<td style="text-align:left;"> IRB or Pry with Galaaz preloaded (JRuby + JVM flags). </td>
|
|
192
187
|
<td style="text-align:left;"> Yes </td>
|
|
193
188
|
</tr>
|
|
194
189
|
<tr>
|
|
195
190
|
<td style="text-align:left;"> run_example </td>
|
|
196
|
-
<td style="text-align:left;"> Run one Ruby file using the same
|
|
191
|
+
<td style="text-align:left;"> Run one Ruby file using the same JRuby/JVM setup as tests. </td>
|
|
197
192
|
<td style="text-align:left;"> Yes </td>
|
|
198
193
|
</tr>
|
|
199
194
|
<tr>
|
|
200
195
|
<td style="text-align:left;"> galaaz </td>
|
|
201
|
-
<td style="text-align:left;"> Forward arguments to rake (needs rake;
|
|
196
|
+
<td style="text-align:left;"> Forward arguments to rake (needs rake; usually JRuby). </td>
|
|
202
197
|
<td style="text-align:left;"> Yes </td>
|
|
203
198
|
</tr>
|
|
204
199
|
</tbody>
|
|
@@ -217,18 +212,18 @@ bin/galaaz-ruby -S rspec
|
|
|
217
212
|
<tbody>
|
|
218
213
|
<tr>
|
|
219
214
|
<td style="text-align:left;"> gknit </td>
|
|
220
|
-
<td style="text-align:left;"> Knit .Rmd via
|
|
215
|
+
<td style="text-align:left;"> Knit .Rmd via JRuby and R Markdown render. </td>
|
|
221
216
|
<td style="text-align:left;"> Yes </td>
|
|
222
217
|
</tr>
|
|
223
218
|
<tr>
|
|
224
219
|
<td style="text-align:left;"> gknit-draft </td>
|
|
225
|
-
<td style="text-align:left;"> Drafts from rticles
|
|
220
|
+
<td style="text-align:left;"> Drafts from rticles templates; legacy polyglot wrapper. </td>
|
|
226
221
|
<td style="text-align:left;"> Legacy </td>
|
|
227
222
|
</tr>
|
|
228
223
|
<tr>
|
|
229
224
|
<td style="text-align:left;"> gknit-draft.rb </td>
|
|
230
|
-
<td style="text-align:left;"> Ruby entry: GKnit.draft (use with
|
|
231
|
-
<td style="text-align:left;">
|
|
225
|
+
<td style="text-align:left;"> Ruby entry: GKnit.draft (use with JRuby + LOAD_PATH). </td>
|
|
226
|
+
<td style="text-align:left;"> JRuby </td>
|
|
232
227
|
</tr>
|
|
233
228
|
<tr>
|
|
234
229
|
<td style="text-align:left;"> gknit_Rscript </td>
|
|
@@ -238,7 +233,9 @@ bin/galaaz-ruby -S rspec
|
|
|
238
233
|
</tbody>
|
|
239
234
|
</table>
|
|
240
235
|
|
|
241
|
-
**`gknit` CLI** (see `gknit -h`): `--output_format`, `--output_file`,
|
|
236
|
+
**`gknit` CLI** (see `gknit -h`): `--output_format`, `--output_file`,
|
|
237
|
+
`--output_dir`, `--bridge_timeout_sec`, `--callback_timeout_ms`.
|
|
238
|
+
If `--output_format` is omitted, the **first** YAML `output:` target wins.
|
|
242
239
|
|
|
243
240
|
Prefer **`galaaz-jruby`** for **`gknit-draft`** workflows until that wrapper matches the **`gknit`** stack.
|
|
244
241
|
|
|
@@ -260,7 +257,7 @@ Prefer **`galaaz-jruby`** for **`gknit-draft`** workflows until that wrapper mat
|
|
|
260
257
|
</tr>
|
|
261
258
|
<tr>
|
|
262
259
|
<td style="text-align:left;"> run_all_rspec </td>
|
|
263
|
-
<td style="text-align:left;"> Compile ext/new_bridge; run specs/ and new_bridge_specs
|
|
260
|
+
<td style="text-align:left;"> Compile ext/new_bridge; run specs/ and new_bridge_specs/. </td>
|
|
264
261
|
<td style="text-align:left;"> Yes </td>
|
|
265
262
|
</tr>
|
|
266
263
|
<tr>
|
|
@@ -294,7 +291,7 @@ Prefer **`galaaz-jruby`** for **`gknit-draft`** workflows until that wrapper mat
|
|
|
294
291
|
<tbody>
|
|
295
292
|
<tr>
|
|
296
293
|
<td style="text-align:left;"> grun </td>
|
|
297
|
-
<td style="text-align:left;"> Graal-era launcher: polyglot ruby
|
|
294
|
+
<td style="text-align:left;"> Graal-era launcher: polyglot ruby --jvm; prefer galaaz-jruby. </td>
|
|
298
295
|
<td style="text-align:left;"> No </td>
|
|
299
296
|
</tr>
|
|
300
297
|
<tr>
|
|
@@ -337,8 +334,9 @@ The supported install is **`gem install` + compile the gatekeeper**. You do not
|
|
|
337
334
|
4. Compile the native gatekeeper from the installed gem:
|
|
338
335
|
|
|
339
336
|
```
|
|
340
|
-
gem_dir="$(ruby -e
|
|
341
|
-
|
|
337
|
+
gem_dir="$(ruby -e \
|
|
338
|
+
"puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
|
|
339
|
+
# under JRuby: use jruby -e instead of ruby -e
|
|
342
340
|
make -C "${gem_dir}/ext/new_bridge" all
|
|
343
341
|
```
|
|
344
342
|
|
|
@@ -352,16 +350,18 @@ A **table of all `bin/` scripts** (bootstrap, Ruby launcher, gstudio, gknit, tes
|
|
|
352
350
|
|
|
353
351
|
1. Install **bundler** if needed, then run **`bundle install`** with your chosen Ruby
|
|
354
352
|
(`jruby -S bundle install` or CRuby `bundle install`) in the repository root.
|
|
355
|
-
2. Build the bridge native code: **`make -C ext/new_bridge all`**
|
|
353
|
+
2. Build the bridge native code: **`make -C ext/new_bridge all`**
|
|
354
|
+
(or **`rake compile_gatekeeper`**).
|
|
356
355
|
3. Run scripts with **`bin/galaaz-ruby`** (uses `ruby` on `PATH`; set **`GALAAZ_RUBY=jruby`** or
|
|
357
356
|
**`GALAAZ_RUBY=ruby`** to force an engine). Spec runners: **`bin/run_rspec`** /
|
|
358
357
|
**`bin/run_all_rspec`** (same `GALAAZ_RUBY` rule). **`bin/galaaz-jruby`** remains a thin
|
|
359
358
|
wrapper that forces JRuby.
|
|
360
359
|
|
|
361
360
|
A **gstudio** try image with Galaaz already installed is available for both engines:
|
|
362
|
-
**JRuby** — `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:gstudio`
|
|
363
|
-
`./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
|
|
364
|
-
`docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby`
|
|
361
|
+
**JRuby** — `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:gstudio`
|
|
362
|
+
(or `./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
|
|
363
|
+
`docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby`
|
|
364
|
+
(or `./docker/try-cruby/run.sh`).
|
|
365
365
|
Maintainers can prove a RubyGems install on a throwaway Ubuntu machine (no repo inside
|
|
366
366
|
the container) with `./docker/cold-install/run.sh published-specs` (JRuby) or
|
|
367
367
|
`./docker/cold-install-cruby/run.sh published-specs` (CRuby).
|
|
@@ -401,18 +401,40 @@ WSL integration is enabled for the distro where Galaaz is installed.
|
|
|
401
401
|
vec = R.c(1, 2, 3, 4)
|
|
402
402
|
puts vec
|
|
403
403
|
|
|
404
|
-
# R.foo(...) calls an R *function*. Datasets are objects — fetch with
|
|
404
|
+
# R.foo(...) calls an R *function*. Datasets are objects — fetch with
|
|
405
|
+
# ~:
|
|
405
406
|
df = ~R[:mtcars]
|
|
406
407
|
puts R.summary(df)
|
|
407
408
|
```
|
|
408
409
|
|
|
409
410
|
```
|
|
410
411
|
## [1] 1 2 3 4
|
|
412
|
+
## mpg cyl disp hp
|
|
413
|
+
## Min. :10.40 Min. :4.000 Min. : 71.1 Min. : 52.0
|
|
414
|
+
## 1st Qu.:15.43 1st Qu.:4.000 1st Qu.:120.8 1st Qu.: 96.5
|
|
415
|
+
## Median :19.20 Median :6.000 Median :196.3 Median :123.0
|
|
416
|
+
## Mean :20.09 Mean :6.188 Mean :230.7 Mean :146.7
|
|
417
|
+
## 3rd Qu.:22.80 3rd Qu.:8.000 3rd Qu.:326.0 3rd Qu.:180.0
|
|
418
|
+
## Max. :33.90 Max. :8.000 Max. :472.0 Max. :335.0
|
|
419
|
+
## drat wt qsec vs
|
|
420
|
+
## Min. :2.760 Min. :1.513 Min. :14.50 Min. :0.0000
|
|
421
|
+
## 1st Qu.:3.080 1st Qu.:2.581 1st Qu.:16.89 1st Qu.:0.0000
|
|
422
|
+
## Median :3.695 Median :3.325 Median :17.71 Median :0.0000
|
|
423
|
+
## Mean :3.597 Mean :3.217 Mean :17.85 Mean :0.4375
|
|
424
|
+
## 3rd Qu.:3.920 3rd Qu.:3.610 3rd Qu.:18.90 3rd Qu.:1.0000
|
|
425
|
+
## Max. :4.930 Max. :5.424 Max. :22.90 Max. :1.0000
|
|
426
|
+
## am gear carb
|
|
427
|
+
## Min. :0.0000 Min. :3.000 Min. :1.000
|
|
428
|
+
## 1st Qu.:0.0000 1st Qu.:3.000 1st Qu.:2.000
|
|
429
|
+
## Median :0.0000 Median :4.000 Median :2.000
|
|
430
|
+
## Mean :0.4062 Mean :3.688 Mean :2.812
|
|
431
|
+
## 3rd Qu.:1.0000 3rd Qu.:4.000 3rd Qu.:4.000
|
|
432
|
+
## Max. :1.0000 Max. :5.000 Max. :8.000
|
|
411
433
|
```
|
|
412
434
|
|
|
413
435
|
(`R.mtcars` is wrong: it becomes `mtcars()` in R and fails. With
|
|
414
436
|
`using Galaaz::SymbolDSL`, the short form `~:mtcars` also works.)
|
|
415
|
-
|
|
437
|
+
|
|
416
438
|
* Run all specs
|
|
417
439
|
|
|
418
440
|
> galaaz specs:all
|
|
@@ -457,15 +479,13 @@ A practical pattern is:
|
|
|
457
479
|
|
|
458
480
|
1. Use threads (or a connection pool) to read from **multiple databases or shards** in parallel.
|
|
459
481
|
2. Merge the rows in Ruby under a `Mutex` if you collect into one structure.
|
|
460
|
-
3. Hand the merged table to R **once
|
|
461
|
-
|
|
462
|
-
only the path crosses the bridge). Then run dplyr in R.
|
|
482
|
+
3. Hand the merged table to R **once** (for example with `R::Arrow.from_ruby_batches` and dplyr,
|
|
483
|
+
or by building a data frame) so heavy statistics run in R with fewer bridge round-trips.
|
|
463
484
|
|
|
464
485
|
A runnable sketch lives in
|
|
465
486
|
`examples/multithread_shards_to_r/shards_to_r.rb` (simulated shard queries; swap in your DB
|
|
466
487
|
driver). For concurrency tests on the bridge itself, see `specs/bridge_concurrent_spec.rb` and
|
|
467
|
-
`specs/arrow_from_ruby_batches_spec.rb`.
|
|
468
|
-
`specs/arrow_ipc_export_spec.rb`.
|
|
488
|
+
`specs/arrow_from_ruby_batches_spec.rb`.
|
|
469
489
|
|
|
470
490
|
## Long-running R calls and a completion block
|
|
471
491
|
|
|
@@ -484,8 +504,9 @@ For R work that can take a long time **on the bridge**, the bridge can avoid a R
|
|
|
484
504
|
**`R.<rname>`**. Optional keyword **`timeout:`** applies a Ruby-side wait limit (completion receives
|
|
485
505
|
**`NewBridge::SessionClient::TimeoutError`** if R is too slow).
|
|
486
506
|
|
|
487
|
-
**Important:** **`R.foo(...) { |x| }`** is already used for dplyr-style
|
|
488
|
-
so async R calls must use **`R::Async`**
|
|
507
|
+
**Important:** **`R.foo(...) { |x| }`** is already used for dplyr-style
|
|
508
|
+
scopes (`R::Support.new_scope`), so async R calls must use **`R::Async`**
|
|
509
|
+
or **`R.eval_r_async`**, not a bare **`R.foo` with a block.**
|
|
489
510
|
|
|
490
511
|
`NewBridge::EvalResult` exposes **`#ok?`**, **`#value`**, and **`#error`**. The completion block runs on a
|
|
491
512
|
**background thread** (not the bridge reader thread).
|
|
@@ -502,9 +523,11 @@ completion = Queue.new
|
|
|
502
523
|
|
|
503
524
|
R.eval_r_async('({ Sys.sleep(0.3); 42L })', timeout: nil) do |result|
|
|
504
525
|
if result.ok?
|
|
505
|
-
puts "[completion] R finished;
|
|
526
|
+
puts "[completion] R finished; value: " +
|
|
527
|
+
"#{result.value.inspect}"
|
|
506
528
|
else
|
|
507
|
-
puts "[completion] R/bridge error:
|
|
529
|
+
puts "[completion] R/bridge error: " +
|
|
530
|
+
"#{result.error.class}: #{result.error.message}"
|
|
508
531
|
end
|
|
509
532
|
completion.push(:done)
|
|
510
533
|
end
|
|
@@ -522,7 +545,7 @@ puts "[main] R completion has run; exiting."
|
|
|
522
545
|
## [main] other Ruby work step 1
|
|
523
546
|
## [main] other Ruby work step 2
|
|
524
547
|
## [main] other Ruby work step 3
|
|
525
|
-
## [completion] R finished;
|
|
548
|
+
## [completion] R finished; value: "[1] 42"
|
|
526
549
|
## [main] R completion has run; exiting.
|
|
527
550
|
```
|
|
528
551
|
|
|
@@ -550,8 +573,10 @@ finishes** (default: no wall-clock limit). Optional limit: `GALAAZ_INSTALL_TIMEO
|
|
|
550
573
|
`make`/`gcc` cannot OOM the shell. Stale `00LOCK-*` dirs are cleared before the next install.
|
|
551
574
|
Only one install runs at a time (`install.lock`).
|
|
552
575
|
|
|
576
|
+
|
|
553
577
|
``` ruby
|
|
554
|
-
# May take a long time the first time (e.g. caret); the bridge is not
|
|
578
|
+
# May take a long time the first time (e.g. caret); the bridge is not
|
|
579
|
+
# used for compile.
|
|
555
580
|
R.install_and_loads 'caret'
|
|
556
581
|
```
|
|
557
582
|
|
|
@@ -560,24 +585,33 @@ R.install_and_loads 'caret'
|
|
|
560
585
|
Prefer the **block** form (like `File.open`): await the child, yield the job, return the
|
|
561
586
|
block’s value. Without a block, the methods still await by default and return the `Job`.
|
|
562
587
|
|
|
588
|
+
|
|
563
589
|
``` ruby
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
590
|
+
begin
|
|
591
|
+
coef = R::Job.eval(<<~R) { |job| job.load_rds }
|
|
592
|
+
fit <- lm(mpg ~ wt, data = mtcars)
|
|
593
|
+
saveRDS(unname(coef(fit)), result_path)
|
|
594
|
+
R
|
|
595
|
+
puts coef
|
|
596
|
+
rescue => e
|
|
597
|
+
puts e.class.to_s
|
|
598
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
599
|
+
end
|
|
569
600
|
```
|
|
570
601
|
|
|
571
602
|
```
|
|
572
603
|
## [1] 37.285126 -5.344472
|
|
573
604
|
```
|
|
574
605
|
|
|
606
|
+
|
|
575
607
|
``` ruby
|
|
576
|
-
# Without a block: awaits (wait: true is the default) and returns the
|
|
608
|
+
# Without a block: awaits (wait: true is the default) and returns the
|
|
609
|
+
# Job
|
|
577
610
|
job = R::Job.eval(code)
|
|
578
611
|
job = R::Job.eval(code, wait: false) # start only; call job.wait later
|
|
579
612
|
|
|
580
|
-
# Script file; trailing args → commandArgs(trailingOnly=TRUE) in the
|
|
613
|
+
# Script file; trailing args → commandArgs(trailingOnly=TRUE) in the
|
|
614
|
+
# child
|
|
581
615
|
res = R::Job.script('train.R', '5') { |job| job.load_rds }
|
|
582
616
|
```
|
|
583
617
|
|
|
@@ -600,10 +634,7 @@ app. The baseline we used in WSL aimed at:
|
|
|
600
634
|
|
|
601
635
|
1. Rails boots under **JRuby or CRuby** (same bridge; see Installation).
|
|
602
636
|
2. Galaaz is loaded from a local checkout (before publishing to RubyGems).
|
|
603
|
-
3. A request path can execute **`R.eval(...)`**
|
|
604
|
-
|
|
605
|
-
You keep statistical work in R; Rails owns HTTP, sessions, and HTML. See **R-on-Rails: the
|
|
606
|
-
one-person app for R scientists** in the Introduction for the product framing.
|
|
637
|
+
3. A request path can execute **`R.eval(...)`** and return a result.
|
|
607
638
|
|
|
608
639
|
### 1) Create the app with Ruby-friendly options
|
|
609
640
|
|
|
@@ -612,7 +643,8 @@ extension paths on JRuby, or deployment extras you do not need). A minimal app a
|
|
|
612
643
|
|
|
613
644
|
```bash
|
|
614
645
|
cd /home/rbotafogo/desenv_linux
|
|
615
|
-
jruby -S rails new hedi --skip-git --minimal
|
|
646
|
+
jruby -S rails new hedi --skip-git --minimal \
|
|
647
|
+
--skip-kamal --skip-solid --skip-active-record
|
|
616
648
|
```
|
|
617
649
|
|
|
618
650
|
Then install gems:
|
|
@@ -650,7 +682,8 @@ A direct smoke test from Rails runner:
|
|
|
650
682
|
|
|
651
683
|
```bash
|
|
652
684
|
cd /home/rbotafogo/desenv_linux/hedi
|
|
653
|
-
jruby -S bundle exec rails runner
|
|
685
|
+
jruby -S bundle exec rails runner \
|
|
686
|
+
"puts R.eval('sum(c(1,2,3,4,5))').inspect"
|
|
654
687
|
```
|
|
655
688
|
|
|
656
689
|
Expected output:
|
|
@@ -718,39 +751,72 @@ puts ~R[:mtcars]
|
|
|
718
751
|
```
|
|
719
752
|
|
|
720
753
|
```
|
|
721
|
-
## mpg cyl disp hp drat wt qsec vs am gear
|
|
722
|
-
## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
|
|
723
|
-
## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
|
|
724
|
-
## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4
|
|
725
|
-
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
|
|
726
|
-
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
|
|
727
|
-
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3
|
|
728
|
-
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
|
|
729
|
-
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4
|
|
730
|
-
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4
|
|
731
|
-
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4
|
|
732
|
-
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4
|
|
733
|
-
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3
|
|
734
|
-
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3
|
|
735
|
-
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3
|
|
736
|
-
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
|
|
737
|
-
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
|
|
738
|
-
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3
|
|
739
|
-
## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4
|
|
740
|
-
## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4
|
|
741
|
-
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4
|
|
742
|
-
## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3
|
|
743
|
-
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3
|
|
744
|
-
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3
|
|
745
|
-
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
|
|
746
|
-
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3
|
|
747
|
-
## Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4
|
|
748
|
-
## Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5
|
|
749
|
-
## Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5
|
|
750
|
-
## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5
|
|
751
|
-
## Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5
|
|
752
|
-
## Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5
|
|
753
|
-
## Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4
|
|
754
|
+
## mpg cyl disp hp drat wt qsec vs am gear
|
|
755
|
+
## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
|
|
756
|
+
## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
|
|
757
|
+
## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4
|
|
758
|
+
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
|
|
759
|
+
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
|
|
760
|
+
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3
|
|
761
|
+
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
|
|
762
|
+
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4
|
|
763
|
+
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4
|
|
764
|
+
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4
|
|
765
|
+
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4
|
|
766
|
+
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3
|
|
767
|
+
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3
|
|
768
|
+
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3
|
|
769
|
+
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
|
|
770
|
+
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
|
|
771
|
+
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3
|
|
772
|
+
## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4
|
|
773
|
+
## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4
|
|
774
|
+
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4
|
|
775
|
+
## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3
|
|
776
|
+
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3
|
|
777
|
+
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3
|
|
778
|
+
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
|
|
779
|
+
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3
|
|
780
|
+
## Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4
|
|
781
|
+
## Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5
|
|
782
|
+
## Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5
|
|
783
|
+
## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5
|
|
784
|
+
## Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5
|
|
785
|
+
## Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5
|
|
786
|
+
## Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4
|
|
787
|
+
## carb
|
|
788
|
+
## Mazda RX4 4
|
|
789
|
+
## Mazda RX4 Wag 4
|
|
790
|
+
## Datsun 710 1
|
|
791
|
+
## Hornet 4 Drive 1
|
|
792
|
+
## Hornet Sportabout 2
|
|
793
|
+
## Valiant 1
|
|
794
|
+
## Duster 360 4
|
|
795
|
+
## Merc 240D 2
|
|
796
|
+
## Merc 230 2
|
|
797
|
+
## Merc 280 4
|
|
798
|
+
## Merc 280C 4
|
|
799
|
+
## Merc 450SE 3
|
|
800
|
+
## Merc 450SL 3
|
|
801
|
+
## Merc 450SLC 3
|
|
802
|
+
## Cadillac Fleetwood 4
|
|
803
|
+
## Lincoln Continental 4
|
|
804
|
+
## Chrysler Imperial 4
|
|
805
|
+
## Fiat 128 1
|
|
806
|
+
## Honda Civic 2
|
|
807
|
+
## Toyota Corolla 1
|
|
808
|
+
## Toyota Corona 1
|
|
809
|
+
## Dodge Challenger 2
|
|
810
|
+
## AMC Javelin 2
|
|
811
|
+
## Camaro Z28 4
|
|
812
|
+
## Pontiac Firebird 2
|
|
813
|
+
## Fiat X1-9 1
|
|
814
|
+
## Porsche 914-2 2
|
|
815
|
+
## Lotus Europa 2
|
|
816
|
+
## Ford Pantera L 4
|
|
817
|
+
## Ferrari Dino 6
|
|
818
|
+
## Maserati Bora 8
|
|
819
|
+
## Volvo 142E 2
|
|
754
820
|
```
|
|
755
821
|
|
|
756
822
|
## Scoped symbols and lexical scoping
|
|
@@ -896,9 +962,9 @@ puts vec.map { |x| x + 2 }
|
|
|
896
962
|
|
|
897
963
|
This manual has been formatted using gKnit. gKnit uses knitr and R Markdown to knit
|
|
898
964
|
a document in Ruby or R and output it in any of the available formats for R Markdown.
|
|
899
|
-
gKnit runs with **JRuby or CRuby**, **GNU R**, and Galaaz. In gKnit, Ruby variables are persisted between
|
|
900
|
-
chunks, making it an ideal solution for literate programming. Also, since it is based
|
|
901
|
-
on Galaaz, Ruby chunks can have access to R variables and combining Ruby with R in one
|
|
965
|
+
gKnit runs with **JRuby or CRuby**, **GNU R**, and Galaaz. In gKnit, Ruby variables are persisted between
|
|
966
|
+
chunks, making it an ideal solution for literate programming. Also, since it is based
|
|
967
|
+
on Galaaz, Ruby chunks can have access to R variables and combining Ruby with R in one
|
|
902
968
|
document is natural.
|
|
903
969
|
|
|
904
970
|
The idea of "literate programming" was first introduced by Donald Knuth in the
|
|
@@ -1251,7 +1317,9 @@ a linear regression line (method = "lm") for every manufacturer.
|
|
|
1251
1317
|
library(ggplot2)
|
|
1252
1318
|
data(mpg, package="ggplot2")
|
|
1253
1319
|
|
|
1254
|
-
mpg_select <- mpg[
|
|
1320
|
+
mpg_select <- mpg[
|
|
1321
|
+
mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"),
|
|
1322
|
+
]
|
|
1255
1323
|
|
|
1256
1324
|
# Scatterplot
|
|
1257
1325
|
theme_set(theme_bw()) # pre-set the bw theme.
|
|
@@ -1334,7 +1402,8 @@ with the 'rb' engine. The following chunk specification will
|
|
|
1334
1402
|
create and inline Ruby text:
|
|
1335
1403
|
|
|
1336
1404
|
````
|
|
1337
|
-
This is some text with inline Ruby accessing
|
|
1405
|
+
This is some text with inline Ruby accessing
|
|
1406
|
+
variable 'b' which has value:
|
|
1338
1407
|
```{rb puts b}
|
|
1339
1408
|
```
|
|
1340
1409
|
and is followed by some other text!
|
|
@@ -2199,14 +2268,16 @@ templates for the following journals with the respective template name:
|
|
|
2199
2268
|
In order to create a document with one of those templates, use the following command:
|
|
2200
2269
|
|
|
2201
2270
|
```
|
|
2202
|
-
gknit-draft --filename <my_document>
|
|
2203
|
-
|
|
2271
|
+
gknit-draft --filename <my_document> \
|
|
2272
|
+
--template <template> --package <package> \
|
|
2273
|
+
--create_dir
|
|
2204
2274
|
```
|
|
2205
2275
|
So, in order to create a template for writing an R Journal, use:
|
|
2206
2276
|
|
|
2207
2277
|
```
|
|
2208
|
-
gknit-draft --filename my_r_article
|
|
2209
|
-
|
|
2278
|
+
gknit-draft --filename my_r_article \
|
|
2279
|
+
--template rjournal_article --package rticles \
|
|
2280
|
+
--create_dir
|
|
2210
2281
|
```
|
|
2211
2282
|
|
|
2212
2283
|
# Accessing R variables
|
|
@@ -2739,7 +2810,10 @@ data frame is 'data.frame', in Galaaz we use 'data\_\_frame'.
|
|
|
2739
2810
|
|
|
2740
2811
|
|
|
2741
2812
|
``` ruby
|
|
2742
|
-
df = R.data__frame(
|
|
2813
|
+
df = R.data__frame(
|
|
2814
|
+
typeof: vec.typeof,
|
|
2815
|
+
mode: vec.mode,
|
|
2816
|
+
storage__mode: vec.storage__mode)
|
|
2743
2817
|
puts df
|
|
2744
2818
|
```
|
|
2745
2819
|
|
|
@@ -2765,7 +2839,10 @@ puts vec
|
|
|
2765
2839
|
|
|
2766
2840
|
|
|
2767
2841
|
``` ruby
|
|
2768
|
-
df = R.data__frame(
|
|
2842
|
+
df = R.data__frame(
|
|
2843
|
+
typeof: vec.typeof,
|
|
2844
|
+
mode: vec.mode,
|
|
2845
|
+
storage__mode: vec.storage__mode)
|
|
2769
2846
|
outputs df.kable.kable_styling
|
|
2770
2847
|
```
|
|
2771
2848
|
|
|
@@ -2793,25 +2870,19 @@ of the error.
|
|
|
2793
2870
|
|
|
2794
2871
|
|
|
2795
2872
|
``` ruby
|
|
2796
|
-
|
|
2873
|
+
begin
|
|
2874
|
+
vec = R.c(1, hello, 5)
|
|
2875
|
+
rescue => e
|
|
2876
|
+
puts e.class.to_s
|
|
2877
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
2878
|
+
end
|
|
2797
2879
|
```
|
|
2798
2880
|
|
|
2799
2881
|
```
|
|
2882
|
+
## NameError
|
|
2800
2883
|
## undefined local variable or method 'hello' for an instance of RC
|
|
2801
2884
|
```
|
|
2802
2885
|
|
|
2803
|
-
```
|
|
2804
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/util/exec_ruby.rb:170:in 'exec_ruby'
|
|
2805
|
-
## org/jruby/RubyKernel.java:1268:in 'eval'
|
|
2806
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/util/exec_ruby.rb:169:in 'exec_ruby'
|
|
2807
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/gknit/knitr_engine.rb:777:in 'block in initialize'
|
|
2808
|
-
## org/jruby/RubyBasicObject.java:2695:in 'instance_eval'
|
|
2809
|
-
## org/jruby/RubyBasicObject.java:2723:in 'instance_eval'
|
|
2810
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/gknit/knitr_engine.rb:748:in 'block in initialize'
|
|
2811
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/R_interface/new_bridge_adapter.rb:358:in 'block in register_callback_proc_stub'
|
|
2812
|
-
## /home/rbotafogo/desenv_linux/galaaz/lib/new_bridge/session_client.rb:413:in 'block in handle_call'
|
|
2813
|
-
```
|
|
2814
|
-
|
|
2815
2886
|
Here is a vector with logical values
|
|
2816
2887
|
|
|
2817
2888
|
|
|
@@ -3253,9 +3324,9 @@ puts (~R[:mtcars])[['mpg']]
|
|
|
3253
3324
|
```
|
|
3254
3325
|
|
|
3255
3326
|
```
|
|
3256
|
-
## [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3
|
|
3257
|
-
## [
|
|
3258
|
-
## [
|
|
3327
|
+
## [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3
|
|
3328
|
+
## [14] 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3
|
|
3329
|
+
## [27] 26.0 30.4 15.8 19.7 15.0 21.4
|
|
3259
3330
|
```
|
|
3260
3331
|
|
|
3261
3332
|
A data frame column can also be accessed as if it were an instance variable of the data frame:
|
|
@@ -3266,9 +3337,9 @@ puts (~R[:mtcars]).mpg
|
|
|
3266
3337
|
```
|
|
3267
3338
|
|
|
3268
3339
|
```
|
|
3269
|
-
## [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3
|
|
3270
|
-
## [
|
|
3271
|
-
## [
|
|
3340
|
+
## [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3
|
|
3341
|
+
## [14] 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3
|
|
3342
|
+
## [27] 26.0 30.4 15.8 19.7 15.0 21.4
|
|
3272
3343
|
```
|
|
3273
3344
|
|
|
3274
3345
|
Slicing a data frame can be done by indexing it with a vector (we use 'head' to reduce the
|
|
@@ -3311,9 +3382,9 @@ puts automatic
|
|
|
3311
3382
|
```
|
|
3312
3383
|
|
|
3313
3384
|
```
|
|
3314
|
-
## [1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
|
|
3315
|
-
## [
|
|
3316
|
-
## [
|
|
3385
|
+
## [1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
|
|
3386
|
+
## [12] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE
|
|
3387
|
+
## [23] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
|
|
3317
3388
|
```
|
|
3318
3389
|
|
|
3319
3390
|
Using this logical vector, the data frame is indexed, returning a new data frame in
|
|
@@ -3326,26 +3397,46 @@ puts (~R[:mtcars])[automatic, :all]
|
|
|
3326
3397
|
```
|
|
3327
3398
|
|
|
3328
3399
|
```
|
|
3329
|
-
## mpg cyl disp hp drat wt qsec vs am gear
|
|
3330
|
-
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
|
|
3331
|
-
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
|
|
3332
|
-
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3
|
|
3333
|
-
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
|
|
3334
|
-
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4
|
|
3335
|
-
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4
|
|
3336
|
-
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4
|
|
3337
|
-
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4
|
|
3338
|
-
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3
|
|
3339
|
-
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3
|
|
3340
|
-
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3
|
|
3341
|
-
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
|
|
3342
|
-
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
|
|
3343
|
-
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3
|
|
3344
|
-
## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3
|
|
3345
|
-
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3
|
|
3346
|
-
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3
|
|
3347
|
-
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
|
|
3348
|
-
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3
|
|
3400
|
+
## mpg cyl disp hp drat wt qsec vs am gear
|
|
3401
|
+
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
|
|
3402
|
+
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
|
|
3403
|
+
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3
|
|
3404
|
+
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
|
|
3405
|
+
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4
|
|
3406
|
+
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4
|
|
3407
|
+
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4
|
|
3408
|
+
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4
|
|
3409
|
+
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3
|
|
3410
|
+
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3
|
|
3411
|
+
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3
|
|
3412
|
+
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
|
|
3413
|
+
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
|
|
3414
|
+
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3
|
|
3415
|
+
## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3
|
|
3416
|
+
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3
|
|
3417
|
+
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3
|
|
3418
|
+
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
|
|
3419
|
+
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3
|
|
3420
|
+
## carb
|
|
3421
|
+
## Hornet 4 Drive 1
|
|
3422
|
+
## Hornet Sportabout 2
|
|
3423
|
+
## Valiant 1
|
|
3424
|
+
## Duster 360 4
|
|
3425
|
+
## Merc 240D 2
|
|
3426
|
+
## Merc 230 2
|
|
3427
|
+
## Merc 280 4
|
|
3428
|
+
## Merc 280C 4
|
|
3429
|
+
## Merc 450SE 3
|
|
3430
|
+
## Merc 450SL 3
|
|
3431
|
+
## Merc 450SLC 3
|
|
3432
|
+
## Cadillac Fleetwood 4
|
|
3433
|
+
## Lincoln Continental 4
|
|
3434
|
+
## Chrysler Imperial 4
|
|
3435
|
+
## Toyota Corona 1
|
|
3436
|
+
## Dodge Challenger 2
|
|
3437
|
+
## AMC Javelin 2
|
|
3438
|
+
## Camaro Z28 4
|
|
3439
|
+
## Pontiac Firebird 2
|
|
3349
3440
|
```
|
|
3350
3441
|
|
|
3351
3442
|
# Writing Expressions in Galaaz
|
|
@@ -3550,17 +3641,18 @@ puts flights.head
|
|
|
3550
3641
|
|
|
3551
3642
|
```
|
|
3552
3643
|
## # A tibble: 6 × 19
|
|
3553
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3554
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3555
|
-
## 1 2013 1 1 517 515 2 830
|
|
3556
|
-
## 2 2013 1 1 533 529 4 850
|
|
3557
|
-
## 3 2013 1 1 542 540 2 923
|
|
3558
|
-
## 4 2013 1 1 544 545 -1 1004
|
|
3559
|
-
## 5 2013 1 1 554 600 -6 812
|
|
3560
|
-
## 6 2013 1 1 554 558 -4 740
|
|
3561
|
-
## # ℹ
|
|
3562
|
-
## #
|
|
3563
|
-
## #
|
|
3644
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3645
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3646
|
+
## 1 2013 1 1 517 515 2 830
|
|
3647
|
+
## 2 2013 1 1 533 529 4 850
|
|
3648
|
+
## 3 2013 1 1 542 540 2 923
|
|
3649
|
+
## 4 2013 1 1 544 545 -1 1004
|
|
3650
|
+
## 5 2013 1 1 554 600 -6 812
|
|
3651
|
+
## 6 2013 1 1 554 558 -4 740
|
|
3652
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3653
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3654
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3655
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3564
3656
|
```
|
|
3565
3657
|
|
|
3566
3658
|
## Filtering rows with Filter
|
|
@@ -3575,17 +3667,18 @@ puts flights.filter((R[:month].eq 1), (R[:day].eq 1)).head
|
|
|
3575
3667
|
|
|
3576
3668
|
```
|
|
3577
3669
|
## # A tibble: 6 × 19
|
|
3578
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3579
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3580
|
-
## 1 2013 1 1 517 515 2 830
|
|
3581
|
-
## 2 2013 1 1 533 529 4 850
|
|
3582
|
-
## 3 2013 1 1 542 540 2 923
|
|
3583
|
-
## 4 2013 1 1 544 545 -1 1004
|
|
3584
|
-
## 5 2013 1 1 554 600 -6 812
|
|
3585
|
-
## 6 2013 1 1 554 558 -4 740
|
|
3586
|
-
## # ℹ
|
|
3587
|
-
## #
|
|
3588
|
-
## #
|
|
3670
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3671
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3672
|
+
## 1 2013 1 1 517 515 2 830
|
|
3673
|
+
## 2 2013 1 1 533 529 4 850
|
|
3674
|
+
## 3 2013 1 1 542 540 2 923
|
|
3675
|
+
## 4 2013 1 1 544 545 -1 1004
|
|
3676
|
+
## 5 2013 1 1 554 600 -6 812
|
|
3677
|
+
## 6 2013 1 1 554 558 -4 740
|
|
3678
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3679
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3680
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3681
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3589
3682
|
```
|
|
3590
3683
|
|
|
3591
3684
|
## Logical Operators
|
|
@@ -3599,17 +3692,18 @@ puts flights.filter((R[:month].eq 11) | (R[:month].eq 12)).head
|
|
|
3599
3692
|
|
|
3600
3693
|
```
|
|
3601
3694
|
## # A tibble: 6 × 19
|
|
3602
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3603
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3604
|
-
## 1 2013 11 1 5 2359 6 352
|
|
3605
|
-
## 2 2013 11 1 35 2250 105 123
|
|
3606
|
-
## 3 2013 11 1 455 500 -5 641
|
|
3607
|
-
## 4 2013 11 1 539 545 -6 856
|
|
3608
|
-
## 5 2013 11 1 542 545 -3 831
|
|
3609
|
-
## 6 2013 11 1 549 600 -11 912
|
|
3610
|
-
## # ℹ
|
|
3611
|
-
## #
|
|
3612
|
-
## #
|
|
3695
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3696
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3697
|
+
## 1 2013 11 1 5 2359 6 352
|
|
3698
|
+
## 2 2013 11 1 35 2250 105 123
|
|
3699
|
+
## 3 2013 11 1 455 500 -5 641
|
|
3700
|
+
## 4 2013 11 1 539 545 -6 856
|
|
3701
|
+
## 5 2013 11 1 542 545 -3 831
|
|
3702
|
+
## 6 2013 11 1 549 600 -11 912
|
|
3703
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3704
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3705
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3706
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3613
3707
|
```
|
|
3614
3708
|
|
|
3615
3709
|
The same as above, but using the 'in' operator. In R, it is possible to define many operators
|
|
@@ -3624,17 +3718,18 @@ puts flights.filter(R[:month]._ :in, R.c(11, 12)).head
|
|
|
3624
3718
|
|
|
3625
3719
|
```
|
|
3626
3720
|
## # A tibble: 6 × 19
|
|
3627
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3628
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3629
|
-
## 1 2013 11 1 5 2359 6 352
|
|
3630
|
-
## 2 2013 11 1 35 2250 105 123
|
|
3631
|
-
## 3 2013 11 1 455 500 -5 641
|
|
3632
|
-
## 4 2013 11 1 539 545 -6 856
|
|
3633
|
-
## 5 2013 11 1 542 545 -3 831
|
|
3634
|
-
## 6 2013 11 1 549 600 -11 912
|
|
3635
|
-
## # ℹ
|
|
3636
|
-
## #
|
|
3637
|
-
## #
|
|
3721
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3722
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3723
|
+
## 1 2013 11 1 5 2359 6 352
|
|
3724
|
+
## 2 2013 11 1 35 2250 105 123
|
|
3725
|
+
## 3 2013 11 1 455 500 -5 641
|
|
3726
|
+
## 4 2013 11 1 539 545 -6 856
|
|
3727
|
+
## 5 2013 11 1 542 545 -3 831
|
|
3728
|
+
## 6 2013 11 1 549 600 -11 912
|
|
3729
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3730
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3731
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3732
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3638
3733
|
```
|
|
3639
3734
|
|
|
3640
3735
|
## Filtering with NA (Not Available)
|
|
@@ -3700,17 +3795,18 @@ puts flights.arrange(:year, :month, :day).head
|
|
|
3700
3795
|
|
|
3701
3796
|
```
|
|
3702
3797
|
## # A tibble: 6 × 19
|
|
3703
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3704
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3705
|
-
## 1 2013 1 1 517 515 2 830
|
|
3706
|
-
## 2 2013 1 1 533 529 4 850
|
|
3707
|
-
## 3 2013 1 1 542 540 2 923
|
|
3708
|
-
## 4 2013 1 1 544 545 -1 1004
|
|
3709
|
-
## 5 2013 1 1 554 600 -6 812
|
|
3710
|
-
## 6 2013 1 1 554 558 -4 740
|
|
3711
|
-
## # ℹ
|
|
3712
|
-
## #
|
|
3713
|
-
## #
|
|
3798
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3799
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3800
|
+
## 1 2013 1 1 517 515 2 830
|
|
3801
|
+
## 2 2013 1 1 533 529 4 850
|
|
3802
|
+
## 3 2013 1 1 542 540 2 923
|
|
3803
|
+
## 4 2013 1 1 544 545 -1 1004
|
|
3804
|
+
## 5 2013 1 1 554 600 -6 812
|
|
3805
|
+
## 6 2013 1 1 554 558 -4 740
|
|
3806
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3807
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3808
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3809
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3714
3810
|
```
|
|
3715
3811
|
|
|
3716
3812
|
To arrange in descending order, use function 'desc'
|
|
@@ -3722,17 +3818,18 @@ puts flights.arrange(R[:dep_delay].desc).head
|
|
|
3722
3818
|
|
|
3723
3819
|
```
|
|
3724
3820
|
## # A tibble: 6 × 19
|
|
3725
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3726
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3727
|
-
## 1 2013 1 9 641 900 1301 1242
|
|
3728
|
-
## 2 2013 6 15 1432 1935 1137 1607
|
|
3729
|
-
## 3 2013 1 10 1121 1635 1126 1239
|
|
3730
|
-
## 4 2013 9 20 1139 1845 1014 1457
|
|
3731
|
-
## 5 2013 7 22 845 1600 1005 1044
|
|
3732
|
-
## 6 2013 4 10 1100 1900 960 1342
|
|
3733
|
-
## # ℹ
|
|
3734
|
-
## #
|
|
3735
|
-
## #
|
|
3821
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3822
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3823
|
+
## 1 2013 1 9 641 900 1301 1242
|
|
3824
|
+
## 2 2013 6 15 1432 1935 1137 1607
|
|
3825
|
+
## 3 2013 1 10 1121 1635 1126 1239
|
|
3826
|
+
## 4 2013 9 20 1139 1845 1014 1457
|
|
3827
|
+
## 5 2013 7 22 845 1600 1005 1044
|
|
3828
|
+
## 6 2013 4 10 1100 1900 960 1342
|
|
3829
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3830
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3831
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3832
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3736
3833
|
```
|
|
3737
3834
|
|
|
3738
3835
|
## Selecting columns
|
|
@@ -3814,17 +3911,18 @@ puts flights.select(:year, :month, :day, E.everything).head
|
|
|
3814
3911
|
|
|
3815
3912
|
```
|
|
3816
3913
|
## # A tibble: 6 × 19
|
|
3817
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3818
|
-
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3819
|
-
## 1 2013 1 1 517 515 2 830
|
|
3820
|
-
## 2 2013 1 1 533 529 4 850
|
|
3821
|
-
## 3 2013 1 1 542 540 2 923
|
|
3822
|
-
## 4 2013 1 1 544 545 -1 1004
|
|
3823
|
-
## 5 2013 1 1 554 600 -6 812
|
|
3824
|
-
## 6 2013 1 1 554 558 -4 740
|
|
3825
|
-
## # ℹ
|
|
3826
|
-
## #
|
|
3827
|
-
## #
|
|
3914
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3915
|
+
## <int> <int> <int> <int> <int> <dbl> <int>
|
|
3916
|
+
## 1 2013 1 1 517 515 2 830
|
|
3917
|
+
## 2 2013 1 1 533 529 4 850
|
|
3918
|
+
## 3 2013 1 1 542 540 2 923
|
|
3919
|
+
## 4 2013 1 1 544 545 -1 1004
|
|
3920
|
+
## 5 2013 1 1 554 600 -6 812
|
|
3921
|
+
## 6 2013 1 1 554 558 -4 740
|
|
3922
|
+
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
|
|
3923
|
+
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
|
|
3924
|
+
## # dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
|
|
3925
|
+
## # minute <dbl>, time_hour <dttm>
|
|
3828
3926
|
```
|
|
3829
3927
|
|
|
3830
3928
|
## Add variables to a dataframe with 'mutate'
|
|
@@ -3954,48 +4052,48 @@ puts R.head(flights, 12)
|
|
|
3954
4052
|
|
|
3955
4053
|
```
|
|
3956
4054
|
## [1] 336776 19
|
|
3957
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
3958
|
-
## <int> <int> <int> <int> <int> <num> <int>
|
|
3959
|
-
## 1: 2013 1 1 517 515 2 830
|
|
3960
|
-
## 2: 2013 1 1 533 529 4 850
|
|
3961
|
-
## 3: 2013 1 1 542 540 2 923
|
|
3962
|
-
## 4: 2013 1 1 544 545 -1 1004
|
|
3963
|
-
## 5: 2013 1 1 554 600 -6 812
|
|
3964
|
-
## 6: 2013 1 1 554 558 -4 740
|
|
3965
|
-
## 7: 2013 1 1 555 600 -5 913
|
|
3966
|
-
## 8: 2013 1 1 557 600 -3 709
|
|
3967
|
-
## 9: 2013 1 1 557 600 -3 838
|
|
3968
|
-
## 10: 2013 1 1 558 600 -2 753
|
|
3969
|
-
## 11: 2013 1 1 558 600 -2 849
|
|
3970
|
-
## 12: 2013 1 1 558 600 -2 853
|
|
3971
|
-
## arr_delay carrier flight tailnum origin dest
|
|
3972
|
-
##
|
|
3973
|
-
## 1: 11 UA 1545 N14228 EWR IAH
|
|
3974
|
-
## 2: 20 UA 1714 N24211 LGA IAH
|
|
3975
|
-
## 3: 33 AA 1141 N619AA JFK MIA
|
|
3976
|
-
## 4: -18 B6 725 N804JB JFK BQN
|
|
3977
|
-
## 5: -25 DL 461 N668DN LGA ATL
|
|
3978
|
-
## 6: 12 UA 1696 N39463 EWR ORD
|
|
3979
|
-
## 7: 19 B6 507 N516JB EWR FLL
|
|
3980
|
-
## 8: -14 EV 5708 N829AS LGA IAD
|
|
3981
|
-
## 9: -8 B6 79 N593JB JFK MCO
|
|
3982
|
-
## 10: 8 AA 301 N3ALAA LGA ORD
|
|
3983
|
-
## 11: -2 B6 49 N793JB JFK PBI
|
|
3984
|
-
## 12: -3 B6 71 N657JB JFK TPA
|
|
3985
|
-
## minute time_hour
|
|
3986
|
-
##
|
|
3987
|
-
## 1: 15 2013-01-01 05:00:00
|
|
3988
|
-
## 2: 29 2013-01-01 05:00:00
|
|
3989
|
-
## 3: 40 2013-01-01 05:00:00
|
|
3990
|
-
## 4: 45 2013-01-01 05:00:00
|
|
3991
|
-
## 5: 0 2013-01-01 06:00:00
|
|
3992
|
-
## 6: 58 2013-01-01 05:00:00
|
|
3993
|
-
## 7: 0 2013-01-01 06:00:00
|
|
3994
|
-
## 8: 0 2013-01-01 06:00:00
|
|
3995
|
-
## 9: 0 2013-01-01 06:00:00
|
|
3996
|
-
## 10: 0 2013-01-01 06:00:00
|
|
3997
|
-
## 11: 0 2013-01-01 06:00:00
|
|
3998
|
-
## 12: 0 2013-01-01 06:00:00
|
|
4055
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
4056
|
+
## <int> <int> <int> <int> <int> <num> <int>
|
|
4057
|
+
## 1: 2013 1 1 517 515 2 830
|
|
4058
|
+
## 2: 2013 1 1 533 529 4 850
|
|
4059
|
+
## 3: 2013 1 1 542 540 2 923
|
|
4060
|
+
## 4: 2013 1 1 544 545 -1 1004
|
|
4061
|
+
## 5: 2013 1 1 554 600 -6 812
|
|
4062
|
+
## 6: 2013 1 1 554 558 -4 740
|
|
4063
|
+
## 7: 2013 1 1 555 600 -5 913
|
|
4064
|
+
## 8: 2013 1 1 557 600 -3 709
|
|
4065
|
+
## 9: 2013 1 1 557 600 -3 838
|
|
4066
|
+
## 10: 2013 1 1 558 600 -2 753
|
|
4067
|
+
## 11: 2013 1 1 558 600 -2 849
|
|
4068
|
+
## 12: 2013 1 1 558 600 -2 853
|
|
4069
|
+
## sched_arr_time arr_delay carrier flight tailnum origin dest
|
|
4070
|
+
## <int> <num> <char> <int> <char> <char> <char>
|
|
4071
|
+
## 1: 819 11 UA 1545 N14228 EWR IAH
|
|
4072
|
+
## 2: 830 20 UA 1714 N24211 LGA IAH
|
|
4073
|
+
## 3: 850 33 AA 1141 N619AA JFK MIA
|
|
4074
|
+
## 4: 1022 -18 B6 725 N804JB JFK BQN
|
|
4075
|
+
## 5: 837 -25 DL 461 N668DN LGA ATL
|
|
4076
|
+
## 6: 728 12 UA 1696 N39463 EWR ORD
|
|
4077
|
+
## 7: 854 19 B6 507 N516JB EWR FLL
|
|
4078
|
+
## 8: 723 -14 EV 5708 N829AS LGA IAD
|
|
4079
|
+
## 9: 846 -8 B6 79 N593JB JFK MCO
|
|
4080
|
+
## 10: 745 8 AA 301 N3ALAA LGA ORD
|
|
4081
|
+
## 11: 851 -2 B6 49 N793JB JFK PBI
|
|
4082
|
+
## 12: 856 -3 B6 71 N657JB JFK TPA
|
|
4083
|
+
## air_time distance hour minute time_hour
|
|
4084
|
+
## <num> <num> <num> <num> <POSc>
|
|
4085
|
+
## 1: 227 1400 5 15 2013-01-01 05:00:00
|
|
4086
|
+
## 2: 227 1416 5 29 2013-01-01 05:00:00
|
|
4087
|
+
## 3: 160 1089 5 40 2013-01-01 05:00:00
|
|
4088
|
+
## 4: 183 1576 5 45 2013-01-01 05:00:00
|
|
4089
|
+
## 5: 116 762 6 0 2013-01-01 06:00:00
|
|
4090
|
+
## 6: 150 719 5 58 2013-01-01 05:00:00
|
|
4091
|
+
## 7: 158 1065 6 0 2013-01-01 06:00:00
|
|
4092
|
+
## 8: 53 229 6 0 2013-01-01 06:00:00
|
|
4093
|
+
## 9: 140 944 6 0 2013-01-01 06:00:00
|
|
4094
|
+
## 10: 138 733 6 0 2013-01-01 06:00:00
|
|
4095
|
+
## 11: 149 1028 6 0 2013-01-01 06:00:00
|
|
4096
|
+
## 12: 158 1005 6 0 2013-01-01 06:00:00
|
|
3999
4097
|
```
|
|
4000
4098
|
|
|
4001
4099
|
|
|
@@ -4040,42 +4138,42 @@ puts ans
|
|
|
4040
4138
|
```
|
|
4041
4139
|
|
|
4042
4140
|
```
|
|
4043
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
4044
|
-
## <int> <int> <int> <int> <int> <num> <int>
|
|
4045
|
-
## 1: 2013 6 1 2 2359 3 341
|
|
4046
|
-
## 2: 2013 6 1 538 545 -7 925
|
|
4047
|
-
## 3: 2013 6 1 539 540 -1 832
|
|
4048
|
-
## 4: 2013 6 1 553 600 -7 700
|
|
4049
|
-
## 5: 2013 6 1 554 600 -6 851
|
|
4050
|
-
## 6: 2013 6 1 557 600 -3 934
|
|
4051
|
-
## arr_delay carrier flight tailnum origin dest
|
|
4052
|
-
##
|
|
4053
|
-
## 1: -9 B6 739 N618JB JFK PSE
|
|
4054
|
-
## 2: 3 B6 725 N806JB JFK BQN
|
|
4055
|
-
## 3: -8 AA 701 N5EAAA JFK MIA
|
|
4056
|
-
## 4: -11 EV 5716 N835AS JFK IAD
|
|
4057
|
-
## 5: -17 UA 1159 N33132 JFK LAX
|
|
4058
|
-
## 6: -8 B6 715 N766JB JFK SJU
|
|
4059
|
-
## minute time_hour
|
|
4060
|
-
##
|
|
4061
|
-
## 1: 59 2013-06-01 23:00:00
|
|
4062
|
-
## 2: 45 2013-06-01 05:00:00
|
|
4063
|
-
## 3: 40 2013-06-01 05:00:00
|
|
4064
|
-
## 4: 0 2013-06-01 06:00:00
|
|
4065
|
-
## 5: 0 2013-06-01 06:00:00
|
|
4066
|
-
## 6: 0 2013-06-01 06:00:00
|
|
4067
|
-
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
4068
|
-
## <int> <int> <int> <int> <int> <num> <int>
|
|
4069
|
-
## 1: 2013 1 1 517 515 2 830
|
|
4070
|
-
## 2: 2013 1 1 533 529 4 850
|
|
4071
|
-
## arr_delay carrier flight tailnum origin dest
|
|
4072
|
-
##
|
|
4073
|
-
## 1: 11 UA 1545 N14228 EWR IAH
|
|
4074
|
-
## 2: 20 UA 1714 N24211 LGA IAH
|
|
4075
|
-
## minute time_hour
|
|
4076
|
-
##
|
|
4077
|
-
## 1: 15 2013-01-01 05:00:00
|
|
4078
|
-
## 2: 29 2013-01-01 05:00:00
|
|
4141
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
4142
|
+
## <int> <int> <int> <int> <int> <num> <int>
|
|
4143
|
+
## 1: 2013 6 1 2 2359 3 341
|
|
4144
|
+
## 2: 2013 6 1 538 545 -7 925
|
|
4145
|
+
## 3: 2013 6 1 539 540 -1 832
|
|
4146
|
+
## 4: 2013 6 1 553 600 -7 700
|
|
4147
|
+
## 5: 2013 6 1 554 600 -6 851
|
|
4148
|
+
## 6: 2013 6 1 557 600 -3 934
|
|
4149
|
+
## sched_arr_time arr_delay carrier flight tailnum origin dest
|
|
4150
|
+
## <int> <num> <char> <int> <char> <char> <char>
|
|
4151
|
+
## 1: 350 -9 B6 739 N618JB JFK PSE
|
|
4152
|
+
## 2: 922 3 B6 725 N806JB JFK BQN
|
|
4153
|
+
## 3: 840 -8 AA 701 N5EAAA JFK MIA
|
|
4154
|
+
## 4: 711 -11 EV 5716 N835AS JFK IAD
|
|
4155
|
+
## 5: 908 -17 UA 1159 N33132 JFK LAX
|
|
4156
|
+
## 6: 942 -8 B6 715 N766JB JFK SJU
|
|
4157
|
+
## air_time distance hour minute time_hour
|
|
4158
|
+
## <num> <num> <num> <num> <POSc>
|
|
4159
|
+
## 1: 200 1617 23 59 2013-06-01 23:00:00
|
|
4160
|
+
## 2: 203 1576 5 45 2013-06-01 05:00:00
|
|
4161
|
+
## 3: 140 1089 5 40 2013-06-01 05:00:00
|
|
4162
|
+
## 4: 42 228 6 0 2013-06-01 06:00:00
|
|
4163
|
+
## 5: 330 2475 6 0 2013-06-01 06:00:00
|
|
4164
|
+
## 6: 198 1598 6 0 2013-06-01 06:00:00
|
|
4165
|
+
## year month day dep_time sched_dep_time dep_delay arr_time
|
|
4166
|
+
## <int> <int> <int> <int> <int> <num> <int>
|
|
4167
|
+
## 1: 2013 1 1 517 515 2 830
|
|
4168
|
+
## 2: 2013 1 1 533 529 4 850
|
|
4169
|
+
## sched_arr_time arr_delay carrier flight tailnum origin dest
|
|
4170
|
+
## <int> <num> <char> <int> <char> <char> <char>
|
|
4171
|
+
## 1: 819 11 UA 1545 N14228 EWR IAH
|
|
4172
|
+
## 2: 830 20 UA 1714 N24211 LGA IAH
|
|
4173
|
+
## air_time distance hour minute time_hour
|
|
4174
|
+
## <num> <num> <num> <num> <POSc>
|
|
4175
|
+
## 1: 227 1400 5 15 2013-01-01 05:00:00
|
|
4176
|
+
## 2: 227 1416 5 29 2013-01-01 05:00:00
|
|
4079
4177
|
```
|
|
4080
4178
|
|
|
4081
4179
|
|
|
@@ -4109,83 +4207,46 @@ ans = flights[:all, E.list(R[:arr_delay], R[:dep_delay])]
|
|
|
4109
4207
|
# Apache Arrow
|
|
4110
4208
|
|
|
4111
4209
|
[Apache Arrow](https://arrow.apache.org/) is a **columnar** in-memory format used heavily in R
|
|
4112
|
-
and Python for analytics.
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
2. **Stage B1 (Ruby → R IPC file):** **`Galaaz::ArrowIpc.write`** / **`write_batches`** writes an
|
|
4118
|
-
Arrow IPC file (prefer **`/dev/shm`**); **`R::Arrow.open_ipc(path)`** opens it in R. Only the
|
|
4119
|
-
**path** crosses NewBridge. This is **mmap/IPC file handoff**, not a shared heap.
|
|
4120
|
-
3. **Stage B2 (R → Ruby IPC file):** **`R::Arrow.write_ipc(obj)`** writes uncompressed IPC; Ruby
|
|
4121
|
-
reads with **`Galaaz::ArrowIpc.read`** (column hash) or **`read_batches`** (row hashes). Call
|
|
4122
|
-
**`Galaaz::ArrowIpc.release(path)`** when finished.
|
|
4123
|
-
4. **Stage C (not shipped):** named shared-memory bus. Do not claim 0 ms shared RAM until then.
|
|
4124
|
-
See **`Documentation/ROADMAP_ARROW_RUBY_R.md`**.
|
|
4125
|
-
|
|
4126
|
-
After ingest, use R’s **`arrow`** / **`dplyr`** on the proxy (`group_by`, `summarise`, `collect`)
|
|
4127
|
-
and unbox only KPIs you need in Ruby.
|
|
4128
|
-
|
|
4129
|
-
**Optional Ruby backends for Stage B**
|
|
4130
|
-
|
|
4131
|
-
* **CRuby:** Apache **red-arrow** — `gem install red-arrow` pinned to the same major as
|
|
4132
|
-
`pkg-config --modversion arrow-glib`, plus system **Arrow GLib** (`libarrow-glib-dev` from the
|
|
4133
|
-
[Apache Arrow APT](https://arrow.apache.org/install/) repo). Do **not** install the unrelated
|
|
4134
|
-
legacy Rubygems package named `arrow`. `bundle exec` still sees a user-installed `red-arrow`
|
|
4135
|
-
via Galaaz’s load-path helper.
|
|
4136
|
-
* **JRuby:** Apache Arrow **Java** JARs — **`GALAAZ_ARROW_JARS`**, `~/arrow_jars`, or
|
|
4137
|
-
`jar-dependencies`. Export **`JAVA_OPTS=--add-opens=java.base/java.nio=ALL-UNNAMED`** on the
|
|
4138
|
-
**child** JVM (`bin/galaaz-jruby`, `mise.toml`). `jruby -J... -S bundle exec rspec` does **not**
|
|
4139
|
-
pass `-J` to rspec.
|
|
4140
|
-
|
|
4141
|
-
**R packages:** **`arrow`** and **`dplyr`**. B2 writes IPC with **`compression: 'uncompressed'`**
|
|
4142
|
-
so JRuby Arrow Java can read without extra compression JARs.
|
|
4143
|
-
|
|
4144
|
-
**Tests:** `specs/arrow_from_ruby_batches_spec.rb` (A);
|
|
4145
|
-
`specs/arrow_ipc_handoff_spec.rb`, `specs/arrow_ipc_export_spec.rb` (B, sync);
|
|
4146
|
-
`new_bridge_specs/arrow_ipc_async_spec.rb`, `new_bridge_specs/arrow_ipc_export_async_spec.rb` (B, async).
|
|
4147
|
-
|
|
4148
|
-
## `R::Arrow` and `Galaaz::ArrowIpc`
|
|
4149
|
-
|
|
4150
|
-
* **`R::Arrow.from_ruby_batches`** — Stage A ingest.
|
|
4151
|
-
* **`R::Arrow.open_ipc(path)`** — Stage B1: IPC file → R Table proxy.
|
|
4152
|
-
* **`R::Arrow.write_ipc(obj, path = nil)`** — Stage B2: R Table/tibble → IPC path (scratch if omitted).
|
|
4153
|
-
* **`Galaaz::ArrowIpc.write` / `write_batches` / `read` / `read_batches` / `allocate_path` / `release` / `available?`**
|
|
4154
|
-
* **`R::Arrow.table_from(df)`** — wrap an R `data.frame` / tibble as an Arrow table.
|
|
4155
|
-
* **`R::Arrow.read_feather` / `write_feather`**, **`read_parquet`**, **`dataset(path)`** — file and
|
|
4156
|
-
dataset IO on paths visible to R.
|
|
4210
|
+
and Python for analytics. In Galaaz, **Ruby does not hold an Arrow C++ table itself**; instead you
|
|
4211
|
+
build ordinary Ruby structures (arrays of row hashes), and **`R::Arrow.from_ruby_batches`** creates
|
|
4212
|
+
a real **Arrow `Table` inside GNU R**. From there you use R’s **`arrow`** and **`dplyr`** packages
|
|
4213
|
+
as usual: **`group_by`** on the Arrow table, **`summarise`** for aggregates, then **`collect()`** to
|
|
4214
|
+
materialize a tibble when you need in-memory R rows.
|
|
4157
4215
|
|
|
4158
|
-
|
|
4216
|
+
That pattern matches production use: **JRuby threads** or a **multi-process CRuby** app
|
|
4217
|
+
(or sequential code) assemble many rows in
|
|
4218
|
+
Ruby; you pay **one** bridge-heavy handoff to R; **dplyr** runs vectorised work on the Arrow table
|
|
4219
|
+
in R.
|
|
4159
4220
|
|
|
4160
|
-
|
|
4161
|
-
|
|
4221
|
+
**Prerequisites:** install R packages **`arrow`** and **`dplyr`**. Run scripts with
|
|
4222
|
+
**`bin/galaaz-jruby`** (or the same JVM flags as in **`docs/testing.md`**) so the Arrow JNI stack is
|
|
4223
|
+
available.
|
|
4162
4224
|
|
|
4163
|
-
|
|
4164
|
-
path = Galaaz::ArrowIpc.write(id: [1, 2, 3], grp: %w[a a b], value: [1.0, 2.0, 3.5])
|
|
4165
|
-
tbl = R::Arrow.open_ipc(path)
|
|
4166
|
-
Galaaz::ArrowIpc.release(path)
|
|
4225
|
+
## Other `R::Arrow` helpers
|
|
4167
4226
|
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
```
|
|
4227
|
+
The Ruby module **`R::Arrow`** (see `lib/R_interface/r_arrow.rb`) also includes:
|
|
4228
|
+
|
|
4229
|
+
* **`R::Arrow.table_from(df)`** — wrap an R `data.frame` / tibble as an Arrow table.
|
|
4230
|
+
* **`R::Arrow.read_feather` / `write_feather`**, **`read_parquet`**, **`dataset(path)`** — file and
|
|
4231
|
+
dataset IO on paths visible to R.
|
|
4174
4232
|
|
|
4175
4233
|
## Example: many Ruby rows → Arrow in R → grouped statistics
|
|
4176
4234
|
|
|
4177
4235
|
The repository test **`slow-specs/arrow_large_pipeline_spec.rb`** builds **200k rows** in parallel
|
|
4178
|
-
(eight threads × 25,000 rows), pushes them through **`R::Arrow.from_ruby_batches
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
over NewBridge, use Stage B (`write_batches` + `open_ipc`) instead of `from_ruby_batches`.
|
|
4236
|
+
(eight threads × 25,000 rows), pushes them through **`R::Arrow.from_ruby_batches`**, then checks that
|
|
4237
|
+
**dplyr** group summaries match a Ruby reference calculation. The same logic appears below at a
|
|
4238
|
+
**smaller scale** so this manual can knit quickly; increase `thread_count` and `rows_per_thread`
|
|
4239
|
+
when experimenting locally.
|
|
4183
4240
|
|
|
4184
4241
|
|
|
4185
4242
|
``` ruby
|
|
4186
4243
|
# Scaled-down version of slow-specs/arrow_large_pipeline_spec.rb.
|
|
4187
|
-
|
|
4188
|
-
|
|
4244
|
+
arrow_ok = R::Support.eval(
|
|
4245
|
+
"requireNamespace('arrow', quietly=TRUE) && " +
|
|
4246
|
+
"requireNamespace('dplyr', quietly=TRUE)")
|
|
4247
|
+
unless arrow_ok == true
|
|
4248
|
+
puts '(Skip: need arrow + dplyr in R; ' +
|
|
4249
|
+
'use bin/galaaz-jruby outside gKnit.)'
|
|
4189
4250
|
else
|
|
4190
4251
|
thread_count = 4
|
|
4191
4252
|
rows_per_thread = 500
|
|
@@ -4228,7 +4289,9 @@ else
|
|
|
4228
4289
|
|
|
4229
4290
|
total_n = 0
|
|
4230
4291
|
(1..(out.nrow >> 0)).each { |i| total_n += (out[['n']][i] >> 0) }
|
|
4231
|
-
puts "Sum of group counts n
|
|
4292
|
+
puts "Sum of group counts n " +
|
|
4293
|
+
"(should equal #{thread_count * rows_per_thread}): " +
|
|
4294
|
+
"#{total_n}"
|
|
4232
4295
|
end
|
|
4233
4296
|
```
|
|
4234
4297
|
|
|
@@ -4244,11 +4307,13 @@ end
|
|
|
4244
4307
|
## Sum of group counts n (should equal 2000): 2000
|
|
4245
4308
|
```
|
|
4246
4309
|
|
|
4247
|
-
**What to notice:** (1) Ruby only sees **`Hash`** rows and Ruby **`Thread`** objects;
|
|
4248
|
-
**`from_ruby_batches`** call
|
|
4249
|
-
**`
|
|
4250
|
-
**`dplyr::summarise`** / **`dplyr::collect`**
|
|
4251
|
-
|
|
4310
|
+
**What to notice:** (1) Ruby only sees **`Hash`** rows and Ruby **`Thread`** objects;
|
|
4311
|
+
(2) a single **`from_ruby_batches`** call creates the Arrow table in R;
|
|
4312
|
+
(3) **`dplyr___group_by`** / **`dplyr___summarise`** / **`dplyr___collect`**
|
|
4313
|
+
mirror **`dplyr::group_by`** / **`dplyr::summarise`** / **`dplyr::collect`**
|
|
4314
|
+
on an Arrow-backed table. For a lighter test, see
|
|
4315
|
+
**`specs/arrow_from_ruby_batches_spec.rb`**;
|
|
4316
|
+
for the full-size benchmark, run
|
|
4252
4317
|
**`bin/run_slow_rspec slow-specs/arrow_large_pipeline_spec.rb`**.
|
|
4253
4318
|
|
|
4254
4319
|
# Bioconductor and DESeq2
|
|
@@ -4277,8 +4342,10 @@ The script **`examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb`** is
|
|
|
4277
4342
|
version in the repository. Run it from the **Galaaz repository root** with either engine, for example:
|
|
4278
4343
|
|
|
4279
4344
|
```text
|
|
4280
|
-
bin/galaaz-ruby
|
|
4281
|
-
|
|
4345
|
+
bin/galaaz-ruby \
|
|
4346
|
+
examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
4347
|
+
# or: bin/galaaz-jruby \
|
|
4348
|
+
# examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
4282
4349
|
```
|
|
4283
4350
|
|
|
4284
4351
|
The workflow in Ruby mirrors a standard DESeq2 vignette:
|
|
@@ -4306,7 +4373,8 @@ manual is knitted, because **DESeq2** is heavy and may be absent on the build ma
|
|
|
4306
4373
|
|
|
4307
4374
|
|
|
4308
4375
|
``` ruby
|
|
4309
|
-
# Canonical script:
|
|
4376
|
+
# Canonical script:
|
|
4377
|
+
# examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
4310
4378
|
# Run: bin/galaaz-ruby examples/.../deseq2_airway_galaaz.rb (repo root).
|
|
4311
4379
|
|
|
4312
4380
|
require 'galaaz'
|
|
@@ -4333,7 +4401,8 @@ puts "Samples: #{R.ncol(dds)}"
|
|
|
4333
4401
|
puts "Genes after prefilter: #{R.nrow(dds)}"
|
|
4334
4402
|
puts "Result rows: #{R.nrow(res)}"
|
|
4335
4403
|
puts "Result columns: #{R.colnames(res)}"
|
|
4336
|
-
puts "Significant genes (padj < 0.05):
|
|
4404
|
+
puts "Significant genes (padj < 0.05): " +
|
|
4405
|
+
"#{R.sum(res.padj < 0.05, na__rm: true)}"
|
|
4337
4406
|
|
|
4338
4407
|
res_ordered = res[R.order(res.padj), :all]
|
|
4339
4408
|
puts R.head(R.as__data__frame(res_ordered), 10)
|
|
@@ -4349,8 +4418,12 @@ preview (it does **not** run **`DESeq`** so the manual knits quickly).
|
|
|
4349
4418
|
|
|
4350
4419
|
|
|
4351
4420
|
``` ruby
|
|
4352
|
-
|
|
4353
|
-
|
|
4421
|
+
deseq_ok = R::Support.eval(
|
|
4422
|
+
"requireNamespace('DESeq2', quietly=TRUE) && " +
|
|
4423
|
+
"requireNamespace('airway', quietly=TRUE)")
|
|
4424
|
+
unless deseq_ok
|
|
4425
|
+
puts '(Skip: install DESeq2 and airway via ' +
|
|
4426
|
+
'BiocManager in R for the full example.)'
|
|
4354
4427
|
else
|
|
4355
4428
|
R.library('DESeq2')
|
|
4356
4429
|
R.library('airway')
|
|
@@ -4365,14 +4438,14 @@ end
|
|
|
4365
4438
|
```
|
|
4366
4439
|
## airway object (head of assay / dims via R):
|
|
4367
4440
|
## ncol(samples): [1] 8
|
|
4368
|
-
## SRR1039508 SRR1039509 SRR1039512 SRR1039513
|
|
4369
|
-
## ENSG00000000003 679 448 873 408
|
|
4370
|
-
## ENSG00000000005 0 0 0 0
|
|
4371
|
-
## ENSG00000000419 467 515 621 365
|
|
4372
|
-
## SRR1039517 SRR1039520 SRR1039521
|
|
4373
|
-
## ENSG00000000003 1047 770 572
|
|
4374
|
-
## ENSG00000000005 0 0 0
|
|
4375
|
-
## ENSG00000000419 799 417 508
|
|
4441
|
+
## SRR1039508 SRR1039509 SRR1039512 SRR1039513
|
|
4442
|
+
## ENSG00000000003 679 448 873 408
|
|
4443
|
+
## ENSG00000000005 0 0 0 0
|
|
4444
|
+
## ENSG00000000419 467 515 621 365
|
|
4445
|
+
## SRR1039516 SRR1039517 SRR1039520 SRR1039521
|
|
4446
|
+
## ENSG00000000003 1138 1047 770 572
|
|
4447
|
+
## ENSG00000000005 0 0 0 0
|
|
4448
|
+
## ENSG00000000419 587 799 417 508
|
|
4376
4449
|
```
|
|
4377
4450
|
|
|
4378
4451
|
# Performance
|
|
@@ -4387,9 +4460,8 @@ Practical tips:
|
|
|
4387
4460
|
glue.
|
|
4388
4461
|
* **Reuse one process**: running many short scripts cold-starts Ruby, the JVM, and R each time;
|
|
4389
4462
|
a long-lived process or repeated calls in one run amortize setup (see benchmarks below).
|
|
4390
|
-
* **Batch data**: merge shards in Ruby, then **`R::Arrow.from_ruby_batches`** (
|
|
4391
|
-
|
|
4392
|
-
When Ruby needs a bulky result table back, **`R::Arrow.write_ipc`** + **`Galaaz::ArrowIpc.read_batches`**.
|
|
4463
|
+
* **Batch data**: merge shards in Ruby, then call **`R::Arrow.from_ruby_batches`** (or build one
|
|
4464
|
+
data frame) instead of millions of tiny R calls.
|
|
4393
4465
|
|
|
4394
4466
|
For measured discussion (including DESeq2-style workloads and warm comparisons), see
|
|
4395
4467
|
**`docs/performance.md`** and **`docs/deseq2_airway_benchmark.md`** in the Galaaz repository.
|
|
@@ -4426,20 +4498,20 @@ puts mtcars.head
|
|
|
4426
4498
|
```
|
|
4427
4499
|
|
|
4428
4500
|
```
|
|
4429
|
-
## mpg cyl disp hp drat wt qsec vs am gear
|
|
4430
|
-
## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3
|
|
4431
|
-
## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3
|
|
4432
|
-
## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3
|
|
4433
|
-
## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3
|
|
4434
|
-
## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3
|
|
4435
|
-
## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5
|
|
4436
|
-
##
|
|
4437
|
-
## Cadillac Fleetwood
|
|
4438
|
-
## Lincoln Continental Lincoln Continental -1.61 below
|
|
4439
|
-
## Camaro Z28
|
|
4440
|
-
## Duster 360
|
|
4441
|
-
## Chrysler Imperial
|
|
4442
|
-
## Maserati Bora
|
|
4501
|
+
## mpg cyl disp hp drat wt qsec vs am gear
|
|
4502
|
+
## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3
|
|
4503
|
+
## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3
|
|
4504
|
+
## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3
|
|
4505
|
+
## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3
|
|
4506
|
+
## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3
|
|
4507
|
+
## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5
|
|
4508
|
+
## carb car_name mpg_z mpg_type
|
|
4509
|
+
## Cadillac Fleetwood 4 Cadillac Fleetwood -1.61 below
|
|
4510
|
+
## Lincoln Continental 4 Lincoln Continental -1.61 below
|
|
4511
|
+
## Camaro Z28 4 Camaro Z28 -1.13 below
|
|
4512
|
+
## Duster 360 4 Duster 360 -0.96 below
|
|
4513
|
+
## Chrysler Imperial 4 Chrysler Imperial -0.89 below
|
|
4514
|
+
## Maserati Bora 8 Maserati Bora -0.84 below
|
|
4443
4515
|
```
|
|
4444
4516
|
Now, let's plot the diverging bar plot. When using gKnit, you normally do **not** need to open a
|
|
4445
4517
|
graphics device manually; gKnit arranges the figure device for chunk output. Galaaz
|
|
@@ -4461,13 +4533,17 @@ but in this graph we want the bars to be horizontally laid so we add 'coord\_fli
|
|
|
4461
4533
|
``` ruby
|
|
4462
4534
|
require 'ggplot'
|
|
4463
4535
|
|
|
4464
|
-
puts mtcars.ggplot(
|
|
4465
|
-
|
|
4466
|
-
R.
|
|
4467
|
-
|
|
4468
|
-
|
|
4536
|
+
puts mtcars.ggplot(
|
|
4537
|
+
E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
|
|
4538
|
+
R.geom_bar(E.aes(fill: :mpg_type),
|
|
4539
|
+
stat: 'identity', width: 0.5) +
|
|
4540
|
+
R.scale_fill_manual(
|
|
4541
|
+
name: 'Mileage',
|
|
4542
|
+
labels: R.c('Above Average', 'Below Average'),
|
|
4543
|
+
values: R.c('above': '#00ba38',
|
|
4544
|
+
'below': '#f8766d')) +
|
|
4469
4545
|
R.labs(subtitle: "Normalised mileage from 'mtcars'",
|
|
4470
|
-
title: "Diverging Bars") +
|
|
4546
|
+
title: "Diverging Bars") +
|
|
4471
4547
|
R.coord_flip
|
|
4472
4548
|
```
|
|
4473
4549
|
|
|
@@ -4590,7 +4666,8 @@ In Galaaz the method mutate_y below will work fine and will never fail silently.
|
|
|
4590
4666
|
|
|
4591
4667
|
``` ruby
|
|
4592
4668
|
def mutate_y(df)
|
|
4593
|
-
#
|
|
4669
|
+
# Column names are Ruby kwargs (y: …).
|
|
4670
|
+
# Use .assign only for R `<-` expressions.
|
|
4594
4671
|
df.mutate(y: R[:a] + R[:x])
|
|
4595
4672
|
end
|
|
4596
4673
|
```
|
|
@@ -4616,10 +4693,16 @@ definition of 'mutate\_y' above:
|
|
|
4616
4693
|
|
|
4617
4694
|
``` ruby
|
|
4618
4695
|
a = 10
|
|
4619
|
-
|
|
4696
|
+
begin
|
|
4697
|
+
mutate_y(df1)
|
|
4698
|
+
rescue => e
|
|
4699
|
+
puts e.class.to_s
|
|
4700
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
4701
|
+
end
|
|
4620
4702
|
```
|
|
4621
4703
|
|
|
4622
4704
|
```
|
|
4705
|
+
## NewBridge::SessionClient::RProcessError
|
|
4623
4706
|
## Error: ℹ In argument: `y = a + x`.
|
|
4624
4707
|
## Caused by error:
|
|
4625
4708
|
## ! object 'a' not found
|
|
@@ -4966,16 +5049,16 @@ puts (~R[:starwars]).head
|
|
|
4966
5049
|
|
|
4967
5050
|
```
|
|
4968
5051
|
## # A tibble: 6 × 14
|
|
4969
|
-
## name
|
|
4970
|
-
## <chr>
|
|
4971
|
-
## 1 Luke
|
|
4972
|
-
## 2 C-3PO
|
|
4973
|
-
## 3 R2-D2
|
|
4974
|
-
## 4 Darth
|
|
4975
|
-
## 5 Leia
|
|
4976
|
-
## 6 Owen
|
|
4977
|
-
## # ℹ
|
|
4978
|
-
## # vehicles <list>, starships <list>
|
|
5052
|
+
## name height mass hair_color skin_color eye_color birth_year sex
|
|
5053
|
+
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
|
|
5054
|
+
## 1 Luke … 172 77 blond fair blue 19 male
|
|
5055
|
+
## 2 C-3PO 167 75 <NA> gold yellow 112 none
|
|
5056
|
+
## 3 R2-D2 96 32 <NA> white, bl… red 33 none
|
|
5057
|
+
## 4 Darth… 202 136 none white yellow 41.9 male
|
|
5058
|
+
## 5 Leia … 150 49 brown light brown 19 fema…
|
|
5059
|
+
## 6 Owen … 178 120 brown, gr… light blue 52 male
|
|
5060
|
+
## # ℹ 6 more variables: gender <chr>, homeworld <chr>, species <chr>,
|
|
5061
|
+
## # films <list>, vehicles <list>, starships <list>
|
|
4979
5062
|
```
|
|
4980
5063
|
The grouped_mean function below will receive a grouping variable and calculate summaries for
|
|
4981
5064
|
the value\_variables given:
|
|
@@ -5004,8 +5087,8 @@ gm = starwars %>%
|
|
|
5004
5087
|
## # Auto named with `tibble::lst()`: tibble::lst(mean, median)
|
|
5005
5088
|
##
|
|
5006
5089
|
## # Using lambdas list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
|
|
5007
|
-
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning
|
|
5008
|
-
## generated.
|
|
5090
|
+
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning
|
|
5091
|
+
## was generated.
|
|
5009
5092
|
```
|
|
5010
5093
|
|
|
5011
5094
|
``` r
|
|
@@ -5039,11 +5122,19 @@ def grouped_mean(data, grouping_variables, value_variables)
|
|
|
5039
5122
|
data.
|
|
5040
5123
|
group_by_at(grouping_variables).
|
|
5041
5124
|
mutate(count: E.n).
|
|
5042
|
-
summarise_at(
|
|
5043
|
-
|
|
5125
|
+
summarise_at(
|
|
5126
|
+
E.c(value_variables, "count"),
|
|
5127
|
+
~R[:mean],
|
|
5128
|
+
na__rm: true).
|
|
5129
|
+
rename_at(
|
|
5130
|
+
value_variables,
|
|
5131
|
+
E.funs(E.paste0("mean_", value_variables)))
|
|
5044
5132
|
end
|
|
5045
5133
|
|
|
5046
|
-
puts grouped_mean(
|
|
5134
|
+
puts grouped_mean(
|
|
5135
|
+
(~R[:starwars]),
|
|
5136
|
+
"eye_color",
|
|
5137
|
+
E.c("mass", "birth_year"))
|
|
5047
5138
|
```
|
|
5048
5139
|
|
|
5049
5140
|
```
|
|
@@ -5077,7 +5168,7 @@ arguments.
|
|
|
5077
5168
|
* Fork it
|
|
5078
5169
|
* Create your feature branch (`git checkout -b my-new-feature`)
|
|
5079
5170
|
* Write tests — use **`bin/run_rspec`** or **`bin/run_all_rspec`** (JRuby or CRuby via
|
|
5080
|
-
**`GALAAZ_RUBY`**) so
|
|
5171
|
+
**`GALAAZ_RUBY`**) so the load path matches **`docs/testing.md`**
|
|
5081
5172
|
* Commit your changes (`git commit -am 'Add some feature'`)
|
|
5082
5173
|
* Push to the branch (`git push origin my-new-feature`)
|
|
5083
5174
|
* Open a pull request
|