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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/Rakefile +20 -2
  4. data/bin/check_gemfile_lock_version +46 -0
  5. data/bin/release_bump +26 -0
  6. data/blogs/README.md +4 -0
  7. data/blogs/galaaz_2_0/galaaz_2_0.Rmd +385 -0
  8. data/blogs/galaaz_2_0/galaaz_2_0.md +409 -0
  9. data/blogs/galaaz_2_0/galaaz_2_0.tex +756 -0
  10. data/blogs/galaaz_2_0/images/galaaz-header.png +0 -0
  11. data/blogs/galaaz_2_0/images/galaaz-lockup-stacked.png +0 -0
  12. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +76 -58
  13. data/blogs/galaaz_ggplot/galaaz_ggplot.md +188 -161
  14. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +185 -117
  15. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
  16. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
  17. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
  18. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
  19. data/blogs/galaaz_ggplot/images/galaaz-lockup-stacked.png +0 -0
  20. data/blogs/gknit/gknit.Rmd +48 -28
  21. data/blogs/gknit/gknit.md +60 -43
  22. data/blogs/gknit/gknit.tex +1409 -0
  23. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  24. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  25. data/blogs/gknit/gknit_files/figure-latex/bubble-1.png +0 -0
  26. data/blogs/gknit/images/galaaz-lockup-stacked.png +0 -0
  27. data/blogs/manual/images/galaaz-lockup-stacked.png +0 -0
  28. data/blogs/manual/manual.Rmd +161 -71
  29. data/blogs/manual/manual.md +573 -482
  30. data/blogs/manual/manual.tex +1113 -517
  31. data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
  32. data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
  33. data/blogs/manual/manual_files/figure-markdown_github/bubble-1.png +0 -0
  34. data/blogs/manual/manual_files/figure-markdown_github/diverging_bar.png +0 -0
  35. data/blogs/nse_dplyr/images/galaaz-lockup-stacked.png +0 -0
  36. data/blogs/nse_dplyr/nse_dplyr.Rmd +42 -8
  37. data/blogs/nse_dplyr/nse_dplyr.md +69 -50
  38. data/blogs/nse_dplyr/nse_dplyr.tex +1626 -0
  39. data/blogs/oh_my/images/galaaz-lockup-stacked.png +0 -0
  40. data/blogs/oh_my/oh_my.Rmd +206 -55
  41. data/blogs/oh_my/oh_my.md +247 -96
  42. data/blogs/oh_my/oh_my.tex +2038 -93
  43. data/blogs/r_on_rails_ledger/images/00_portfolio_page.png +0 -0
  44. data/blogs/r_on_rails_ledger/images/01_results_panel.png +0 -0
  45. data/blogs/r_on_rails_ledger/images/02_density_tail_risk.png +0 -0
  46. data/blogs/r_on_rails_ledger/images/03_mc_cone.png +0 -0
  47. data/blogs/r_on_rails_ledger/images/04_rolling_var.png +0 -0
  48. data/blogs/r_on_rails_ledger/images/galaaz-lockup-stacked.png +0 -0
  49. data/blogs/r_on_rails_ledger/r_on_rails_ledger.Rmd +354 -0
  50. data/blogs/r_on_rails_ledger/r_on_rails_ledger.md +365 -0
  51. data/blogs/r_on_rails_ledger/r_on_rails_ledger.tex +670 -0
  52. data/blogs/ruby_plot/images/galaaz-lockup-stacked.png +0 -0
  53. data/blogs/ruby_plot/ruby_plot.Rmd +56 -35
  54. data/blogs/ruby_plot/ruby_plot.md +63 -47
  55. data/blogs/ruby_plot/ruby_plot.tex +194 -125
  56. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  57. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  58. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  59. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  60. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  61. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  62. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  63. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  64. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  65. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  66. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  67. data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
  68. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  69. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  70. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  71. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  72. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  73. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  74. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  75. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  76. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  77. data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  78. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/dose_len.png +0 -0
  79. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  80. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  81. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  82. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  83. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  84. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  85. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  86. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  87. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  88. data/blogs/ruby_plot/ruby_plot_files/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  89. data/lib/galaaz/cli.rb +98 -13
  90. data/logos/icon-font/README.md +27 -0
  91. data/logos/icon-font/build_font.py +130 -0
  92. data/logos/icon-font/galaaz-mark.svg +34 -0
  93. data/script/omarchy/README.md +9 -2
  94. data/script/omarchy/fonts/galaaz.ttf +0 -0
  95. data/script/omarchy/galaaz-guide.sh +1 -1
  96. data/script/omarchy/install-galaaz.sh +8 -1
  97. data/script/omarchy/omarchy-menu.jsonc +21 -9
  98. data/sty/galaaz-header.png +0 -0
  99. data/sty/galaaz-headers-from-p3.tex +4 -0
  100. data/sty/galaaz.sty +76 -23
  101. data/version.rb +1 -1
  102. metadata +46 -7
  103. data/blogs/galaaz_ggplot/galaaz_ggplot.log +0 -754
  104. data/blogs/manual/manual.log +0 -1786
  105. data/blogs/nse_dplyr/nse_dplyr.log +0 -928
  106. data/blogs/oh_my/oh_my.log +0 -804
  107. data/blogs/ruby_plot/ruby_plot.log +0 -885
