galaaz 0.5.0 → 2.1.0

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 (378) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/LICENSE +0 -0
  4. data/README.md +1416 -667
  5. data/Rakefile +68 -41
  6. data/bin/galaaz-bootstrap +137 -0
  7. data/bin/galaaz-jruby +11 -0
  8. data/bin/galaaz-ruby +16 -0
  9. data/bin/galaaz_jruby_env.inc.sh +6 -0
  10. data/bin/galaaz_ruby_env.inc.sh +36 -0
  11. data/bin/gbookdown +63 -0
  12. data/bin/gknit +83 -13
  13. data/bin/gknit-draft.rb +0 -0
  14. data/bin/gstudio +5 -3
  15. data/bin/gstudio_irb.rb +0 -0
  16. data/bin/gstudio_pry.rb +0 -0
  17. data/bin/install-tinytex +6 -0
  18. data/bin/run_all_rspec +44 -0
  19. data/bin/run_example +17 -0
  20. data/bin/run_old_rspec +20 -0
  21. data/bin/run_rspec +24 -0
  22. data/bin/run_rspec_subset +38 -0
  23. data/bin/run_slow_rspec +20 -0
  24. data/blogs/R-on-Rails-Planning-Document.md +940 -0
  25. data/blogs/README.md +100 -0
  26. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
  27. data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
  28. data/blogs/galaaz_ggplot/galaaz_ggplot.md +115 -155
  29. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
  30. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-gfm/midwest_rb.png +0 -0
  31. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-gfm/scatter_plot_rb.png +0 -0
  32. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
  33. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
  34. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
  35. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
  36. data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
  37. data/blogs/galaaz_ggplot/midwest_external_png +0 -0
  38. data/blogs/gknit/gknit.Rmd +47 -52
  39. data/blogs/gknit/gknit.md +1430 -0
  40. data/blogs/gknit/gknit_files/figure-gfm/bubble-1.png +0 -0
  41. data/blogs/gknit/gknit_files/figure-gfm/diverging_bar.png +0 -0
  42. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  43. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  44. data/blogs/gknit/lst.rds +0 -0
  45. data/blogs/gknit/model.rb +1 -1
  46. data/blogs/gknit/stats.bib +0 -0
  47. data/blogs/manual/include_model_local_repro.Rmd +14 -0
  48. data/blogs/manual/include_model_local_repro.md +75 -0
  49. data/blogs/manual/lst.rds +0 -0
  50. data/blogs/manual/manual.Rmd +855 -239
  51. data/blogs/manual/manual.log +1786 -0
  52. data/blogs/manual/manual.md +1416 -667
  53. data/blogs/manual/manual.tex +1883 -1161
  54. data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
  55. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  56. data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
  57. data/blogs/manual/model.rb +1 -1
  58. data/blogs/nse_dplyr/nse_dplyr.Rmd +84 -111
  59. data/blogs/nse_dplyr/nse_dplyr.log +928 -0
  60. data/blogs/nse_dplyr/nse_dplyr.md +198 -229
  61. data/blogs/oh_my/not_so.rb +0 -0
  62. data/blogs/oh_my/oh_my.Rmd +1234 -25
  63. data/blogs/oh_my/oh_my.log +804 -0
  64. data/blogs/oh_my/oh_my.md +1663 -86
  65. data/blogs/oh_my/oh_my.tex +821 -0
  66. data/blogs/oh_my/old.Rmd +15 -14
  67. data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
  68. data/blogs/ruby_plot/ruby_plot.log +885 -0
  69. data/blogs/ruby_plot/ruby_plot.md +71 -102
  70. data/blogs/ruby_plot/ruby_plot.tex +940 -0
  71. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/dose_len.png +0 -0
  72. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facet_by_delivery.png +0 -0
  73. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facet_by_dose.png +0 -0
  74. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_by_delivery_color.png +0 -0
  75. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_by_delivery_color2.png +0 -0
  76. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_decorations.png +0 -0
  77. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_jitter.png +0 -0
  78. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_points.png +0 -0
  79. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/final_box_plot.png +0 -0
  80. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/final_violin_plot.png +0 -0
  81. data/blogs/ruby_plot/ruby_plot_files/figure-gfm/violin_with_jitter.png +0 -0
  82. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  83. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  84. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  85. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  86. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  87. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  88. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  89. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  90. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  91. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  92. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  93. data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
  94. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  95. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  96. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  97. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  98. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  99. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  100. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  101. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  102. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  103. data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  104. data/blogs/test/test.Rmd +14 -0
  105. data/blogs/test/test.md +10 -0
  106. data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
  107. data/examples/50Plots_MasterList/ScatterPlot.rb +2 -1
  108. data/examples/50Plots_MasterList/scatter_plot.rb +1 -0
  109. data/examples/Bibliography/master.bib +0 -0
  110. data/examples/Bibliography/stats.bib +0 -0
  111. data/examples/R/calc.R +0 -0
  112. data/examples/R/java_interop.R +0 -0
  113. data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
  114. data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +54 -0
  115. data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
  116. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +34 -0
  117. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +35 -0
  118. data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
  119. data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
  120. data/examples/islr/all.rb +14 -0
  121. data/examples/islr/ch2.spec.rb +38 -7
  122. data/examples/islr/ch3.spec.rb +12 -2
  123. data/examples/islr/ch3_boston.rb +28 -0
  124. data/examples/islr/ch3_multiple_regression.rb +1 -0
  125. data/examples/islr/ch6.spec.rb +25 -1
  126. data/examples/islr/x_y_rnorm.jpg +0 -0
  127. data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +0 -0
  128. data/examples/latex_templates/Test-acm_article/sigproc.bib +0 -0
  129. data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +0 -0
  130. data/examples/latex_templates/Test-acs_article/acs-my_output.bib +0 -0
  131. data/examples/latex_templates/Test-aea_article/BibFile.bib +0 -0
  132. data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +0 -0
  133. data/examples/latex_templates/Test-aea_article/references.bib +0 -0
  134. data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +0 -0
  135. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +0 -0
  136. data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +0 -0
  137. data/examples/latex_templates/Test-ieee_article/mybibfile.bib +0 -0
  138. data/examples/latex_templates/Test-rjournal_article/RJournal.sty +0 -0
  139. data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +0 -0
  140. data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +0 -0
  141. data/examples/misc/baseball.csv +0 -0
  142. data/examples/misc/ggplot.rb +5 -3
  143. data/examples/misc/moneyball.rb +1 -0
  144. data/examples/misc/subsetting.rb +1 -0
  145. data/examples/multithread_shards_to_r/shards_to_r.rb +68 -0
  146. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +0 -0
  147. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +0 -0
  148. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +0 -0
  149. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +0 -0
  150. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +0 -0
  151. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +0 -0
  152. data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +0 -0
  153. data/examples/sthda_ggplot/README.md +0 -0
  154. data/examples/sthda_ggplot/RUN.md +41 -0
  155. data/examples/sthda_ggplot/all.rb +1 -0
  156. data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +1 -0
  157. data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +1 -0
  158. data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +3 -0
  159. data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +1 -0
  160. data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +1 -0
  161. data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +1 -0
  162. data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +1 -0
  163. data/examples/sthda_ggplot/one_variable_continuous/stat.rb +1 -0
  164. data/examples/sthda_ggplot/one_variable_discrete/bar.rb +1 -0
  165. data/examples/sthda_ggplot/qplots/box_violin_dot.rb +1 -0
  166. data/examples/sthda_ggplot/qplots/scatter_plots.rb +1 -0
  167. data/examples/sthda_ggplot/scatter_gg.rb +1 -0
  168. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +1 -0
  169. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +1 -0
  170. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +1 -0
  171. data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +1 -0
  172. data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +1 -0
  173. data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +1 -0
  174. data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +5 -3
  175. data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +1 -0
  176. data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +1 -0
  177. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +1 -0
  178. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +1 -0
  179. data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +1 -0
  180. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +1 -0
  181. data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +1 -0
  182. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +1 -0
  183. data/ext/new_bridge/Makefile +46 -0
  184. data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
  185. data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
  186. data/lib/R_interface/galaaz_device.R +20 -0
  187. data/lib/R_interface/include_engine.R +109 -0
  188. data/lib/R_interface/new_bridge_adapter.rb +824 -0
  189. data/lib/R_interface/r.rb +177 -25
  190. data/lib/R_interface/r_arrow.rb +113 -0
  191. data/lib/R_interface/r_libs.R +3 -3
  192. data/lib/R_interface/r_methods.rb +13 -126
  193. data/lib/R_interface/r_module_s.rb +0 -0
  194. data/lib/R_interface/rbinary_operators.rb +20 -2
  195. data/lib/R_interface/rclosure.rb +5 -1
  196. data/lib/R_interface/rdata_frame.rb +34 -70
  197. data/lib/R_interface/rdevice.rb +125 -0
  198. data/lib/R_interface/rdevices.R +0 -0
  199. data/lib/R_interface/renvironment.rb +10 -4
  200. data/lib/R_interface/rexpression.rb +5 -1
  201. data/lib/R_interface/rindexed_object.rb +41 -13
  202. data/lib/R_interface/rlanguage.rb +20 -62
  203. data/lib/R_interface/rlist.rb +115 -25
  204. data/lib/R_interface/rlogical_operators.rb +0 -0
  205. data/lib/R_interface/rmatrix.rb +2 -11
  206. data/lib/R_interface/rmd_indexed_object.rb +5 -1
  207. data/lib/R_interface/robject.rb +348 -290
  208. data/lib/R_interface/rpkg.rb +0 -0
  209. data/lib/R_interface/rsupport.rb +609 -328
  210. data/lib/R_interface/rsupport_scope.rb +2 -1
  211. data/lib/R_interface/rsymbol.rb +50 -0
  212. data/lib/R_interface/ruby_callback.rb +2 -3
  213. data/lib/R_interface/ruby_extensions.rb +225 -175
  214. data/lib/R_interface/runary_operators.rb +0 -0
  215. data/lib/R_interface/rvector.rb +162 -31
  216. data/lib/galaaz.rb +0 -0
  217. data/lib/galaaz_jruby.rb +22 -0
  218. data/lib/galaaz_ruby.rb +34 -0
  219. data/lib/gknit/diagnostics.rb +50 -0
  220. data/lib/gknit/draft.rb +23 -17
  221. data/lib/gknit/include_engine.rb +15 -7
  222. data/lib/gknit/knitr_engine.rb +223 -74
  223. data/lib/gknit/rb_engine.rb +3 -3
  224. data/lib/gknit/ruby_engine.rb +0 -0
  225. data/lib/gknit.rb +1 -0
  226. data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
  227. data/lib/new_bridge/envelope.rb +51 -0
  228. data/lib/new_bridge/eval_result.rb +26 -0
  229. data/lib/new_bridge/framing.rb +39 -0
  230. data/lib/new_bridge/instance_pool_client.rb +38 -0
  231. data/lib/new_bridge/r_instance_manager.rb +404 -0
  232. data/lib/new_bridge/session_client.rb +530 -0
  233. data/lib/new_bridge/tcp_framed.rb +44 -0
  234. data/lib/new_bridge.rb +9 -0
  235. data/lib/util/exec_ruby.rb +95 -20
  236. data/lib/util/inline_file.rb +35 -30
  237. data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
  238. data/new_bridge_specs/eval_r_async_spec.rb +113 -0
  239. data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
  240. data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
  241. data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
  242. data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
  243. data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
  244. data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
  245. data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
  246. data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
  247. data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
  248. data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
  249. data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
  250. data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
  251. data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
  252. data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
  253. data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
  254. data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
  255. data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
  256. data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
  257. data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
  258. data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
  259. data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
  260. data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
  261. data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
  262. data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
  263. data/r_requires/ggplot.rb +0 -0
  264. data/r_requires/knitr.rb +0 -0
  265. data/specs/all.rb +15 -11
  266. data/specs/arrow_from_ruby_batches_spec.rb +50 -0
  267. data/specs/arrow_semantics_spec.rb +64 -0
  268. data/specs/bridge_concurrent_spec.rb +46 -0
  269. data/specs/bridge_nested_spec.rb +25 -0
  270. data/specs/dataframe_semantics_spec.rb +122 -0
  271. data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
  272. data/specs/dispatch_probe_cache_spec.rb +38 -0
  273. data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
  274. data/specs/dispatch_probe_fallback_spec.rb +18 -0
  275. data/specs/environment_semantics_spec.rb +89 -0
  276. data/specs/field_access_spec.rb +31 -0
  277. data/specs/figures/bg.jpeg +0 -0
  278. data/specs/figures/bg.png +0 -0
  279. data/specs/figures/bg.svg +168 -57
  280. data/specs/figures/dose_len.png +0 -0
  281. data/specs/figures/no_args.jpeg +0 -0
  282. data/specs/figures/no_args.png +0 -0
  283. data/specs/figures/no_args.svg +168 -57
  284. data/specs/figures/width_height.jpeg +0 -0
  285. data/specs/figures/width_height.png +0 -0
  286. data/specs/figures/width_height_units1.jpeg +0 -0
  287. data/specs/figures/width_height_units1.png +0 -0
  288. data/specs/figures/width_height_units2.jpeg +0 -0
  289. data/specs/figures/width_height_units2.png +0 -0
  290. data/specs/formula_semantics_spec.rb +81 -0
  291. data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
  292. data/specs/galaaz_util_inline_file_spec.rb +54 -0
  293. data/specs/gknit_cli_option_permutation_spec.rb +24 -0
  294. data/specs/gknit_include_engine_spec.rb +72 -0
  295. data/specs/gknit_install_timeout_report_spec.rb +69 -0
  296. data/specs/gknit_internal_error_report_spec.rb +57 -0
  297. data/specs/gknit_vector_map_output_spec.rb +59 -0
  298. data/specs/globalenv_guardrail_spec.rb +52 -0
  299. data/specs/language_expression_semantics_spec.rb +145 -0
  300. data/specs/list_semantics_spec.rb +111 -0
  301. data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
  302. data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
  303. data/specs/new_bridge_callback_timeout_spec.rb +69 -0
  304. data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
  305. data/specs/nil_null_spec.rb +42 -0
  306. data/specs/object_build_phase2_spec.rb +53 -0
  307. data/specs/phase1_callback_bridge_spec.rb +84 -0
  308. data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
  309. data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
  310. data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
  311. data/specs/plot_device_semantics_spec.rb +28 -0
  312. data/specs/plot_snapshot_semantics_spec.rb +58 -0
  313. data/specs/protocol_result_spec.rb +236 -0
  314. data/specs/r_batch_fail_fast_spec.rb +47 -0
  315. data/specs/r_bridge_bootstrap_spec.rb +11 -0
  316. data/specs/r_devices.spec.rb +1 -1
  317. data/specs/r_eval.spec.rb +16 -18
  318. data/specs/r_function.spec.rb +1 -1
  319. data/specs/r_instance_manager_spec.rb +285 -0
  320. data/specs/r_list_apply.spec.rb +15 -15
  321. data/specs/r_matrix.spec.rb +0 -0
  322. data/specs/r_nse.spec.rb +5 -5
  323. data/specs/r_object_send_dispatch_spec.rb +13 -0
  324. data/specs/r_vector_comparator_spec.rb +8 -0
  325. data/specs/r_vector_creation.spec.rb +0 -0
  326. data/specs/r_vector_functions.spec.rb +0 -0
  327. data/specs/r_vector_object.spec.rb +0 -0
  328. data/specs/r_vector_operators.spec.rb +0 -0
  329. data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
  330. data/specs/r_vector_subsetting.spec.rb +0 -0
  331. data/specs/range_helper_spec.rb +21 -0
  332. data/specs/rsupport_scope_spec.rb +28 -0
  333. data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
  334. data/specs/scalar_character_spec.rb +44 -0
  335. data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
  336. data/specs/session_env_bridge_spec.rb +25 -0
  337. data/specs/simplecov_bootstrap_spec.rb +10 -0
  338. data/specs/spec_helper.rb +10 -0
  339. data/specs/tmp.rb +0 -0
  340. data/specs/unboxing_recursion_regression_spec.rb +30 -0
  341. data/specs/unboxing_spec.rb +49 -0
  342. data/specs/verify_callbacks.rb +42 -0
  343. data/sty/galaaz.sty +0 -0
  344. data/version.rb +1 -1
  345. metadata +219 -63
  346. data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -520
  347. data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
  348. data/blogs/galaaz_ggplot/midwest.html +0 -188
  349. data/blogs/gknit/gknit.html +0 -2266
  350. data/blogs/gknit/gknit.pdf +0 -0
  351. data/blogs/manual/manual.html +0 -4638
  352. data/blogs/manual/manual.pdf +0 -0
  353. data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
  354. data/blogs/nse_dplyr/nse_dplyr.html +0 -878
  355. data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
  356. data/blogs/oh_my/oh_my.html +0 -568
  357. data/blogs/ruby_plot/ruby_plot.html +0 -544
  358. data/blogs/ruby_plot/ruby_plot.pdf +0 -0
  359. data/examples/latex_templates/Test-acs_article/Test-acs_article.pdf +0 -0
  360. data/examples/latex_templates/Test-aea_article/Test-aea_article.pdf +0 -0
  361. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdf +0 -0
  362. data/examples/latex_templates/Test-amq_article/pics/Figure2.pdf +0 -0
  363. data/examples/latex_templates/Test-asa_article/Test-asa_article.pdf +0 -0
  364. data/examples/latex_templates/Test-ieee_article/Test-ieee_article.pdf +0 -0
  365. data/examples/latex_templates/Test-rjournal_article/RJwrapper.pdf +0 -0
  366. data/examples/latex_templates/Test-springer_article/Test-springer_article.pdf +0 -0
  367. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.pdf +0 -0
  368. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.pdf +0 -0
  369. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.pdf +0 -0
  370. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.pdf +0 -0
  371. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.pdf +0 -0
  372. data/specs/r_dataframe.spec.rb +0 -379
  373. data/specs/r_environment.spec.rb +0 -140
  374. data/specs/r_formula.spec.rb +0 -232
  375. data/specs/r_language.spec.rb +0 -112
  376. data/specs/r_list.spec.rb +0 -293
  377. data/specs/r_plots.spec.rb +0 -72
  378. data/specs/ruby_expression.spec.rb +0 -316
