galaaz 0.4.2 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +25 -0
  3. data/Rakefile +8 -0
  4. data/bin/gknit +9 -5
  5. data/bin/gstudio +4 -2
  6. data/bin/gstudio.rb +32 -2
  7. data/blogs/dev/dev.html +219 -34
  8. data/blogs/dev/dev.md +26 -26
  9. data/blogs/dev/dev_files/figure-html/bubble-1.png +0 -0
  10. data/blogs/dev/dev_files/figure-html/diverging_bar.png +0 -0
  11. data/blogs/dplyr/dplyr.rb +63 -0
  12. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -26
  13. data/blogs/galaaz_ggplot/galaaz_ggplot.aux +16 -17
  14. data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
  15. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +65 -31
  16. data/blogs/oh_my/not_so.rb +2342 -0
  17. data/blogs/oh_my/oh_my.Rmd +493 -0
  18. data/blogs/oh_my/oh_my.html +680 -0
  19. data/blogs/oh_my/oh_my.md +597 -0
  20. data/blogs/oh_my/old.Rmd +2100 -0
  21. data/blogs/ruby_plot/figures/facets_with_decorations.png +0 -0
  22. data/blogs/ruby_plot/figures/facets_with_jitter.png +0 -0
  23. data/blogs/ruby_plot/figures/final_box_plot.png +0 -0
  24. data/blogs/ruby_plot/figures/final_violin_plot.png +0 -0
  25. data/blogs/ruby_plot/figures/violin_with_jitter.png +0 -0
  26. data/blogs/ruby_plot/ruby_plot.Rmd +147 -122
  27. data/blogs/ruby_plot/ruby_plot.Rmd_external_figs +662 -0
  28. data/blogs/ruby_plot/ruby_plot.html +49 -54
  29. data/blogs/ruby_plot/ruby_plot.md +147 -122
  30. data/blogs/ruby_plot/ruby_plot.pdf +0 -0
  31. data/blogs/ruby_plot/ruby_plot.tex +776 -157
  32. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +57 -0
  33. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.svg +106 -0
  34. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.svg +110 -0
  35. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.svg +174 -0
  36. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.svg +236 -0
  37. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  38. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.svg +296 -0
  39. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.svg +236 -0
  40. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.svg +218 -0
  41. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.svg +128 -0
  42. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.svg +150 -0
  43. data/examples/islr/ch2.spec.rb +21 -18
  44. data/examples/islr/ch3_boston.rb +14 -5
  45. data/examples/islr/ch3_multiple_regression.rb +2 -3
  46. data/examples/islr/ch6.spec.rb +1 -1
  47. data/examples/islr/x_y_rnorm.jpg +0 -0
  48. data/lib/R_interface/r.rb +14 -10
  49. data/lib/R_interface/r_libs.R +9 -0
  50. data/lib/R_interface/r_methods.rb +77 -6
  51. data/lib/R_interface/{expression.rb → r_module_s.rb} +13 -14
  52. data/lib/R_interface/rbinary_operators.rb +58 -71
  53. data/lib/R_interface/rdata_frame.rb +2 -1
  54. data/lib/R_interface/rdevices.R +4 -0
  55. data/lib/R_interface/rdevices.rb +1 -1
  56. data/lib/R_interface/renvironment.rb +34 -1
  57. data/lib/R_interface/rexpression.rb +108 -2
  58. data/lib/R_interface/rindexed_object.rb +3 -1
  59. data/lib/R_interface/rlanguage.rb +18 -2
  60. data/lib/R_interface/rmatrix.rb +14 -0
  61. data/lib/R_interface/rmd_indexed_object.rb +5 -1
  62. data/lib/R_interface/robject.rb +61 -23
  63. data/lib/R_interface/rsupport.rb +111 -53
  64. data/lib/R_interface/rsymbol.rb +6 -5
  65. data/lib/R_interface/ruby_extensions.rb +130 -4
  66. data/lib/R_interface/runary_operators.rb +35 -3
  67. data/lib/R_interface/rvector.rb +1 -0
  68. data/lib/galaaz.rb +0 -2
  69. data/lib/gknit/knitr_engine.rb +58 -4
  70. data/lib/gknit/ruby_engine.rb +5 -6
  71. data/lib/util/exec_ruby.rb +55 -9
  72. data/specs/all.rb +13 -3
  73. data/specs/figures/dose_len.png +0 -0
  74. data/specs/r_dataframe.spec.rb +49 -26
  75. data/specs/r_environment.spec.rb +140 -0
  76. data/specs/r_eval.spec.rb +0 -15
  77. data/specs/r_formula.spec.rb +232 -0
  78. data/specs/r_function.spec.rb +7 -8
  79. data/specs/r_list.spec.rb +4 -0
  80. data/specs/r_list_apply.spec.rb +11 -11
  81. data/specs/r_matrix.spec.rb +3 -3
  82. data/specs/{r_plots.spec.rb~ → r_nse.spec.rb} +29 -6
  83. data/specs/r_vector_creation.spec.rb +6 -0
  84. data/specs/r_vector_object.spec.rb +2 -2
  85. data/specs/r_vector_operators.spec.rb +3 -3
  86. data/specs/r_vector_subsetting.spec.rb +4 -4
  87. data/specs/ruby_expression.spec.rb +324 -0
  88. data/specs/tmp.rb +12 -524
  89. data/sty/galaaz.sty +71 -0
  90. data/version.rb +1 -1
  91. metadata +31 -41
  92. data/bin/gknit2~ +0 -6
  93. data/bin/ogk~ +0 -4
  94. data/bin/prepareR.rb~ +0 -1
  95. data/blogs/dev/dev.Rmd~ +0 -104
  96. data/blogs/galaaz_ggplot/galaaz_ggplot.dvi +0 -0
  97. data/blogs/galaaz_ggplot/midwest_external_png~ +0 -1
  98. data/blogs/gknit/gknit.Rmd~ +0 -184
  99. data/blogs/gknit/gknit.Rnd~ +0 -17
  100. data/blogs/gknit/model.rb~ +0 -46
  101. data/blogs/ruby_plot/ruby_plot.Rmd~ +0 -215
  102. data/examples/islr/Figure.jpg +0 -0
  103. data/examples/misc/moneyball.rb~ +0 -16
  104. data/examples/misc/subsetting.rb~ +0 -372
  105. data/lib/R/eng_ruby.R~ +0 -63
  106. data/lib/R_interface/capture_plot.rb~ +0 -23
  107. data/lib/R_interface/r.rb~ +0 -121
  108. data/lib/R_interface/rdevices.rb~ +0 -27
  109. data/lib/gknit.rb~ +0 -26
  110. data/lib/gknit/knitr_engine.rb~ +0 -102
  111. data/lib/gknit/ruby_engine.rb~ +0 -72
  112. data/lib/util/inline_file.rb~ +0 -23
  113. data/r_requires/knitr.rb~ +0 -4
  114. data/specs/r_language.spec.rb +0 -157