@@ -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: "../../sty/galaaz.sty"
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
- **Python** remains a strong competitor for end-to-end data science stacks (NumPy, pandas,
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
- Ruby is a dynamic, object-oriented language that became widely known through **Ruby on Rails**
51
- (RoR). It remains a practical choice for web applications and general-purpose scripting.
52
- Until Galaaz, Ruby lacked a tight, ecosystem-complete bridge to GNU R. Library wrapping
53
- (one gem per package) does not scale; Galaaz wraps **the R language**, so thousands of R
54
- packages are available without a new handcrafted wrapper for each one.
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. Earlier GraalVM / TruffleRuby / FastR experiments
60
- are no longer the focus.
61
-
62
- The bridge handles **communication and typing** between the two worlds. Large tables can use
63
- **Apache Arrow** in two shipped modes (described later): **Stage A** copies Ruby batches into an
64
- R-side Arrow table (`R::Arrow.from_ruby_batches`); **Stage B** writes an Arrow IPC file and only
65
- the **path** crosses NewBridge (`Galaaz::ArrowIpc` + `R::Arrow.open_ipc` / `write_ipc`). Shared-heap
66
- zero-copy is **Stage C** and is not shipped.
67
-
68
- ## R-on-Rails: the one-person app for R scientists
69
-
70
- If you already think in R, the usual web options are painful: Shiny for some apps, or a full
71
- rewrite in another stack. **R-on-Rails** means:
72
-
73
- 1. **Keep your science in R** — packages, formulas, plots, Bioconductor, the same engine as RStudio.
74
- 2. **Learn enough Ruby/Rails** — routes, controllers, views, jobs, auth—not a second statistics career.
75
- 3. **Call R from the app** — Galaaz loads R behind the scenes; long jobs can complete asynchronously
76
- while Rails stays responsive (see later sections on the bridge, `R::Async`, and `R::Job`).
77
- 4. **Ship alone when you need to** — one developer can own both the analysis and the product UI,
78
- without waiting for a separate “stats engineer” and “Rails engineer.”
79
-
80
- Typical shape:
81
-
82
- - Interactive exploration and reports: **gstudio**, **gknit** (R Markdown with Ruby chunks).
83
- - Product: a **Rails** (or Sinatra) app that calls `R.*` for the heavy statistical steps.
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 or poppler for gKnit PDF. </td>
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;"> Thin wrapper that forces JRuby (same flags as galaaz-ruby under JRuby). </td>
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 when the interpreter is JRuby; sets GALAAZ_REQUIRED_JRUBY_J_ARGS. </td>
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-ruby` / `galaaz-jruby` examples** (from repo root):
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-ruby -S rspec
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 (ruby on PATH; JVM flags on JRuby). </td>
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 Ruby/JVM setup as tests. </td>
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; same GALAAZ_RUBY as other launchers). </td>
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 ruby on PATH (JRuby or CRuby) and R Markdown render. </td>
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-style templates; wrapper still uses legacy polyglot ruby. </td>
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 galaaz-ruby + LOAD_PATH). </td>
231
- <td style="text-align:left;"> Yes </td>
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`, `--output_dir`, `--bridge_timeout_sec`, `--callback_timeout_ms`. If `--output_format` is omitted, the **first** YAML `output:` target wins.
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/ together. </td>
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 with --jvm. Use galaaz-jruby -S instead. </td>
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 "puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
341
- # under JRuby: gem_dir="$(jruby -e "puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
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`** (or **`rake compile_gatekeeper`**).
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` (or
363
- `./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
364
- `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby` (or `./docker/try-cruby/run.sh`).
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**: **`R::Arrow.from_ruby_batches`** (Stage A: copy into R) or
461
- **`Galaaz::ArrowIpc.write` / `write_batches`** then **`R::Arrow.open_ipc`** (Stage B: IPC file;
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`. Stage B IPC tests: `specs/arrow_ipc_handoff_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 scopes (`R::Support.new_scope`),
488
- so async R calls must use **`R::Async`** or **`R.eval_r_async`**, not a bare **`R.foo` with a block.**
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; eval_r-style value: #{result.value.inspect}"
526
+ puts "[completion] R finished; value: " +
527
+ "#{result.value.inspect}"
506
528
  else
507
- puts "[completion] R/bridge error: #{result.error.class}: #{result.error.message}"
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; eval_r-style value: "[1] 42"
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 used for compile.
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
- coef = R::Job.eval(<<~R) { |job| job.load_rds }
565
- fit <- lm(mpg ~ wt, data = mtcars)
566
- saveRDS(unname(coef(fit)), result_path)
567
- R
568
- puts coef
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 Job
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 child
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(...)`** (or `R.*`) and return a result.
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 --skip-kamal --skip-solid --skip-active-record
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 "puts R.eval('sum(c(1,2,3,4,5))').inspect"
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 carb
722
- ## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
723
- ## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
724
- ## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
725
- ## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
726
- ## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
727
- ## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
728
- ## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
729
- ## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
730
- ## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
731
- ## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
732
- ## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
733
- ## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
734
- ## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
735
- ## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
736
- ## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
737
- ## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
738
- ## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
739
- ## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
740
- ## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
741
- ## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
742
- ## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
743
- ## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
744
- ## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
745
- ## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
746
- ## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
747
- ## Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
748
- ## Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
749
- ## Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
750
- ## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
751
- ## Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
752
- ## Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
753
- ## Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
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[mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"), ]
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 variable 'b' which has value:
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> --template <template> --package <package>
2203
- --create_dir
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 --template rjournal_article --package rticles
2209
- --create_dir
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(typeof: vec.typeof, mode: vec.mode, storage__mode: vec.storage__mode)
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(typeof: vec.typeof, mode: vec.mode, storage__mode: vec.storage__mode)
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
- vec = R.c(1, hello, 5)
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 15.2 10.4
3257
- ## [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
3258
- ## [31] 15.0 21.4
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 15.2 10.4
3270
- ## [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
3271
- ## [31] 15.0 21.4
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 TRUE
3315
- ## [13] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
3316
- ## [25] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
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 carb
3330
- ## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
3331
- ## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
3332
- ## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
3333
- ## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
3334
- ## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
3335
- ## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
3336
- ## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
3337
- ## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
3338
- ## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
3339
- ## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
3340
- ## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
3341
- ## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
3342
- ## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
3343
- ## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
3344
- ## Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
3345
- ## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
3346
- ## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
3347
- ## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
3348
- ## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
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 sched_arr_time
3554
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3555
- ## 1 2013 1 1 517 515 2 830 819
3556
- ## 2 2013 1 1 533 529 4 850 830
3557
- ## 3 2013 1 1 542 540 2 923 850
3558
- ## 4 2013 1 1 544 545 -1 1004 1022
3559
- ## 5 2013 1 1 554 600 -6 812 837
3560
- ## 6 2013 1 1 554 558 -4 740 728
3561
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3562
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3563
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3579
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3580
- ## 1 2013 1 1 517 515 2 830 819
3581
- ## 2 2013 1 1 533 529 4 850 830
3582
- ## 3 2013 1 1 542 540 2 923 850
3583
- ## 4 2013 1 1 544 545 -1 1004 1022
3584
- ## 5 2013 1 1 554 600 -6 812 837
3585
- ## 6 2013 1 1 554 558 -4 740 728
3586
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3587
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3588
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3603
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3604
- ## 1 2013 11 1 5 2359 6 352 345
3605
- ## 2 2013 11 1 35 2250 105 123 2356
3606
- ## 3 2013 11 1 455 500 -5 641 651
3607
- ## 4 2013 11 1 539 545 -6 856 827
3608
- ## 5 2013 11 1 542 545 -3 831 855
3609
- ## 6 2013 11 1 549 600 -11 912 923
3610
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3611
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3612
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3628
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3629
- ## 1 2013 11 1 5 2359 6 352 345
3630
- ## 2 2013 11 1 35 2250 105 123 2356
3631
- ## 3 2013 11 1 455 500 -5 641 651
3632
- ## 4 2013 11 1 539 545 -6 856 827
3633
- ## 5 2013 11 1 542 545 -3 831 855
3634
- ## 6 2013 11 1 549 600 -11 912 923
3635
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3636
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3637
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3704
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3705
- ## 1 2013 1 1 517 515 2 830 819
3706
- ## 2 2013 1 1 533 529 4 850 830
3707
- ## 3 2013 1 1 542 540 2 923 850
3708
- ## 4 2013 1 1 544 545 -1 1004 1022
3709
- ## 5 2013 1 1 554 600 -6 812 837
3710
- ## 6 2013 1 1 554 558 -4 740 728
3711
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3712
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3713
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3726
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3727
- ## 1 2013 1 9 641 900 1301 1242 1530
3728
- ## 2 2013 6 15 1432 1935 1137 1607 2120
3729
- ## 3 2013 1 10 1121 1635 1126 1239 1810
3730
- ## 4 2013 9 20 1139 1845 1014 1457 2210
3731
- ## 5 2013 7 22 845 1600 1005 1044 1815
3732
- ## 6 2013 4 10 1100 1900 960 1342 2211
3733
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3734
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3735
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3818
- ## <int> <int> <int> <int> <int> <dbl> <int> <int>
3819
- ## 1 2013 1 1 517 515 2 830 819
3820
- ## 2 2013 1 1 533 529 4 850 830
3821
- ## 3 2013 1 1 542 540 2 923 850
3822
- ## 4 2013 1 1 544 545 -1 1004 1022
3823
- ## 5 2013 1 1 554 600 -6 812 837
3824
- ## 6 2013 1 1 554 558 -4 740 728
3825
- ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
3826
- ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
3827
- ## # hour <dbl>, minute <dbl>, time_hour <dttm>
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 sched_arr_time
3958
- ## <int> <int> <int> <int> <int> <num> <int> <int>
3959
- ## 1: 2013 1 1 517 515 2 830 819
3960
- ## 2: 2013 1 1 533 529 4 850 830
3961
- ## 3: 2013 1 1 542 540 2 923 850
3962
- ## 4: 2013 1 1 544 545 -1 1004 1022
3963
- ## 5: 2013 1 1 554 600 -6 812 837
3964
- ## 6: 2013 1 1 554 558 -4 740 728
3965
- ## 7: 2013 1 1 555 600 -5 913 854
3966
- ## 8: 2013 1 1 557 600 -3 709 723
3967
- ## 9: 2013 1 1 557 600 -3 838 846
3968
- ## 10: 2013 1 1 558 600 -2 753 745
3969
- ## 11: 2013 1 1 558 600 -2 849 851
3970
- ## 12: 2013 1 1 558 600 -2 853 856
3971
- ## arr_delay carrier flight tailnum origin dest air_time distance hour
3972
- ## <num> <char> <int> <char> <char> <char> <num> <num> <num>
3973
- ## 1: 11 UA 1545 N14228 EWR IAH 227 1400 5
3974
- ## 2: 20 UA 1714 N24211 LGA IAH 227 1416 5
3975
- ## 3: 33 AA 1141 N619AA JFK MIA 160 1089 5
3976
- ## 4: -18 B6 725 N804JB JFK BQN 183 1576 5
3977
- ## 5: -25 DL 461 N668DN LGA ATL 116 762 6
3978
- ## 6: 12 UA 1696 N39463 EWR ORD 150 719 5
3979
- ## 7: 19 B6 507 N516JB EWR FLL 158 1065 6
3980
- ## 8: -14 EV 5708 N829AS LGA IAD 53 229 6
3981
- ## 9: -8 B6 79 N593JB JFK MCO 140 944 6
3982
- ## 10: 8 AA 301 N3ALAA LGA ORD 138 733 6
3983
- ## 11: -2 B6 49 N793JB JFK PBI 149 1028 6
3984
- ## 12: -3 B6 71 N657JB JFK TPA 158 1005 6
3985
- ## minute time_hour
3986
- ## <num> <POSc>
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 sched_arr_time
4044
- ## <int> <int> <int> <int> <int> <num> <int> <int>
4045
- ## 1: 2013 6 1 2 2359 3 341 350
4046
- ## 2: 2013 6 1 538 545 -7 925 922
4047
- ## 3: 2013 6 1 539 540 -1 832 840
4048
- ## 4: 2013 6 1 553 600 -7 700 711
4049
- ## 5: 2013 6 1 554 600 -6 851 908
4050
- ## 6: 2013 6 1 557 600 -3 934 942
4051
- ## arr_delay carrier flight tailnum origin dest air_time distance hour
4052
- ## <num> <char> <int> <char> <char> <char> <num> <num> <num>
4053
- ## 1: -9 B6 739 N618JB JFK PSE 200 1617 23
4054
- ## 2: 3 B6 725 N806JB JFK BQN 203 1576 5
4055
- ## 3: -8 AA 701 N5EAAA JFK MIA 140 1089 5
4056
- ## 4: -11 EV 5716 N835AS JFK IAD 42 228 6
4057
- ## 5: -17 UA 1159 N33132 JFK LAX 330 2475 6
4058
- ## 6: -8 B6 715 N766JB JFK SJU 198 1598 6
4059
- ## minute time_hour
4060
- ## <num> <POSc>
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 sched_arr_time
4068
- ## <int> <int> <int> <int> <int> <num> <int> <int>
4069
- ## 1: 2013 1 1 517 515 2 830 819
4070
- ## 2: 2013 1 1 533 529 4 850 830
4071
- ## arr_delay carrier flight tailnum origin dest air_time distance hour
4072
- ## <num> <char> <int> <char> <char> <char> <num> <num> <num>
4073
- ## 1: 11 UA 1545 N14228 EWR IAH 227 1400 5
4074
- ## 2: 20 UA 1714 N24211 LGA IAH 227 1416 5
4075
- ## minute time_hour
4076
- ## <num> <POSc>
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. GNU R still runs in a **separate process**. Ruby does **not** hold a
4113
- shared Arrow C++ table with R. Stages:
4114
-
4115
- 1. **Stage A (copy over the bridge):** Ruby row hashes → **`R::Arrow.from_ruby_batches`** builds
4116
- an Arrow `Table` **inside GNU R**. You get a **proxy**.
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
- ## Example: Stage B round-trip (IPC file)
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
- Requires `Galaaz::ArrowIpc.available?` (red-arrow or Arrow JARs) and R **`arrow`**. Not knitted
4161
- below so a machine without the optional backend still builds this manual.
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
- ```ruby
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
- summed = R.dplyr___summarise(R.dplyr___group_by(tbl, :grp), total: E.sum(:value))
4169
- out_path = R::Arrow.write_ipc(summed)
4170
- rows = Galaaz::ArrowIpc.read_batches(out_path)
4171
- Galaaz::ArrowIpc.release(out_path)
4172
- # rows => [{:grp=>"a", :total=>3.0}, {:grp=>"b", :total=>3.5}] (illustrative)
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`** (Stage A), then
4179
- checks that **dplyr** group summaries match a Ruby reference calculation. The same logic appears
4180
- below at a **smaller scale** so this manual can knit quickly; increase `thread_count` and
4181
- `rows_per_thread` when experimenting locally. For the same ingest **without** copying every cell
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
- unless R::Support.eval("requireNamespace('arrow', quietly=TRUE) && requireNamespace('dplyr', quietly=TRUE)") == true
4188
- puts '(Skip: need arrow + dplyr in R; use bin/galaaz-jruby outside gKnit.)'
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 (should equal #{thread_count * rows_per_thread}): #{total_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; (2) a single
4248
- **`from_ruby_batches`** call **copies** those columns into an Arrow table in R; (3) **`dplyr___group_by`** /
4249
- **`dplyr___summarise`** / **`dplyr___collect`** mirror **`dplyr::group_by`** /
4250
- **`dplyr::summarise`** / **`dplyr::collect`** on an Arrow-backed table. For a lighter test, see
4251
- **`specs/arrow_from_ruby_batches_spec.rb`**; for the full-size Stage A benchmark, run
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 examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
4281
- # or: bin/galaaz-jruby examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
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: examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
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): #{R.sum(res.padj < 0.05, na__rm: true)}"
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
- unless R::Support.eval("requireNamespace('DESeq2', quietly=TRUE) && requireNamespace('airway', quietly=TRUE)")
4353
- puts '(Skip: install DESeq2 and airway via BiocManager in R to run the full example.)'
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 SRR1039516
4369
- ## ENSG00000000003 679 448 873 408 1138
4370
- ## ENSG00000000005 0 0 0 0 0
4371
- ## ENSG00000000419 467 515 621 365 587
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`** (Stage A) or
4391
- **`Galaaz::ArrowIpc`** + **`R::Arrow.open_ipc`** (Stage B) instead of millions of tiny R calls.
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 carb
4430
- ## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3 4
4431
- ## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3 4
4432
- ## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3 4
4433
- ## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3 4
4434
- ## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3 4
4435
- ## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5 8
4436
- ## car_name mpg_z mpg_type
4437
- ## Cadillac Fleetwood Cadillac Fleetwood -1.61 below
4438
- ## Lincoln Continental Lincoln Continental -1.61 below
4439
- ## Camaro Z28 Camaro Z28 -1.13 below
4440
- ## Duster 360 Duster 360 -0.96 below
4441
- ## Chrysler Imperial Chrysler Imperial -0.89 below
4442
- ## Maserati Bora Maserati Bora -0.84 below
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(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
4465
- R.geom_bar(E.aes(fill: :mpg_type), stat: 'identity', width: 0.5) +
4466
- R.scale_fill_manual(name: 'Mileage',
4467
- labels: R.c('Above Average', 'Below Average'),
4468
- values: R.c('above': '#00ba38', 'below': '#f8766d')) +
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
- # Mutate column names are Ruby kwargs (y: …). Use .assign only for R `<-` expressions.
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
- mutate_y(df1)
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 height mass hair_color skin_color eye_color birth_year sex gender
4970
- ## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
4971
- ## 1 Luke Sky… 172 77 blond fair blue 19 male mascu…
4972
- ## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
4973
- ## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
4974
- ## 4 Darth Va… 202 136 none white yellow 41.9 male mascu…
4975
- ## 5 Leia Org… 150 49 brown light brown 19 fema… femin…
4976
- ## 6 Owen Lars 178 120 brown, gr… light blue 52 male mascu…
4977
- ## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
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 was
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(E.c(value_variables, "count"), ~R[:mean], na__rm: true).
5043
- rename_at(value_variables, E.funs(E.paste0("mean_", value_variables)))
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((~R[:starwars]), "eye_color", E.c("mass", "birth_year"))
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 JVM flags and the load path match **`docs/testing.md`**
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