@@ -3,8 +3,8 @@ title: "Non Standard Evaluation in dplyr with Galaaz"
3
3
  author:
4
4
  - "Rodrigo Botafogo"
5
5
  - "Daniel Mossé - University of Pittsburgh"
6
- tags: [Tech, Data Science, Ruby, R, GraalVM]
7
- date: "10/05/2019"
6
+ tags: [Tech, Data Science, Ruby, R, JRuby, "GNU R", Galaaz, dplyr]
7
+ date: "10/05/2019 (narrative updated for Galaaz 2.0, 2026)"
8
8
  output:
9
9
  html_document:
10
10
  self_contained: true
@@ -24,7 +24,7 @@ fontsize: 11pt
24
24
 
25
25
  # Introduction
26
26
 
27
- According to Steven Sagaert answer on Quora about "Is programming language R overrated?":
27
+ According to Steven Sagaert’s answer on Quora about “Is programming language R overrated?”:
28
28
 
29
29
  > R is a sophisticated language with an unusual (i.e. non-mainstream) set of features. It‘s
30
30
  > an impure functional programming language with sophisticated metaprogramming and 3
@@ -37,16 +37,15 @@ According to Steven Sagaert answer on Quora about "Is programming language R ove
37
37
  > Mastering R (the language) and its ecosystem is not a matter of weeks or months but
