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
@@ -0,0 +1,1430 @@
1
+ ---
2
+ title: "How to do reproducible research in Ruby with gKnit"
3
+ author:
4
+ - "Rodrigo Botafogo"
5
+ - "Daniel Mossé - University of Pittsburgh"
6
+ tags: [Tech, Data Science, Ruby, R, JRuby, "GNU R", Galaaz, gKnit, knitr]
7
+ date: "29/04/2019 (narrative updated for Galaaz 2.0, 2026)"
8
+ bibliography: stats.bib
9
+ output:
10
+ pdf_document:
11
+ includes:
12
+ in_header: ["../../sty/galaaz.sty"]
13
+ number_sections: yes
14
+ html_document:
15
+ self_contained: true
16
+ keep_md: true
17
+ biblio-style: apsr
18
+ ---
19
+
20
+
21
+
22
+ # Introduction
23
+
24
+ The idea of "literate programming" was first introduced by Donald Knuth in the
25
+ 1980's [@Knuth:literate_programming].
26
+ The main intention of this approach was to develop software interspersing macro snippets,
27
+ traditional source code, and a natural language such as English in a document
28
+ that could be compiled into
29
+ executable code and at the same time easily read by a human developer. According to Knuth
30
+ "The practitioner of
31
+ literate programming can be regarded as an essayist, whose main concern is with exposition
32
+ and excellence of style."
33
+
34
+ The idea of literate programming evolved into the idea of reproducible research, in which
35
+ all the data, software code, documentation, graphics etc. needed to reproduce the research
36
+ and its reports could be included in a
37
+ single document or set of documents that when distributed to peers could be rerun generating
38
+ the same output and reports.
39
+
40
+ The R community has put a great deal of effort in reproducible research. In 2002, Sweave was
41
+ introduced and it allowed mixing R code with LaTeX, generating high-quality PDF documents. A
42
+ Sweave document could include code, the results of executing the code, graphics and text
43
+ such that it contained the whole narrative to reproduce the research. In
44
+ 2012, Knitr, developed by Yihui Xie from RStudio was released to replace Sweave and to
45
+ consolidate in one single package the many extensions and add-on packages that
46
+ were necessary for Sweave.
47
+
48
+ With Knitr, __R markdown__ was also developed, an extension to the
49
+ Markdown format. With __R markdown__ and Knitr it is possible to generate reports in a multitude
50
+ of formats such as HTML, Markdown, LaTeX, PDF, DVI, etc. __R markdown__ also allows the use of
51
+ multiple programming languages such as R, Ruby, Python, etc. in the same document.
52
+
53
+ In __R markdown__, text is interspersed with
54
+ code chunks that can be executed and both the code and its results can become
55
+ part of the final report. Although __R markdown__ allows multiple programming languages in the
56
+ same document, only R and Python (with
57
+ the reticulate package) can persist variables between chunks. For other languages, such as
58
+ Ruby, every chunk will start a new process and thus all data is lost between chunks, unless it
59
+ is somehow stored in a data file that is read by the next chunk.
60
+
61
+ Being able to persist data
62
+ between chunks is critical for literate programming otherwise the flow of the narrative is lost
63
+ by all the effort of having to save data and then reload it. Although this might, at first, seem like
64
+ a small nuisance, not being able to persist data between chunks is a major issue. For example, let's
65
+ take a look at the following simple example in which we want to show how to create a list and the
66
+ use it. Let's first assume that data cannot be persisted between chunks. In the next chunk we
67
+ create a list, then we would need to save it to file, but to save it, we need somehow to marshal the
68
+ data into a binary format:
69
+
70
+
71
+ ``` ruby
72
+ lst = R.list(a: 1, b: 2, c: 3)
73
+ lst.saveRDS("lst.rds")
74
+ ```
75
+ then, on the next chunk, where variable 'lst' is used, we need to read back it's value
76
+
77
+
78
+ ``` ruby
79
+ lst = R.readRDS("lst.rds")
80
+ puts lst
81
+ ```
82
+
83
+ ```
84
+ ## $a
85
+ ## [1] 1
86
+ ##
87
+ ## $b
88
+ ## [1] 2
89
+ ##
90
+ ## $c
91
+ ## [1] 3
92
+ ```
93
+
94
+ Now, any single code has dozens of variables that we might want to use and reuse between chunks.
95
+ Clearly, such an approach becomes quickly unmanageable. Probably, because of
96
+ this problem, it is very rare to see any __R markdown__ document in the Ruby community.
97
+
98
+ When variables can be used accross chunks, then no overhead is needed:
99
+
100
+
101
+ ``` ruby
102
+ lst = R.list(a: 1, b: 2, c: 3)
103
+ # any other code can be added here
104
+ ```
105
+
106
+
107
+ ``` ruby
108
+ puts lst
109
+ ```
110
+
111
+ ```
112
+ ## $a
113
+ ## [1] 1
114
+ ##
115
+ ## $b
116
+ ## [1] 2
117
+ ##
118
+ ## $c
119
+ ## [1] 3
120
+ ```
121
+
122
+ In the Python community, the same effort to have code and text in an integrated environment
123
+ started around the first decade of the 2000s. In 2006 IPython 0.7.2 was released. In 2014,
124
+ Fernando Pérez spun off the Jupyter project from IPython, creating a web-based interactive
125
+ computation environment. Jupyter can now be used with many languages, including Ruby with the
126
+ iruby gem (https://github.com/SciRuby/iruby). In order to have multiple languages in a Jupyter
127
+ notebook the SoS kernel was developed (https://vatlab.github.io/sos-docs/).
128
+
129
+ # gKnitting a Document
130
+
131
+ This document describes gKnit. gKnit is based on knitr and __R markdown__ and can knit a document
132
+ written both in Ruby and/or R and output it in any of the available formats of __R markdown__. gKnit
133
+ allows ruby developers to do literate programming and reproducible research by allowing them to
134
+ have in a single document, text and code.
135
+
136
+ gKnit runs with **JRuby**, **GNU R**, and **Galaaz** (the integration layer between Ruby and R—see below).
137
+ Knitr and **R Markdown** orchestrate the document; Galaaz’s engine keeps **Ruby state across chunks**
138
+ and talks to R through the **bridge**. Ruby chunks can read and update R variables (`~R[:name]`, `R.*`)
139
+ without GraalVM-style polyglot interop.
140
+
141
+ Galaaz has already been describe in the following posts:
142
+
143
+ * https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021 (older GraalVM-era article; plotting ideas still apply).
144
+ * https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857
145
+
146
+ This is not a blog post on __R markdown__, and the interested user is directed to the following links
147
+ for detailed information on its capabilities and use.
148
+
149
+ * https://rmarkdown.rstudio.com/ or
150
+ * https://bookdown.org/yihui/rmarkdown/
151
+
152
+ In this post, we will describe just the main aspects of __R markdown__, so the user can start
153
+ gKnitting Ruby and R documents quickly.
154
+
155
+ ## The Yaml header
156
+
157
+ An __R markdown__ document should start with a Yaml header and be stored in a file with
158
+ '.Rmd' extension. This document has the following header for gKnitting an HTML document.
159
+
160
+ ```
161
+ ---
162
+ title: "How to do reproducible research in Ruby with gKnit"
163
+ author:
164
+ - "Rodrigo Botafogo"
165
+ - "Daniel Mossé - University of Pittsburgh"
166
+ tags: [Tech, Data Science, Ruby, R, JRuby, "GNU R", Galaaz]
167
+ date: "20/02/2019"
168
+ output:
169
+ html_document:
170
+ self_contained: true
171
+ keep_md: true
172
+ pdf_document:
173
+ includes:
174
+ in_header: ["../../sty/galaaz.sty"]
175
+ number_sections: yes
176
+ ---
177
+ ```
178
+
179
+ For more information on the options in the Yaml header, check https://bookdown.org/yihui/rmarkdown/html-document.html.
180
+
181
+ ## __R Markdown__ formatting
182
+
183
+ Document formatting can be done with simple markups such as:
184
+
185
+ ### Headers
186
+
187
+ ```
188
+ # Header 1
189
+
190
+ ## Header 2
191
+
192
+ ### Header 3
193
+
194
+ ```
195
+
196
+ ### Lists
197
+
198
+ ```
199
+ Unordered lists:
200
+
201
+ * Item 1
202
+ * Item 2
203
+ + Item 2a
204
+ + Item 2b
205
+ ```
206
+
207
+ ```
208
+ Ordered Lists
209
+
210
+ 1. Item 1
211
+ 2. Item 2
212
+ 3. Item 3
213
+ + Item 3a
214
+ + Item 3b
215
+ ```
216
+
217
+ For more R markdown formatting go to https://rmarkdown.rstudio.com/authoring_basics.html.
218
+
219
+ ### R chunks
220
+
221
+ Running and executing Ruby and R code is actually what really interests us is this blog.
222
+ Inserting a code chunk is done by adding code in a block delimited by three back ticks
223
+ followed by an open
224
+ curly brace ('{') followed with the engine name (r, ruby, rb, include, ...), an
225
+ any optional chunk_label and options, as shown below:
226
+
227
+ ````
228
+ ```{engine_name [chunk_label], [chunk_options]}
229
+ ```
230
+ ````
231
+
232
+ for instance, let's add an R chunk to the document labeled 'first_r_chunk'. This is
233
+ a very simple code just to create a variable and print it out, as follows:
234
+
235
+ ````
236
+ ```{r first_r_chunk}
237
+ vec <- c(1, 2, 3)
238
+ print(vec)
239
+ ```
240
+ ````
241
+
242
+ If this block is added to an __R markdown__ document and gKnitted the result will be:
243
+
244
+
245
+ ``` r
246
+ vec <- c(1, 2, 3)
247
+ print(vec)
248
+ ```
249
+
250
+ ```
251
+ ## [1] 1 2 3
252
+ ```
253
+
254
+ Now let's say that we want to do some analysis in the code, but just print the result and not the
255
+ code itself. For this, we need to add the option 'echo = FALSE'.
256
+
257
+ ````
258
+ ```{r second_r_chunk, echo = FALSE}
259
+ vec2 <- c(10, 20, 30)
260
+ vec3 <- vec * vec2
261
+ print(vec3)
262
+ ```
263
+ ````
264
+ Here is how this block will show up in the document. Observe that the code is not shown
265
+ and we only see the execution result in a white box
266
+
267
+
268
+ ```
269
+ ## [1] 10 40 90
270
+ ```
271
+
272
+ A description of the available chunk options can be found in https://yihui.name/knitr/.
273
+
274
+ Let's add another R chunk with a function definition. In this example, a vector
275
+ 'r_vec' is created and
276
+ a new function 'reduce_sum' is defined. The chunk specification is
277
+
278
+ ````
279
+ ```{r data_creation}
280
+ r_vec <- c(1, 2, 3, 4, 5)
281
+
282
+ reduce_sum <- function(...) {
283
+ Reduce(sum, as.list(...))
284
+ }
285
+ ```
286
+ ````
287
+
288
+ and this is how it will look like once executed. From now on, to be concise in the
289
+ presentation we will not show chunk definitions any longer.
290
+
291
+
292
+
293
+ ``` r
294
+ r_vec <- c(1, 2, 3, 4, 5)
295
+
296
+ reduce_sum <- function(...) {
297
+ Reduce(sum, as.list(...))
298
+ }
299
+ ```
300
+
301
+ We can, possibly in another chunk, access the vector and call the function as follows:
302
+
303
+
304
+ ``` r
305
+ print(r_vec)
306
+ ```
307
+
308
+ ```
309
+ ## [1] 1 2 3 4 5
310
+ ```
311
+
312
+ ``` r
313
+ print(reduce_sum(r_vec))
314
+ ```
315
+
316
+ ```
317
+ ## [1] 15
318
+ ```
319
+ ### R Graphics with ggplot
320
+
321
+ In the following chunk, we create a bubble chart in R using ggplot and include it in
322
+ this document. Note that there is no directive in the code to include the image, this
323
+ occurs automatically. The 'mpg' dataframe is natively available to R and to Galaaz as
324
+ well.
325
+
326
+ For the reader not knowledgeable of ggplot, ggplot is a graphics library based on "the
327
+ grammar of graphics" [@Wilkinson:grammar_of_graphics]. The idea of the grammar of graphics
328
+ is to build a graphics by adding layers to the plot. More information can be found in
329
+ https://towardsdatascience.com/a-comprehensive-guide-to-the-grammar-of-graphics-for-effective-visualization-of-multi-dimensional-1f92b4ed4149.
330
+
331
+ In the plot below the 'mpg' dataset from base R is used. "The data concerns city-cycle fuel
332
+ consumption in miles per gallon, to be predicted in terms of 3 multivalued discrete and 5
333
+ continuous attributes." (Quinlan, 1993)
334
+
335
+ First, the 'mpg' dataset if filtered to extract only cars from the following manumactures: Audi, Ford,
336
+ Honda, and Hyundai and stored in the 'mpg_select' variable. Then, the selected dataframe is passed
337
+ to the ggplot function specifying in the aesthetic method (aes) that 'displacement' (disp) should
338
+ be plotted in the 'x' axis and 'city mileage' should be on the 'y' axis. In the 'labs' layer we
339
+ pass the 'title' and 'subtitle' for the plot. To the basic plot 'g', geom\_jitter is added, that
340
+ plots cars from the same manufactures with the same color (col=manufactures) and the size of the
341
+ car point equal its high way consumption (size = hwy). Finally, a last layer is plotter containing
342
+ a linear regression line (method = "lm") for every manufacturer.
343
+
344
+
345
+ ``` r
346
+ # load package and data
347
+ library(ggplot2)
348
+ data(mpg, package="ggplot2")
349
+
350
+ mpg_select <- mpg[mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"), ]
351
+
352
+ # Scatterplot
353
+ theme_set(theme_bw()) # pre-set the bw theme.
354
+ g <- ggplot(mpg_select, aes(displ, cty)) +
355
+ labs(subtitle="mpg: Displacement vs City Mileage",
356
+ title="Bubble chart")
357
+
358
+ g + geom_jitter(aes(col=manufacturer, size=hwy)) +
359
+ geom_smooth(aes(col=manufacturer), method="lm", se=F)
360
+ ```
361
+
362
+ ```
363
+ ## `geom_smooth()` using formula = 'y ~ x'
364
+ ```
365
+
366
+ ![](gknit_files/figure-html/bubble-1.png)<!-- -->
367
+
368
+ ### Ruby chunks
369
+
370
+
371
+ Including a Ruby chunk is just as easy as including an R chunk in the document: just
372
+ change the name of the engine to 'ruby'. It is also possible to pass chunk options
373
+ to the Ruby engine; however, this version does not accept all the options that are
374
+ available to R chunks. Future versions will add those options.
375
+
376
+ ````
377
+ ```{ruby first_ruby_chunk}
378
+ ```
379
+ ````
380
+
381
+ In this example, the ruby chunk is called 'first_ruby_chunk'. One important
382
+ aspect of chunk labels is that they cannot be duplicated. If a chunk label is
383
+ duplicated, gKnit will stop with an error.
384
+
385
+ In the following chunk, variable 'a', 'b' and 'c' are standard Ruby variables
386
+ and 'vec' and 'vec2' are two vectors created by calling the 'c' method on the
387
+ R module.
388
+
389
+ In Galaaz, the R module allows us to access R functions transparently. The 'c'
390
+ function in R, is a function that concatenates its arguments making a vector.
391
+
392
+ It
393
+ should be clear that there is no requirement in gknit to call or use any R
394
+ functions. gKnit will knit standard Ruby code, or even general text without
395
+ any code.
396
+
397
+
398
+ ``` ruby
399
+ a = [1, 2, 3]
400
+ b = "US$ 250.000"
401
+ c = "The 'outputs' function"
402
+
403
+ vec = R.c(1, 2, 3)
404
+ vec2 = R.c(10, 20, 30)
405
+ ```
406
+
407
+ In the next block, variables 'a', 'vec' and 'vec2' are used and printed.
408
+
409
+
410
+ ``` ruby
411
+ puts a
412
+ puts vec * vec2
413
+ ```
414
+
415
+ ```
416
+ ## 1
417
+ ## 2
418
+ ## 3
419
+ ## [1] 10 40 90
420
+ ```
421
+
422
+ Note that 'a' is a standard Ruby Array and 'vec' and 'vec2' are vectors that behave accordingly,
423
+ where multiplication works as expected.
424
+
425
+
426
+ ### Accessing R from Ruby
427
+
428
+ One of the nice aspects of Galaaz 2.0 is that variables and functions defined in R can
429
+ be easily accessed from Ruby. This next chunk, reads data from R and uses the 'reduce_sum'
430
+ function defined previously. To access an R variable from Ruby the '~' function should be
431
+ applied to the Ruby symbol representing the R variable. Since the R variable is called 'r_vec',
432
+ in Ruby, the symbol to acess it is ':r_vec' and thus '~R[:r_vec]' retrieves the value of the
433
+ variable.
434
+
435
+
436
+ ``` ruby
437
+ puts ~R[:r_vec]
438
+ ```
439
+
440
+ ```
441
+ ## [1] 1 2 3 4 5
442
+ ```
443
+
444
+ In order to call an R function, the 'R.' module is used as follows
445
+
446
+
447
+ ``` ruby
448
+ puts R.reduce_sum(~R[:r_vec])
449
+ ```
450
+
451
+ ```
452
+ ## [1] 15
453
+ ```
454
+
455
+ ### Ruby Plotting
456
+
457
+ We have seen an example of plotting with R. Plotting with Ruby does not require
458
+ anything different from plotting with R. In the following example, we plot a
459
+ diverging bar graph using the 'mtcars' dataframe from R. This data was extracted
460
+ from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects
461
+ of automobile design and performance for 32 automobiles (1973–74 models). The
462
+ ten aspects are:
463
+
464
+ * mpg: Miles/(US) gallon
465
+ * cyl: Number of cylinders
466
+ * disp: Displacement (cu.in.)
467
+ * hp: Gross horsepower
468
+ * drat: Rear axle ratio
469
+ * wt: Weight (1000 lbs)
470
+ * qsec: 1/4 mile time
471
+ * vs: Engine (0 = V-shaped, 1 = straight)
472
+ * am: Transmission (0 = automatic, 1 = manual)
473
+ * gear: Number of forward gears
474
+ * carb: Number of carburetors
475
+
476
+
477
+
478
+ ``` ruby
479
+ # copy the R variable :mtcars to the Ruby mtcars variable
480
+ mtcars = ~R[:mtcars]
481
+
482
+ # create a new column 'car_name' to store the car names so that it can be
483
+ # used for plotting. The 'rownames' of the data frame cannot be used as
484
+ # data for plotting
485
+ mtcars.car_name = R.rownames(:mtcars)
486
+
487
+ # compute normalized mpg and add it to a new column called mpg_z
488
+ # Note that the mean value for mpg can be obtained by calling the 'mean'
489
+ # function on the vector 'mtcars.mpg'. The same with the standard
490
+ # deviation 'sd'. The vector is then rounded to two digits with 'round 2'
491
+ mtcars.mpg_z = ((mtcars.mpg - mtcars.mpg.mean)/mtcars.mpg.sd).round 2
492
+
493
+ # create a new column 'mpg_type'. Function 'ifelse' is a vectorized function
494
+ # that looks at every element of the mpg_z vector and if the value is below
495
+ # 0, returns 'below', otherwise returns 'above'
496
+ mtcars.mpg_type = (mtcars.mpg_z < 0).ifelse("below", "above")
497
+
498
+ # order the mtcar data set by the mpg_z vector from smaler to larger values
499
+ mtcars = mtcars[mtcars.mpg_z.order, :all]
500
+
501
+ # convert the car_name column to a factor to retain sorted order in plot
502
+ mtcars.car_name = mtcars.car_name.factor levels: mtcars.car_name
503
+
504
+ # let's look at the first records of the final data frame
505
+ puts mtcars.head
506
+ ```
507
+
508
+ ```
509
+ ## mpg cyl disp hp drat wt qsec vs am gear carb
510
+ ## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3 4
511
+ ## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3 4
512
+ ## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3 4
513
+ ## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3 4
514
+ ## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3 4
515
+ ## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5 8
516
+ ## car_name mpg_z mpg_type
517
+ ## Cadillac Fleetwood Cadillac Fleetwood -1.61 below
518
+ ## Lincoln Continental Lincoln Continental -1.61 below
519
+ ## Camaro Z28 Camaro Z28 -1.13 below
520
+ ## Duster 360 Duster 360 -0.96 below
521
+ ## Chrysler Imperial Chrysler Imperial -0.89 below
522
+ ## Maserati Bora Maserati Bora -0.84 below
523
+ ```
524
+
525
+
526
+ ``` ruby
527
+ require 'ggplot'
528
+
529
+ puts mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
530
+ R.geom_bar(E.aes(fill: :mpg_type), stat: 'identity', width: 0.5) +
531
+ R.scale_fill_manual(name: 'Mileage',
532
+ labels: R.c('Above Average', 'Below Average'),
533
+ values: R.c('above': '#00ba38', 'below': '#f8766d')) +
534
+ R.labs(subtitle: "Normalised mileage from 'mtcars'",
535
+ title: "Diverging Bars") +
536
+ R.coord_flip
537
+ ```
538
+
539
+
540
+ ![](gknit_files/figure-html/diverging_bar.png)
541
+
542
+ ### Inline Ruby code
543
+
544
+ When using a Ruby chunk, the code and the output are formatted in blocks as seen above.
545
+ This formatting is not always desired. Sometimes, we want to have the results of the
546
+ Ruby evaluation included in the middle of a phrase. gKnit allows adding inline Ruby code
547
+ with the 'rb' engine. The following chunk specification will
548
+ create and inline Ruby text:
549
+
550
+ ````
551
+ This is some text with inline Ruby accessing variable 'b' which has value:
552
+ ```{rb puts b}
553
+ ```
554
+ and is followed by some other text!
555
+ ````
556
+
557
+ <div style="margin-bottom:30px;">
558
+ </div>
559
+
560
+ This is some text with inline Ruby accessing variable 'b' which has value:
561
+ US$ 250.000
562
+ and is followed by some other text!
563
+
564
+ <div style="margin-bottom:30px;">
565
+ </div>
566
+
567
+ Note that it is important not to add any new line before of after the code
568
+ block if we want everything to be in only one line, resulting in the following sentence
569
+ with inline Ruby code.
570
+
571
+
572
+ ### The 'outputs' function
573
+
574
+ He have previously used the standard 'puts' method in Ruby chunks in order produce
575
+ output. The result of a 'puts', as seen in all previous chunks that use it, is formatted
576
+ inside a white box that
577
+ follows the code block. Many times however, we would like to do some processing in the
578
+ Ruby chunk and have the result of this processing generate and output that is
579
+ "included" in the document as if we had typed it in __R markdown__ document.
580
+
581
+ For example, suppose we want to create a new heading in our document, but the heading
582
+ phrase is the result of some code processing: maybe it's the first line of a file we are
583
+ going to read. Method 'outputs' adds its output as if typed in the __R markdown__ document.
584
+
585
+ Take now a look at variable 'c' (it was defined in a previous block above) as
586
+ 'c = "The 'outputs' function". "The 'outputs' function" is actually the name of this
587
+ section and it was created using the 'outputs' function inside a Ruby chunk.
588
+
589
+ The ruby chunk to generate this heading is:
590
+
591
+ ````
592
+ ```{ruby heading}
593
+ outputs "### #{c}"
594
+ ```
595
+ ````
596
+
597
+ The three '###' is the way we add a Heading 3 in __R markdown__.
598
+
599
+
600
+ ### HTML Output from Ruby Chunks
601
+
602
+ We've just seen the use of method 'outputs' to add text to the the __R markdown__
603
+ document. This technique can also be used to add HTML code to the document. In
604
+ __R markdown__, any html code typed directly in the document will be properly rendered.
605
+ Here, for instance, is a table definition in HTML and its output in the document:
606
+
607
+ ```
608
+ <table style="width:100%">
609
+ <tr>
610
+ <th>Firstname</th>
611
+ <th>Lastname</th>
612
+ <th>Age</th>
613
+ </tr>
614
+ <tr>
615
+ <td>Jill</td>
616
+ <td>Smith</td>
617
+ <td>50</td>
618
+ </tr>
619
+ <tr>
620
+ <td>Eve</td>
621
+ <td>Jackson</td>
622
+ <td>94</td>
623
+ </tr>
624
+ </table>
625
+ ```
626
+ <div style="margin-bottom:30px;">
627
+ </div>
628
+
629
+ <table style="width:100%">
630
+ <tr>
631
+ <th>Firstname</th>
632
+ <th>Lastname</th>
633
+ <th>Age</th>
634
+ </tr>
635
+ <tr>
636
+ <td>Jill</td>
637
+ <td>Smith</td>
638
+ <td>50</td>
639
+ </tr>
640
+ <tr>
641
+ <td>Eve</td>
642
+ <td>Jackson</td>
643
+ <td>94</td>
644
+ </tr>
645
+ </table>
646
+
647
+ <div style="margin-bottom:30px;">
648
+ </div>
649
+
650
+ But manually creating HTML output is not always easy or desirable, specially
651
+ if we intend the document to be rendered in other formats, for example, as LaTeX.
652
+ Also, The above
653
+ table looks ugly. The 'kableExtra' library is a great library for
654
+ creating beautiful tables. Take a look at https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html
655
+
656
+ In the next chunk, we output the 'mtcars' dataframe from R in a nicely formatted
657
+ table. Note that we retrieve the mtcars dataframe by using '~R[:mtcars]'.
658
+
659
+
660
+ ``` ruby
661
+ R.install_and_loads('kableExtra')
662
+ outputs (~R[:mtcars]).kable.kable_styling
663
+ ```
664
+
665
+ <table class="table" style="margin-left: auto; margin-right: auto;">
666
+ <thead>
667
+ <tr>
668
+ <th style="text-align:left;"> </th>
669
+ <th style="text-align:right;"> mpg </th>
670
+ <th style="text-align:right;"> cyl </th>
671
+ <th style="text-align:right;"> disp </th>
672
+ <th style="text-align:right;"> hp </th>
673
+ <th style="text-align:right;"> drat </th>
674
+ <th style="text-align:right;"> wt </th>
675
+ <th style="text-align:right;"> qsec </th>
676
+ <th style="text-align:right;"> vs </th>
677
+ <th style="text-align:right;"> am </th>
678
+ <th style="text-align:right;"> gear </th>
679
+ <th style="text-align:right;"> carb </th>
680
+ </tr>
681
+ </thead>
682
+ <tbody>
683
+ <tr>
684
+ <td style="text-align:left;"> Mazda RX4 </td>
685
+ <td style="text-align:right;"> 21.0 </td>
686
+ <td style="text-align:right;"> 6 </td>
687
+ <td style="text-align:right;"> 160.0 </td>
688
+ <td style="text-align:right;"> 110 </td>
689
+ <td style="text-align:right;"> 3.90 </td>
690
+ <td style="text-align:right;"> 2.620 </td>
691
+ <td style="text-align:right;"> 16.46 </td>
692
+ <td style="text-align:right;"> 0 </td>
693
+ <td style="text-align:right;"> 1 </td>
694
+ <td style="text-align:right;"> 4 </td>
695
+ <td style="text-align:right;"> 4 </td>
696
+ </tr>
697
+ <tr>
698
+ <td style="text-align:left;"> Mazda RX4 Wag </td>
699
+ <td style="text-align:right;"> 21.0 </td>
700
+ <td style="text-align:right;"> 6 </td>
701
+ <td style="text-align:right;"> 160.0 </td>
702
+ <td style="text-align:right;"> 110 </td>
703
+ <td style="text-align:right;"> 3.90 </td>
704
+ <td style="text-align:right;"> 2.875 </td>
705
+ <td style="text-align:right;"> 17.02 </td>
706
+ <td style="text-align:right;"> 0 </td>
707
+ <td style="text-align:right;"> 1 </td>
708
+ <td style="text-align:right;"> 4 </td>
709
+ <td style="text-align:right;"> 4 </td>
710
+ </tr>
711
+ <tr>
712
+ <td style="text-align:left;"> Datsun 710 </td>
713
+ <td style="text-align:right;"> 22.8 </td>
714
+ <td style="text-align:right;"> 4 </td>
715
+ <td style="text-align:right;"> 108.0 </td>
716
+ <td style="text-align:right;"> 93 </td>
717
+ <td style="text-align:right;"> 3.85 </td>
718
+ <td style="text-align:right;"> 2.320 </td>
719
+ <td style="text-align:right;"> 18.61 </td>
720
+ <td style="text-align:right;"> 1 </td>
721
+ <td style="text-align:right;"> 1 </td>
722
+ <td style="text-align:right;"> 4 </td>
723
+ <td style="text-align:right;"> 1 </td>
724
+ </tr>
725
+ <tr>
726
+ <td style="text-align:left;"> Hornet 4 Drive </td>
727
+ <td style="text-align:right;"> 21.4 </td>
728
+ <td style="text-align:right;"> 6 </td>
729
+ <td style="text-align:right;"> 258.0 </td>
730
+ <td style="text-align:right;"> 110 </td>
731
+ <td style="text-align:right;"> 3.08 </td>
732
+ <td style="text-align:right;"> 3.215 </td>
733
+ <td style="text-align:right;"> 19.44 </td>
734
+ <td style="text-align:right;"> 1 </td>
735
+ <td style="text-align:right;"> 0 </td>
736
+ <td style="text-align:right;"> 3 </td>
737
+ <td style="text-align:right;"> 1 </td>
738
+ </tr>
739
+ <tr>
740
+ <td style="text-align:left;"> Hornet Sportabout </td>
741
+ <td style="text-align:right;"> 18.7 </td>
742
+ <td style="text-align:right;"> 8 </td>
743
+ <td style="text-align:right;"> 360.0 </td>
744
+ <td style="text-align:right;"> 175 </td>
745
+ <td style="text-align:right;"> 3.15 </td>
746
+ <td style="text-align:right;"> 3.440 </td>
747
+ <td style="text-align:right;"> 17.02 </td>
748
+ <td style="text-align:right;"> 0 </td>
749
+ <td style="text-align:right;"> 0 </td>
750
+ <td style="text-align:right;"> 3 </td>
751
+ <td style="text-align:right;"> 2 </td>
752
+ </tr>
753
+ <tr>
754
+ <td style="text-align:left;"> Valiant </td>
755
+ <td style="text-align:right;"> 18.1 </td>
756
+ <td style="text-align:right;"> 6 </td>
757
+ <td style="text-align:right;"> 225.0 </td>
758
+ <td style="text-align:right;"> 105 </td>
759
+ <td style="text-align:right;"> 2.76 </td>
760
+ <td style="text-align:right;"> 3.460 </td>
761
+ <td style="text-align:right;"> 20.22 </td>
762
+ <td style="text-align:right;"> 1 </td>
763
+ <td style="text-align:right;"> 0 </td>
764
+ <td style="text-align:right;"> 3 </td>
765
+ <td style="text-align:right;"> 1 </td>
766
+ </tr>
767
+ <tr>
768
+ <td style="text-align:left;"> Duster 360 </td>
769
+ <td style="text-align:right;"> 14.3 </td>
770
+ <td style="text-align:right;"> 8 </td>
771
+ <td style="text-align:right;"> 360.0 </td>
772
+ <td style="text-align:right;"> 245 </td>
773
+ <td style="text-align:right;"> 3.21 </td>
774
+ <td style="text-align:right;"> 3.570 </td>
775
+ <td style="text-align:right;"> 15.84 </td>
776
+ <td style="text-align:right;"> 0 </td>
777
+ <td style="text-align:right;"> 0 </td>
778
+ <td style="text-align:right;"> 3 </td>
779
+ <td style="text-align:right;"> 4 </td>
780
+ </tr>
781
+ <tr>
782
+ <td style="text-align:left;"> Merc 240D </td>
783
+ <td style="text-align:right;"> 24.4 </td>
784
+ <td style="text-align:right;"> 4 </td>
785
+ <td style="text-align:right;"> 146.7 </td>
786
+ <td style="text-align:right;"> 62 </td>
787
+ <td style="text-align:right;"> 3.69 </td>
788
+ <td style="text-align:right;"> 3.190 </td>
789
+ <td style="text-align:right;"> 20.00 </td>
790
+ <td style="text-align:right;"> 1 </td>
791
+ <td style="text-align:right;"> 0 </td>
792
+ <td style="text-align:right;"> 4 </td>
793
+ <td style="text-align:right;"> 2 </td>
794
+ </tr>
795
+ <tr>
796
+ <td style="text-align:left;"> Merc 230 </td>
797
+ <td style="text-align:right;"> 22.8 </td>
798
+ <td style="text-align:right;"> 4 </td>
799
+ <td style="text-align:right;"> 140.8 </td>
800
+ <td style="text-align:right;"> 95 </td>
801
+ <td style="text-align:right;"> 3.92 </td>
802
+ <td style="text-align:right;"> 3.150 </td>
803
+ <td style="text-align:right;"> 22.90 </td>
804
+ <td style="text-align:right;"> 1 </td>
805
+ <td style="text-align:right;"> 0 </td>
806
+ <td style="text-align:right;"> 4 </td>
807
+ <td style="text-align:right;"> 2 </td>
808
+ </tr>
809
+ <tr>
810
+ <td style="text-align:left;"> Merc 280 </td>
811
+ <td style="text-align:right;"> 19.2 </td>
812
+ <td style="text-align:right;"> 6 </td>
813
+ <td style="text-align:right;"> 167.6 </td>
814
+ <td style="text-align:right;"> 123 </td>
815
+ <td style="text-align:right;"> 3.92 </td>
816
+ <td style="text-align:right;"> 3.440 </td>
817
+ <td style="text-align:right;"> 18.30 </td>
818
+ <td style="text-align:right;"> 1 </td>
819
+ <td style="text-align:right;"> 0 </td>
820
+ <td style="text-align:right;"> 4 </td>
821
+ <td style="text-align:right;"> 4 </td>
822
+ </tr>
823
+ <tr>
824
+ <td style="text-align:left;"> Merc 280C </td>
825
+ <td style="text-align:right;"> 17.8 </td>
826
+ <td style="text-align:right;"> 6 </td>
827
+ <td style="text-align:right;"> 167.6 </td>
828
+ <td style="text-align:right;"> 123 </td>
829
+ <td style="text-align:right;"> 3.92 </td>
830
+ <td style="text-align:right;"> 3.440 </td>
831
+ <td style="text-align:right;"> 18.90 </td>
832
+ <td style="text-align:right;"> 1 </td>
833
+ <td style="text-align:right;"> 0 </td>
834
+ <td style="text-align:right;"> 4 </td>
835
+ <td style="text-align:right;"> 4 </td>
836
+ </tr>
837
+ <tr>
838
+ <td style="text-align:left;"> Merc 450SE </td>
839
+ <td style="text-align:right;"> 16.4 </td>
840
+ <td style="text-align:right;"> 8 </td>
841
+ <td style="text-align:right;"> 275.8 </td>
842
+ <td style="text-align:right;"> 180 </td>
843
+ <td style="text-align:right;"> 3.07 </td>
844
+ <td style="text-align:right;"> 4.070 </td>
845
+ <td style="text-align:right;"> 17.40 </td>
846
+ <td style="text-align:right;"> 0 </td>
847
+ <td style="text-align:right;"> 0 </td>
848
+ <td style="text-align:right;"> 3 </td>
849
+ <td style="text-align:right;"> 3 </td>
850
+ </tr>
851
+ <tr>
852
+ <td style="text-align:left;"> Merc 450SL </td>
853
+ <td style="text-align:right;"> 17.3 </td>
854
+ <td style="text-align:right;"> 8 </td>
855
+ <td style="text-align:right;"> 275.8 </td>
856
+ <td style="text-align:right;"> 180 </td>
857
+ <td style="text-align:right;"> 3.07 </td>
858
+ <td style="text-align:right;"> 3.730 </td>
859
+ <td style="text-align:right;"> 17.60 </td>
860
+ <td style="text-align:right;"> 0 </td>
861
+ <td style="text-align:right;"> 0 </td>
862
+ <td style="text-align:right;"> 3 </td>
863
+ <td style="text-align:right;"> 3 </td>
864
+ </tr>
865
+ <tr>
866
+ <td style="text-align:left;"> Merc 450SLC </td>
867
+ <td style="text-align:right;"> 15.2 </td>
868
+ <td style="text-align:right;"> 8 </td>
869
+ <td style="text-align:right;"> 275.8 </td>
870
+ <td style="text-align:right;"> 180 </td>
871
+ <td style="text-align:right;"> 3.07 </td>
872
+ <td style="text-align:right;"> 3.780 </td>
873
+ <td style="text-align:right;"> 18.00 </td>
874
+ <td style="text-align:right;"> 0 </td>
875
+ <td style="text-align:right;"> 0 </td>
876
+ <td style="text-align:right;"> 3 </td>
877
+ <td style="text-align:right;"> 3 </td>
878
+ </tr>
879
+ <tr>
880
+ <td style="text-align:left;"> Cadillac Fleetwood </td>
881
+ <td style="text-align:right;"> 10.4 </td>
882
+ <td style="text-align:right;"> 8 </td>
883
+ <td style="text-align:right;"> 472.0 </td>
884
+ <td style="text-align:right;"> 205 </td>
885
+ <td style="text-align:right;"> 2.93 </td>
886
+ <td style="text-align:right;"> 5.250 </td>
887
+ <td style="text-align:right;"> 17.98 </td>
888
+ <td style="text-align:right;"> 0 </td>
889
+ <td style="text-align:right;"> 0 </td>
890
+ <td style="text-align:right;"> 3 </td>
891
+ <td style="text-align:right;"> 4 </td>
892
+ </tr>
893
+ <tr>
894
+ <td style="text-align:left;"> Lincoln Continental </td>
895
+ <td style="text-align:right;"> 10.4 </td>
896
+ <td style="text-align:right;"> 8 </td>
897
+ <td style="text-align:right;"> 460.0 </td>
898
+ <td style="text-align:right;"> 215 </td>
899
+ <td style="text-align:right;"> 3.00 </td>
900
+ <td style="text-align:right;"> 5.424 </td>
901
+ <td style="text-align:right;"> 17.82 </td>
902
+ <td style="text-align:right;"> 0 </td>
903
+ <td style="text-align:right;"> 0 </td>
904
+ <td style="text-align:right;"> 3 </td>
905
+ <td style="text-align:right;"> 4 </td>
906
+ </tr>
907
+ <tr>
908
+ <td style="text-align:left;"> Chrysler Imperial </td>
909
+ <td style="text-align:right;"> 14.7 </td>
910
+ <td style="text-align:right;"> 8 </td>
911
+ <td style="text-align:right;"> 440.0 </td>
912
+ <td style="text-align:right;"> 230 </td>
913
+ <td style="text-align:right;"> 3.23 </td>
914
+ <td style="text-align:right;"> 5.345 </td>
915
+ <td style="text-align:right;"> 17.42 </td>
916
+ <td style="text-align:right;"> 0 </td>
917
+ <td style="text-align:right;"> 0 </td>
918
+ <td style="text-align:right;"> 3 </td>
919
+ <td style="text-align:right;"> 4 </td>
920
+ </tr>
921
+ <tr>
922
+ <td style="text-align:left;"> Fiat 128 </td>
923
+ <td style="text-align:right;"> 32.4 </td>
924
+ <td style="text-align:right;"> 4 </td>
925
+ <td style="text-align:right;"> 78.7 </td>
926
+ <td style="text-align:right;"> 66 </td>
927
+ <td style="text-align:right;"> 4.08 </td>
928
+ <td style="text-align:right;"> 2.200 </td>
929
+ <td style="text-align:right;"> 19.47 </td>
930
+ <td style="text-align:right;"> 1 </td>
931
+ <td style="text-align:right;"> 1 </td>
932
+ <td style="text-align:right;"> 4 </td>
933
+ <td style="text-align:right;"> 1 </td>
934
+ </tr>
935
+ <tr>
936
+ <td style="text-align:left;"> Honda Civic </td>
937
+ <td style="text-align:right;"> 30.4 </td>
938
+ <td style="text-align:right;"> 4 </td>
939
+ <td style="text-align:right;"> 75.7 </td>
940
+ <td style="text-align:right;"> 52 </td>
941
+ <td style="text-align:right;"> 4.93 </td>
942
+ <td style="text-align:right;"> 1.615 </td>
943
+ <td style="text-align:right;"> 18.52 </td>
944
+ <td style="text-align:right;"> 1 </td>
945
+ <td style="text-align:right;"> 1 </td>
946
+ <td style="text-align:right;"> 4 </td>
947
+ <td style="text-align:right;"> 2 </td>
948
+ </tr>
949
+ <tr>
950
+ <td style="text-align:left;"> Toyota Corolla </td>
951
+ <td style="text-align:right;"> 33.9 </td>
952
+ <td style="text-align:right;"> 4 </td>
953
+ <td style="text-align:right;"> 71.1 </td>
954
+ <td style="text-align:right;"> 65 </td>
955
+ <td style="text-align:right;"> 4.22 </td>
956
+ <td style="text-align:right;"> 1.835 </td>
957
+ <td style="text-align:right;"> 19.90 </td>
958
+ <td style="text-align:right;"> 1 </td>
959
+ <td style="text-align:right;"> 1 </td>
960
+ <td style="text-align:right;"> 4 </td>
961
+ <td style="text-align:right;"> 1 </td>
962
+ </tr>
963
+ <tr>
964
+ <td style="text-align:left;"> Toyota Corona </td>
965
+ <td style="text-align:right;"> 21.5 </td>
966
+ <td style="text-align:right;"> 4 </td>
967
+ <td style="text-align:right;"> 120.1 </td>
968
+ <td style="text-align:right;"> 97 </td>
969
+ <td style="text-align:right;"> 3.70 </td>
970
+ <td style="text-align:right;"> 2.465 </td>
971
+ <td style="text-align:right;"> 20.01 </td>
972
+ <td style="text-align:right;"> 1 </td>
973
+ <td style="text-align:right;"> 0 </td>
974
+ <td style="text-align:right;"> 3 </td>
975
+ <td style="text-align:right;"> 1 </td>
976
+ </tr>
977
+ <tr>
978
+ <td style="text-align:left;"> Dodge Challenger </td>
979
+ <td style="text-align:right;"> 15.5 </td>
980
+ <td style="text-align:right;"> 8 </td>
981
+ <td style="text-align:right;"> 318.0 </td>
982
+ <td style="text-align:right;"> 150 </td>
983
+ <td style="text-align:right;"> 2.76 </td>
984
+ <td style="text-align:right;"> 3.520 </td>
985
+ <td style="text-align:right;"> 16.87 </td>
986
+ <td style="text-align:right;"> 0 </td>
987
+ <td style="text-align:right;"> 0 </td>
988
+ <td style="text-align:right;"> 3 </td>
989
+ <td style="text-align:right;"> 2 </td>
990
+ </tr>
991
+ <tr>
992
+ <td style="text-align:left;"> AMC Javelin </td>
993
+ <td style="text-align:right;"> 15.2 </td>
994
+ <td style="text-align:right;"> 8 </td>
995
+ <td style="text-align:right;"> 304.0 </td>
996
+ <td style="text-align:right;"> 150 </td>
997
+ <td style="text-align:right;"> 3.15 </td>
998
+ <td style="text-align:right;"> 3.435 </td>
999
+ <td style="text-align:right;"> 17.30 </td>
1000
+ <td style="text-align:right;"> 0 </td>
1001
+ <td style="text-align:right;"> 0 </td>
1002
+ <td style="text-align:right;"> 3 </td>
1003
+ <td style="text-align:right;"> 2 </td>
1004
+ </tr>
1005
+ <tr>
1006
+ <td style="text-align:left;"> Camaro Z28 </td>
1007
+ <td style="text-align:right;"> 13.3 </td>
1008
+ <td style="text-align:right;"> 8 </td>
1009
+ <td style="text-align:right;"> 350.0 </td>
1010
+ <td style="text-align:right;"> 245 </td>
1011
+ <td style="text-align:right;"> 3.73 </td>
1012
+ <td style="text-align:right;"> 3.840 </td>
1013
+ <td style="text-align:right;"> 15.41 </td>
1014
+ <td style="text-align:right;"> 0 </td>
1015
+ <td style="text-align:right;"> 0 </td>
1016
+ <td style="text-align:right;"> 3 </td>
1017
+ <td style="text-align:right;"> 4 </td>
1018
+ </tr>
1019
+ <tr>
1020
+ <td style="text-align:left;"> Pontiac Firebird </td>
1021
+ <td style="text-align:right;"> 19.2 </td>
1022
+ <td style="text-align:right;"> 8 </td>
1023
+ <td style="text-align:right;"> 400.0 </td>
1024
+ <td style="text-align:right;"> 175 </td>
1025
+ <td style="text-align:right;"> 3.08 </td>
1026
+ <td style="text-align:right;"> 3.845 </td>
1027
+ <td style="text-align:right;"> 17.05 </td>
1028
+ <td style="text-align:right;"> 0 </td>
1029
+ <td style="text-align:right;"> 0 </td>
1030
+ <td style="text-align:right;"> 3 </td>
1031
+ <td style="text-align:right;"> 2 </td>
1032
+ </tr>
1033
+ <tr>
1034
+ <td style="text-align:left;"> Fiat X1-9 </td>
1035
+ <td style="text-align:right;"> 27.3 </td>
1036
+ <td style="text-align:right;"> 4 </td>
1037
+ <td style="text-align:right;"> 79.0 </td>
1038
+ <td style="text-align:right;"> 66 </td>
1039
+ <td style="text-align:right;"> 4.08 </td>
1040
+ <td style="text-align:right;"> 1.935 </td>
1041
+ <td style="text-align:right;"> 18.90 </td>
1042
+ <td style="text-align:right;"> 1 </td>
1043
+ <td style="text-align:right;"> 1 </td>
1044
+ <td style="text-align:right;"> 4 </td>
1045
+ <td style="text-align:right;"> 1 </td>
1046
+ </tr>
1047
+ <tr>
1048
+ <td style="text-align:left;"> Porsche 914-2 </td>
1049
+ <td style="text-align:right;"> 26.0 </td>
1050
+ <td style="text-align:right;"> 4 </td>
1051
+ <td style="text-align:right;"> 120.3 </td>
1052
+ <td style="text-align:right;"> 91 </td>
1053
+ <td style="text-align:right;"> 4.43 </td>
1054
+ <td style="text-align:right;"> 2.140 </td>
1055
+ <td style="text-align:right;"> 16.70 </td>
1056
+ <td style="text-align:right;"> 0 </td>
1057
+ <td style="text-align:right;"> 1 </td>
1058
+ <td style="text-align:right;"> 5 </td>
1059
+ <td style="text-align:right;"> 2 </td>
1060
+ </tr>
1061
+ <tr>
1062
+ <td style="text-align:left;"> Lotus Europa </td>
1063
+ <td style="text-align:right;"> 30.4 </td>
1064
+ <td style="text-align:right;"> 4 </td>
1065
+ <td style="text-align:right;"> 95.1 </td>
1066
+ <td style="text-align:right;"> 113 </td>
1067
+ <td style="text-align:right;"> 3.77 </td>
1068
+ <td style="text-align:right;"> 1.513 </td>
1069
+ <td style="text-align:right;"> 16.90 </td>
1070
+ <td style="text-align:right;"> 1 </td>
1071
+ <td style="text-align:right;"> 1 </td>
1072
+ <td style="text-align:right;"> 5 </td>
1073
+ <td style="text-align:right;"> 2 </td>
1074
+ </tr>
1075
+ <tr>
1076
+ <td style="text-align:left;"> Ford Pantera L </td>
1077
+ <td style="text-align:right;"> 15.8 </td>
1078
+ <td style="text-align:right;"> 8 </td>
1079
+ <td style="text-align:right;"> 351.0 </td>
1080
+ <td style="text-align:right;"> 264 </td>
1081
+ <td style="text-align:right;"> 4.22 </td>
1082
+ <td style="text-align:right;"> 3.170 </td>
1083
+ <td style="text-align:right;"> 14.50 </td>
1084
+ <td style="text-align:right;"> 0 </td>
1085
+ <td style="text-align:right;"> 1 </td>
1086
+ <td style="text-align:right;"> 5 </td>
1087
+ <td style="text-align:right;"> 4 </td>
1088
+ </tr>
1089
+ <tr>
1090
+ <td style="text-align:left;"> Ferrari Dino </td>
1091
+ <td style="text-align:right;"> 19.7 </td>
1092
+ <td style="text-align:right;"> 6 </td>
1093
+ <td style="text-align:right;"> 145.0 </td>
1094
+ <td style="text-align:right;"> 175 </td>
1095
+ <td style="text-align:right;"> 3.62 </td>
1096
+ <td style="text-align:right;"> 2.770 </td>
1097
+ <td style="text-align:right;"> 15.50 </td>
1098
+ <td style="text-align:right;"> 0 </td>
1099
+ <td style="text-align:right;"> 1 </td>
1100
+ <td style="text-align:right;"> 5 </td>
1101
+ <td style="text-align:right;"> 6 </td>
1102
+ </tr>
1103
+ <tr>
1104
+ <td style="text-align:left;"> Maserati Bora </td>
1105
+ <td style="text-align:right;"> 15.0 </td>
1106
+ <td style="text-align:right;"> 8 </td>
1107
+ <td style="text-align:right;"> 301.0 </td>
1108
+ <td style="text-align:right;"> 335 </td>
1109
+ <td style="text-align:right;"> 3.54 </td>
1110
+ <td style="text-align:right;"> 3.570 </td>
1111
+ <td style="text-align:right;"> 14.60 </td>
1112
+ <td style="text-align:right;"> 0 </td>
1113
+ <td style="text-align:right;"> 1 </td>
1114
+ <td style="text-align:right;"> 5 </td>
1115
+ <td style="text-align:right;"> 8 </td>
1116
+ </tr>
1117
+ <tr>
1118
+ <td style="text-align:left;"> Volvo 142E </td>
1119
+ <td style="text-align:right;"> 21.4 </td>
1120
+ <td style="text-align:right;"> 4 </td>
1121
+ <td style="text-align:right;"> 121.0 </td>
1122
+ <td style="text-align:right;"> 109 </td>
1123
+ <td style="text-align:right;"> 4.11 </td>
1124
+ <td style="text-align:right;"> 2.780 </td>
1125
+ <td style="text-align:right;"> 18.60 </td>
1126
+ <td style="text-align:right;"> 1 </td>
1127
+ <td style="text-align:right;"> 1 </td>
1128
+ <td style="text-align:right;"> 4 </td>
1129
+ <td style="text-align:right;"> 2 </td>
1130
+ </tr>
1131
+ </tbody>
1132
+ </table>
1133
+
1134
+ ### Including Ruby files in a chunk
1135
+
1136
+ R is a language that was created to be easy and fast for statisticians to use. As far
1137
+ as I know, it was not a
1138
+ language to be used for developing large systems. Of course, there are large systems and
1139
+ libraries in R, but the focus of the language is for developing statistical models and
1140
+ distribute that to peers.
1141
+
1142
+ Ruby on the other hand, is a language for large software development. Systems written in
1143
+ Ruby will have dozens, hundreds or even thousands of files. To document a
1144
+ large system with literate programming, we cannot expect the developer to add all the
1145
+ files in a single '.Rmd' file. gKnit provides the 'include' chunk engine to include
1146
+ a Ruby file as if it had being typed in the '.Rmd' file.
1147
+
1148
+ To include a file, the following chunk should be created, where <filename> is the name of
1149
+ the file to be included and where the extension, if it is '.rb', does not need to be added.
1150
+ If the 'relative' option is not included, then it is treated as TRUE. When 'relative' is
1151
+ true, ruby's 'require\_relative' semantics is used to load the file, when false, Ruby's
1152
+ \$LOAD_PATH is searched to find the file and it is 'require'd.
1153
+
1154
+ ````
1155
+ ```{include <filename>, relative = <TRUE/FALSE>}
1156
+ ```
1157
+ ````
1158
+
1159
+ Below we include file 'model.rb', which is in the same directory of this blog.
1160
+ This code uses R 'caret' package to split a dataset in a train and test sets.
1161
+ The 'caret' package is a very important a useful package for doing Data Analysis,
1162
+ it has hundreds of functions for all steps of the Data Analysis workflow. To
1163
+ use 'caret' just to split a dataset is like using the proverbial cannon to
1164
+ kill the fly. We use it here only to show that integrating Ruby and R and
1165
+ using even a very complex package as 'caret' is trivial with Galaaz.
1166
+
1167
+ A word of advice: the 'caret' package has lots of dependencies and installing
1168
+ it in a Linux system is a time consuming operation. Method 'R.install_and_loads'
1169
+ will install the package if it is not already installed and can take a while.
1170
+
1171
+ ````
1172
+ ```{include model}
1173
+ ```
1174
+ ````
1175
+
1176
+
1177
+ ``` include
1178
+ require 'galaaz'
1179
+
1180
+ # Loads the R 'caret' package. If not present, installs it
1181
+ R.install_and_loads 'caret'
1182
+
1183
+ class Model
1184
+
1185
+ attr_reader :data
1186
+ attr_reader :test
1187
+ attr_reader :train
1188
+
1189
+ #==========================================================
1190
+ #
1191
+ #==========================================================
1192
+
1193
+ def initialize(data, percent_train:, seed: 123)
1194
+
1195
+ R.set__seed(seed)
1196
+ @data = data
1197
+ @percent_train = percent_train
1198
+ @seed = seed
1199
+
1200
+ end
1201
+
1202
+ #==========================================================
1203
+ #
1204
+ #==========================================================
1205
+
1206
+ def partition(field)
1207
+
1208
+ train_index =
1209
+ R.createDataPartition(@data.send(field), p: @percent_train,
1210
+ list: false, times: 1)
1211
+ @train = @data[train_index, :all]
1212
+ @test = @data[-train_index, :all]
1213
+
1214
+ end
1215
+
1216
+ end
1217
+ ```
1218
+
1219
+
1220
+ ``` ruby
1221
+ mtcars = ~R[:mtcars]
1222
+ model = Model.new(mtcars, percent_train: 0.8)
1223
+ model.partition(:mpg)
1224
+ puts model.train.head
1225
+ puts model.test.head
1226
+ ```
1227
+
1228
+ ```
1229
+ ## mpg cyl disp hp drat wt qsec vs am gear carb
1230
+ ## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
1231
+ ## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
1232
+ ## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
1233
+ ## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
1234
+ ## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
1235
+ ## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
1236
+ ## mpg cyl disp hp drat wt qsec vs am gear carb
1237
+ ## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
1238
+ ## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
1239
+ ## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
1240
+ ## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
1241
+ ```
1242
+
1243
+ ### Documenting Gems
1244
+
1245
+ gKnit also allows developers to document and load files that are not in the same directory
1246
+ of the '.Rmd' file.
1247
+
1248
+ Here is an example of loading the 'find.rb' file from **JRuby** (via `$LOAD_PATH`). In this example, relative
1249
+ is set to FALSE, so Ruby will look for the file in its $LOAD\_PATH, and the user does not
1250
+ need to know its directory.
1251
+
1252
+ ````
1253
+ ```{include find, relative = FALSE}
1254
+ ```
1255
+ ````
1256
+
1257
+
1258
+ ``` include
1259
+ # frozen_string_literal: true
1260
+ #
1261
+ # find.rb: the Find module for processing all files under a given directory.
1262
+ #
1263
+
1264
+ #
1265
+ # The +Find+ module supports the top-down traversal of a set of file paths.
1266
+ #
1267
+ # For example, to total the size of all files under your home directory,
1268
+ # ignoring anything in a "dot" directory (e.g. $HOME/.ssh):
1269
+ #
1270
+ # require 'find'
1271
+ #
1272
+ # total_size = 0
1273
+ #
1274
+ # Find.find(ENV["HOME"]) do |path|
1275
+ # if FileTest.directory?(path)
1276
+ # if File.basename(path).start_with?('.')
1277
+ # Find.prune # Don't look any further into this directory.
1278
+ # else
1279
+ # next
1280
+ # end
1281
+ # else
1282
+ # total_size += FileTest.size(path)
1283
+ # end
1284
+ # end
1285
+ #
1286
+ module Find
1287
+
1288
+ VERSION = "0.2.0"
1289
+
1290
+ #
1291
+ # Calls the associated block with the name of every file and directory listed
1292
+ # as arguments, then recursively on their subdirectories, and so on.
1293
+ #
1294
+ # Returns an enumerator if no block is given.
1295
+ #
1296
+ # See the +Find+ module documentation for an example.
1297
+ #
1298
+ def find(*paths, ignore_error: true) # :yield: path
1299
+ block_given? or return enum_for(__method__, *paths, ignore_error: ignore_error)
1300
+
1301
+ fs_encoding = Encoding.find("filesystem")
1302
+
1303
+ paths.collect!{|d| raise Errno::ENOENT, d unless File.exist?(d); d.dup}.each do |path|
1304
+ path = path.to_path if path.respond_to? :to_path
1305
+ enc = path.encoding == Encoding::US_ASCII ? fs_encoding : path.encoding
1306
+ ps = [path]
1307
+ while file = ps.shift
1308
+ catch(:prune) do
1309
+ yield file.dup
1310
+ begin
1311
+ s = File.lstat(file)
1312
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG, Errno::EINVAL
1313
+ raise unless ignore_error
1314
+ next
1315
+ end
1316
+ if s.directory? then
1317
+ begin
1318
+ fs = Dir.children(file, encoding: enc)
1319
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG, Errno::EINVAL
1320
+ raise unless ignore_error
1321
+ next
1322
+ end
1323
+ fs.sort!
1324
+ fs.reverse_each {|f|
1325
+ f = File.join(file, f)
1326
+ ps.unshift f
1327
+ }
1328
+ end
1329
+ end
1330
+ end
1331
+ end
1332
+ nil
1333
+ end
1334
+
1335
+ #
1336
+ # Skips the current file or directory, restarting the loop with the next
1337
+ # entry. If the current file is a directory, that directory will not be
1338
+ # recursively entered. Meaningful only within the block associated with
1339
+ # Find:R[:find].
1340
+ #
1341
+ # See the +Find+ module documentation for an example.
1342
+ #
1343
+ def prune
1344
+ throw :prune
1345
+ end
1346
+
1347
+ module_function :find, :prune
1348
+ end
1349
+ ```
1350
+
1351
+ ## Converting to PDF
1352
+
1353
+ One of the beauties of knitr is that the same input can be converted to many different outputs.
1354
+ One very useful format, is, of course, PDF. In order to converted an __R markdown__ file to PDF
1355
+ it is necessary to have LaTeX installed on the system. We will not explain here how to
1356
+ install LaTeX as there are plenty of documents on the web showing how to proceed.
1357
+
1358
+ gKnit comes with a simple LaTeX style file for gknitting this blog as a PDF document. Here is
1359
+ the Yaml header to generate this blog in PDF format instead of HTML:
1360
+
1361
+ ```
1362
+ ---
1363
+ title: "gKnit - Ruby and R Knitting with Galaaz (JRuby + GNU R)"
1364
+ author: "Rodrigo Botafogo"
1365
+ tags: [Galaaz, Ruby, R, JRuby, "GNU R", knitr, gknit]
1366
+ date: "29 October 2018"
1367
+ output:
1368
+ pdf\_document:
1369
+ includes:
1370
+ in\_header: ["../../sty/galaaz.sty"]
1371
+ number\_sections: yes
1372
+ ---
1373
+ ```
1374
+
1375
+
1376
+ # Conclusion
1377
+
1378
+ In order to do reproducible research, one of the main basic tools needed is a system that
1379
+ allows "literate programming" where text, code and possibly a set of files can be compiled
1380
+ onto a report that can be easily distributed to peers. Peers should be able to use this
1381
+ same set of files to rerun the compilation by their own obtaining the exact same original
1382
+ report. gKnit is such a system for Ruby and R. It uses __R Markdown__ to integrate
1383
+ text and code chunks, where code chunks can either be part of the __R Markdown__ file or
1384
+ be imported from files in the system. Ideally, in reproducible research, all the files
1385
+ needed to rebuild a report should be easily packed together (in the same zipped directory)
1386
+ and distributed to peers for reexecution.
1387
+
1388
+ **Galaaz 2.0** pairs **JRuby** with **GNU R**: you keep the full CRAN/Bioconductor world in R while
1389
+ writing orchestration, reuse, and application code in Ruby. The effort to wrap Ruby over R (Galaaz)
1390
+ and to wrap Knitr as gKnit was tiny compared to reimplementing R’s ecosystem in Ruby—much like
1391
+ Python’s investment in NumPy and Pandas, which no Ruby project is likely to duplicate.
1392
+
1393
+ An **earlier** prototype used Oracle’s **GraalVM** and Truffle interop; the **current** stack is
1394
+ deliberately **standard GNU R** plus the Galaaz **bridge**, documented in the project manual.
1395
+
1396
+ More interesting than wrapping the R libraries with Ruby, is that Ruby adds
1397
+ value to R, by allowing developers to use powerful and modern constructs for code reuse that
1398
+ are not the strong points of R. As shown in this blog, R and Ruby can easily communicate
1399
+ and R can be structured in classes and modules in a way that greatly expands its power and
1400
+ readability.
1401
+
1402
+ # Installing gKnit
1403
+
1404
+ ## Prerequisites (Galaaz 2.0)
1405
+
1406
+ * **JRuby** and a compatible **JDK**
1407
+ * **GNU R** on your `PATH`
1408
+
1409
+ The following R packages will be automatically installed when necessary, but could be installed prior
1410
+ to using gKnit if desired:
1411
+
1412
+ * ggplot2
1413
+ * gridExtra
1414
+ * knitr
1415
+
1416
+ Installation of R packages requires a development environment and can be time consuming. On Linux,
1417
+ the usual build tools are typically enough. On macOS, Xcode command-line tools are commonly required.
1418
+
1419
+ ## Preparation
1420
+
1421
+ * Install the **galaaz** gem (RubyGems or a local build / `path:`).
1422
+
1423
+ ## Usage
1424
+
1425
+ * **`bin/gknit`** \<filename\> (from the Galaaz repo or your install layout); use **`--output_format all`** for HTML and PDF together.
1426
+ * Run Ruby with **`bin/galaaz-jruby`** when you need the same JVM flags as the project (see the manual).
1427
+
1428
+
1429
+ # References
1430
+