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
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/blogs/manual/manual.Rmd
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
|
|
@@ -25,13 +30,20 @@ fontsize: 11pt
|
|
|
25
30
|
---
|
|
26
31
|
|
|
27
32
|
```{ruby setup, echo=FALSE}
|
|
28
|
-
# Bridge default
|
|
33
|
+
# Bridge default 60s; Arrow/dplyr pipes may need more.
|
|
29
34
|
ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] ||= '300'
|
|
35
|
+
# Writable jobs dir for R::Job demos when knitting (avoid Permission denied).
|
|
36
|
+
ENV['GALAAZ_JOBS_DIR'] ||= File.join(Dir.tmpdir, 'galaaz_jobs_manual')
|
|
30
37
|
|
|
31
|
-
R.options(crayon__enabled: false)
|
|
38
|
+
R.options(crayon__enabled: false, width: 70)
|
|
32
39
|
R.install_and_loads('kableExtra')
|
|
33
40
|
```
|
|
34
41
|
|
|
42
|
+
```{r brand_logo, echo=FALSE, fig.align='center', out.width='45%', eval=knitr::is_latex_output()}
|
|
43
|
+
# PDF only — HTML uses _logo_before_body.html (above the TOC).
|
|
44
|
+
knitr::include_graphics("images/galaaz-lockup-stacked.png")
|
|
45
|
+
```
|
|
46
|
+
|
|
35
47
|
# Introduction
|
|
36
48
|
|
|
37
49
|
Galaaz is a system for tightly coupling Ruby and R. Ruby is a powerful language, with a large
|
|
@@ -126,15 +138,20 @@ JRuby (`bin/galaaz_jruby_env.inc.sh` / `lib/galaaz_jruby.rb`). **`bin/galaaz-jru
|
|
|
126
138
|
|
|
127
139
|
```{r bin-tables-helper, echo=FALSE}
|
|
128
140
|
bin_tbl <- function(df) {
|
|
129
|
-
k <- knitr::kable(
|
|
130
|
-
|
|
141
|
+
k <- knitr::kable(
|
|
142
|
+
df, row.names = FALSE, booktabs = TRUE, linesep = "",
|
|
143
|
+
col.names = c("Script", "Role", "2.0?"))
|
|
131
144
|
if (knitr::is_latex_output()) {
|
|
132
|
-
k <- kableExtra::kable_styling(
|
|
145
|
+
k <- kableExtra::kable_styling(
|
|
146
|
+
k, font_size = 9, latex_options = "scale_down")
|
|
133
147
|
k <- kableExtra::column_spec(k, 1, width = "2.5cm")
|
|
134
148
|
k <- kableExtra::column_spec(k, 2, width = "9.5cm")
|
|
135
149
|
k <- kableExtra::column_spec(k, 3, width = "2.8cm")
|
|
136
150
|
} else {
|
|
137
|
-
k <- kableExtra::kable_styling(
|
|
151
|
+
k <- kableExtra::kable_styling(
|
|
152
|
+
k,
|
|
153
|
+
bootstrap_options = c("striped", "condensed"),
|
|
154
|
+
full_width = TRUE)
|
|
138
155
|
}
|
|
139
156
|
k
|
|
140
157
|
}
|
|
@@ -142,11 +159,13 @@ bin_tbl <- function(df) {
|
|
|
142
159
|
|
|
143
160
|
```{r bin-tables-bootstrap, echo=FALSE}
|
|
144
161
|
df_boot <- data.frame(
|
|
145
|
-
Script = c(
|
|
162
|
+
Script = c(
|
|
163
|
+
"galaaz-bootstrap", "galaaz-jruby",
|
|
164
|
+
"galaaz_jruby_env.inc.sh", "install-tinytex"),
|
|
146
165
|
Role = c(
|
|
147
|
-
"WSL2 helper: Docker checks; optional TinyTeX
|
|
148
|
-
"JRuby with repo lib/ on LOAD_PATH and
|
|
149
|
-
"Sourced by bash wrappers; sets
|
|
166
|
+
"WSL2 helper: Docker checks; optional TinyTeX/poppler.",
|
|
167
|
+
"JRuby with repo lib/ on LOAD_PATH and JVM flags.",
|
|
168
|
+
"Sourced by bash wrappers; sets JRUBY_J_ARGS.",
|
|
150
169
|
"Install TinyTeX for PDF output."
|
|
151
170
|
),
|
|
152
171
|
X2 = c("Yes*", "Yes", "Yes†", "Yes"),
|
|
@@ -189,7 +208,7 @@ df_gk <- data.frame(
|
|
|
189
208
|
Script = c("gknit", "gknit-draft", "gknit-draft.rb", "gknit_Rscript"),
|
|
190
209
|
Role = c(
|
|
191
210
|
"Knit .Rmd via JRuby and R Markdown render.",
|
|
192
|
-
"Drafts from rticles
|
|
211
|
+
"Drafts from rticles templates; legacy polyglot wrapper.",
|
|
193
212
|
"Ruby entry: GKnit.draft (use with JRuby + LOAD_PATH).",
|
|
194
213
|
"Polyglot Rscript launcher; hard-coded LOAD_PATH sample."
|
|
195
214
|
),
|
|
@@ -199,7 +218,9 @@ df_gk <- data.frame(
|
|
|
199
218
|
bin_tbl(df_gk)
|
|
200
219
|
```
|
|
201
220
|
|
|
202
|
-
**`gknit` CLI** (see `gknit -h`): `--output_format`, `--output_file`,
|
|
221
|
+
**`gknit` CLI** (see `gknit -h`): `--output_format`, `--output_file`,
|
|
222
|
+
`--output_dir`, `--bridge_timeout_sec`, `--callback_timeout_ms`.
|
|
223
|
+
If `--output_format` is omitted, the **first** YAML `output:` target wins.
|
|
203
224
|
|
|
204
225
|
Prefer **`galaaz-jruby`** for **`gknit-draft`** workflows until that wrapper matches the **`gknit`** stack.
|
|
205
226
|
|
|
@@ -207,10 +228,12 @@ Prefer **`galaaz-jruby`** for **`gknit-draft`** workflows until that wrapper mat
|
|
|
207
228
|
|
|
208
229
|
```{r bin-tables-tests, echo=FALSE}
|
|
209
230
|
df_ts <- data.frame(
|
|
210
|
-
Script = c(
|
|
231
|
+
Script = c(
|
|
232
|
+
"run_rspec", "run_all_rspec", "run_slow_rspec",
|
|
233
|
+
"run_old_rspec", "run_rspec_subset"),
|
|
211
234
|
Role = c(
|
|
212
235
|
"Top-level specs/*_spec.rb with spec_helper (see docs/testing.md).",
|
|
213
|
-
"Compile ext/new_bridge; run specs/ and new_bridge_specs
|
|
236
|
+
"Compile ext/new_bridge; run specs/ and new_bridge_specs/.",
|
|
214
237
|
"Suites under slow-specs/ (read script header for spec_helper).",
|
|
215
238
|
"Legacy suites under old_specs/.",
|
|
216
239
|
"Numbered subset 1–18 (Documentation/Spec_Subsets.md)."
|
|
@@ -227,7 +250,7 @@ bin_tbl(df_ts)
|
|
|
227
250
|
df_ot <- data.frame(
|
|
228
251
|
Script = c("grun", "gstudio_irb.rb / gstudio_pry.rb"),
|
|
229
252
|
Role = c(
|
|
230
|
-
"Graal-era launcher: polyglot ruby
|
|
253
|
+
"Graal-era launcher: polyglot ruby --jvm; prefer galaaz-jruby.",
|
|
231
254
|
"Loaded by gstudio; not meant to be run standalone."
|
|
232
255
|
),
|
|
233
256
|
X2 = c("No", "Yes"),
|
|
@@ -268,8 +291,9 @@ The supported install is **`gem install` + compile the gatekeeper**. You do not
|
|
|
268
291
|
4. Compile the native gatekeeper from the installed gem:
|
|
269
292
|
|
|
270
293
|
```
|
|
271
|
-
gem_dir="$(ruby -e
|
|
272
|
-
|
|
294
|
+
gem_dir="$(ruby -e \
|
|
295
|
+
"puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
|
|
296
|
+
# under JRuby: use jruby -e instead of ruby -e
|
|
273
297
|
make -C "${gem_dir}/ext/new_bridge" all
|
|
274
298
|
```
|
|
275
299
|
|
|
@@ -283,16 +307,18 @@ A **table of all `bin/` scripts** (bootstrap, Ruby launcher, gstudio, gknit, tes
|
|
|
283
307
|
|
|
284
308
|
1. Install **bundler** if needed, then run **`bundle install`** with your chosen Ruby
|
|
285
309
|
(`jruby -S bundle install` or CRuby `bundle install`) in the repository root.
|
|
286
|
-
2. Build the bridge native code: **`make -C ext/new_bridge all`**
|
|
310
|
+
2. Build the bridge native code: **`make -C ext/new_bridge all`**
|
|
311
|
+
(or **`rake compile_gatekeeper`**).
|
|
287
312
|
3. Run scripts with **`bin/galaaz-ruby`** (uses `ruby` on `PATH`; set **`GALAAZ_RUBY=jruby`** or
|
|
288
313
|
**`GALAAZ_RUBY=ruby`** to force an engine). Spec runners: **`bin/run_rspec`** /
|
|
289
314
|
**`bin/run_all_rspec`** (same `GALAAZ_RUBY` rule). **`bin/galaaz-jruby`** remains a thin
|
|
290
315
|
wrapper that forces JRuby.
|
|
291
316
|
|
|
292
317
|
A **gstudio** try image with Galaaz already installed is available for both engines:
|
|
293
|
-
**JRuby** — `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:gstudio`
|
|
294
|
-
`./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
|
|
295
|
-
`docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby`
|
|
318
|
+
**JRuby** — `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:gstudio`
|
|
319
|
+
(or `./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
|
|
320
|
+
`docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby`
|
|
321
|
+
(or `./docker/try-cruby/run.sh`).
|
|
296
322
|
Maintainers can prove a RubyGems install on a throwaway Ubuntu machine (no repo inside
|
|
297
323
|
the container) with `./docker/cold-install/run.sh published-specs` (JRuby) or
|
|
298
324
|
`./docker/cold-install-cruby/run.sh published-specs` (CRuby).
|
|
@@ -331,7 +357,8 @@ WSL integration is enabled for the distro where Galaaz is installed.
|
|
|
331
357
|
vec = R.c(1, 2, 3, 4)
|
|
332
358
|
puts vec
|
|
333
359
|
|
|
334
|
-
# R.foo(...) calls an R *function*. Datasets are objects — fetch with
|
|
360
|
+
# R.foo(...) calls an R *function*. Datasets are objects — fetch with
|
|
361
|
+
# ~:
|
|
335
362
|
df = ~R[:mtcars]
|
|
336
363
|
puts R.summary(df)
|
|
337
364
|
```
|
|
@@ -408,8 +435,9 @@ For R work that can take a long time **on the bridge**, the bridge can avoid a R
|
|
|
408
435
|
**`R.<rname>`**. Optional keyword **`timeout:`** applies a Ruby-side wait limit (completion receives
|
|
409
436
|
**`NewBridge::SessionClient::TimeoutError`** if R is too slow).
|
|
410
437
|
|
|
411
|
-
**Important:** **`R.foo(...) { |x| }`** is already used for dplyr-style
|
|
412
|
-
so async R calls must use **`R::Async`**
|
|
438
|
+
**Important:** **`R.foo(...) { |x| }`** is already used for dplyr-style
|
|
439
|
+
scopes (`R::Support.new_scope`), so async R calls must use **`R::Async`**
|
|
440
|
+
or **`R.eval_r_async`**, not a bare **`R.foo` with a block.**
|
|
413
441
|
|
|
414
442
|
`NewBridge::EvalResult` exposes **`#ok?`**, **`#value`**, and **`#error`**. The completion block runs on a
|
|
415
443
|
**background thread** (not the bridge reader thread).
|
|
@@ -425,9 +453,11 @@ completion = Queue.new
|
|
|
425
453
|
|
|
426
454
|
R.eval_r_async('({ Sys.sleep(0.3); 42L })', timeout: nil) do |result|
|
|
427
455
|
if result.ok?
|
|
428
|
-
puts "[completion] R finished;
|
|
456
|
+
puts "[completion] R finished; value: " +
|
|
457
|
+
"#{result.value.inspect}"
|
|
429
458
|
else
|
|
430
|
-
puts "[completion] R/bridge error:
|
|
459
|
+
puts "[completion] R/bridge error: " +
|
|
460
|
+
"#{result.error.class}: #{result.error.message}"
|
|
431
461
|
end
|
|
432
462
|
completion.push(:done)
|
|
433
463
|
end
|
|
@@ -466,7 +496,8 @@ finishes** (default: no wall-clock limit). Optional limit: `GALAAZ_INSTALL_TIMEO
|
|
|
466
496
|
Only one install runs at a time (`install.lock`).
|
|
467
497
|
|
|
468
498
|
```{ruby r_job_install_note, eval=FALSE}
|
|
469
|
-
# May take a long time the first time (e.g. caret); the bridge is not
|
|
499
|
+
# May take a long time the first time (e.g. caret); the bridge is not
|
|
500
|
+
# used for compile.
|
|
470
501
|
R.install_and_loads 'caret'
|
|
471
502
|
```
|
|
472
503
|
|
|
@@ -476,19 +507,26 @@ Prefer the **block** form (like `File.open`): await the child, yield the job, re
|
|
|
476
507
|
block’s value. Without a block, the methods still await by default and return the `Job`.
|
|
477
508
|
|
|
478
509
|
```{ruby r_job_eval_block}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
510
|
+
begin
|
|
511
|
+
coef = R::Job.eval(<<~R) { |job| job.load_rds }
|
|
512
|
+
fit <- lm(mpg ~ wt, data = mtcars)
|
|
513
|
+
saveRDS(unname(coef(fit)), result_path)
|
|
514
|
+
R
|
|
515
|
+
puts coef
|
|
516
|
+
rescue => e
|
|
517
|
+
puts e.class.to_s
|
|
518
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
519
|
+
end
|
|
484
520
|
```
|
|
485
521
|
|
|
486
522
|
```{ruby r_job_eval_no_block, eval=FALSE}
|
|
487
|
-
# Without a block: awaits (wait: true is the default) and returns the
|
|
523
|
+
# Without a block: awaits (wait: true is the default) and returns the
|
|
524
|
+
# Job
|
|
488
525
|
job = R::Job.eval(code)
|
|
489
526
|
job = R::Job.eval(code, wait: false) # start only; call job.wait later
|
|
490
527
|
|
|
491
|
-
# Script file; trailing args → commandArgs(trailingOnly=TRUE) in the
|
|
528
|
+
# Script file; trailing args → commandArgs(trailingOnly=TRUE) in the
|
|
529
|
+
# child
|
|
492
530
|
res = R::Job.script('train.R', '5') { |job| job.load_rds }
|
|
493
531
|
```
|
|
494
532
|
|
|
@@ -520,7 +558,8 @@ extension paths on JRuby, or deployment extras you do not need). A minimal app a
|
|
|
520
558
|
|
|
521
559
|
```bash
|
|
522
560
|
cd /home/rbotafogo/desenv_linux
|
|
523
|
-
jruby -S rails new hedi --skip-git --minimal
|
|
561
|
+
jruby -S rails new hedi --skip-git --minimal \
|
|
562
|
+
--skip-kamal --skip-solid --skip-active-record
|
|
524
563
|
```
|
|
525
564
|
|
|
526
565
|
Then install gems:
|
|
@@ -558,7 +597,8 @@ A direct smoke test from Rails runner:
|
|
|
558
597
|
|
|
559
598
|
```bash
|
|
560
599
|
cd /home/rbotafogo/desenv_linux/hedi
|
|
561
|
-
jruby -S bundle exec rails runner
|
|
600
|
+
jruby -S bundle exec rails runner \
|
|
601
|
+
"puts R.eval('sum(c(1,2,3,4,5))').inspect"
|
|
562
602
|
```
|
|
563
603
|
|
|
564
604
|
Expected output:
|
|
@@ -1028,7 +1068,9 @@ a linear regression line (method = "lm") for every manufacturer.
|
|
|
1028
1068
|
library(ggplot2)
|
|
1029
1069
|
data(mpg, package="ggplot2")
|
|
1030
1070
|
|
|
1031
|
-
mpg_select <- mpg[
|
|
1071
|
+
mpg_select <- mpg[
|
|
1072
|
+
mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"),
|
|
1073
|
+
]
|
|
1032
1074
|
|
|
1033
1075
|
# Scatterplot
|
|
1034
1076
|
theme_set(theme_bw()) # pre-set the bw theme.
|
|
@@ -1096,7 +1138,8 @@ with the 'rb' engine. The following chunk specification will
|
|
|
1096
1138
|
create and inline Ruby text:
|
|
1097
1139
|
|
|
1098
1140
|
````
|
|
1099
|
-
This is some text with inline Ruby accessing
|
|
1141
|
+
This is some text with inline Ruby accessing
|
|
1142
|
+
variable 'b' which has value:
|
|
1100
1143
|
```{rb puts "```{rb puts b}\n```"}
|
|
1101
1144
|
```
|
|
1102
1145
|
and is followed by some other text!
|
|
@@ -1347,14 +1390,16 @@ templates for the following journals with the respective template name:
|
|
|
1347
1390
|
In order to create a document with one of those templates, use the following command:
|
|
1348
1391
|
|
|
1349
1392
|
```
|
|
1350
|
-
gknit-draft --filename <my_document>
|
|
1351
|
-
|
|
1393
|
+
gknit-draft --filename <my_document> \
|
|
1394
|
+
--template <template> --package <package> \
|
|
1395
|
+
--create_dir
|
|
1352
1396
|
```
|
|
1353
1397
|
So, in order to create a template for writing an R Journal, use:
|
|
1354
1398
|
|
|
1355
1399
|
```
|
|
1356
|
-
gknit-draft --filename my_r_article
|
|
1357
|
-
|
|
1400
|
+
gknit-draft --filename my_r_article \
|
|
1401
|
+
--template rjournal_article --package rticles \
|
|
1402
|
+
--create_dir
|
|
1358
1403
|
```
|
|
1359
1404
|
|
|
1360
1405
|
# Accessing R variables
|
|
@@ -1411,7 +1456,10 @@ Data frames will later be more carefully described. In R, the method used to cr
|
|
|
1411
1456
|
data frame is 'data.frame', in Galaaz we use 'data\_\_frame'.
|
|
1412
1457
|
|
|
1413
1458
|
```{ruby typeof_integer}
|
|
1414
|
-
df = R.data__frame(
|
|
1459
|
+
df = R.data__frame(
|
|
1460
|
+
typeof: vec.typeof,
|
|
1461
|
+
mode: vec.mode,
|
|
1462
|
+
storage__mode: vec.storage__mode)
|
|
1415
1463
|
puts df
|
|
1416
1464
|
```
|
|
1417
1465
|
|
|
@@ -1426,7 +1474,10 @@ puts vec
|
|
|
1426
1474
|
```
|
|
1427
1475
|
|
|
1428
1476
|
```{ruby typeof_float}
|
|
1429
|
-
df = R.data__frame(
|
|
1477
|
+
df = R.data__frame(
|
|
1478
|
+
typeof: vec.typeof,
|
|
1479
|
+
mode: vec.mode,
|
|
1480
|
+
storage__mode: vec.storage__mode)
|
|
1430
1481
|
outputs df.kable.kable_styling
|
|
1431
1482
|
```
|
|
1432
1483
|
|
|
@@ -1436,7 +1487,12 @@ the first with a message explaining what went wrong and the second with the full
|
|
|
1436
1487
|
of the error.
|
|
1437
1488
|
|
|
1438
1489
|
```{ruby r_exception}
|
|
1439
|
-
|
|
1490
|
+
begin
|
|
1491
|
+
vec = R.c(1, hello, 5)
|
|
1492
|
+
rescue => e
|
|
1493
|
+
puts e.class.to_s
|
|
1494
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
1495
|
+
end
|
|
1440
1496
|
```
|
|
1441
1497
|
|
|
1442
1498
|
Here is a vector with logical values
|
|
@@ -2120,8 +2176,12 @@ when experimenting locally.
|
|
|
2120
2176
|
|
|
2121
2177
|
```{ruby arrow_pipeline_example, message=FALSE, warning=FALSE}
|
|
2122
2178
|
# Scaled-down version of slow-specs/arrow_large_pipeline_spec.rb.
|
|
2123
|
-
|
|
2124
|
-
|
|
2179
|
+
arrow_ok = R::Support.eval(
|
|
2180
|
+
"requireNamespace('arrow', quietly=TRUE) && " +
|
|
2181
|
+
"requireNamespace('dplyr', quietly=TRUE)")
|
|
2182
|
+
unless arrow_ok == true
|
|
2183
|
+
puts '(Skip: need arrow + dplyr in R; ' +
|
|
2184
|
+
'use bin/galaaz-jruby outside gKnit.)'
|
|
2125
2185
|
else
|
|
2126
2186
|
thread_count = 4
|
|
2127
2187
|
rows_per_thread = 500
|
|
@@ -2164,15 +2224,19 @@ else
|
|
|
2164
2224
|
|
|
2165
2225
|
total_n = 0
|
|
2166
2226
|
(1..(out.nrow >> 0)).each { |i| total_n += (out[['n']][i] >> 0) }
|
|
2167
|
-
puts "Sum of group counts n
|
|
2227
|
+
puts "Sum of group counts n " +
|
|
2228
|
+
"(should equal #{thread_count * rows_per_thread}): " +
|
|
2229
|
+
"#{total_n}"
|
|
2168
2230
|
end
|
|
2169
2231
|
```
|
|
2170
2232
|
|
|
2171
|
-
**What to notice:** (1) Ruby only sees **`Hash`** rows and Ruby **`Thread`** objects;
|
|
2172
|
-
**`from_ruby_batches`** call creates the Arrow table in R;
|
|
2173
|
-
**`
|
|
2174
|
-
**`dplyr::summarise`** / **`dplyr::collect`**
|
|
2175
|
-
|
|
2233
|
+
**What to notice:** (1) Ruby only sees **`Hash`** rows and Ruby **`Thread`** objects;
|
|
2234
|
+
(2) a single **`from_ruby_batches`** call creates the Arrow table in R;
|
|
2235
|
+
(3) **`dplyr___group_by`** / **`dplyr___summarise`** / **`dplyr___collect`**
|
|
2236
|
+
mirror **`dplyr::group_by`** / **`dplyr::summarise`** / **`dplyr::collect`**
|
|
2237
|
+
on an Arrow-backed table. For a lighter test, see
|
|
2238
|
+
**`specs/arrow_from_ruby_batches_spec.rb`**;
|
|
2239
|
+
for the full-size benchmark, run
|
|
2176
2240
|
**`bin/run_slow_rspec slow-specs/arrow_large_pipeline_spec.rb`**.
|
|
2177
2241
|
|
|
2178
2242
|
# Bioconductor and DESeq2
|
|
@@ -2201,8 +2265,10 @@ The script **`examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb`** is
|
|
|
2201
2265
|
version in the repository. Run it from the **Galaaz repository root** with either engine, for example:
|
|
2202
2266
|
|
|
2203
2267
|
```text
|
|
2204
|
-
bin/galaaz-ruby
|
|
2205
|
-
|
|
2268
|
+
bin/galaaz-ruby \
|
|
2269
|
+
examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
2270
|
+
# or: bin/galaaz-jruby \
|
|
2271
|
+
# examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
2206
2272
|
```
|
|
2207
2273
|
|
|
2208
2274
|
The workflow in Ruby mirrors a standard DESeq2 vignette:
|
|
@@ -2229,7 +2295,8 @@ Below is the full listing (same as the file in the repository). It is **not** ex
|
|
|
2229
2295
|
manual is knitted, because **DESeq2** is heavy and may be absent on the build machine.
|
|
2230
2296
|
|
|
2231
2297
|
```{ruby deseq2_airway_full_listing, eval=FALSE}
|
|
2232
|
-
# Canonical script:
|
|
2298
|
+
# Canonical script:
|
|
2299
|
+
# examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
|
|
2233
2300
|
# Run: bin/galaaz-ruby examples/.../deseq2_airway_galaaz.rb (repo root).
|
|
2234
2301
|
|
|
2235
2302
|
require 'galaaz'
|
|
@@ -2256,7 +2323,8 @@ puts "Samples: #{R.ncol(dds)}"
|
|
|
2256
2323
|
puts "Genes after prefilter: #{R.nrow(dds)}"
|
|
2257
2324
|
puts "Result rows: #{R.nrow(res)}"
|
|
2258
2325
|
puts "Result columns: #{R.colnames(res)}"
|
|
2259
|
-
puts "Significant genes (padj < 0.05):
|
|
2326
|
+
puts "Significant genes (padj < 0.05): " +
|
|
2327
|
+
"#{R.sum(res.padj < 0.05, na__rm: true)}"
|
|
2260
2328
|
|
|
2261
2329
|
res_ordered = res[R.order(res.padj), :all]
|
|
2262
2330
|
puts R.head(R.as__data__frame(res_ordered), 10)
|
|
@@ -2271,8 +2339,12 @@ If **DESeq2** and **airway** are installed, the next chunk loads the data and pr
|
|
|
2271
2339
|
preview (it does **not** run **`DESeq`** so the manual knits quickly).
|
|
2272
2340
|
|
|
2273
2341
|
```{ruby deseq2_airway_smoke, message=FALSE, warning=FALSE}
|
|
2274
|
-
|
|
2275
|
-
|
|
2342
|
+
deseq_ok = R::Support.eval(
|
|
2343
|
+
"requireNamespace('DESeq2', quietly=TRUE) && " +
|
|
2344
|
+
"requireNamespace('airway', quietly=TRUE)")
|
|
2345
|
+
unless deseq_ok
|
|
2346
|
+
puts '(Skip: install DESeq2 and airway via ' +
|
|
2347
|
+
'BiocManager in R for the full example.)'
|
|
2276
2348
|
else
|
|
2277
2349
|
R.library('DESeq2')
|
|
2278
2350
|
R.library('airway')
|
|
@@ -2350,13 +2422,17 @@ but in this graph we want the bars to be horizontally laid so we add 'coord\_fli
|
|
|
2350
2422
|
```{ruby diverging_bar, fig.width = 9.1, fig.height = 6.5}
|
|
2351
2423
|
require 'ggplot'
|
|
2352
2424
|
|
|
2353
|
-
puts mtcars.ggplot(
|
|
2354
|
-
|
|
2355
|
-
R.
|
|
2356
|
-
|
|
2357
|
-
|
|
2425
|
+
puts mtcars.ggplot(
|
|
2426
|
+
E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
|
|
2427
|
+
R.geom_bar(E.aes(fill: :mpg_type),
|
|
2428
|
+
stat: 'identity', width: 0.5) +
|
|
2429
|
+
R.scale_fill_manual(
|
|
2430
|
+
name: 'Mileage',
|
|
2431
|
+
labels: R.c('Above Average', 'Below Average'),
|
|
2432
|
+
values: R.c('above': '#00ba38',
|
|
2433
|
+
'below': '#f8766d')) +
|
|
2358
2434
|
R.labs(subtitle: "Normalised mileage from 'mtcars'",
|
|
2359
|
-
title: "Diverging Bars") +
|
|
2435
|
+
title: "Diverging Bars") +
|
|
2360
2436
|
R.coord_flip
|
|
2361
2437
|
```
|
|
2362
2438
|
|
|
@@ -2448,7 +2524,8 @@ In Galaaz the method mutate_y below will work fine and will never fail silently.
|
|
|
2448
2524
|
|
|
2449
2525
|
```{ruby mutate_y, warning=FALSE}
|
|
2450
2526
|
def mutate_y(df)
|
|
2451
|
-
#
|
|
2527
|
+
# Column names are Ruby kwargs (y: …).
|
|
2528
|
+
# Use .assign only for R `<-` expressions.
|
|
2452
2529
|
df.mutate(y: R[:a] + R[:x])
|
|
2453
2530
|
end
|
|
2454
2531
|
```
|
|
@@ -2465,7 +2542,12 @@ definition of 'mutate\_y' above:
|
|
|
2465
2542
|
|
|
2466
2543
|
```{ruby call_mutate_y, warning = FALSE}
|
|
2467
2544
|
a = 10
|
|
2468
|
-
|
|
2545
|
+
begin
|
|
2546
|
+
mutate_y(df1)
|
|
2547
|
+
rescue => e
|
|
2548
|
+
puts e.class.to_s
|
|
2549
|
+
e.message.to_s.scan(/.{1,68}/).each { |line| puts line }
|
|
2550
|
+
end
|
|
2469
2551
|
```
|
|
2470
2552
|
## Different expressions
|
|
2471
2553
|
|
|
@@ -2736,11 +2818,19 @@ def grouped_mean(data, grouping_variables, value_variables)
|
|
|
2736
2818
|
data.
|
|
2737
2819
|
group_by_at(grouping_variables).
|
|
2738
2820
|
mutate(count: E.n).
|
|
2739
|
-
summarise_at(
|
|
2740
|
-
|
|
2821
|
+
summarise_at(
|
|
2822
|
+
E.c(value_variables, "count"),
|
|
2823
|
+
~R[:mean],
|
|
2824
|
+
na__rm: true).
|
|
2825
|
+
rename_at(
|
|
2826
|
+
value_variables,
|
|
2827
|
+
E.funs(E.paste0("mean_", value_variables)))
|
|
2741
2828
|
end
|
|
2742
2829
|
|
|
2743
|
-
puts grouped_mean(
|
|
2830
|
+
puts grouped_mean(
|
|
2831
|
+
(~R[:starwars]),
|
|
2832
|
+
"eye_color",
|
|
2833
|
+
E.c("mass", "birth_year"))
|
|
2744
2834
|
```
|
|
2745
2835
|
|
|
2746
2836
|
The examples above cover programmatic dplyr with string column names and `_at` helpers. The same
|