38
38
  > takes years. The rabbit hole goes pretty deep…
39
39
 
40
- Although having a highly configurable language might give extreme power to the programmer,
41
- it can also be, as stated above, a question of years to master it. Programming with _dplyr_
42
- for instance, requires learning a set of complex concepts and rules that are not easily
43
- accessible for casual users or _unsofisticated_ programmers as many users of R are. Being
44
- _unsofisticated_ is NOT used here in a negative sense, as R was build for statitians and
45
- not programmers, that need to solve real problems, often in a short time spam and are not
46
- concerned about creating complex computer systems.
40
+ Although a highly configurable language can give programmers a great deal of power,
41
+ it can also take years to master—as noted above. Programming with _dplyr_, for instance,
42
+ means learning evaluation rules that are not always approachable for **statisticians and
43
+ analysts who are not full-time software engineers**. That is not a criticism: R was **built**
44
+ for **statisticians** who need trustworthy results on a deadline, not necessarily for building
45
+ large applications.
47
46
 
48
- Unfortunatelly, if this _unsofisticated_ programmer decides to move unto more sofisticated
49
- coding, the learning curve might become a serious impediment.
47
+ **Unfortunately**, when such a user moves on to more **sophisticated** programming patterns,
48
+ the learning curve can become a real hurdle.
50
49
 
51
50
  In this post we will see how to program with _dplyr_ in Galaaz and how Ruby can simplify
52
51
  the learning curve of mastering _dplyr_ coding.
@@ -58,9 +57,9 @@ a large community, a very large set of libraries and great for web development.
58
57
  easy to learn. However,
59
58
  it lacks libraries for data science, statistics, scientific plotting and machine learning.
60
59
  On the other hand, R is considered one of the most powerful languages for solving all of the
61
- above problems. Maybe the strongest competitor to R is Python with libraries such as NumPy,
62
- Pandas, SciPy, SciKit-Learn and many more. We will not get here in the discussion on R
63
- versus Python, both are excellent languages with powerful features, benefits and drawbacks.
60
+ above problems. **Python** is a strong competitor, with NumPy, pandas, SciPy, scikit-learn,
61
+ and **many thousands** of other packages on PyPI. We will not dwell on R **versus** Python here:
62
+ both are excellent languages with different strengths.
64
63
  Our interest is to bring to yet another excellent language, Ruby, the data science libraries
65
64
  that it lacks.
66
65
 
@@ -73,37 +72,14 @@ post that programming with _dplyr_ is easier in Galaaz than in R.
73
72
 
74
73
  R users are probably quite knowledgeable about _dplyr_. For the Ruby developer, _dplyr_ and
75
74
  the _tidyverse_ libraries are a set of libraries for data manipulation in R, developed by
76
- Hardley Wickham, chief scientis at RStudio and a prolific R coder and writer.
75
+ Hadley Wickham, Chief Scientist at Posit (formerly RStudio) and a prolific R coder and writer.
77
76
 
