galaaz 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +32 -0
- data/Rakefile +177 -0
- data/bin/galaaz +8 -0
- data/examples/50Plots_MasterList/scatter_plot.rb +51 -0
- data/examples/baseball.csv +1 -0
- data/examples/baseball.rb +16 -0
- data/examples/ggplot.rb +178 -0
- data/examples/islr/Figure.jpg +0 -0
- data/examples/islr/all.rb +32 -0
- data/examples/islr/ch2.spec.rb +148 -0
- data/examples/islr/ch3.spec.rb +28 -0
- data/examples/islr/ch3_boston.rb +77 -0
- data/examples/islr/ch3_multiple_regression.rb +36 -0
- data/examples/islr/ch6.spec.rb +64 -0
- data/examples/paper/paper.rb +36 -0
- data/examples/sthda_ggplot/README.md +38 -0
- data/examples/sthda_ggplot/all.rb +68 -0
- data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +52 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +61 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +77 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +69 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +69 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +62 -0
- data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +55 -0
- data/examples/sthda_ggplot/one_variable_continuous/stat.rb +62 -0
- data/examples/sthda_ggplot/one_variable_discrete/bar.rb +54 -0
- data/examples/sthda_ggplot/qplots/box_violin_dot.rb +57 -0
- data/examples/sthda_ggplot/qplots/scatter_plots.rb +67 -0
- data/examples/sthda_ggplot/scatter_gg.rb +60 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +49 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +64 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +52 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +65 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +66 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +83 -0
- data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +63 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +85 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +62 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +75 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +74 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +55 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +70 -0
- data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +40 -0
- data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +108 -0
- data/examples/subsetting.rb +372 -0
- data/lib/expression.rb +45 -0
- data/lib/galaaz.rb +27 -0
- data/lib/r.rb +118 -0
- data/lib/r_methods.rb +89 -0
- data/lib/rbinary_operators.rb +226 -0
- data/lib/rclosure.rb +34 -0
- data/lib/rdata_frame.rb +63 -0
- data/lib/renvironment.rb +34 -0
- data/lib/rexpression.rb +34 -0
- data/lib/rindexed_object.rb +68 -0
- data/lib/rlanguage.rb +64 -0
- data/lib/rlist.rb +72 -0
- data/lib/rmatrix.rb +38 -0
- data/lib/rmd_indexed_object.rb +43 -0
- data/lib/robject.rb +297 -0
- data/lib/rpkg.rb +53 -0
- data/lib/rsupport.rb +292 -0
- data/lib/rsupport_scope.rb +77 -0
- data/lib/rsymbol.rb +57 -0
- data/lib/ruby_callback.rb +83 -0
- data/lib/ruby_extensions.rb +74 -0
- data/lib/runary_operators.rb +58 -0
- data/lib/rvector.rb +117 -0
- data/r_requires/ggplot.rb +31 -0
- data/specs/all.rb +45 -0
- data/specs/r_dataframe.spec.rb +181 -0
- data/specs/r_eval.spec.rb +164 -0
- data/specs/r_function.spec.rb +105 -0
- data/specs/r_language.spec.rb +135 -0
- data/specs/r_list.spec.rb +129 -0
- data/specs/r_list_apply.spec.rb +99 -0
- data/specs/r_matrix.spec.rb +83 -0
- data/specs/r_vector_creation.spec.rb +99 -0
- data/specs/r_vector_functions.spec.rb +59 -0
- data/specs/r_vector_object.spec.rb +94 -0
- data/specs/r_vector_operators.spec.rb +174 -0
- data/specs/r_vector_subsetting.spec.rb +136 -0
- data/specs/tmp.rb +134 -0
- data/version.rb +2 -0
- metadata +198 -0
@@ -0,0 +1,31 @@
|
|
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
|
+
# check if packages are already installed and if not intall them
|
25
|
+
R.install_rlibs('ggplot2', 'grid', 'gridExtra', 'ggplotify')
|
26
|
+
|
27
|
+
# Load plotting libraries
|
28
|
+
R.library('ggplot2')
|
29
|
+
R.library('grid')
|
30
|
+
R.library('gridExtra')
|
31
|
+
R.library('ggplotify')
|
data/specs/all.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
##########################################################################################
|
4
|
+
# @author Rodrigo Botafogo
|
5
|
+
#
|
6
|
+
# Copyright © 2013 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_relative 'r_eval.spec'
|
25
|
+
|
26
|
+
# Specification for R::Vector
|
27
|
+
require_relative 'r_vector_creation.spec'
|
28
|
+
require_relative 'r_vector_object.spec'
|
29
|
+
require_relative 'r_vector_subsetting.spec'
|
30
|
+
require_relative 'r_vector_functions.spec'
|
31
|
+
require_relative 'r_vector_operators.spec'
|
32
|
+
|
33
|
+
# Specification for R::Lists
|
34
|
+
require_relative 'r_list.spec'
|
35
|
+
require_relative 'r_list_apply.spec'
|
36
|
+
|
37
|
+
# Specification for R::Matrix
|
38
|
+
require_relative 'r_matrix.spec'
|
39
|
+
|
40
|
+
# Specification for R::Dataframes
|
41
|
+
require_relative 'r_dataframe.spec'
|
42
|
+
|
43
|
+
# Specification for language features
|
44
|
+
require_relative 'r_function.spec'
|
45
|
+
require_relative 'r_language.spec'
|
@@ -0,0 +1,181 @@
|
|
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::DataFrame do
|
27
|
+
|
28
|
+
#----------------------------------------------------------------------------------------
|
29
|
+
context "Create DataFrame" do
|
30
|
+
|
31
|
+
it "should create a dataframe from a vector" do
|
32
|
+
vec = R.seq(6)
|
33
|
+
vec.dim = R.c(2, 3)
|
34
|
+
|
35
|
+
# create a DataFrame from a vector
|
36
|
+
df = R.as__data__frame(vec)
|
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
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
#----------------------------------------------------------------------------------------
|
46
|
+
context "Subsetting" do
|
47
|
+
|
48
|
+
it "should do integer subsetting" do
|
49
|
+
grades = R.c(1.0, 2.0, 2.0, 3.0, 1.0)
|
50
|
+
|
51
|
+
info = R.data__frame(
|
52
|
+
grade: (3..1),
|
53
|
+
desc: R.c("Excellent", "Good", "Poor"),
|
54
|
+
fail: R.c(false, false, true)
|
55
|
+
)
|
56
|
+
|
57
|
+
id = R.match(grades, info.grade)
|
58
|
+
table = info[id, :all]
|
59
|
+
|
60
|
+
expect(table.grade[1]).to eq 1
|
61
|
+
expect(table.desc.levels[2]).to eq "Good"
|
62
|
+
expect(table.fail[4]).to eq false
|
63
|
+
|
64
|
+
info.rownames = info.grade
|
65
|
+
table2 = info[grades.as__character, :all]
|
66
|
+
|
67
|
+
expect(table2.grade[2]).to eq 2
|
68
|
+
expect(table2.desc.levels[1]).to eq "Excellent"
|
69
|
+
expect(table2.fail[4]).to eq true
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should do 'each_column'" do
|
74
|
+
|
75
|
+
mtcars = ~:mtcars
|
76
|
+
|
77
|
+
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
|
81
|
+
when "mpg"
|
82
|
+
expect col[1] == 21
|
83
|
+
expect col[9] == 22.8
|
84
|
+
expect col[32] == 21.4
|
85
|
+
when "cyl"
|
86
|
+
expect col[1] == 6
|
87
|
+
expect col[10] == 6
|
88
|
+
expect col[32] == 4
|
89
|
+
when "disp"
|
90
|
+
expect col[1] == 160
|
91
|
+
expect col[32] == 121
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should do 'each_row'" do
|
99
|
+
|
100
|
+
mtcars = ~:mtcars
|
101
|
+
|
102
|
+
mtcars.each_row do |row, row_name|
|
103
|
+
case row_name << 0
|
104
|
+
when "Mazda RX4"
|
105
|
+
expect row['mpg'] == 21
|
106
|
+
expect row.qsec == 16.46
|
107
|
+
when "Hornet Sportabout"
|
108
|
+
expect row['cyl'] == 8
|
109
|
+
expect row['wt'] == 3.44
|
110
|
+
when "Merc 240D"
|
111
|
+
expect row['hp'] == 62
|
112
|
+
expect row.drat == 3.69
|
113
|
+
when "Volvo 142E"
|
114
|
+
expect row.hp == 109
|
115
|
+
expect row.am == 1
|
116
|
+
expect row.carb == 2
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
#----------------------------------------------------------------------------------------
|
126
|
+
context "Boostraping" do
|
127
|
+
|
128
|
+
before(:each) do
|
129
|
+
@df = R.data__frame(x: R.rep((1..3), each: 2), y: (6..1), z: (~:letters)[(1..6)])
|
130
|
+
R.set__seed(10)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should do reordering with integer subsetting" do
|
134
|
+
|
135
|
+
table = @df[R.sample(@df.nrow), :all]
|
136
|
+
expect(table.x[3]).to eq 3
|
137
|
+
expect(table.y[2]).to eq 5
|
138
|
+
expect(table.z.levels[6]).to eq "f"
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should select random rows with integer subsetting" do
|
143
|
+
table = @df[R.sample(@df.nrow, 3), :all]
|
144
|
+
|
145
|
+
expect(table.x[3]).to eq 3
|
146
|
+
expect(table.y[1]).to eq 3
|
147
|
+
expect(table.z.levels[table.z[2]]).to eq "b"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should randomly reorder a dataframe" do
|
151
|
+
df2 = @df[R.sample(@df.nrow), (3..1)]
|
152
|
+
|
153
|
+
expect(df2.z.levels[df2.z[4]]).to eq "c"
|
154
|
+
expect(df2.y[2]).to eq 5
|
155
|
+
expect(df2.x[5]).to eq 1
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should reorder by a given variable" do
|
159
|
+
df2 = @df[R.sample(@df.nrow), (3..1)]
|
160
|
+
df2 = df2[df2.x.order, :all]
|
161
|
+
|
162
|
+
expect(df2.x[1]).to eq 1
|
163
|
+
expect(df2.y[1]).to eq 5
|
164
|
+
expect(df2.z.levels[df2.z[1]]).to eq "b"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should reorder variables" do
|
168
|
+
df2 = @df[R.sample(@df.nrow), (3..1)]
|
169
|
+
df2 = df2[df2.x.order, :all]
|
170
|
+
|
171
|
+
df2 = df2[:all, df2.names.order]
|
172
|
+
|
173
|
+
expect(df2.names.all__equal R.c("x", "y", "z")).to eq true
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
# df = R.tibble::tibble(x = 1:3, y = 3:1, z = letters[1:3])
|
179
|
+
|
180
|
+
end
|
181
|
+
|
@@ -0,0 +1,164 @@
|
|
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 do
|
27
|
+
|
28
|
+
context "Accessing R through R::Support.eval" do
|
29
|
+
|
30
|
+
before(:each) do
|
31
|
+
R::Support.eval(<<-R)
|
32
|
+
# x is a "double" vector
|
33
|
+
x <- c(1, 2, 3)
|
34
|
+
hyp <- function(x, y) { sqrt(x^2 + y^2) };
|
35
|
+
R
|
36
|
+
end
|
37
|
+
|
38
|
+
it "Integer values in R are automatically unboxed as float" do
|
39
|
+
var = R::Support.eval("5L")
|
40
|
+
# although var is an Interop, it is automatically unboxed, when it is a vector of length
|
41
|
+
# one, and can thus be compared with a number.
|
42
|
+
expect(5).to eq var
|
43
|
+
expect(5.0).to eq var
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Interop pointers can be operated through eval" do
|
47
|
+
var = R::Support.eval("5L")
|
48
|
+
# calling method 'class' on var returns a vector of size one with a string that
|
49
|
+
# contains the class of the object
|
50
|
+
expect("integer").to eq R::Support.eval("class").call(var).to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
it "A number evaluated in R is automatically unboxed as float in Ruby" do
|
54
|
+
var = R::Support.eval("4")
|
55
|
+
expect(4.0).to eq var
|
56
|
+
expect("numeric").to eq R::Support.eval("class").call(var).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
it "R vectors can be indexed by the indexing method of the host language" do
|
60
|
+
var = R::Support.eval("'Hello'")
|
61
|
+
expect(var[0]).to eq "Hello"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should retrieve named R objects to Ruby variables using eval. Returned value should be an Interop" do
|
65
|
+
# retrieve x and hyp from R and attribute it to local Ruby variables
|
66
|
+
x = R::Support.eval("x")
|
67
|
+
# hyp is an R function and works like a named function in Ruby
|
68
|
+
hyp = R::Support.eval("hyp")
|
69
|
+
|
70
|
+
# is is a foreign object
|
71
|
+
expect(Truffle::Interop.foreign?(x)).to be true
|
72
|
+
# we can index the object starting at 0. This is a property offered by
|
73
|
+
# Interop API
|
74
|
+
expect(x[0]).to eq 1.0
|
75
|
+
|
76
|
+
# calling a named function or block is done by use of the 'call' method
|
77
|
+
expect(hyp.call(3, 4)).to eq 5.0
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
context "Basic access to R without R::Support" do
|
83
|
+
|
84
|
+
it "should retrieve named R objects to Ruby variables by using '~' " do
|
85
|
+
# retrieve x and hyp from R and attribute it to local Ruby variables
|
86
|
+
x = ~:x
|
87
|
+
|
88
|
+
expect(x.is_a? R::Vector).to eq true
|
89
|
+
expect(x.length).to eq 3
|
90
|
+
# it is not a foreign object. It's an R::Vectors
|
91
|
+
expect(Truffle::Interop.foreign?(x)).to be false
|
92
|
+
# Values are indexed starting with 1, the same as R notation
|
93
|
+
expect(x[1]).to eq 1.0
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return a String Vector" do
|
97
|
+
# Interop will take a one dimensional array and return the value of the first
|
98
|
+
# element. This might change on a future release. At the present moment, var
|
99
|
+
# becomes a character array with 5 elements
|
100
|
+
var = R.c("Hello")
|
101
|
+
|
102
|
+
expect(var.length).to eq 1
|
103
|
+
expect(var.typeof).to eq "character"
|
104
|
+
expect(var.is_a? R::Vector).to eq true
|
105
|
+
expect(var[1]).to eq "Hello"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "shoud access named objects in R" do
|
109
|
+
# to create a double vector through the Ruby interface, we need that at least
|
110
|
+
# one element of the vector is a 'float'
|
111
|
+
double = R.c(1.0, 2, 3)
|
112
|
+
expect((~:x).identical double).to eq true
|
113
|
+
expect(R.hyp(3, 4)).to eq 5
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should box R functions in R::Closure Ruby class" do
|
117
|
+
# hyp is an R function and works like a named function in Ruby
|
118
|
+
hyp = ~:hyp
|
119
|
+
|
120
|
+
# calling a named function or block is done by use of the 'call' method
|
121
|
+
expect(hyp.call(3, 4)).to eq 5.0
|
122
|
+
expect(hyp.typeof).to eq "closure"
|
123
|
+
expect(hyp.is_a? R::Closure).to eq true
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should print values the same way as R" do
|
127
|
+
# retrieve x and hyp from R and attribute it to local Ruby variables
|
128
|
+
x = ~:x
|
129
|
+
|
130
|
+
# Converting to string (to_s) will print as an R vector would
|
131
|
+
expect(x[1].to_s).to eq ("[1] 1")
|
132
|
+
expect(x.to_s).to eq ("[1] 1 2 3")
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should allow logical comparison using R::Objects" do
|
136
|
+
# retrieve x and hyp from R and attribute it to local Ruby variables
|
137
|
+
x = ~:x
|
138
|
+
|
139
|
+
expect(x[1] == 1).to eq true
|
140
|
+
expect(x[2] == 1).to eq false
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should have NA" do
|
144
|
+
expect(R.is__na R::NA).to eq true
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
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
|
+
end
|
@@ -0,0 +1,105 @@
|
|
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 do
|
27
|
+
|
28
|
+
#----------------------------------------------------------------------------------------
|
29
|
+
context "When calling R functions" do
|
30
|
+
|
31
|
+
# Let's call a function passing named parameters
|
32
|
+
it "should pass named parameters" do
|
33
|
+
# Named parameters are in Ruby are converted to named parameters in R
|
34
|
+
m = R.matrix(R.seq(1, 10), nrow: 2,
|
35
|
+
dimnames: R.list(R.c("1", "2"),
|
36
|
+
R.c("a", "b", "c", "d", "e")))
|
37
|
+
expect(m.dimnames[[1]].identical(R.c("1", "2"))).to eq true
|
38
|
+
expect(m.dimnames[[2]].identical(R.c("a", "b", "c", "d", "e"))).to eq true
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
#----------------------------------------------------------------------------------------
|
44
|
+
context "Using Ruby Procs as parameters to R functions and expressions" do
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@x = @y = R.seq(-~:pi, ~:pi, length: 10)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should accept a Proc as parameter" do
|
51
|
+
# call R outer function passing in a Proc
|
52
|
+
# note that x and y are Ruby objects that were received from an
|
53
|
+
# R function, so they are R::Vectors or another type of R::Object. We
|
54
|
+
# can operate on them with R functions: for instance, R.cos(y)
|
55
|
+
f = R.outer(@x, @y,
|
56
|
+
lambda { |x, y|
|
57
|
+
R.cos(y) / (x**2 + 1)})
|
58
|
+
expect(f[1, 1] == -0.09199967).to eq true
|
59
|
+
expect(f[7, 6] == -0.04599983).to eq true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should accept a Method as parameter" do
|
63
|
+
|
64
|
+
module Calculation
|
65
|
+
# note that x and y are Ruby objects that were received from an
|
66
|
+
# R function, so they are R::Vectors or another type of R::Object. We
|
67
|
+
# can operate on them with R functions: for instance, R.cos(y)
|
68
|
+
def self.func(x, y)
|
69
|
+
R.cos(y) / (x**2 + 1)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
f = R.outer(@x, @y, Calculation.method(:func))
|
74
|
+
expect(f[1, 1] == -0.09199967).to eq true
|
75
|
+
expect(f[7, 6] == -0.04599983).to eq true
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should accept Procs in Expressions" do
|
80
|
+
|
81
|
+
df = R.data__frame(x: @x, y: @y)
|
82
|
+
# create a quoted function f that takes 3 parameters :x, :y and a Proc
|
83
|
+
# we want to evaluate f in the scope of the dataframe 'df'
|
84
|
+
f = E.outer(:x, :y, lambda { |x, y| R.cos(y) / (1 + x**2) })
|
85
|
+
|
86
|
+
# now lets evaluate f in the scope of df, where :x and :y are defined
|
87
|
+
res = f.eval(df)
|
88
|
+
expect(res[1, 1] == -0.09199967).to eq true
|
89
|
+
expect(res[10, 10] == -0.09199967).to eq true
|
90
|
+
end
|
91
|
+
|
92
|
+
it "Should be able to 'eval' a Proc in expression" do
|
93
|
+
|
94
|
+
df = R.data__frame(x: R.c(1, 2, 3), y: R.c(4, 5, 6))
|
95
|
+
f = E.outer(:x, :y, Proc.new { |x, y| x + y })
|
96
|
+
|
97
|
+
res = f.eval(df)
|
98
|
+
expect(res[1, :all] == R.c(5, 6, 7)).to eq true
|
99
|
+
expect(res[3, :all] == R.c(7, 8, 9)).to eq true
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|