@@ -23,6 +23,15 @@
23
23
 
24
24
  require_relative 'r_eval.spec'
25
25
 
26
+ # Specification for Functions
27
+ require_relative 'r_function.spec'
28
+
29
+ # Specification for Ruby expressions
30
+ require_relative 'ruby_expression.spec'
31
+
32
+ # Specification for R::Environment
33
+ require_relative 'r_environment.spec'
34
+
26
35
  # Specification for R::Vector
27
36
  require_relative 'r_vector_creation.spec'
28
37
  require_relative 'r_vector_object.spec'
@@ -40,6 +49,7 @@ require_relative 'r_matrix.spec'
40
49
  # Specification for R::Dataframes
41
50
  require_relative 'r_dataframe.spec'
42
51
 
43
- # Specification for language features
44
- require_relative 'r_function.spec'
45
- require_relative 'r_language.spec'
52
+ require_relative 'r_formula.spec'
53
+
54
+ # Testes for NSE
55
+ # require_relative 'r_nse.spec'
@@ -33,11 +33,13 @@ describe R::DataFrame do
33
33
  vec.dim = R.c(2, 3)
34
34
 
35
35
  # create a DataFrame from a vector
36
- df = R.as__data__frame(vec)
36
+ df = vec.as__data__frame
37
37
  expect(df[1, "V1"]).to eq 1
