galaaz 0.4.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 +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
|