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
@@ -25,13 +30,20 @@ fontsize: 11pt
25
30
  ---
26
31
 
27
32
  ```{ruby setup, echo=FALSE}
28
- # Bridge default is 60s; some chunks (Arrow, large dplyr pipes) need more.
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(df, row.names = FALSE, booktabs = TRUE, linesep = "",
130
- col.names = c("Script", "Role", "2.0?"))
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(k, font_size = 9, latex_options = "scale_down")
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(k, bootstrap_options = c("striped", "condensed"), full_width = TRUE)
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("galaaz-bootstrap", "galaaz-jruby", "galaaz_jruby_env.inc.sh", "install-tinytex"),
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 or poppler for gKnit PDF.",
148
- "JRuby with repo lib/ on LOAD_PATH and required JVM flags (e.g. Arrow).",
149
- "Sourced by bash wrappers; sets GALAAZ_REQUIRED_JRUBY_J_ARGS.",
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-style templates; wrapper still uses legacy polyglot ruby.",
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`, `--output_dir`, `--bridge_timeout_sec`, `--callback_timeout_ms`. If `--output_format` is omitted, the **first** YAML `output:` target wins.
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("run_rspec", "run_all_rspec", "run_slow_rspec", "run_old_rspec", "run_rspec_subset"),
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/ together.",
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 with --jvm. Use galaaz-jruby -S instead.",
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 "puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
272
- # under JRuby: gem_dir="$(jruby -e "puts Gem::Specification.find_by_name('galaaz').full_gem_path")"
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`** (or **`rake compile_gatekeeper`**).
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` (or
294
- `./docker/try-gstudio/run.sh` from a checkout); **CRuby** —
295
- `docker run --rm -it ghcr.io/rbotafogo/galaaz-try:cruby` (or `./docker/try-cruby/run.sh`).
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 scopes (`R::Support.new_scope`),
412
- so async R calls must use **`R::Async`** or **`R.eval_r_async`**, not a bare **`R.foo` with a block.**
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; eval_r-style value: #{result.value.inspect}"
456
+ puts "[completion] R finished; value: " +
457
+ "#{result.value.inspect}"
429
458
  else
430
- puts "[completion] R/bridge error: #{result.error.class}: #{result.error.message}"
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 used for compile.
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
- coef = R::Job.eval(<<~R) { |job| job.load_rds }
480
- fit <- lm(mpg ~ wt, data = mtcars)
481
- saveRDS(unname(coef(fit)), result_path)
482
- R
483
- puts coef
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 Job
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 child
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 --skip-kamal --skip-solid --skip-active-record
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 "puts R.eval('sum(c(1,2,3,4,5))').inspect"
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[mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"), ]
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 variable 'b' which has value:
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> --template <template> --package <package>
1351
- --create_dir
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 --template rjournal_article --package rticles
1357
- --create_dir
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(typeof: vec.typeof, mode: vec.mode, storage__mode: vec.storage__mode)
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(typeof: vec.typeof, mode: vec.mode, storage__mode: vec.storage__mode)
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
- vec = R.c(1, hello, 5)
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
- unless R::Support.eval("requireNamespace('arrow', quietly=TRUE) && requireNamespace('dplyr', quietly=TRUE)") == true
2124
- puts '(Skip: need arrow + dplyr in R; use bin/galaaz-jruby outside gKnit.)'
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 (should equal #{thread_count * rows_per_thread}): #{total_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; (2) a single
2172
- **`from_ruby_batches`** call creates the Arrow table in R; (3) **`dplyr___group_by`** /
2173
- **`dplyr___summarise`** / **`dplyr___collect`** mirror **`dplyr::group_by`** /
2174
- **`dplyr::summarise`** / **`dplyr::collect`** on an Arrow-backed table. For a lighter test, see
2175
- **`specs/arrow_from_ruby_batches_spec.rb`**; for the full-size benchmark, run
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 examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
2205
- # or: bin/galaaz-jruby examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
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: examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb
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): #{R.sum(res.padj < 0.05, na__rm: true)}"
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
- unless R::Support.eval("requireNamespace('DESeq2', quietly=TRUE) && requireNamespace('airway', quietly=TRUE)")
2275
- puts '(Skip: install DESeq2 and airway via BiocManager in R to run the full example.)'
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(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
2354
- R.geom_bar(E.aes(fill: :mpg_type), stat: 'identity', width: 0.5) +
2355
- R.scale_fill_manual(name: 'Mileage',
2356
- labels: R.c('Above Average', 'Below Average'),
2357
- values: R.c('above': '#00ba38', 'below': '#f8766d')) +
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
- # Mutate column names are Ruby kwargs (y: …). Use .assign only for R `<-` expressions.
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
- mutate_y(df1)
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(E.c(value_variables, "count"), ~R[:mean], na__rm: true).
2740
- rename_at(value_variables, E.funs(E.paste0("mean_", value_variables)))
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((~R[:starwars]), "eye_color", E.c("mass", "birth_year"))
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