38
- expect df[1, 'V2'] == 3
39
- expect df[1, :all] == R.c(V1: 1, V2: 3, V3: 5)
40
-
38
+ expect(df[1, 'V2']).to eq 3
39
+ # When you extract a single row from a data frame you get a one-row data frame.
40
+ # Convert it to a numeric vector with 'as__numeric'
41
+ expect(df[1, :all].as__numeric).to eq R.c(V1: 1, V2: 3, V3: 5)
42
+
41
43
  end
42
44
 
43
45
  end
@@ -69,26 +71,39 @@ describe R::DataFrame do
69
71
  expect(table2.fail[4]).to eq true
70
72
 
71
73
  end
74
+
75
+ end
76
+ #----------------------------------------------------------------------------------------
77
+ context "Ruby 'each'" do
72
78
 
73
79
  it "should do 'each_column'" do
74
80
 
75
81
  mtcars = ~:mtcars
76
82
 
77
83
  mtcars.each_column do |col, col_name|
78
- # col_name is an R::Vector with one string element.
79
- # Extract the 'native' value by indexing with '<< 0'
80
- case col_name << 0
84
+ # col_name a Ruby string with the column name
85
+ case col_name
81
86
  when "mpg"
82
- expect col[1] == 21
83
- expect col[9] == 22.8
84
- expect col[32] == 21.4
87
+ expect(col[1]).to eq 21
88
+ expect(col[9]).to eq 22.8
89
+ expect(col[32]).to eq 21.4
90
+ expect(col[1] == 21).to eq true
91
+ expect(col[9] == 22.8).to eq true
92
+ expect(col[9] == 30).to eq false
93
+ expect(col[32] == 21.4).to eq true
85
94
  when "cyl"
86
- expect col[1] == 6
87
- expect col[10] == 6
88
- expect col[32] == 4
95
+ expect(col[1] == 6).to eq true
96
+ expect(col[10] == 6).to eq true
97
+ expect(col[32] == 4).to eq true
98
+ expect(col[1]).to eq 6
99
+ expect(col[10]).to eq 6
100
+ expect(col[32]).to eq 4
89
101
  when "disp"
90
- expect col[1] == 160
91
- expect col[32] == 121
102
+ expect(col[1]).to eq 160
103
+ expect(col[32]).to eq 121
104
+ expect(col[1] == 160).to eq true
105
+ expect(col[1] == 200).to eq false
106
+ expect(col[32] == 121).to eq true
92
107
  end
93
108
 
94
109
  end
@@ -100,20 +115,28 @@ describe R::DataFrame do
100
115
  mtcars = ~:mtcars
101
116
 
102
117
  mtcars.each_row do |row, row_name|
103
- case row_name << 0
118
+ # row_name a Ruby string with the column name
119
+ case row_name
104
120
  when "Mazda RX4"
105
- expect row['mpg'] == 21
106
- expect row.qsec == 16.46
121
+ expect(row[['mpg']]).to eq 21
122
+ expect(row.mpg). to eq 21
123
+ expect(row.qsec).to eq 16.46
124
+ expect(row['mpg'] == 21).to eq true
125
+ expect(row.qsec == 16.46).to eq true
107
126
  when "Hornet Sportabout"
108
- expect row['cyl'] == 8
109
- expect row['wt'] == 3.44
127
+ expect(row[['cyl']]).to eq 8
128
+ expect(row.cyl).to eq 8
129
+ expect(row[['wt']]).to eq 3.44
130
+ expect(row['cyl'] == 8).to eq true
131
+ expect(row['wt'] == 3.44).to eq true
110
132
  when "Merc 240D"
111
- expect row['hp'] == 62
112
- expect row.drat == 3.69
133
+ expect(row[['hp']]).to eq 62
134
+ expect(row['hp'] == 62).to eq true
135
+ expect(row.drat).to eq 3.69
113
136
  when "Volvo 142E"
114
- expect row.hp == 109
115
- expect row.am == 1
116
- expect row.carb == 2
137
+ expect(row.hp).to eq 109
138
+ expect(row.am).to eq 1
139
+ expect(row.carb).to eq 2
117
140
  end
118
141
 
119
142
  end
@@ -121,7 +144,7 @@ describe R::DataFrame do
121
144
  end
122
145
 