78
- For the coupling of Ruby and R, we use new technologies provided by Oracle: GraalVM,
79
- TruffleRuby and FastR. GraalVM home page had the following definition:
80
-
81
- GraalVM is a universal virtual machine for running applications
82
- written in JavaScript, Python 3, Ruby, R, JVM-based languages like Java,
83
- Scala, Kotlin, and LLVM-based languages such as C and C++.
84
-
85
- GraalVM removes the isolation between programming languages and enables
86
- interoperability in a shared runtime. It can run either standalone or in
87
- the context of OpenJDK, Node.js, Oracle Database, or MySQL.
88
-
89
- GraalVM allows you to write polyglot applications with a seamless way to
90
- pass values from one language to another. With GraalVM there is no copying
91
- or marshaling necessary as it is with other polyglot systems. This lets
92
- you achieve high performance when language boundaries are crossed. Most
93
- of the time there is no additional cost for crossing a language boundary
94
- at all.
95
-
96
- Often developers have to make uncomfortable compromises that require them
97
- to rewrite their software in other languages. For example:
98
-
99
- * “That library is not available in my language. I need to rewrite it.”
100
- * “That language would be the perfect fit for my problem, but we cannot
101
- run it in our environment.”
102
- * “That problem is already solved in my language, but the language is
103
- too slow.”
104
-
105
- With GraalVM we aim to allow developers to freely choose the right language
106
- for the task at hand without making compromises.
77
+ For the coupling of Ruby and R, **Galaaz 2.0** uses **[JRuby](https://www.jruby.org/)** (Ruby on the JVM)
78
+ together with **GNU R**. A **bridge** sends expressions and data between Ruby and an R process so that
79
+ Ruby can call **dplyr** and the rest of the tidyverse as if they were part of the same workflow.
80
+ An **earlier** Galaaz line of work used Oracle’s **GraalVM** with **TruffleRuby** and **FastR** in a single
81
+ runtime; that approach is **no longer** the supported stack—see the project **manual** for setup,
82
+ **`bin/galaaz-jruby`**, and **gKnit**.
107
83
 
108
84
 
109
85
  # Tidyverse and dplyr
@@ -137,7 +113,7 @@ multiple datasets, programming becomes necessary.
137
113
  # Programming with dplyr
138
114
 
139
115
  In the vignette ["Programming with dplyr"](https://dplyr.tidyverse.org/articles/programming.html),
140
- Hardley Wickham states:
116
+ Hadley Wickham states:
141
117
 
142
118
  > Most dplyr functions use non-standard evaluation (NSE). This is a catch-all term that
143
119
  > means they don’t follow the usual R rules of evaluation. Instead, they capture the
@@ -160,7 +136,7 @@ But then he goes on:
160
136
  > with a seemingly equivalent object that you’ve defined elsewhere. In other words, this code:
161
137
 
162
138
 
163
- ```r
139
+ ``` r
164
140
  df <- data.frame(x = 1:3, y = 3:1)
165
141
  print(filter(df, x == 1))
166
142
  #> # A tibble: 1 x 2
@@ -171,7 +147,7 @@ print(filter(df, x == 1))
171
147
  > Is not equivalent to this code:
172
148
 
173
149
 
174
- ```r
150
+ ``` r
175
151
  my_var <- x
176
152
  #> Error in eval(expr, envir, enclos): object 'x' not found
177
153
  filter(df, my_var == 1)
@@ -180,7 +156,7 @@ filter(df, my_var == 1)
180
156
  > This makes it hard to create functions with arguments that change how dplyr verbs are computed.
181
157
 
182
158
  As a result of this, programming with _dplyr_ requires learning a set of new ideas and concepts.
183
- In this vignette Hardley goes on showing how to program ever more difficult problems with _dplyr_,
159
+ In this vignette Hadley goes on showing how to program ever more difficult problems with _dplyr_,
184
160
  showing the problems it faces and the new concepts needed to solve them.
185
161
 
186
162
  In this blog, we will look at all the problems presented by Harley on the vignette and show how
@@ -220,7 +196,7 @@ where you are reading this blog) with gKnit (a tool provided by Galaaz). In Rmar
220
196
  possible to write text and code blocks that are executed to generate the final report. Code
221
197
  blocks appear inside a 'box' and the result of their execution appear either in another type
222
198
  of 'box' with a different background (HTML) or as normal text (PDF). Every output line from
223
- the code execution is preceeded by '##'.
199
+ the code execution is preceded by '##'.
224
200
 
225
201
  ## Expressions from operators
226
202
 
@@ -228,24 +204,36 @@ The code below creates an expression summing two symbols. Note that :a and :b ar
228
204
  are not bound to any values at the time of expression definition:
229
205
 
230
206
 
231
- ```ruby
207
+ ``` ruby
232
208
  exp1 = :a + :b
233
209
  puts exp1
234
210
  ```
235
211
 
236
212
  ```
237
- ## a + b
213
+ ## undefined method '+' for an instance of Symbol
214
+ ```
215
+
216
+ ```
217
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/util/exec_ruby.rb:170:in 'exec_ruby'
218
+ ## org/jruby/RubyKernel.java:1268:in 'eval'
219
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/util/exec_ruby.rb:169:in 'exec_ruby'
220
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/gknit/knitr_engine.rb:777:in 'block in initialize'
221
+ ## org/jruby/RubyBasicObject.java:2695:in 'instance_eval'
222
+ ## org/jruby/RubyBasicObject.java:2723:in 'instance_eval'
223
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/gknit/knitr_engine.rb:748:in 'block in initialize'
224
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/R_interface/new_bridge_adapter.rb:358:in 'block in register_callback_proc_stub'
225
+ ## /home/rbotafogo/desenv_linux/galaaz/lib/new_bridge/session_client.rb:413:in 'block in handle_call'
238
226
  ```
239
227
  In Galaaz, we can build any complex mathematical expression such as:
240
228
 
241
229
 
242
- ```ruby
243
- exp2 = (:a + :b) * 2.0 + :c ** 2 / :z
230
+ ``` ruby
231
+ exp2 = (R[:a] + R[:b]) * 2.0 + R[:c] ** 2 / R[:z]
244
232
  puts exp2
245
233
  ```
246
234
 
247
235
  ```
248
- ## (a + b) * 2 + c^2L/z
236
+ ## a + b * 2.0 + c ^ 2L / z
249
237
  ```
250
238
  Expressions are printed with the same format as the equivalent R expressions. The 'L' after
251
239
  2 indicates that 2 is an integer.
@@ -258,8 +246,8 @@ float.
258
246
  It is also possible to use inequality operators in building expressions:
259
247
 
260
248
 
261
- ```ruby
262
- exp3 = (:a + :b) >= :z
249
+ ``` ruby
250
+ exp3 = (R[:a] + R[:b]) >= R[:z]
263
251
  puts exp3
264
252
  ```
265
253
 
@@ -269,15 +257,15 @@ puts exp3
269
257
  Expressions' definition can also make use of normal Ruby variables without any problem:
270
258
 
271
259
 
272
- ```ruby
260
+ ``` ruby
273
261
  x = 20
274
262
  y = 30.0
275
- exp_var = (:a + :b) * x <= :z - y
263
+ exp_var = (R[:a] + R[:b]) * x <= R[:z] - y
276
264
  puts exp_var
277
265
  ```
278
266
 
279
267
  ```
280
- ## (a + b) * 20L <= z - 30
268
+ ## a + b * 20L <= z - 30.0
281
269
  ```
282
270
 
283
271
  Galaaz provides both symbolic representations for operators, such as (>, <, !=) as functional
@@ -285,8 +273,8 @@ notation for those operators such as (.gt, .ge, etc.). So the same expression w
285
273
  above can also be written as
286
274
 
287
275
 
288
- ```ruby
289
- exp4 = (:a + :b).ge :z
276
+ ``` ruby
277
+ exp4 = (R[:a] + R[:b]).ge R[:z]
290
278
  puts exp4
291
279
  ```
292
280
 
@@ -302,8 +290,8 @@ In order to write an expression involving '==' we
302
290
  need to use the method '.eq' and for '=' we need the function '.assign':
303
291
 
304
292
 
305
- ```ruby
306
- exp5 = (:a + :b).eq :z
293
+ ``` ruby
294
+ exp5 = (R[:a] + R[:b]).eq R[:z]
307
295
  puts exp5
308
296
  ```
309
297
 
@@ -312,8 +300,8 @@ puts exp5
312
300
  ```
313
301
 
314
302
 
315
- ```ruby
316
- exp6 = :y.assign :a + :b
303
+ ``` ruby
304
+ exp6 = R[:y].assign R[:a] + R[:b]
317
305
  puts exp6
318
306
  ```
319
307
 
@@ -325,19 +313,16 @@ this will generate an error, that might be a bit cryptic (in future releases of
325
313
  plan to improve the error message).
326
314
 
327
315
 
328
- ```ruby
329
- exp_wrong = (:a + :b) == :z
316
+ ``` ruby
317
+ exp_wrong = (R[:a] + R[:b]) == R[:z]
330
318
  puts exp_wrong
331
319
  ```
332
320
 
333
321
  ```
334
- ## Message:
335
- ## Error in function (x, y, num.eq = TRUE, single.NA = TRUE, attrib.as.set = TRUE, :
336
- ## object 'a' not found (RError)
337
- ## Translated to internal error
322
+ ## false
338
323
  ```
339
324
  The problem lies with the fact that
340
- when using '==' we are comparing expression (:a + :b) to expression :z with '=='. When this
325
+ when using '==' we are comparing expression (R[:a] + R[:b]) to expression R[:z] with '=='. When this
341
326
  comparison is executed, the system tries to evaluate :a, :b and :z, and those symbols, at
342
327
  this time, are not bound to anything giving the "object 'a' not found" message.
343
328
 
@@ -350,8 +335,8 @@ the function to be part of the expression, we call the function preceeding it
350
335
  by the letter E, such as 'E.sin(x)'
351
336
 
352
337
 
353
- ```ruby
354
- exp7 = :y.assign E.sin(:x)
338
+ ``` ruby
339
+ exp7 = R[:y].assign E.sin(R[:x])
355
340
  puts exp7
356
341
  ```
357
342
 
@@ -361,8 +346,8 @@ puts exp7
361
346
  Function expressions can also be written using '.' notation:
362
347
 
363
348
 
364
- ```ruby
365
- exp8 = :y.assign :x.sin
349
+ ``` ruby
350
+ exp8 = R[:y].assign R[:x].sin
366
351
  puts exp8
367
352
  ```
368
353
 
@@ -374,8 +359,8 @@ the R concatenate function 'c', that concatenates two or more arguments can be p
374
359
  an expression as:
375
360
 
376
361
 
377
- ```ruby
378
- exp9 = :x.c(:y)
362
+ ``` ruby
363
+ exp9 = R[:x].c(R[:y])
379
364
  puts exp9
380
365
  ```
381
366
 
@@ -394,19 +379,19 @@ can be evaluated by calling function 'eval' with a binding.
394
379
  A binding can be provided with a list or a data frame as shown below:
395
380
 
396
381
 
397
- ```ruby
398
- exp = (:a + :b) * 2.0 + :c ** 2 / :z
382
+ ``` ruby
383
+ exp = (R[:a] + R[:b]) * 2.0 + R[:c] ** 2 / R[:z]
399
384
  puts exp.eval(R.list(a: 10, b: 20, c: 30, z: 40))
400
385
  ```
401
386
 
402
387
  ```
403
- ## [1] 82.5
388
+ ## [1] 72.5
404
389
  ```
405
390
 
406
391
  with a data frame:
407
392
 
408
393
 
409
- ```ruby
394
+ ``` ruby
410
395
  df = R.data__frame(
411
396
  a: R.c(1, 2, 3),
412
397
  b: R.c(10, 20, 30),
@@ -417,7 +402,7 @@ puts exp.eval(df)
417
402
  ```
418
403
 
419
404
  ```
420
- ## [1] 32 64 96
405
+ ## [1] 31 62 93
421
406
  ```
422
407
 
423
408
  # Using Galaaz to call R functions
@@ -433,7 +418,7 @@ with 'R.'. For instance, to create a vector in R, the 'c' function is used. In
433
418
  vector can be created by using 'R.c':
434
419
 
435
420
 
436
- ```ruby
421
+ ``` ruby
437
422
  vec = R.c(1.0, 2, 3)
438
423
  puts vec
439
424
  ```
@@ -444,7 +429,7 @@ puts vec
444
429
  A list is created in R with the 'list' function, so in Galaaz we do:
445
430
 
446
431
 
447
- ```ruby
432
+ ``` ruby
448
433
  list = R.list(a: 1.0, b: 2, c: 3)
449
434
  puts list
450
435
  ```
@@ -462,7 +447,7 @@ puts list
462
447
  Note that we can use named arguments in our list. The same code in R would be:
463
448
 
464
449
 
465
- ```r
450
+ ``` r
466
451
  lst = list(a = 1, b = 2L, c = 3L)
467
452
  print(lst)
468
453
  ```
@@ -482,8 +467,8 @@ the expression $y = sin(45^\circ)$, which is $y = 0.850...$. In this case,
482
467
  we will use 'R.sin':
483
468
 
484
469
 
485
- ```ruby
486
- exp10 = :y.assign R.sin(45)
470
+ ``` ruby
471
+ exp10 = R[:y].assign R.sin(45)
487
472
  puts exp10
488
473
  ```
489
474
 
@@ -501,42 +486,17 @@ Transportation Statistics.
501
486
  Let's start by taking a look at this dataset:
502
487
 
503
488
 
504
- ```ruby
489
+ ``` ruby
505
490
  R.library('nycflights13')
506
491
  # check it's dimension
507
- puts ~:flights.dim
492
+ puts ~R[:flights].dim
508
493
  # and the structure
509
- ~:flights.str
494
+ ~R[:flights].str
510
495
  ```
511
496
 
512
497
  ```
513
- ## Message:
514
- ## Method ~ not found in R environment
515
- ```
516
-
517
- ```
518
- ## Message:
519
- ## /home/rbotafogo/desenv/galaaz/lib/R_interface/rsupport.rb:90:in `eval'
520
- ## /home/rbotafogo/desenv/galaaz/lib/R_interface/rsupport.rb:270:in `exec_function_name'
521
- ## /home/rbotafogo/desenv/galaaz/lib/R_interface/robject.rb:166:in `method_missing'
522
- ## /home/rbotafogo/desenv/galaaz/lib/util/exec_ruby.rb:105:in `get_binding'
523
- ## /home/rbotafogo/desenv/galaaz/lib/util/exec_ruby.rb:102:in `eval'
524
- ## /home/rbotafogo/desenv/galaaz/lib/util/exec_ruby.rb:102:in `exec_ruby'
525
- ## /home/rbotafogo/desenv/galaaz/lib/gknit/knitr_engine.rb:650:in `block in initialize'
526
- ## /home/rbotafogo/desenv/galaaz/lib/R_interface/ruby_callback.rb:77:in `call'
527
- ## /home/rbotafogo/desenv/galaaz/lib/R_interface/ruby_callback.rb:77:in `callback'
528
- ## (eval):3:in `function(...) {\n rb_method(...)'
529
- ## unknown.r:1:in `in_dir'
530
- ## unknown.r:1:in `block_exec'
531
- ## /usr/local/lib/graalvm-ce-java11-20.0.0/languages/R/library/knitr/R/block.R:92:in `call_block'
532
- ## /usr/local/lib/graalvm-ce-java11-20.0.0/languages/R/library/knitr/R/block.R:6:in `process_group.block'
533
- ## /usr/local/lib/graalvm-ce-java11-20.0.0/languages/R/library/knitr/R/block.R:3:in `<no source>'
534
- ## unknown.r:1:in `withCallingHandlers'
535
- ## unknown.r:1:in `process_file'
536
- ## unknown.r:1:in `<no source>'
537
- ## unknown.r:1:in `<no source>'
538
- ## <REPL>:4:in `<repl wrapper>'
539
- ## <REPL>:1
498
+ ## ~(dim(flights))
499
+ ## <environment: 0x5f0b6a5b7790>
540
500
  ```
541
501
 
542
502
  Now, let's use a first verb of _dplyr_: 'filter'. This verb, obviously, will filter the data
@@ -549,34 +509,34 @@ The second and third arguments are expressions that will be used by the filter f
549
509
  filter by columns, looking for entries in which the month and day are equal to 1.
550
510
 
551
511
 
552
- ```ruby
553
- puts R.filter(:flights, (:month.eq 1), (:day.eq 1))
512
+ ``` ruby
513
+ puts R.filter(:flights, (R[:month].eq 1), (R[:day].eq 1))
554
514
  ```
555
515
 
556
516
  ```
557
- ## # A tibble: 842 x 19
558
- ## year month day dep_time sched_dep_time dep_delay arr_time
559
- ## <int> <int> <int> <int> <int> <dbl> <int>
560
- ## 1 2013 1 1 517 515 2 830
561
- ## 2 2013 1 1 533 529 4 850
562
- ## 3 2013 1 1 542 540 2 923
563
- ## 4 2013 1 1 544 545 -1 1004
564
- ## 5 2013 1 1 554 600 -6 812
565
- ## 6 2013 1 1 554 558 -4 740
566
- ## 7 2013 1 1 555 600 -5 913
567
- ## 8 2013 1 1 557 600 -3 709
568
- ## 9 2013 1 1 557 600 -3 838
569
- ## 10 2013 1 1 558 600 -2 753
570
- ## # … with 832 more rows, and 12 more variables: sched_arr_time <int>,
571
- ## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
572
- ## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
573
- ## # minute <dbl>, time_hour <dttm>
517
+ ## # A tibble: 842 × 19
518
+ ## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
519
+ ## <int> <int> <int> <int> <int> <dbl> <int> <int>
520
+ ## 1 2013 1 1 517 515 2 830 819
521
+ ## 2 2013 1 1 533 529 4 850 830
522
+ ## 3 2013 1 1 542 540 2 923 850
523
+ ## 4 2013 1 1 544 545 -1 1004 1022
524
+ ## 5 2013 1 1 554 600 -6 812 837
525
+ ## 6 2013 1 1 554 558 -4 740 728
526
+ ## 7 2013 1 1 555 600 -5 913 854
527
+ ## 8 2013 1 1 557 600 -3 709 723
528
+ ## 9 2013 1 1 557 600 -3 838 846
529
+ ## 10 2013 1 1 558 600 -2 753 745
530
+ ## # ℹ 832 more rows
531
+ ## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
532
+ ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
533
+ ## # hour <dbl>, minute <dbl>, time_hour <dttm>
574
534
  ```
575
535
 
576
536
 
577
537
  ## Programming with _dplyr_: problems and how to solve them in Galaaz
578
538
 
579
- In this section we look at the list of problems that Hardley describes in the "Programming with dplyr"
539
+ In this section we look at the list of problems that Hadley describes in the "Programming with dplyr"
580
540
  vignette and show how those problems are solved and coded with Galaaz. Readers interested in
581
541
  how those problems are treated in _dplyr_ should read the vignette and use it as a comparison with
582
542
  this blog.
@@ -590,7 +550,7 @@ functions that have a '.' in them, we need to substitute the '.' with '__'. So,
590
550
  'data.frame' in R, is called in Galaaz as 'R.data\_\_frame':
591
551
 
592
552
 
593
- ```ruby
553
+ ``` ruby
594
554
  df = R.data__frame(x: (1..3), y: (3..1))
595
555
  puts df
596
556
  ```
@@ -608,16 +568,16 @@ by using dot notation.
608
568
 
609
569
  -------FIX---------
610
570
 
611
- We prefer to use dot notation as shown bellow. The argument to 'filter' should be an
571
+ We prefer to use dot notation as shown below. The argument to 'filter' should be an
612
572
  expression. Note that if we gave to filter a Ruby expression such as
613
573
  'x == 1', we would get an error, since there is no variable 'x' defined and if 'x' was a variable
614
574
  then 'x == 1' would either be 'true' or 'false'. Our goal is to filter our data frame returning
615
- all rows in which the 'x' value is equal to 1. To express this we want: ':x.eq 1', where :x will
575
+ all rows in which the 'x' value is equal to 1. To express this we want: 'R[:x].eq 1', where :x will
616
576
  be interpreted by filter as the 'x' column.
617
577
 
618
578
 
619
- ```ruby
620
- puts df.filter(:x.eq 1)
579
+ ``` ruby
580
+ puts df.filter(R[:x].eq 1)
621
581
  ```
622
582
 
623
583
  ```
@@ -629,21 +589,21 @@ In R, and when coding with 'tidyverse', arguments to a function are usually not
629
589
  object that you’ve defined elsewhere. In other words, this code
630
590
 
631
591
 
632
- ```r
592
+ ``` r
633
593
  my_var <- x
634
594
  filter(df, my_var == 1)
635
595
  ```
636
596
  Generates the following error: "object 'x' not found.
637
597
 
638
598
  However, in Galaaz, arguments are referencially transparent as can be seen by the
639
- code bellow. Note initally that 'my_var = :x' will not give the error "object 'x' not found"
599
+ code below. Note initially that 'my_var = R[:x]' will not give the error "object 'x' not found"
640
600
  since ':x' is treated as an expression and assigned to my\_var. Then when doing (my\_var.eq 1),
641
- my\_var is a variable that resolves to ':x' and it becomes equivalent to (:x.eq 1) which is
601
+ my\_var is a variable that resolves to ':x' and it becomes equivalent to (R[:x].eq 1) which is
642
602
  what we want.
643
603
 
644
604
 
645
- ```ruby
646
- my_var = :x
605
+ ``` ruby
606
+ my_var = R[:x]
647
607
  puts df.filter(my_var.eq 1)
648
608
  ```
649
609
 
@@ -651,7 +611,7 @@ puts df.filter(my_var.eq 1)
651
611
  ## x y
652
612
  ## 1 1 3
653
613
  ```
654
- As stated by Hardley
614
+ As stated by Hadley
655
615
 
656
616
  > dplyr code is ambiguous. Depending on what variables are defined where,
657
617
  > filter(df, x == y) could be equivalent to any of:
@@ -663,18 +623,18 @@ df[x == df$y, ]
663
623
  df[x == y, ]
664
624
  ```
665
625
  In galaaz this ambiguity does not exist, filter(df, x.eq y) is not a valid expression as
666
- expressions are build with symbols. In doing filter(df, :x.eq y) we are looking for elements
626
+ expressions are build with symbols. In doing filter(df, R[:x].eq y) we are looking for elements
667
627
  of the 'x' column that are equal to a previously defined y variable. Finally in
668
- filter(df, :x.eq :y) we are looking for elements in which the 'x' column value is equal to
628
+ filter(df, R[:x].eq R[:y]) we are looking for elements in which the 'x' column value is equal to
669
629
  the 'y' column value. This can be seen in the following two chunks of code:
670
630
 
671
631
 
672
- ```ruby
632
+ ``` ruby
673
633
  y = 1
674
634
  x = 2
675
635
 
676
636
  # looking for values where the 'x' column is equal to the 'y' column
677
- puts df.filter(:x.eq :y)
637
+ puts df.filter(R[:x].eq R[:y])
678
638
  ```
679
639
 
680
640
  ```
@@ -683,10 +643,10 @@ puts df.filter(:x.eq :y)
683
643
  ```
684
644
 
685
645
 
686
- ```ruby
646
+ ``` ruby
687
647
  # looking for values where the 'x' column is equal to the 'y' variable
688
648
  # in this case, the number 1
689
- puts df.filter(:x.eq y)
649
+ puts df.filter(R[:x].eq y)
690
650
  ```
691
651
 
692
652
  ```
@@ -718,18 +678,19 @@ Unfortunately, in R, this function can fail silently if one of the variables isn
718
678
  in the data frame, but is present in the global environment. We will not go through here how
719
679
  to solve this problem in R.
720
680
 
721
- In Galaaz the method mutate_y bellow will work fine and will never fail silently.
681
+ In Galaaz the method mutate_y below will work fine and will never fail silently.
722
682
 
723
683
 
724
- ```ruby
684
+ ``` ruby
725
685
  def mutate_y(df)
726
- df.mutate(:y.assign :a + :x)
686
+ # Mutate column names are Ruby kwargs (y: …). Use .assign only for R `<-` expressions.
687
+ df.mutate(y: R[:a] + R[:x])
727
688
  end
728
689
  ```
729
690
  Here we create a data frame that has only one column named 'x':
730
691
 
731
692
 
732
- ```ruby
693
+ ``` ruby
733
694
  df1 = R.data__frame(x: (1..3))
734
695
  puts df1
735
696
  ```
@@ -742,33 +703,29 @@ puts df1
742
703
  ```
743
704
 
744
705
  Note that method mutate_y will fail independetly from the fact that variable 'a' is defined and
745
- in the scope of the method. Variable 'a' has no relationship with the symbol ':a' used in the
706
+ in the scope of the method. Variable 'a' has no relationship with the symbol `R[:a]` used in the
746
707
  definition of 'mutate\_y' above:
747
708
 
748
709
 
749
- ```ruby
710
+ ``` ruby
750
711
  a = 10
751
712
  mutate_y(df1)
752
713
  ```
753
714
 
754
715
  ```
755
- ## Message:
756
- ## Error in mutate_impl(.data, dots) :
757
- ## Evaluation error: object 'a' not found.
758
- ## In addition: Warning message:
759
- ## In mutate_impl(.data, dots) :
760
- ## mismatched protect/unprotect (unprotect with empty protect stack) (RError)
761
- ## Translated to internal error
716
+ ## Error: ℹ In argument: `y = a + x`.
717
+ ## Caused by error:
718
+ ## ! object 'a' not found
762
719
  ```
763
720
  ## Different expressions
764
721
 
765
- Let's move to the next problem as presented by Hardley where trying to write a function in R
722
+ Let's move to the next problem as presented by Hadley where trying to write a function in R
766
723
  that will receive two argumens, the first a variable and the second an expression is not trivial.
767
- Bellow we create a data frame and we want to write a function that groups data by a variable and
724
+ Below we create a data frame and we want to write a function that groups data by a variable and
768
725
  summarises it by an expression:
769
726
 
770
727
 
771
- ```r
728
+ ``` r
772
729
  set.seed(123)
773
730
 
774
731
  df <- data.frame(
@@ -790,7 +747,7 @@ as.data.frame(df)
790
747
  ## 5 2 1 1 4
791
748
  ```
792
749
 
793
- ```r
750
+ ``` r
794
751
  d2 <- df %>%
795
752
  group_by(g1) %>%
796
753
  summarise(a = mean(a))
@@ -804,7 +761,7 @@ as.data.frame(d2)
804
761
  ## 2 2 3.333333
805
762
  ```
806
763
 
807
- ```r
764
+ ``` r
808
765
  d2 <- df %>%
809
766
  group_by(g2) %>%
810
767
  summarise(a = mean(a))
@@ -818,10 +775,10 @@ as.data.frame(d2)
818
775
  ## 2 2 3
819
776
  ```
820
777
 
821
- As shown by Hardley, one might expect this function to do the trick:
778
+ As shown by Hadley, one might expect this function to do the trick:
822
779
 
823
780
 
824
- ```r
781
+ ``` r
825
782
  my_summarise <- function(df, group_var) {
826
783
  df %>%
827
784
  group_by(group_var) %>%
@@ -834,24 +791,25 @@ my_summarise <- function(df, group_var) {
834
791
 
835
792
  In order to solve this problem, coding with dplyr requires the introduction of many new concepts
836
793
  and functions such as 'quo', 'quos', 'enquo', 'enquos', '!!' (bang bang), '!!!' (triple bang).
837
- Again, we'll leave to Hardley the explanation on how to use all those functions.
794
+ Again, we'll leave to Hadley the explanation on how to use all those functions.
838
795
 
839
796
  Now, let's try to implement the same function in galaaz. The next code block first prints the
840
- 'df' data frame define previously in R (to access an R variable from Galaaz, we use the tilda
797
+ 'df' data frame defined previously in R (to access an R variable from Galaaz, we use the tilde
841
798
  operator '~' applied to the R variable name as symbol, i.e., ':df'. We then create the
842
799
  'my_summarize' method and call it passing the R data frame and the group by variable ':g1':
843
800
 
844
801
 
845
- ```ruby
846
- puts ~:df
847
- print "\n"
802
+ ``` ruby
803
+ puts ~R[:df]
804
+ print "
805
+ "
848
806
 
849
807
  def my_summarize(df, group_var)
850
808
  df.group_by(group_var).
851
- summarize(a: :a.mean)
809
+ summarize(a: R[:a].mean)
852
810
  end
853
811
 
854
- puts my_summarize(:df, :g1)
812
+ puts my_summarize(~R[:df], R[:g1])
855
813
  ```
856
814
 
857
815
  ```
@@ -862,7 +820,7 @@ puts my_summarize(:df, :g1)
862
820
  ## 4 2 2 4 5
863
821
  ## 5 2 1 1 4
864
822
  ##
865
- ## # A tibble: 2 x 2
823
+ ## # A tibble: 2 × 2
866
824
  ## g1 a
867
825
  ## <dbl> <dbl>
868
826
  ## 1 1 2.5
@@ -871,12 +829,12 @@ puts my_summarize(:df, :g1)
871
829
  It works!!! Well, let's make sure this was not just some coincidence
872
830
 
873
831
 
874
- ```ruby
875
- puts my_summarize(:df, :g2)
832
+ ``` ruby
833
+ puts my_summarize(~R[:df], R[:g2])
876
834
  ```
877
835
 
878
836
  ```
879
- ## # A tibble: 2 x 2
837
+ ## # A tibble: 2 × 2
880
838
  ## g2 a
881
839
  ## <dbl> <dbl>
882
840
  ## 1 1 3
@@ -892,7 +850,7 @@ In the previous section we've managed to get rid of all NSE formulation for a si
892
850
  does this remain true for more complex examples, or will the Galaaz way prove inpractical for
893
851
  more complex code?
894
852
 
895
- In the next example Hardley proposes us to write a function that given an expression such as 'a'
853
+ In the next example Hadley proposes us to write a function that given an expression such as 'a'
896
854
  or 'a * b', calculates three summaries. What we want a function that does the same as these R
897
855
  statements:
898
856
 
@@ -913,7 +871,7 @@ summarise(df, mean = mean(a * b), sum = sum(a * b), n = n())
913
871
  Let's try it in galaaz:
914
872
 
915
873
 
916
- ```ruby
874
+ ``` ruby
917
875
  def my_summarise2(df, expr)
918
876
  df.summarize(
919
877
  mean: E.mean(expr),
@@ -922,8 +880,8 @@ def my_summarise2(df, expr)
922
880
  )
923
881
  end
924
882
 
925
- puts my_summarise2((~:df), :a)
926
- puts my_summarise2((~:df), :a * :b)
883
+ puts my_summarise2((~R[:df]), :a)
884
+ puts my_summarise2((~R[:df]), R[:a] * R[:b])
927
885
  ```
928
886
 
929
887
  ```
@@ -938,7 +896,7 @@ careful about is the use of 'E' to build expressions from functions 'mean', 'sum
938
896
 
939
897
  ## Different input and output variable
940
898
 
941
- Now the next challenge presented by Hardley is to vary the name of the output variables based on
899
+ Now the next challenge presented by Hadley is to vary the name of the output variables based on
942
900
  the received expression. So, if the input expression is 'a', we want our data frame columns to
943
901
  be named 'mean\_a' and 'sum\_a'. Now, if the input expression is 'b', columns
944
902
  should be named 'mean\_b' and 'sum\_b'.
@@ -964,13 +922,13 @@ mutate(df, mean_b = mean(b), sum_b = sum(b))
964
922
  #> 4 2 2 5 4 3 15
965
923
  #> # … with 1 more row
966
924
  ```
967
- In order to solve this problem in R, Hardley needs to introduce some more new functions and notations:
925
+ In order to solve this problem in R, Hadley needs to introduce some more new functions and notations:
968
926
  'quo_name' and the ':=' operator from package 'rlang'
969
927
 
970
928
  Here is our Ruby code:
971
929
 
972
930
 
973
- ```ruby
931
+ ``` ruby
974
932
  def my_mutate(df, expr)
975
933
  mean_name = "mean_#{expr.to_s}"
976
934
  sum_name = "sum_#{expr.to_s}"
@@ -979,8 +937,8 @@ def my_mutate(df, expr)
979
937
  sum_name => E.sum(expr))
980
938
  end
981
939
 
982
- puts my_mutate((~:df), :a)
983
- puts my_mutate((~:df), :b)
940
+ puts my_mutate((~R[:df]), :a)
941
+ puts my_mutate((~R[:df]), :b)
984
942
  ```
985
943
 
986
944
  ```
@@ -1007,25 +965,25 @@ and variable mean\_name is not followed by ':' but by '=>'. This is standard Ru
1007
965
 
1008
966
  ## Capturing multiple variables
1009
967
 
1010
- Moving on with new complexities, Hardley proposes us to solve the problem in which the
968
+ Moving on with new complexities, Hadley proposes us to solve the problem in which the
1011
969
  summarise function will receive any number of grouping variables.
1012
970
 
1013
971
  This again is quite standard Ruby. In order to receive an undefined number of paramenters
1014
972
  the paramenter is preceded by '*':
1015
973
 
1016
974
 
1017
- ```ruby
975
+ ``` ruby
1018
976
  def my_summarise3(df, *group_vars)
1019
977
  df.group_by(*group_vars).
1020
978
  summarise(a: E.mean(:a))
1021
979
  end
1022
980
 
1023
- puts my_summarise3((~:df), :g1, :g2)
981
+ puts my_summarise3((~R[:df]), :g1, :g2)
1024
982
  ```
1025
983
 
1026
984
  ```
1027
- ## # A tibble: 4 x 3
1028
- ## # Groups: g1 [?]
985
+ ## # A tibble: 4 × 3
986
+ ## # Groups: g1 [2]
1029
987
  ## g1 g2 a
1030
988
  ## <dbl> <dbl> <dbl>
1031
989
  ## 1 1 1 3
@@ -1049,7 +1007,7 @@ In Ruby, there is no lazy evaluation of parameters and 'a' is always a variable
1049
1007
  Variables assume their value as soon as they are used, so 'x = a' is immediately evaluate and
1050
1008
  variable 'x' will receive the value of variable 'a' as soon as the Ruby statement is executed.
1051
1009
  Ruby also provides the notion of a symbol; ':a' is a symbol and does not evaluate to anything.
1052
- Galaaz uses Ruby symbols to build expressions that are not bound to anything: ':a.eq :b' is
1010
+ Galaaz uses Ruby symbols to build expressions that are not bound to anything: 'R[:a].eq R[:b]' is
1053
1011
  clearly an expression and has no relationship whatsoever with the statment 'a = b'. By using
1054
1012
  symbols, variables and expressions all the possible ambiguities that are found in R are
1055
1013
  eliminated in Galaaz.
@@ -1059,7 +1017,7 @@ of input they are expecting, they might be expecting regular variables or they m
1059
1017
  expecting expressions and the R function will know how to deal with an input of the form
1060
1018
  'a = b', now for the Ruby developer it might not be immediately clear if it should call the
1061
1019
  function passing the value 'true' if variable 'a' is equal to variable 'b' or if it should
1062
- call the function passing the expression ':a.eq :b'.
1020
+ call the function passing the expression 'R[:a].eq R[:b]'.
1063
1021
 
1064
1022
 
1065
1023
  # Advanced dplyr features
@@ -1082,28 +1040,28 @@ In the following examples, we show the use of functions 'group\_by\_at', 'summar
1082
1040
  features of characters in the Starwars movies:
1083
1041
 
1084
1042
 
1085
- ```ruby
1086
- puts (~:starwars).head
1043
+ ``` ruby
1044
+ puts (~R[:starwars]).head
1087
1045
  ```
1088
1046
 
1089
1047
  ```
1090
- ## # A tibble: 6 x 13
1091
- ## name height mass hair_color skin_color eye_color birth_year gender
1092
- ## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
1093
- ## 1 Luke… 172 77 blond fair blue 19 male
1094
- ## 2 C-3PO 167 75 <NA> gold yellow 112 <NA>
1095
- ## 3 R2-D2 96 32 <NA> white, bl… red 33 <NA>
1096
- ## 4 Dart… 202 136 none white yellow 41.9 male
1097
- ## 5 Leia… 150 49 brown light brown 19 female
1098
- ## 6 Owen… 178 120 brown, gr… light blue 52 male
1099
- ## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
1048
+ ## # A tibble: 6 × 14
1049
+ ## name height mass hair_color skin_color eye_color birth_year sex gender
1050
+ ## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1051
+ ## 1 Luke Sky… 172 77 blond fair blue 19 male mascu…
1052
+ ## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
1053
+ ## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
1054
+ ## 4 Darth Va… 202 136 none white yellow 41.9 male mascu…
1055
+ ## 5 Leia Org… 150 49 brown light brown 19 fema… femin…
1056
+ ## 6 Owen Lars 178 120 brown, gr… light blue 52 male mascu…
1057
+ ## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
1100
1058
  ## # vehicles <list>, starships <list>
1101
1059
  ```
1102
- The grouped_mean function bellow will receive a grouping variable and calculate summaries for
1060
+ The grouped_mean function below will receive a grouping variable and calculate summaries for
1103
1061
  the value\_variables given:
1104
1062
 
1105
1063
 
1106
- ```r
1064
+ ``` r
1107
1065
  grouped_mean <- function(data, grouping_variables, value_variables) {
1108
1066
  data %>%
1109
1067
  group_by_at(grouping_variables) %>%
@@ -1114,7 +1072,22 @@ grouped_mean <- function(data, grouping_variables, value_variables) {
1114
1072
 
1115
1073
  gm = starwars %>%
1116
1074
  grouped_mean("eye_color", c("mass", "birth_year"))
1075
+ ```
1117
1076
 
1077
+ ```
1078
+ ## Warning: `funs()` was deprecated in dplyr 0.8.0.
1079
+ ## ℹ Please use a list of either functions or lambdas:
1080
+ ##
1081
+ ## # Simple named list: list(mean = mean, median = median)
1082
+ ##
1083
+ ## # Auto named with `tibble::lst()`: tibble::lst(mean, median)
1084
+ ##
1085
+ ## # Using lambdas list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
1086
+ ## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
1087
+ ## generated.
1088
+ ```
1089
+
1090
+ ``` r
1118
1091
  as.data.frame(gm)
1119
1092
  ```
1120
1093
 
@@ -1140,20 +1113,20 @@ as.data.frame(gm)
1140
1113
  The same code with Galaaz, becomes:
1141
1114
 
1142
1115
 
1143
- ```ruby
1116
+ ``` ruby
1144
1117
  def grouped_mean(data, grouping_variables, value_variables)
1145
1118
  data.
1146
1119
  group_by_at(grouping_variables).
1147
1120
  mutate(count: E.n).
1148
- summarise_at(E.c(value_variables, "count"), ~:mean, na__rm: true).
1121
+ summarise_at(E.c(value_variables, "count"), R[:mean], na__rm: true).
1149
1122
  rename_at(value_variables, E.funs(E.paste0("mean_", value_variables)))
1150
1123
  end
1151
1124
 
1152
- puts grouped_mean((~:starwars), "eye_color", E.c("mass", "birth_year"))
1125
+ puts grouped_mean((~R[:starwars]), "eye_color", E.c("mass", "birth_year"))
1153
1126
  ```
1154
1127
 
1155
1128
  ```
1156
- ## # A tibble: 15 x 4
1129
+ ## # A tibble: 15 × 4
1157
1130
  ## eye_color mean_mass mean_birth_year count
1158
1131
  ## <chr> <dbl> <dbl> <dbl>
1159
1132
  ## 1 black 76.3 33 10
@@ -1175,17 +1148,13 @@ puts grouped_mean((~:starwars), "eye_color", E.c("mass", "birth_year"))
1175
1148
 
1176
1149
  # Further reading
1177
1150
 
1178
- For more information on GraalVM, TruffleRuby, fastR, R and Galaaz check out the following sites/posts:
1179
-
1180
- * [GraalVM Home](https://www.graalvm.org/)
1181
- * [TruffleRuby](https://github.com/oracle/truffleruby)
1182
- * [FastR](https://github.com/oracle/fastr)
1183
- * [Faster R with FastR](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb)
1184
- * [How to make Beautiful Ruby Plots with Galaaz](https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857)
1185
- * [Ruby Plotting with Galaaz: An example of tightly coupling Ruby and R in GraalVM](https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021)
1151
+ * [JRuby](https://www.jruby.org/) — Ruby on the JVM (Galaaz 2.0)
1152
+ * [How to make Beautiful Ruby Plots with Galaaz](https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857) (plots; narrative partly pre-2.0)
1153
+ * [Ruby Plotting with Galaaz in GraalVM](https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021) (older stack; ideas still useful)
1186
1154
  * [How to do reproducible research in Ruby with gKnit](https://towardsdatascience.com/how-to-do-reproducible-research-in-ruby-with-gknit-c26d2684d64e)
1187
1155
  * [R for Data Science](https://r4ds.had.co.nz/)
1188
1156
  * [Advanced R](https://adv-r.hadley.nz/)
1157
+ * Historical context: [GraalVM](https://www.graalvm.org/), [TruffleRuby](https://github.com/oracle/truffleruby), [FastR](https://github.com/oracle/fastr)
1189
1158
 
1190
1159
  # Conclusion
1191
1160