galaaz 0.5.0 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/LICENSE +0 -0
- data/README.md +1360 -636
- data/Rakefile +61 -41
- data/bin/galaaz-bootstrap +137 -0
- data/bin/galaaz-jruby +14 -0
- data/bin/galaaz_jruby_env.inc.sh +6 -0
- data/bin/gbookdown +64 -0
- data/bin/gknit +84 -13
- data/bin/gknit-draft.rb +0 -0
- data/bin/gstudio +5 -3
- data/bin/gstudio_irb.rb +0 -0
- data/bin/gstudio_pry.rb +0 -0
- data/bin/install-tinytex +6 -0
- data/bin/run_all_rspec +43 -0
- data/bin/run_example +14 -0
- data/bin/run_old_rspec +19 -0
- data/bin/run_rspec +23 -0
- data/bin/run_rspec_subset +38 -0
- data/bin/run_slow_rspec +19 -0
- data/blogs/R-on-Rails-Planning-Document.md +940 -0
- data/blogs/README.md +100 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
- data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.md +115 -155
- data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
- data/blogs/galaaz_ggplot/midwest_external_png +0 -0
- data/blogs/gknit/gknit.Rmd +47 -52
- data/blogs/gknit/gknit.md +1430 -0
- data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
- data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
- data/blogs/gknit/lst.rds +0 -0
- data/blogs/gknit/model.rb +1 -1
- data/blogs/gknit/stats.bib +0 -0
- data/blogs/manual/include_model_local_repro.Rmd +14 -0
- data/blogs/manual/include_model_local_repro.md +75 -0
- data/blogs/manual/lst.rds +0 -0
- data/blogs/manual/manual.Rmd +852 -239
- data/blogs/manual/manual.log +1786 -0
- data/blogs/manual/manual.md +1360 -636
- data/blogs/manual/manual.tex +1883 -1161
- data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
- data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
- data/blogs/manual/model.rb +1 -1
- data/blogs/nse_dplyr/nse_dplyr.Rmd +84 -111
- data/blogs/nse_dplyr/nse_dplyr.log +928 -0
- data/blogs/nse_dplyr/nse_dplyr.md +198 -229
- data/blogs/oh_my/not_so.rb +0 -0
- data/blogs/oh_my/oh_my.Rmd +1234 -25
- data/blogs/oh_my/oh_my.log +804 -0
- data/blogs/oh_my/oh_my.md +1663 -86
- data/blogs/oh_my/oh_my.tex +821 -0
- data/blogs/oh_my/old.Rmd +15 -14
- data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
- data/blogs/ruby_plot/ruby_plot.log +885 -0
- data/blogs/ruby_plot/ruby_plot.md +71 -102
- data/blogs/ruby_plot/ruby_plot.tex +940 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
- data/blogs/test/test.Rmd +14 -0
- data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
- data/examples/50Plots_MasterList/ScatterPlot.rb +0 -0
- data/examples/50Plots_MasterList/scatter_plot.rb +0 -0
- data/examples/Bibliography/master.bib +0 -0
- data/examples/Bibliography/stats.bib +0 -0
- data/examples/R/calc.R +0 -0
- data/examples/R/java_interop.R +0 -0
- data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
- data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +53 -0
- data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +33 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
- data/examples/islr/all.rb +13 -0
- data/examples/islr/ch2.spec.rb +37 -7
- data/examples/islr/ch3.spec.rb +11 -2
- data/examples/islr/ch3_boston.rb +27 -0
- data/examples/islr/ch3_multiple_regression.rb +0 -0
- data/examples/islr/ch6.spec.rb +24 -1
- data/examples/islr/x_y_rnorm.jpg +0 -0
- data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +0 -0
- data/examples/latex_templates/Test-acm_article/sigproc.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-my_output.bib +0 -0
- data/examples/latex_templates/Test-aea_article/BibFile.bib +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +0 -0
- data/examples/latex_templates/Test-aea_article/references.bib +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +0 -0
- data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +0 -0
- data/examples/latex_templates/Test-ieee_article/mybibfile.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJournal.sty +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +0 -0
- data/examples/misc/baseball.csv +0 -0
- data/examples/misc/ggplot.rb +3 -2
- data/examples/misc/moneyball.rb +0 -0
- data/examples/misc/subsetting.rb +0 -0
- data/examples/multithread_shards_to_r/shards_to_r.rb +67 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +0 -0
- data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +0 -0
- data/examples/sthda_ggplot/README.md +0 -0
- data/examples/sthda_ggplot/RUN.md +41 -0
- data/examples/sthda_ggplot/all.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +2 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/stat.rb +0 -0
- data/examples/sthda_ggplot/one_variable_discrete/bar.rb +0 -0
- data/examples/sthda_ggplot/qplots/box_violin_dot.rb +0 -0
- data/examples/sthda_ggplot/qplots/scatter_plots.rb +0 -0
- data/examples/sthda_ggplot/scatter_gg.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +4 -3
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +0 -0
- data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +0 -0
- data/ext/new_bridge/Makefile +46 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
- data/lib/R_interface/galaaz_device.R +20 -0
- data/lib/R_interface/include_engine.R +109 -0
- data/lib/R_interface/new_bridge_adapter.rb +824 -0
- data/lib/R_interface/r.rb +177 -25
- data/lib/R_interface/r_arrow.rb +113 -0
- data/lib/R_interface/r_libs.R +3 -3
- data/lib/R_interface/r_methods.rb +13 -126
- data/lib/R_interface/r_module_s.rb +0 -0
- data/lib/R_interface/rbinary_operators.rb +20 -2
- data/lib/R_interface/rclosure.rb +5 -1
- data/lib/R_interface/rdata_frame.rb +34 -70
- data/lib/R_interface/rdevice.rb +125 -0
- data/lib/R_interface/rdevices.R +0 -0
- data/lib/R_interface/renvironment.rb +10 -4
- data/lib/R_interface/rexpression.rb +5 -1
- data/lib/R_interface/rindexed_object.rb +41 -13
- data/lib/R_interface/rlanguage.rb +20 -62
- data/lib/R_interface/rlist.rb +115 -25
- data/lib/R_interface/rlogical_operators.rb +0 -0
- data/lib/R_interface/rmatrix.rb +2 -11
- data/lib/R_interface/rmd_indexed_object.rb +5 -1
- data/lib/R_interface/robject.rb +348 -290
- data/lib/R_interface/rpkg.rb +0 -0
- data/lib/R_interface/rsupport.rb +609 -328
- data/lib/R_interface/rsupport_scope.rb +2 -1
- data/lib/R_interface/rsymbol.rb +50 -0
- data/lib/R_interface/ruby_callback.rb +2 -3
- data/lib/R_interface/ruby_extensions.rb +225 -175
- data/lib/R_interface/runary_operators.rb +0 -0
- data/lib/R_interface/rvector.rb +147 -31
- data/lib/galaaz.rb +0 -0
- data/lib/galaaz_jruby.rb +22 -0
- data/lib/gknit/diagnostics.rb +50 -0
- data/lib/gknit/draft.rb +23 -17
- data/lib/gknit/include_engine.rb +15 -7
- data/lib/gknit/knitr_engine.rb +223 -74
- data/lib/gknit/rb_engine.rb +3 -3
- data/lib/gknit/ruby_engine.rb +0 -0
- data/lib/gknit.rb +1 -0
- data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
- data/lib/new_bridge/envelope.rb +51 -0
- data/lib/new_bridge/eval_result.rb +26 -0
- data/lib/new_bridge/framing.rb +39 -0
- data/lib/new_bridge/instance_pool_client.rb +38 -0
- data/lib/new_bridge/r_instance_manager.rb +404 -0
- data/lib/new_bridge/session_client.rb +530 -0
- data/lib/new_bridge/tcp_framed.rb +44 -0
- data/lib/new_bridge.rb +9 -0
- data/lib/util/exec_ruby.rb +95 -20
- data/lib/util/inline_file.rb +35 -30
- data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
- data/new_bridge_specs/eval_r_async_spec.rb +113 -0
- data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
- data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
- data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
- data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
- data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
- data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
- data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
- data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
- data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
- data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
- data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
- data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
- data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
- data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
- data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
- data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
- data/r_requires/ggplot.rb +0 -0
- data/r_requires/knitr.rb +0 -0
- data/specs/all.rb +15 -11
- data/specs/arrow_from_ruby_batches_spec.rb +50 -0
- data/specs/arrow_semantics_spec.rb +64 -0
- data/specs/bridge_concurrent_spec.rb +46 -0
- data/specs/bridge_nested_spec.rb +25 -0
- data/specs/dataframe_semantics_spec.rb +122 -0
- data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
- data/specs/dispatch_probe_cache_spec.rb +38 -0
- data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
- data/specs/dispatch_probe_fallback_spec.rb +18 -0
- data/specs/environment_semantics_spec.rb +89 -0
- data/specs/field_access_spec.rb +31 -0
- data/specs/figures/bg.jpeg +0 -0
- data/specs/figures/bg.png +0 -0
- data/specs/figures/bg.svg +168 -57
- data/specs/figures/dose_len.png +0 -0
- data/specs/figures/no_args.jpeg +0 -0
- data/specs/figures/no_args.png +0 -0
- data/specs/figures/no_args.svg +168 -57
- data/specs/figures/width_height.jpeg +0 -0
- data/specs/figures/width_height.png +0 -0
- data/specs/figures/width_height_units1.jpeg +0 -0
- data/specs/figures/width_height_units1.png +0 -0
- data/specs/figures/width_height_units2.jpeg +0 -0
- data/specs/figures/width_height_units2.png +0 -0
- data/specs/formula_semantics_spec.rb +81 -0
- data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
- data/specs/galaaz_util_inline_file_spec.rb +54 -0
- data/specs/gknit_cli_option_permutation_spec.rb +24 -0
- data/specs/gknit_include_engine_spec.rb +72 -0
- data/specs/gknit_install_timeout_report_spec.rb +69 -0
- data/specs/gknit_internal_error_report_spec.rb +57 -0
- data/specs/gknit_vector_map_output_spec.rb +59 -0
- data/specs/globalenv_guardrail_spec.rb +52 -0
- data/specs/language_expression_semantics_spec.rb +145 -0
- data/specs/list_semantics_spec.rb +111 -0
- data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
- data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
- data/specs/new_bridge_callback_timeout_spec.rb +69 -0
- data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
- data/specs/nil_null_spec.rb +42 -0
- data/specs/object_build_phase2_spec.rb +53 -0
- data/specs/phase1_callback_bridge_spec.rb +84 -0
- data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
- data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
- data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
- data/specs/plot_device_semantics_spec.rb +28 -0
- data/specs/plot_snapshot_semantics_spec.rb +58 -0
- data/specs/protocol_result_spec.rb +236 -0
- data/specs/r_batch_fail_fast_spec.rb +47 -0
- data/specs/r_bridge_bootstrap_spec.rb +11 -0
- data/specs/r_devices.spec.rb +1 -1
- data/specs/r_eval.spec.rb +16 -18
- data/specs/r_function.spec.rb +1 -1
- data/specs/r_instance_manager_spec.rb +285 -0
- data/specs/r_list_apply.spec.rb +15 -15
- data/specs/r_matrix.spec.rb +0 -0
- data/specs/r_nse.spec.rb +5 -5
- data/specs/r_object_send_dispatch_spec.rb +13 -0
- data/specs/r_vector_comparator_spec.rb +8 -0
- data/specs/r_vector_creation.spec.rb +0 -0
- data/specs/r_vector_functions.spec.rb +0 -0
- data/specs/r_vector_object.spec.rb +0 -0
- data/specs/r_vector_operators.spec.rb +0 -0
- data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
- data/specs/r_vector_subsetting.spec.rb +0 -0
- data/specs/range_helper_spec.rb +21 -0
- data/specs/rsupport_scope_spec.rb +28 -0
- data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
- data/specs/scalar_character_spec.rb +44 -0
- data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
- data/specs/session_env_bridge_spec.rb +25 -0
- data/specs/simplecov_bootstrap_spec.rb +10 -0
- data/specs/spec_helper.rb +10 -0
- data/specs/tmp.rb +0 -0
- data/specs/unboxing_recursion_regression_spec.rb +30 -0
- data/specs/unboxing_spec.rb +49 -0
- data/specs/verify_callbacks.rb +42 -0
- data/sty/galaaz.sty +0 -0
- data/version.rb +1 -1
- metadata +194 -64
- data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -520
- data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
- data/blogs/galaaz_ggplot/midwest.html +0 -188
- data/blogs/gknit/gknit.html +0 -2266
- data/blogs/gknit/gknit.pdf +0 -0
- data/blogs/manual/manual.html +0 -4638
- data/blogs/manual/manual.pdf +0 -0
- data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
- data/blogs/nse_dplyr/nse_dplyr.html +0 -878
- data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
- data/blogs/oh_my/oh_my.html +0 -568
- data/blogs/ruby_plot/ruby_plot.html +0 -544
- data/blogs/ruby_plot/ruby_plot.pdf +0 -0
- data/examples/latex_templates/Test-acs_article/Test-acs_article.pdf +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/pics/Figure2.pdf +0 -0
- data/examples/latex_templates/Test-asa_article/Test-asa_article.pdf +0 -0
- data/examples/latex_templates/Test-ieee_article/Test-ieee_article.pdf +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJwrapper.pdf +0 -0
- data/examples/latex_templates/Test-springer_article/Test-springer_article.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.pdf +0 -0
- data/specs/r_dataframe.spec.rb +0 -379
- data/specs/r_environment.spec.rb +0 -140
- data/specs/r_formula.spec.rb +0 -232
- data/specs/r_language.spec.rb +0 -112
- data/specs/r_list.spec.rb +0 -293
- data/specs/r_plots.spec.rb +0 -72
- data/specs/ruby_expression.spec.rb +0 -316
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/blogs/manual/model.rb
CHANGED
|
@@ -29,7 +29,7 @@ class Model
|
|
|
29
29
|
def partition(field)
|
|
30
30
|
|
|
31
31
|
train_index =
|
|
32
|
-
R.createDataPartition(@data.send(field), p: @
|
|
32
|
+
R.createDataPartition(@data.send(field), p: @percent_train,
|
|
33
33
|
list: false, times: 1)
|
|
34
34
|
@train = @data[train_index, :all]
|
|
35
35
|
@test = @data[-train_index, :all]
|
|
@@ -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,
|
|
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
|
|
@@ -29,7 +29,7 @@ library('tibble')
|
|
|
29
29
|
|
|
30
30
|
# Introduction
|
|
31
31
|
|
|
32
|
-
According to Steven Sagaert answer on Quora about
|
|
32
|
+
According to Steven Sagaert’s answer on Quora about “Is programming language R overrated?”:
|
|
33
33
|
|
|
34
34
|
> R is a sophisticated language with an unusual (i.e. non-mainstream) set of features. It‘s
|
|
35
35
|
> an impure functional programming language with sophisticated metaprogramming and 3
|
|
@@ -42,16 +42,15 @@ According to Steven Sagaert answer on Quora about "Is programming language R ove
|
|
|
42
42
|
> Mastering R (the language) and its ecosystem is not a matter of weeks or months but
|
|
43
43
|
> takes years. The rabbit hole goes pretty deep…
|
|
44
44
|
|
|
45
|
-
Although
|
|
46
|
-
it can also
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
concerned about creating complex computer systems.
|
|
45
|
+
Although a highly configurable language can give programmers a great deal of power,
|
|
46
|
+
it can also take years to master—as noted above. Programming with _dplyr_, for instance,
|
|
47
|
+
means learning evaluation rules that are not always approachable for **statisticians and
|
|
48
|
+
analysts who are not full-time software engineers**. That is not a criticism: R was **built**
|
|
49
|
+
for **statisticians** who need trustworthy results on a deadline, not necessarily for building
|
|
50
|
+
large applications.
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
**Unfortunately**, when such a user moves on to more **sophisticated** programming patterns,
|
|
53
|
+
the learning curve can become a real hurdle.
|
|
55
54
|
|
|
56
55
|
In this post we will see how to program with _dplyr_ in Galaaz and how Ruby can simplify
|
|
57
56
|
the learning curve of mastering _dplyr_ coding.
|
|
@@ -63,9 +62,9 @@ a large community, a very large set of libraries and great for web development.
|
|
|
63
62
|
easy to learn. However,
|
|
64
63
|
it lacks libraries for data science, statistics, scientific plotting and machine learning.
|
|
65
64
|
On the other hand, R is considered one of the most powerful languages for solving all of the
|
|
66
|
-
above problems.
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
above problems. **Python** is a strong competitor, with NumPy, pandas, SciPy, scikit-learn,
|
|
66
|
+
and **many thousands** of other packages on PyPI. We will not dwell on R **versus** Python here:
|
|
67
|
+
both are excellent languages with different strengths.
|
|
69
68
|
Our interest is to bring to yet another excellent language, Ruby, the data science libraries
|
|
70
69
|
that it lacks.
|
|
71
70
|
|
|
@@ -78,37 +77,14 @@ post that programming with _dplyr_ is easier in Galaaz than in R.
|
|
|
78
77
|
|
|
79
78
|
R users are probably quite knowledgeable about _dplyr_. For the Ruby developer, _dplyr_ and
|
|
80
79
|
the _tidyverse_ libraries are a set of libraries for data manipulation in R, developed by
|
|
81
|
-
|
|
80
|
+
Hadley Wickham, Chief Scientist at Posit (formerly RStudio) and a prolific R coder and writer.
|
|
82
81
|
|
|
83
|
-
For the coupling of Ruby and R,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
GraalVM removes the isolation between programming languages and enables
|
|
91
|
-
interoperability in a shared runtime. It can run either standalone or in
|
|
92
|
-
the context of OpenJDK, Node.js, Oracle Database, or MySQL.
|
|
93
|
-
|
|
94
|
-
GraalVM allows you to write polyglot applications with a seamless way to
|
|
95
|
-
pass values from one language to another. With GraalVM there is no copying
|
|
96
|
-
or marshaling necessary as it is with other polyglot systems. This lets
|
|
97
|
-
you achieve high performance when language boundaries are crossed. Most
|
|
98
|
-
of the time there is no additional cost for crossing a language boundary
|
|
99
|
-
at all.
|
|
100
|
-
|
|
101
|
-
Often developers have to make uncomfortable compromises that require them
|
|
102
|
-
to rewrite their software in other languages. For example:
|
|
103
|
-
|
|
104
|
-
* “That library is not available in my language. I need to rewrite it.”
|
|
105
|
-
* “That language would be the perfect fit for my problem, but we cannot
|
|
106
|
-
run it in our environment.”
|
|
107
|
-
* “That problem is already solved in my language, but the language is
|
|
108
|
-
too slow.”
|
|
109
|
-
|
|
110
|
-
With GraalVM we aim to allow developers to freely choose the right language
|
|
111
|
-
for the task at hand without making compromises.
|
|
82
|
+
For the coupling of Ruby and R, **Galaaz 2.0** uses **[JRuby](https://www.jruby.org/)** (Ruby on the JVM)
|
|
83
|
+
together with **GNU R**. A **bridge** sends expressions and data between Ruby and an R process so that
|
|
84
|
+
Ruby can call **dplyr** and the rest of the tidyverse as if they were part of the same workflow.
|
|
85
|
+
An **earlier** Galaaz line of work used Oracle’s **GraalVM** with **TruffleRuby** and **FastR** in a single
|
|
86
|
+
runtime; that approach is **no longer** the supported stack—see the project **manual** for setup,
|
|
87
|
+
**`bin/galaaz-jruby`**, and **gKnit**.
|
|
112
88
|
|
|
113
89
|
|
|
114
90
|
# Tidyverse and dplyr
|
|
@@ -142,7 +118,7 @@ multiple datasets, programming becomes necessary.
|
|
|
142
118
|
# Programming with dplyr
|
|
143
119
|
|
|
144
120
|
In the vignette ["Programming with dplyr"](https://dplyr.tidyverse.org/articles/programming.html),
|
|
145
|
-
|
|
121
|
+
Hadley Wickham states:
|
|
146
122
|
|
|
147
123
|
> Most dplyr functions use non-standard evaluation (NSE). This is a catch-all term that
|
|
148
124
|
> means they don’t follow the usual R rules of evaluation. Instead, they capture the
|
|
@@ -183,7 +159,7 @@ filter(df, my_var == 1)
|
|
|
183
159
|
> This makes it hard to create functions with arguments that change how dplyr verbs are computed.
|
|
184
160
|
|
|
185
161
|
As a result of this, programming with _dplyr_ requires learning a set of new ideas and concepts.
|
|
186
|
-
In this vignette
|
|
162
|
+
In this vignette Hadley goes on showing how to program ever more difficult problems with _dplyr_,
|
|
187
163
|
showing the problems it faces and the new concepts needed to solve them.
|
|
188
164
|
|
|
189
165
|
In this blog, we will look at all the problems presented by Harley on the vignette and show how
|
|
@@ -223,7 +199,7 @@ where you are reading this blog) with gKnit (a tool provided by Galaaz). In Rmar
|
|
|
223
199
|
possible to write text and code blocks that are executed to generate the final report. Code
|
|
224
200
|
blocks appear inside a 'box' and the result of their execution appear either in another type
|
|
225
201
|
of 'box' with a different background (HTML) or as normal text (PDF). Every output line from
|
|
226
|
-
the code execution is
|
|
202
|
+
the code execution is preceded by '##'.
|
|
227
203
|
|
|
228
204
|
## Expressions from operators
|
|
229
205
|
|
|
@@ -237,7 +213,7 @@ puts exp1
|
|
|
237
213
|
In Galaaz, we can build any complex mathematical expression such as:
|
|
238
214
|
|
|
239
215
|
```{ruby expr2}
|
|
240
|
-
exp2 = (:a + :b) * 2.0 + :c ** 2 / :z
|
|
216
|
+
exp2 = (R[:a] + R[:b]) * 2.0 + R[:c] ** 2 / R[:z]
|
|
241
217
|
puts exp2
|
|
242
218
|
```
|
|
243
219
|
Expressions are printed with the same format as the equivalent R expressions. The 'L' after
|
|
@@ -251,7 +227,7 @@ float.
|
|
|
251
227
|
It is also possible to use inequality operators in building expressions:
|
|
252
228
|
|
|
253
229
|
```{ruby expr3}
|
|
254
|
-
exp3 = (:a + :b) >= :z
|
|
230
|
+
exp3 = (R[:a] + R[:b]) >= R[:z]
|
|
255
231
|
puts exp3
|
|
256
232
|
```
|
|
257
233
|
Expressions' definition can also make use of normal Ruby variables without any problem:
|
|
@@ -259,7 +235,7 @@ Expressions' definition can also make use of normal Ruby variables without any p
|
|
|
259
235
|
```{ruby expr_with_var}
|
|
260
236
|
x = 20
|
|
261
237
|
y = 30.0
|
|
262
|
-
exp_var = (:a + :b) * x <= :z - y
|
|
238
|
+
exp_var = (R[:a] + R[:b]) * x <= R[:z] - y
|
|
263
239
|
puts exp_var
|
|
264
240
|
```
|
|
265
241
|
|
|
@@ -268,7 +244,7 @@ notation for those operators such as (.gt, .ge, etc.). So the same expression w
|
|
|
268
244
|
above can also be written as
|
|
269
245
|
|
|
270
246
|
```{ruby expr4}
|
|
271
|
-
exp4 = (:a + :b).ge :z
|
|
247
|
+
exp4 = (R[:a] + R[:b]).ge R[:z]
|
|
272
248
|
puts exp4
|
|
273
249
|
```
|
|
274
250
|
|
|
@@ -280,12 +256,12 @@ In order to write an expression involving '==' we
|
|
|
280
256
|
need to use the method '.eq' and for '=' we need the function '.assign':
|
|
281
257
|
|
|
282
258
|
```{ruby expr5}
|
|
283
|
-
exp5 = (:a + :b).eq :z
|
|
259
|
+
exp5 = (R[:a] + R[:b]).eq R[:z]
|
|
284
260
|
puts exp5
|
|
285
261
|
```
|
|
286
262
|
|
|
287
263
|
```{ruby expr6}
|
|
288
|
-
exp6 = :y.assign :a + :b
|
|
264
|
+
exp6 = R[:y].assign R[:a] + R[:b]
|
|
289
265
|
puts exp6
|
|
290
266
|
```
|
|
291
267
|
Users should be careful when writing expressions not to inadvertently use '==' or '=' as
|
|
@@ -293,11 +269,11 @@ this will generate an error, that might be a bit cryptic (in future releases of
|
|
|
293
269
|
plan to improve the error message).
|
|
294
270
|
|
|
295
271
|
```{ruby exp_wrong, warning=FALSE}
|
|
296
|
-
exp_wrong = (:a + :b) == :z
|
|
272
|
+
exp_wrong = (R[:a] + R[:b]) == R[:z]
|
|
297
273
|
puts exp_wrong
|
|
298
274
|
```
|
|
299
275
|
The problem lies with the fact that
|
|
300
|
-
when using '==' we are comparing expression (:a + :b) to expression :z with '=='. When this
|
|
276
|
+
when using '==' we are comparing expression (R[:a] + R[:b]) to expression R[:z] with '=='. When this
|
|
301
277
|
comparison is executed, the system tries to evaluate :a, :b and :z, and those symbols, at
|
|
302
278
|
this time, are not bound to anything giving the "object 'a' not found" message.
|
|
303
279
|
|
|
@@ -310,13 +286,13 @@ the function to be part of the expression, we call the function preceeding it
|
|
|
310
286
|
by the letter E, such as 'E.sin(x)'
|
|
311
287
|
|
|
312
288
|
```{ruby method_expression}
|
|
313
|
-
exp7 = :y.assign E.sin(:x)
|
|
289
|
+
exp7 = R[:y].assign E.sin(R[:x])
|
|
314
290
|
puts exp7
|
|
315
291
|
```
|
|
316
292
|
Function expressions can also be written using '.' notation:
|
|
317
293
|
|
|
318
294
|
```{ruby expression_with_dot}
|
|
319
|
-
exp8 = :y.assign :x.sin
|
|
295
|
+
exp8 = R[:y].assign R[:x].sin
|
|
320
296
|
puts exp8
|
|
321
297
|
```
|
|
322
298
|
When a function has multiple arguments, the first one can be used before the '.'. For instance,
|
|
@@ -324,7 +300,7 @@ the R concatenate function 'c', that concatenates two or more arguments can be p
|
|
|
324
300
|
an expression as:
|
|
325
301
|
|
|
326
302
|
```{ruby expression_multiple_args}
|
|
327
|
-
exp9 = :x.c(:y)
|
|
303
|
+
exp9 = R[:x].c(R[:y])
|
|
328
304
|
puts exp9
|
|
329
305
|
```
|
|
330
306
|
Note that this gives an OO feeling to the code, as if we were saying 'x' concatenates 'y'. As a
|
|
@@ -339,7 +315,7 @@ can be evaluated by calling function 'eval' with a binding.
|
|
|
339
315
|
A binding can be provided with a list or a data frame as shown below:
|
|
340
316
|
|
|
341
317
|
```{ruby eval_expression_list}
|
|
342
|
-
exp = (:a + :b) * 2.0 + :c ** 2 / :z
|
|
318
|
+
exp = (R[:a] + R[:b]) * 2.0 + R[:c] ** 2 / R[:z]
|
|
343
319
|
puts exp.eval(R.list(a: 10, b: 20, c: 30, z: 40))
|
|
344
320
|
```
|
|
345
321
|
|
|
@@ -388,7 +364,7 @@ the expression $y = sin(45^\circ)$, which is $y = 0.850...$. In this case,
|
|
|
388
364
|
we will use 'R.sin':
|
|
389
365
|
|
|
390
366
|
```{ruby eval_sin}
|
|
391
|
-
exp10 = :y.assign R.sin(45)
|
|
367
|
+
exp10 = R[:y].assign R.sin(45)
|
|
392
368
|
puts exp10
|
|
393
369
|
```
|
|
394
370
|
|
|
@@ -404,9 +380,9 @@ Let's start by taking a look at this dataset:
|
|
|
404
380
|
```{ruby nycflights13}
|
|
405
381
|
R.library('nycflights13')
|
|
406
382
|
# check it's dimension
|
|
407
|
-
puts
|
|
383
|
+
puts ~R[:flights].dim
|
|
408
384
|
# and the structure
|
|
409
|
-
|
|
385
|
+
~R[:flights].str
|
|
410
386
|
```
|
|
411
387
|
|
|
412
388
|
Now, let's use a first verb of _dplyr_: 'filter'. This verb, obviously, will filter the data
|
|
@@ -419,13 +395,13 @@ The second and third arguments are expressions that will be used by the filter f
|
|
|
419
395
|
filter by columns, looking for entries in which the month and day are equal to 1.
|
|
420
396
|
|
|
421
397
|
```{ruby filter}
|
|
422
|
-
puts R.filter(:flights, (:month.eq 1), (:day.eq 1))
|
|
398
|
+
puts R.filter(:flights, (R[:month].eq 1), (R[:day].eq 1))
|
|
423
399
|
```
|
|
424
400
|
|
|
425
401
|
|
|
426
402
|
## Programming with _dplyr_: problems and how to solve them in Galaaz
|
|
427
403
|
|
|
428
|
-
In this section we look at the list of problems that
|
|
404
|
+
In this section we look at the list of problems that Hadley describes in the "Programming with dplyr"
|
|
429
405
|
vignette and show how those problems are solved and coded with Galaaz. Readers interested in
|
|
430
406
|
how those problems are treated in _dplyr_ should read the vignette and use it as a comparison with
|
|
431
407
|
this blog.
|
|
@@ -449,15 +425,15 @@ by using dot notation.
|
|
|
449
425
|
|
|
450
426
|
-------FIX---------
|
|
451
427
|
|
|
452
|
-
We prefer to use dot notation as shown
|
|
428
|
+
We prefer to use dot notation as shown below. The argument to 'filter' should be an
|
|
453
429
|
expression. Note that if we gave to filter a Ruby expression such as
|
|
454
430
|
'x == 1', we would get an error, since there is no variable 'x' defined and if 'x' was a variable
|
|
455
431
|
then 'x == 1' would either be 'true' or 'false'. Our goal is to filter our data frame returning
|
|
456
|
-
all rows in which the 'x' value is equal to 1. To express this we want: ':x.eq 1', where :x will
|
|
432
|
+
all rows in which the 'x' value is equal to 1. To express this we want: 'R[:x].eq 1', where :x will
|
|
457
433
|
be interpreted by filter as the 'x' column.
|
|
458
434
|
|
|
459
435
|
```{ruby filter_exp}
|
|
460
|
-
puts df.filter(:x.eq 1)
|
|
436
|
+
puts df.filter(R[:x].eq 1)
|
|
461
437
|
```
|
|
462
438
|
In R, and when coding with 'tidyverse', arguments to a function are usually not
|
|
463
439
|
*referencially transparent*. That is, you can’t replace a value with a seemingly equivalent
|
|
@@ -470,16 +446,16 @@ filter(df, my_var == 1)
|
|
|
470
446
|
Generates the following error: "object 'x' not found.
|
|
471
447
|
|
|
472
448
|
However, in Galaaz, arguments are referencially transparent as can be seen by the
|
|
473
|
-
code
|
|
449
|
+
code below. Note initially that 'my_var = R[:x]' will not give the error "object 'x' not found"
|
|
474
450
|
since ':x' is treated as an expression and assigned to my\_var. Then when doing (my\_var.eq 1),
|
|
475
|
-
my\_var is a variable that resolves to ':x' and it becomes equivalent to (:x.eq 1) which is
|
|
451
|
+
my\_var is a variable that resolves to ':x' and it becomes equivalent to (R[:x].eq 1) which is
|
|
476
452
|
what we want.
|
|
477
453
|
|
|
478
454
|
```{ruby my_var}
|
|
479
|
-
my_var = :x
|
|
455
|
+
my_var = R[:x]
|
|
480
456
|
puts df.filter(my_var.eq 1)
|
|
481
457
|
```
|
|
482
|
-
As stated by
|
|
458
|
+
As stated by Hadley
|
|
483
459
|
|
|
484
460
|
> dplyr code is ambiguous. Depending on what variables are defined where,
|
|
485
461
|
> filter(df, x == y) could be equivalent to any of:
|
|
@@ -491,9 +467,9 @@ df[x == df$y, ]
|
|
|
491
467
|
df[x == y, ]
|
|
492
468
|
```
|
|
493
469
|
In galaaz this ambiguity does not exist, filter(df, x.eq y) is not a valid expression as
|
|
494
|
-
expressions are build with symbols. In doing filter(df, :x.eq y) we are looking for elements
|
|
470
|
+
expressions are build with symbols. In doing filter(df, R[:x].eq y) we are looking for elements
|
|
495
471
|
of the 'x' column that are equal to a previously defined y variable. Finally in
|
|
496
|
-
filter(df, :x.eq :y) we are looking for elements in which the 'x' column value is equal to
|
|
472
|
+
filter(df, R[:x].eq R[:y]) we are looking for elements in which the 'x' column value is equal to
|
|
497
473
|
the 'y' column value. This can be seen in the following two chunks of code:
|
|
498
474
|
|
|
499
475
|
```{ruby disamb1}
|
|
@@ -501,13 +477,13 @@ y = 1
|
|
|
501
477
|
x = 2
|
|
502
478
|
|
|
503
479
|
# looking for values where the 'x' column is equal to the 'y' column
|
|
504
|
-
puts df.filter(:x.eq :y)
|
|
480
|
+
puts df.filter(R[:x].eq R[:y])
|
|
505
481
|
```
|
|
506
482
|
|
|
507
483
|
```{ruby disamb2}
|
|
508
484
|
# looking for values where the 'x' column is equal to the 'y' variable
|
|
509
485
|
# in this case, the number 1
|
|
510
|
-
puts df.filter(:x.eq y)
|
|
486
|
+
puts df.filter(R[:x].eq y)
|
|
511
487
|
```
|
|
512
488
|
## Writing a function that applies to different data sets
|
|
513
489
|
|
|
@@ -534,11 +510,12 @@ Unfortunately, in R, this function can fail silently if one of the variables isn
|
|
|
534
510
|
in the data frame, but is present in the global environment. We will not go through here how
|
|
535
511
|
to solve this problem in R.
|
|
536
512
|
|
|
537
|
-
In Galaaz the method mutate_y
|
|
513
|
+
In Galaaz the method mutate_y below will work fine and will never fail silently.
|
|
538
514
|
|
|
539
515
|
```{ruby mutate_y, warning=FALSE}
|
|
540
516
|
def mutate_y(df)
|
|
541
|
-
|
|
517
|
+
# Mutate column names are Ruby kwargs (y: …). Use .assign only for R `<-` expressions.
|
|
518
|
+
df.mutate(y: R[:a] + R[:x])
|
|
542
519
|
end
|
|
543
520
|
```
|
|
544
521
|
Here we create a data frame that has only one column named 'x':
|
|
@@ -549,7 +526,7 @@ puts df1
|
|
|
549
526
|
```
|
|
550
527
|
|
|
551
528
|
Note that method mutate_y will fail independetly from the fact that variable 'a' is defined and
|
|
552
|
-
in the scope of the method. Variable 'a' has no relationship with the symbol
|
|
529
|
+
in the scope of the method. Variable 'a' has no relationship with the symbol `R[:a]` used in the
|
|
553
530
|
definition of 'mutate\_y' above:
|
|
554
531
|
|
|
555
532
|
```{ruby call_mutate_y, warning = FALSE}
|
|
@@ -558,9 +535,9 @@ mutate_y(df1)
|
|
|
558
535
|
```
|
|
559
536
|
## Different expressions
|
|
560
537
|
|
|
561
|
-
Let's move to the next problem as presented by
|
|
538
|
+
Let's move to the next problem as presented by Hadley where trying to write a function in R
|
|
562
539
|
that will receive two argumens, the first a variable and the second an expression is not trivial.
|
|
563
|
-
|
|
540
|
+
Below we create a data frame and we want to write a function that groups data by a variable and
|
|
564
541
|
summarises it by an expression:
|
|
565
542
|
|
|
566
543
|
```{r diff_expr}
|
|
@@ -588,7 +565,7 @@ d2 <- df %>%
|
|
|
588
565
|
as.data.frame(d2)
|
|
589
566
|
```
|
|
590
567
|
|
|
591
|
-
As shown by
|
|
568
|
+
As shown by Hadley, one might expect this function to do the trick:
|
|
592
569
|
|
|
593
570
|
```{r diff_exp_fnc}
|
|
594
571
|
my_summarise <- function(df, group_var) {
|
|
@@ -603,28 +580,28 @@ my_summarise <- function(df, group_var) {
|
|
|
603
580
|
|
|
604
581
|
In order to solve this problem, coding with dplyr requires the introduction of many new concepts
|
|
605
582
|
and functions such as 'quo', 'quos', 'enquo', 'enquos', '!!' (bang bang), '!!!' (triple bang).
|
|
606
|
-
Again, we'll leave to
|
|
583
|
+
Again, we'll leave to Hadley the explanation on how to use all those functions.
|
|
607
584
|
|
|
608
585
|
Now, let's try to implement the same function in galaaz. The next code block first prints the
|
|
609
|
-
'df' data frame
|
|
586
|
+
'df' data frame defined previously in R (to access an R variable from Galaaz, we use the tilde
|
|
610
587
|
operator '~' applied to the R variable name as symbol, i.e., ':df'. We then create the
|
|
611
588
|
'my_summarize' method and call it passing the R data frame and the group by variable ':g1':
|
|
612
589
|
|
|
613
590
|
```{ruby diff_exp_ruby_func}
|
|
614
|
-
puts
|
|
591
|
+
puts ~R[:df]
|
|
615
592
|
print "\n"
|
|
616
593
|
|
|
617
594
|
def my_summarize(df, group_var)
|
|
618
595
|
df.group_by(group_var).
|
|
619
|
-
summarize(a: :a.mean)
|
|
596
|
+
summarize(a: R[:a].mean)
|
|
620
597
|
end
|
|
621
598
|
|
|
622
|
-
puts my_summarize(:df, :g1)
|
|
599
|
+
puts my_summarize(~R[:df], R[:g1])
|
|
623
600
|
```
|
|
624
601
|
It works!!! Well, let's make sure this was not just some coincidence
|
|
625
602
|
|
|
626
603
|
```{ruby group_g2}
|
|
627
|
-
puts my_summarize(:df, :g2)
|
|
604
|
+
puts my_summarize(~R[:df], R[:g2])
|
|
628
605
|
```
|
|
629
606
|
|
|
630
607
|
Great, everything is fine! No magic, no new functions, no complexities, just normal, standard Ruby
|
|
@@ -636,7 +613,7 @@ In the previous section we've managed to get rid of all NSE formulation for a si
|
|
|
636
613
|
does this remain true for more complex examples, or will the Galaaz way prove inpractical for
|
|
637
614
|
more complex code?
|
|
638
615
|
|
|
639
|
-
In the next example
|
|
616
|
+
In the next example Hadley proposes us to write a function that given an expression such as 'a'
|
|
640
617
|
or 'a * b', calculates three summaries. What we want a function that does the same as these R
|
|
641
618
|
statements:
|
|
642
619
|
|
|
@@ -665,8 +642,8 @@ def my_summarise2(df, expr)
|
|
|
665
642
|
)
|
|
666
643
|
end
|
|
667
644
|
|
|
668
|
-
puts my_summarise2((
|
|
669
|
-
puts my_summarise2((
|
|
645
|
+
puts my_summarise2((~R[:df]), :a)
|
|
646
|
+
puts my_summarise2((~R[:df]), R[:a] * R[:b])
|
|
670
647
|
```
|
|
671
648
|
|
|
672
649
|
Once again, there is no need to use any special theory or functions. The only point to be
|
|
@@ -674,7 +651,7 @@ careful about is the use of 'E' to build expressions from functions 'mean', 'sum
|
|
|
674
651
|
|
|
675
652
|
## Different input and output variable
|
|
676
653
|
|
|
677
|
-
Now the next challenge presented by
|
|
654
|
+
Now the next challenge presented by Hadley is to vary the name of the output variables based on
|
|
678
655
|
the received expression. So, if the input expression is 'a', we want our data frame columns to
|
|
679
656
|
be named 'mean\_a' and 'sum\_a'. Now, if the input expression is 'b', columns
|
|
680
657
|
should be named 'mean\_b' and 'sum\_b'.
|
|
@@ -700,7 +677,7 @@ mutate(df, mean_b = mean(b), sum_b = sum(b))
|
|
|
700
677
|
#> 4 2 2 5 4 3 15
|
|
701
678
|
#> # … with 1 more row
|
|
702
679
|
```
|
|
703
|
-
In order to solve this problem in R,
|
|
680
|
+
In order to solve this problem in R, Hadley needs to introduce some more new functions and notations:
|
|
704
681
|
'quo_name' and the ':=' operator from package 'rlang'
|
|
705
682
|
|
|
706
683
|
Here is our Ruby code:
|
|
@@ -714,8 +691,8 @@ def my_mutate(df, expr)
|
|
|
714
691
|
sum_name => E.sum(expr))
|
|
715
692
|
end
|
|
716
693
|
|
|
717
|
-
puts my_mutate((
|
|
718
|
-
puts my_mutate((
|
|
694
|
+
puts my_mutate((~R[:df]), :a)
|
|
695
|
+
puts my_mutate((~R[:df]), :b)
|
|
719
696
|
```
|
|
720
697
|
It really seems that "Non Standard Evaluation" is actually quite standard in Galaaz! But, you
|
|
721
698
|
might have noticed a small change in the way the arguments to the mutate method were called.
|
|
@@ -727,7 +704,7 @@ and variable mean\_name is not followed by ':' but by '=>'. This is standard Ru
|
|
|
727
704
|
|
|
728
705
|
## Capturing multiple variables
|
|
729
706
|
|
|
730
|
-
Moving on with new complexities,
|
|
707
|
+
Moving on with new complexities, Hadley proposes us to solve the problem in which the
|
|
731
708
|
summarise function will receive any number of grouping variables.
|
|
732
709
|
|
|
733
710
|
This again is quite standard Ruby. In order to receive an undefined number of paramenters
|
|
@@ -739,7 +716,7 @@ def my_summarise3(df, *group_vars)
|
|
|
739
716
|
summarise(a: E.mean(:a))
|
|
740
717
|
end
|
|
741
718
|
|
|
742
|
-
puts my_summarise3((
|
|
719
|
+
puts my_summarise3((~R[:df]), :g1, :g2)
|
|
743
720
|
```
|
|
744
721
|
|
|
745
722
|
# Why does R require NSE and Galaaz does not?
|
|
@@ -757,7 +734,7 @@ In Ruby, there is no lazy evaluation of parameters and 'a' is always a variable
|
|
|
757
734
|
Variables assume their value as soon as they are used, so 'x = a' is immediately evaluate and
|
|
758
735
|
variable 'x' will receive the value of variable 'a' as soon as the Ruby statement is executed.
|
|
759
736
|
Ruby also provides the notion of a symbol; ':a' is a symbol and does not evaluate to anything.
|
|
760
|
-
Galaaz uses Ruby symbols to build expressions that are not bound to anything: ':a.eq :b' is
|
|
737
|
+
Galaaz uses Ruby symbols to build expressions that are not bound to anything: 'R[:a].eq R[:b]' is
|
|
761
738
|
clearly an expression and has no relationship whatsoever with the statment 'a = b'. By using
|
|
762
739
|
symbols, variables and expressions all the possible ambiguities that are found in R are
|
|
763
740
|
eliminated in Galaaz.
|
|
@@ -767,7 +744,7 @@ of input they are expecting, they might be expecting regular variables or they m
|
|
|
767
744
|
expecting expressions and the R function will know how to deal with an input of the form
|
|
768
745
|
'a = b', now for the Ruby developer it might not be immediately clear if it should call the
|
|
769
746
|
function passing the value 'true' if variable 'a' is equal to variable 'b' or if it should
|
|
770
|
-
call the function passing the expression ':a.eq :b'.
|
|
747
|
+
call the function passing the expression 'R[:a].eq R[:b]'.
|
|
771
748
|
|
|
772
749
|
|
|
773
750
|
# Advanced dplyr features
|
|
@@ -790,9 +767,9 @@ In the following examples, we show the use of functions 'group\_by\_at', 'summar
|
|
|
790
767
|
features of characters in the Starwars movies:
|
|
791
768
|
|
|
792
769
|
```{ruby starwars}
|
|
793
|
-
puts (
|
|
770
|
+
puts (~R[:starwars]).head
|
|
794
771
|
```
|
|
795
|
-
The grouped_mean function
|
|
772
|
+
The grouped_mean function below will receive a grouping variable and calculate summaries for
|
|
796
773
|
the value\_variables given:
|
|
797
774
|
|
|
798
775
|
```{r grouped_mean}
|
|
@@ -817,26 +794,22 @@ def grouped_mean(data, grouping_variables, value_variables)
|
|
|
817
794
|
data.
|
|
818
795
|
group_by_at(grouping_variables).
|
|
819
796
|
mutate(count: E.n).
|
|
820
|
-
summarise_at(E.c(value_variables, "count"),
|
|
797
|
+
summarise_at(E.c(value_variables, "count"), R[:mean], na__rm: true).
|
|
821
798
|
rename_at(value_variables, E.funs(E.paste0("mean_", value_variables)))
|
|
822
799
|
end
|
|
823
800
|
|
|
824
|
-
puts grouped_mean((
|
|
801
|
+
puts grouped_mean((~R[:starwars]), "eye_color", E.c("mass", "birth_year"))
|
|
825
802
|
```
|
|
826
803
|
|
|
827
804
|
# Further reading
|
|
828
805
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
* [GraalVM
|
|
832
|
-
* [TruffleRuby](https://github.com/oracle/truffleruby)
|
|
833
|
-
* [FastR](https://github.com/oracle/fastr)
|
|
834
|
-
* [Faster R with FastR](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb)
|
|
835
|
-
* [How to make Beautiful Ruby Plots with Galaaz](https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857)
|
|
836
|
-
* [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)
|
|
806
|
+
* [JRuby](https://www.jruby.org/) — Ruby on the JVM (Galaaz 2.0)
|
|
807
|
+
* [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)
|
|
808
|
+
* [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)
|
|
837
809
|
* [How to do reproducible research in Ruby with gKnit](https://towardsdatascience.com/how-to-do-reproducible-research-in-ruby-with-gknit-c26d2684d64e)
|
|
838
810
|
* [R for Data Science](https://r4ds.had.co.nz/)
|
|
839
811
|
* [Advanced R](https://adv-r.hadley.nz/)
|
|
812
|
+
* Historical context: [GraalVM](https://www.graalvm.org/), [TruffleRuby](https://github.com/oracle/truffleruby), [FastR](https://github.com/oracle/fastr)
|
|
840
813
|
|
|
841
814
|
# Conclusion
|
|
842
815
|
|