123
146
  end
124
-
147
+
125
148
  #----------------------------------------------------------------------------------------
126
149
  context "Boostraping" do
127
150
 
@@ -0,0 +1,140 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # @author Rodrigo Botafogo
5
+ #
6
+ # Copyright © 2018 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
+ # and distribute this software and its documentation, without fee and without a signed
8
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
9
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
10
+ # distributions.
11
+ #
12
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
13
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
14
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
15
+ # POSSIBILITY OF SUCH DAMAGE.
16
+ #
17
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
19
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
20
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
+ # OR MODIFICATIONS.
22
+ ##########################################################################################
23
+
24
+ require 'galaaz'
25
+
26
+ describe R::Environment do
27
+
28
+ #----------------------------------------------------------------------------------------
29
+ context "Using environment" do
30
+
31
+ before(:each) do
32
+ # create two environments
33
+ @a_env = R.env
34
+ @b_env = R.env
35
+ end
36
+
37
+ it "should allow the creation of new environments" do
38
+ expect(@a_env.typeof).to eq R.c("environment")
39
+ expect(@a_env.rclass).to eq R.c("environment")
40
+ expect(@a_env.env_names.length).to eq 0
41
+ expect(@b_env.env_names.length).to eq 0
42
+ end
43
+
44
+ it "should allow accessing key, value pairs to environments, with 'set' and 'get'" do
45
+ @a_env.set(:a, 25)
46
+ expect(@a_env.env_names.length).to eq 1
47
+ expect(@a_env.env_names).to eq R.c("a")
48
+
49
+ expect(@b_env.env_names.length).to eq 0
50
+ expect(@a_env.get(:a)).to eq 25
51
+ @a_env.set(:b, 33)
52
+ expect(@a_env.env_names.length).to eq 2
53
+ expect(@a_env.env_names).to eq R.c("a", "b")
54
+
55
+ expect(@a_env.get(:b)).to eq 33
56
+ expect(@a_env.get(:b)).not_to eq 25
57
+ end
58
+
59
+ it "should allow accessing key, value pairs to environments, with '.x' and 'x ='" do
60
+ expect(@a_env.env_names.length).to eq 0
61
+ @a_env.a = 30
62
+ expect(@a_env.env_names.length).to eq 1
63
+ expect(@a_env.a).to eq 30
64
+
65
+ @b_env.vec = R.c(1, 2, 3, 4)
66
+ expect(@b_env.env_names).to eq "vec"
67
+ expect(@b_env.env_names.length).to eq 1
68
+ expect(@b_env.vec).to eq R.c(1, 2, 3, 4)
69
+ end
70
+
71
+ it "should allow accessing key, value pairs to environments, with '[[" do
72
+ expect(@a_env.env_names.length).to eq 0
73
+ @a_env.a = "This is a string"
74
+ expect(@a_env[["a"]]).to eq R.c("This is a string")
75
+ end
76
+
77
+ it "should call methods on the environment as every other R::Object" do
78
+ # we have already seen that we can apply 'ls' to an environment
79
+ expect(@a_env.env_names.length).to eq 0
80
+ expect(R.env_names(@a_env).length).to eq 0
81
+ end
82
+
83
+ it "allows multiple names to point to the same object" do
84
+ @a_env.a = false
85
+ @a_env.b = "a"
86
+ @a_env.c = (2..3)
87
+ @a_env.d = (1..3)
88
+
89
+ expect(@a_env.b).to eq "a"
90
+ expect(@a_env.d).to eq R.c(1, 2, 3)
91
+
92
+ @a_env.a = @a_env.d
93
+ expect(@a_env.a).to eq R.c(1, 2, 3)
94
+ end
95
+
96
+ it "should allow removing elements from an environment" do
97
+ @a_env.a = false
98
+ @a_env.b = "a"
99
+ @a_env.c = (2..3)
100
+ @a_env.d = (1..3)
101
+
102
+ expect(@a_env.a).to eq false
103
+ expect(@a_env.b).to eq "a"
104
+ R.rm("a", envir: @a_env)
105
+ expect { @a_env.a }.to raise_error(NoMethodError)
106
+ end
107
+
108
+ it "should not be able to subset the environment with '['" do
109
+ @a_env.a = false
110
+ expect { @a_env['a'] }.to raise_error(RuntimeError)
111
+ end
112
+
113
+ end
114
+
115
+ #----------------------------------------------------------------------------------------
116
+ context "Evaluating expressions" do
117
+
118
+ before(:each) do
119
+ R.len = 10
120
+ R.sd = 20
121
+ vec = R.c(1, 2, 3, 4)
122
+ R.x = R.c(1, 2, 3, 4)
123
+ end
124
+
125
+ it "should evaluate an expression in the context of a data maks" do
126
+ myenv = R.env
127
+ myenv.e1 = R.expr(:len)
128
+ myenv.e2 = R.expr(:sd)
129
+ myenv.e3 = R.expr(R.c(1, 2, 3, 4))
130
+
131
+ e4 = R.expr(:e1 + :e2 + :e3)
132
+ expect(e4.to_s).to eq "e1 + e2 + e3"
133
+ expect(e4.eval(myenv.new_data_mask)).to eq R.c(31, 32, 33, 34)
134
+
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
@@ -146,19 +146,4 @@ describe R do
146
146
 
147
147
  end
148
148
 
149
- context "Call Non-standard Evaluation methods" do
150
-
151
- it "should pass delayed evaluation parameters to methods" do
152
- # call the subset method filtering by 'cyl == 8 & carb > 3'
153
- # In order to convert a Ruby symbol to an R symbol we use the '.r' method on the
154
- # Ruby symbol. Ruby bitwise operators '&' and '|' are overloaded and used as
155
- # the equivalent R operators and not as bitwise operators.
156
- mt_subset = (~:mtcars).subset((:cyl == 8) & (:carb > 3))
157
- expect(mt_subset.mpg == R.c(14.3, 10.4, 10.4, 14.7, 13.3, 15.8, 15.0)).to eq true
158
- expect((mt_subset.cyl == 8).all).to eq true
159
- expect((mt_subset.carb > 3).all).to eq true
160
- end
161
-
162
- end
163
-
164
149
  end
@@ -0,0 +1,232 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # @author Rodrigo Botafogo
5
+ #
6
+ # Copyright © 2018 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
+ # and distribute this software and its documentation, without fee and without a signed
8
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
9
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
10
+ # distributions.
11
+ #
12
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
13
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
14
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
15
+ # POSSIBILITY OF SUCH DAMAGE.
16
+ #
17
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
19
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
20
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
+ # OR MODIFICATIONS.
22
+ ##########################################################################################
23
+
24
+ require 'galaaz'
25
+ R.install_and_loads('ISLR', 'MASS')
26
+
27
+ describe R::Language do
28
+
29
+ #========================================================================================
30
+ context "When working with Formulas" do
31
+
32
+ it "should create formulas with the 'formula' function" do
33
+ formula = R.formula("log(y) ~ a + log(x)")
34
+ # formulas also capture their environment. When printing the
35
+ # formula, two lines are printed: the first one with the formula
36
+ # and the second one with the environmnet. We are keeping only the
37
+ # first line for comparing with the expected formula
38
+ expect(formula.to_s.lines.first.chomp).to eq "log(y) ~ a + log(x)"
39
+ end
40
+
41
+ it "should create formulas with the '.til' function" do
42
+ formula = R.formula("cyl ~ exp")
43
+ expect(formula.to_s.lines.first.chomp).to eq "cyl ~ exp"
44
+
45
+ formula = (:cyl.til :exp)
46
+ expect(formula.to_s.lines.first.chomp).to eq "cyl ~ exp"
47
+ rform = R.identity(formula)
48
+ expect(rform.typeof).to eq 'language'
49
+ expect(rform.rclass).to eq 'formula'
50
+ end
51
+
52
+ it "should create a formula with '.' by using the ':all' keyword in the rhs" do
53
+ formula = R.formula("supp ~ .")
54
+ expect(formula.to_s.lines.first.chomp).to eq "supp ~ ."
55
+
56
+ # this formula is interpreted as 'supp ~ .' In this statement formula
57
+ # is an R::Expression which has infix and prefix notation
58
+ formula = :supp.til :__
59
+ expect(formula.to_s.lines.first.chomp).to eq "supp ~ ."
60
+ expect(formula.rclass).to eq "formula"
61
+ expect(formula.typeof).to eq "language"
62
+ end
63
+
64
+ it "should create a formula with '.' by using the ':__' keyword in the lhs" do
65
+ formula = R.formula(". ~ supp")
66
+ expect(formula.to_s.lines.first.chomp).to eq ". ~ supp"
67
+
68
+ # this formula is interpreted as '. ~ supp'
69
+ formula = :__.til :supp
70
+ expect(formula.to_s.lines.first.chomp).to eq ". ~ supp"
71
+ expect(formula.rclass).to eq "formula"
72
+ expect(formula.typeof).to eq "language"
73
+ end
74
+
75
+ it "should create a formula starting with '~' with the ':all' symbol in the lhs" do
76
+ formula = R.formula("~ supp")
77
+ expect(formula.to_s.lines.first.chomp).to eq "~supp"
78
+
79
+ formula = :all.til :supp
80
+ expect(formula.to_s.lines.first.chomp).to eq " ~ supp"
81
+ expect(formula.rclass).to eq "formula"
82
+ expect(formula.typeof).to eq "language"
83
+ end
84
+
85
+ it "should allow formulas with conditional" do
86
+ formula = R.formula("Sepal.Width ~ Petal.Width | Species")
87
+ expect(formula.to_s.lines.first.chomp).to eq "Sepal.Width ~ Petal.Width | Species"
88
+
89
+ formula = :Sepal__Width.til :Petal__Width | :Species
90
+ expect(formula.to_s.lines.first.chomp).to eq "Sepal.Width ~ Petal.Width | Species"
91
+ end
92
+
93
+ it "should allow creating formulas with functions in the lhs" do
94
+ formula = E.log(:y).til :a + E.log(:x)
95
+ expect(formula.to_s.lines.first.chomp).to eq "log(y) ~ a + log(x)"
96
+ end
97
+
98
+ end
99
+
100
+ #========================================================================================
101
+ context "Formula operators" do
102
+
103
+ it "should add multiple independent variables to a formula with '+'" do
104
+ # Use multiple independent variables
105
+ formula = :y.til :x1 + :x2
106
+ expect(formula.to_s.lines.first.chomp).to eq "y ~ x1 + x2"
107
+ end
108
+
109
+ it "should ignore objects in an analysis with '-'" do
110
+ # Ignore objects in an analysis
111
+ formula = :y.til :x1 - :x2
112
+ expect(formula.to_s.lines.first.chomp).to eq "y ~ x1 - x2"
113
+ end
114
+
115
+ it "should create interaction between objects with '*'" do
116
+ # Ignore objects in an analysis
117
+ formula = :y.til :x * :x2
118
+ expect(formula.to_s.lines.first.chomp).to eq "y ~ x * x2"
119
+
120
+ # Set seed
121
+ R.set__seed(123)
122
+
123
+ # Data
124
+ R.x = R.rnorm(5)
125
+ R.x2 = R.rnorm(5)
126
+ R.y = R.rnorm(5)
127
+
128
+ # Model frame
129
+ model = R.model__frame(formula, data: R.data__frame(x: :x, y: :y, x2: :x2))
130
+ expect(model[1, 1].all__equal(1.22408179743946)).to eq true
131
+ expect(model[1, 3].all__equal(1.71506498688328)).to eq true
132
+ expect(model[3, 2].all__equal(1.55870831414912)).to eq true
133
+ expect(model[5, 1].all__equal(-0.555841134754075)).to eq true
134
+ end
135
+
136
+ it "should allow creating formulas with interaction between variables with 'inter'" do
137
+ formula = :y.til :x + :x2 + (:x.inter :x2)
138
+ expect(formula.to_s.lines.first.chomp).to eq "y ~ x + x2 + x:x2"
139
+
140
+ # Set seed
141
+ R.set__seed(123)
142
+
143
+ # Data
144
+ R.x = R.rnorm(5)
145
+ R.x2 = R.rnorm(5)
146
+ R.y = R.rnorm(5)
147
+
148
+ # Model frame
149
+ model = R.model__frame(formula, data: R.data__frame(x: :x, y: :y, x2: :x2))
150
+ expect(model[1, 1].all__equal(1.22408179743946)).to eq true
151
+ expect(model[1, 3].all__equal(1.71506498688328)).to eq true
152
+ expect(model[3, 2].all__equal(1.55870831414912)).to eq true
153
+ expect(model[5, 1].all__equal(-0.555841134754075)).to eq true
154
+ end
155
+
156
+ it "should allow creating formulas with interaction with ':in'" do
157
+ # note that '_' is a method with two arguments ':in' and ':a' and
158
+ # that it is necessary to put the whole expression in parenthesis or
159
+ # add parenthesis on the arguments
160
+ formula = :y.til :a + (:b._ :in, :a)
161
+ expect(formula.to_s.lines.first.chomp).to eq "y ~ a + b %in% a"
162
+ end
163
+
164
+ end
165
+
166
+ #========================================================================================
167
+ context "When modeling with formulas - Simple linear regression" do
168
+
169
+ before(:each) do
170
+ @boston_lm = R.lm((:medv.til :lstat), data: :Boston)
171
+ end
172
+
173
+ it "should obtain data from the model" do
174
+ expect(@boston_lm.coefficients[[1]].all__equal(34.5538408)).to eq true
175
+ expect(@boston_lm.coefficients[[2]].all__equal(-0.950049353)).to eq true
176
+
177
+ expect(@boston_lm.names[[1]]).to eq "coefficients"
178
+ expect(@boston_lm.names[[2]]).to eq "residuals"
179
+ expect(@boston_lm.names[[12]]).to eq "model"
180
+ end
181
+
182
+ it "should do predictions (confidence) based on the model" do
183
+ # predict the confidence interval
184
+ conf = R.predict(@boston_lm, R.data__frame(lstat: (R.c(5, 10, 15))),
185
+ interval: "confidence")
186
+ expect(conf[1, :all][['fit']].all__equal(29.8035941)).to eq true
187
+ expect(conf[2, :all][['lwr']].all__equal(24.4741320)).to eq true
188
+ expect(conf[3, :all][['upr']].all__equal(20.8746129)).to eq true
189
+ end
190
+
191
+ it "should do prediction (prediction) based on the model" do
192
+ pred = R.predict(@boston_lm, R.data__frame(lstat: (R.c(5, 10, 15))),
193
+ interval: "prediction")
194
+ expect(pred[1, :all][['fit']].all__equal(29.8035941)).to eq true
195
+ expect(pred[2, :all][['lwr']].all__equal(12.82762634)).to eq true
196
+ expect(pred[3, :all][['upr']].all__equal(32.5284590)).to eq true
197
+ end
198
+
199
+ end
200
+
201
+ #========================================================================================
202
+ context "Multiple linear regression" do
203
+
204
+ it "should do multiple linear regression" do
205
+ # Multiple linear regression from ISLR book. Chapter 3 Lab, pg 113
206
+ lm_fit = R.lm((:medv.til :lstat + :age), data: :Boston)
207
+
208
+ # Intercept
209
+ expect(lm_fit.coefficients[[1]].all__equal(33.2227605317)).to eq true
210
+ # lstat
211
+ expect(lm_fit.coefficients[[2]].all__equal(-1.0320685641)).to eq true
212
+ expect(lm_fit.coefficients[['lstat']].all__equal(-1.0320685641)).to eq true
213
+ # age
214
+ expect(lm_fit.coefficients[[3]].all__equal(0.0345443385)).to eq true
215
+ end
216
+
217
+ it "should do multiple linear regression with polynomials" do
218
+ lm_fit5 = R.lm((:medv.til E.poly(:lstat, 5)), data: :Boston)
219
+
220
+ # Intercept
221
+ expect(lm_fit5.coefficients[[1]].all__equal(22.53280632411)).to eq true
222
+ # Poly 1
223
+ expect(lm_fit5.coefficients[[2]].all__equal(-152.4595487225)).to eq true
224
+ # Poly 3
225
+ expect(lm_fit5.coefficients[[4]].all__equal(-27.0510978864097)).to eq true
226
+ # Poly 5
227
+ expect(lm_fit5.coefficients[[6]].all__equal(-19.2524177100554)).to eq true
228
+ end
229
+
230
+ end
231
+
232
+ end