statsailr 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +7 -0
  5. data/HISTORY.md +15 -0
  6. data/LICENSE.txt +675 -0
  7. data/README.md +287 -0
  8. data/Rakefile +10 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/example/blank.slr +3 -0
  12. data/example/category.slr +5 -0
  13. data/example/example_read.slr +10 -0
  14. data/example/iris.csv +151 -0
  15. data/example/mtcars.rda +0 -0
  16. data/example/new_mtcars.csv +33 -0
  17. data/example/new_mtcars.rda +0 -0
  18. data/example/plot_reg_example.slr +55 -0
  19. data/example/scatter.png +0 -0
  20. data/exe/sailr +54 -0
  21. data/exe/sailrREPL +75 -0
  22. data/lib/statsailr.rb +7 -0
  23. data/lib/statsailr/block_builder/sts_block.rb +167 -0
  24. data/lib/statsailr/block_builder/sts_block_parse_proc_opts.rb +168 -0
  25. data/lib/statsailr/block_to_r/proc_setting_support/proc_opt_validator.rb +52 -0
  26. data/lib/statsailr/block_to_r/proc_setting_support/proc_setting_manager.rb +49 -0
  27. data/lib/statsailr/block_to_r/proc_setting_support/proc_setting_module.rb +44 -0
  28. data/lib/statsailr/block_to_r/sts_block_to_r.rb +98 -0
  29. data/lib/statsailr/block_to_r/sts_lazy_func_gen.rb +236 -0
  30. data/lib/statsailr/block_to_r/top_stmt/top_stmt_to_r_func.rb +182 -0
  31. data/lib/statsailr/parser/sts_gram_node.rb +9 -0
  32. data/lib/statsailr/parser/sts_parse.output +831 -0
  33. data/lib/statsailr/parser/sts_parse.ry +132 -0
  34. data/lib/statsailr/parser/sts_parse.tab.rb +682 -0
  35. data/lib/statsailr/scanner/sample1.sts +37 -0
  36. data/lib/statsailr/scanner/sts_scanner.rb +433 -0
  37. data/lib/statsailr/scanner/test_sample1.rb +8 -0
  38. data/lib/statsailr/sts_build_exec.rb +304 -0
  39. data/lib/statsailr/sts_controller.rb +66 -0
  40. data/lib/statsailr/sts_output/output_manager.rb +192 -0
  41. data/lib/statsailr/sts_runner.rb +17 -0
  42. data/lib/statsailr/sts_server.rb +85 -0
  43. data/lib/statsailr/version.rb +3 -0
  44. data/statsailr.gemspec +32 -0
  45. metadata +133 -0
data/README.md ADDED
@@ -0,0 +1,287 @@
1
+ # StatSailr
2
+
3
+ StatSailr provides a platform for users to focus on statistics. The backend statistics engine is [R](https://www.r-project.org/), so the results are reliable. The SataSailr script consists of three major blocks, TOPLEVEL, DATA, and PROC. Each block has its way of writing instructions, which works as an intuitive interface for R.
4
+
5
+
6
+ ## Overview
7
+
8
+ StatSailr is a Ruby program that enables users to manipulate data and to apply statistical procedures in an intuiitive way. StatSailr converts StatSailr script into R's internal representation, and executes it. The SataSailr script consists of three major blocks, TOPLEVEL, DATA, and PROC. TOPLEVEL loads and saves datasets. DATA blocks utilize DataSailr package as its backend, which enables wrting data manipulation insturctions in a rowwise way. PROC blocks have a series of PROC instructions, which are converted to R functions and are executed sequentially.
9
+
10
+
11
+ ### Quick Introduction
12
+
13
+ The following is an example of StatSailr script. It consists of TOPLEVEL instruction, DATA block and PROC blocks.
14
+
15
+ ```
16
+ READ builtin="mtcars"
17
+
18
+ DATA new_mtcars set=mtcars
19
+ if(hp > 100){
20
+ powerful = 1
21
+ }else{
22
+ powerful = 0
23
+ }
24
+ END
25
+
26
+ PROC PRINT data=new_mtcars
27
+ head 10
28
+ END
29
+
30
+ PROC REG data=new_mtcars
31
+ lm hp ~ powerful
32
+ END
33
+ ```
34
+
35
+ Save this script as, say, create_new_mtcars.slr and run.
36
+
37
+ ```
38
+ # From command line
39
+ # By installing statsailr gem, sailr command should become available.
40
+
41
+ sailr create_new_mtcars.slr
42
+ ```
43
+
44
+
45
+ ### Commands and options
46
+
47
+ #### sailr
48
+
49
+ sailr command executes StatSailr script.
50
+
51
+ * sailr [filename]
52
+ + --procs-gem <gemX,gemY,...>
53
+ + allow users to specify PROCs gems when they need to use other than default PROCs gem, statsailr_procs_base.
54
+ + To specify multiple gems, separate them with comma(,)
55
+
56
+
57
+ #### sailrREPL
58
+
59
+ Not only sailr command, but sailrREPL command is also provided. It enables interactive executaion of StatSailr script. (For non-UNIX system, sailrREPL --thread can be used, which is thread based.)
60
+
61
+ * sailrREPL
62
+ + --procs-gem <gemX,gemY,...>
63
+ + allow users to specify PROCs gems
64
+ + --thread
65
+ + Thread based implementation of REPL. (Windows requires this option.)
66
+
67
+
68
+ sailrREPL requires the explicit commands. Lines are stored as input script until the following commands are executed. Commands within REPL start from !.
69
+
70
+
71
+ + !! or !exec : Executes StatSailr script input. (and clears the input stored.)
72
+ + !clear : Clears input script.
73
+ + !exit : Finishes StatSailr REPL.
74
+
75
+
76
+ The following example shows how sailrREPL works.
77
+
78
+ ```
79
+ cli > sailrREPL # start REPL
80
+
81
+ (^^)v: READ builtin=mtcars
82
+ (^^)v: !! # execute READ
83
+ ... output ...
84
+ (^^)v: DATA new_mtcars set=mtcars
85
+ (^^)v: if( hp > 100){
86
+ (^^)v: powerful = 1
87
+ (^^)v: }else{
88
+ (^^)v: powerful = 0
89
+ (^^)v: }
90
+ (^^)v: END
91
+ (^^)v: !! # execute DATA block
92
+ ... output ...
93
+ (^^)v: PROC PRINT data=new_mtcars
94
+ (^^)v: head 5
95
+ (^^)v: END
96
+ (^^)v: !! # execute PROC block
97
+ ... output ...
98
+ (^^)v: !exit # exit REPL
99
+
100
+ cli >
101
+
102
+ ```
103
+
104
+ ## Installation
105
+
106
+ ### Requirements
107
+
108
+ * R (>= 4.0 is preferable)
109
+ + datasailr package
110
+ + From R's interpreter, execute 'install.packages("datasailr")'.
111
+ * Ruby (>= 2.7)
112
+ + r_bridge gem
113
+ + Configure PATH, LD_LIBRARY_PATH or RUBY_DLL_PATH to access R's shared library (libR.so or R.dll).
114
+ + Details are mentioned in r_bridge gem's README.
115
+ + After configuring these settings, install r_bridge gem via 'gem install r_bridge'
116
+
117
+
118
+ ### Install StatSailr
119
+
120
+ ```
121
+ $ gem install statsailr
122
+ ```
123
+
124
+ * Then, 'sailr' and 'sailrREPL' become available.
125
+
126
+
127
+ ## Grammar of StatSalr
128
+
129
+ StatSailr script consists of three parts, TOPLEVEL, DATA block and PROC block.
130
+
131
+ The following shows structures of these blocks. Details about TOPLEVEL, DATA and PROC blocks are documented in the [StatSailr official site](https://statsailr.io)
132
+
133
+
134
+ ### TOPLEVEL statement
135
+
136
+ TOPLEVEL statements import and save datasets, and also StatSailr's current working directory.
137
+
138
+
139
+ * import and save datasets.
140
+
141
+ Datasets can come from built-in datasets and files. In R, built-in datasets can be used by data() function, and StatSailr READ with 'builtin=' option does the same job.
142
+
143
+ When importing datasets from files, currently there are three types of files availble, RDS, RDATA and CSV. RDS contains a single R object, and when you import it, you can neme the object using 'as=' option. If you omit 'as=' option, the name is created based on the filename. RDATA can contain multiple R objects, but their names cannot be changed when importing that are decided when saveing. CSV is a comma separated values file.
144
+
145
+ These dataset types are decided as follows. If you specify 'type' option, its type is used. If you do not specify it, it is inferred from the file extension.
146
+
147
+
148
+ ```
149
+ READ builtin="mtcars"
150
+ READ file="./mtcars.rds" type="rds" as="mtcars"
151
+ READ file="./mtcars.rda" type="rdata"
152
+ READ file="./mtcars.csv" type="csv" # 'as=' can be used optionally.
153
+ ```
154
+
155
+ For StatSailr SAVE, specifying dataset name(s) followed by 'file=' option is required. "type=" option can be omitted, and in such a case, file extension is used to infer the file type.
156
+
157
+ ```
158
+ SAVE new_mtcars file="./new_mtcars.rds" type="rds"
159
+ SAVE mtcars new_mtcars file="./new_mtcars.rda" type="rdata"
160
+ SAVE new_mtcars file="./new_mtcars.csv" type="csv"
161
+ ```
162
+
163
+ * show and change working directory
164
+
165
+ The concept of working directory is really important. If you run your SailrScript in an unintentional place and ouput some data, those data might overwrite your importan data.
166
+
167
+ The default working directory should be the directory where StatSailr script file exists. If you do not specify script file, such as when you run REPL, the default working directory should be the directory where you start your command (such as REPL).
168
+
169
+ The following commands show the current working directory and change it to new directory.
170
+
171
+ ```
172
+ GETWD
173
+ SETWD "~/sailr_workspace"
174
+ ```
175
+
176
+
177
+ ### DATA block
178
+
179
+ DATA block starts with the line of DATA, new dataset name and DATA options. For DATA options, 'set=' option is required which specify the input dataset. (Note that unlinke PROC options where 'data=' usually speifies input dataset, "set=" does the same job in DATA block. This difference comes from just an aesthetic reason.) Lines that follws the first DATA line represent how to manipulate input dataset. The lines are writtein in DataSailr script. END keyword specifies the end of DATA block.
180
+
181
+ ```
182
+ DATA new_dataset set=ori_dataset
183
+ // This part is a plain DataSailr script
184
+ // (e.g.)
185
+ if(hp > 100){
186
+ powerful = 1
187
+ }else{
188
+ powerful = 0
189
+ }
190
+ END
191
+ ```
192
+
193
+ The DataSailr script is described in detail at [its official website](https://datasailr.io).
194
+
195
+ Briefly speaking,
196
+
197
+ 1. Rowwise dataset manipulation
198
+ + Varables correspond to column names.
199
+ 2. Simplified available types
200
+ + Int, Double and String(=Characters) are basic types, that can be used in DataSailr script and also those values can be assigned to column value (of dataset).
201
+ + Regular expression and boolean are not assigned to dataset. They can be held by variables, but do not modify dataset.
202
+ + Regular expression is used for if condition and extracting substrings.
203
+ + Boolean is internal type that is used for if condition.
204
+ 3. Assignment operator (=) creates new column with the column name same as the variable left-hand-side(LHS) of assignment operator.
205
+ + If the variable already exits, the column is updated.
206
+ + Exceptions are assigning regular expressions and boolen, which do not modify dataset. Variables pointing to those objects are only used in the script.
207
+ 4. Control flow can be done using if-(else if)-(else) statement.
208
+ + Condition part needs parentheses (), and statement part require curly braces.
209
+ 5. Arithmetic operators
210
+ 6. Built-in functions
211
+ + Mainly used to manipulate strings.
212
+ 7. Regular expression
213
+ 8. UTF-8
214
+ + Use UTF-8 for script and dataset. It is highly recommended that dataset should be saved using UTF-8 beforehand.
215
+ 9. push!() and discard!() built-in functions
216
+ + push!() can create multiple rows from current row.
217
+ + discard!() can filter out specific rows by being used with if statements.
218
+
219
+
220
+ ### PROC block
221
+
222
+ #### statsailr_procs_base gem
223
+
224
+ PROC commands and instructions are now managed in a separate PROCs gem. The gem name is 'statsailr_procs_base' (from ver. 0.71). You need to have the gem installed to use PROCs ,though it is usually installed as a dependency of 'statsailr' gem. If StatSailr complains that PROC PRINT command is not found, please make sure that the PROCs gem is installed.
225
+
226
+ The PROCs gem holds basic PROC settings, such as PRINT and PLOT, and its main class (StatSailr::ProcsBase) just returns the base path for those PROC settings. Please read the README of the PROCs gem if you are interested in how PROCs are implemented.
227
+
228
+
229
+ #### Format
230
+
231
+ A typical PROC block looks like the follwing. The first line start with PROC, followed by PROC command name and PROC options. The PROC first line is followed by a list of instuctions with their main and optional arguments. The PROC block ends with END keyword.
232
+
233
+ ```
234
+ PROC COMMAND proc_opts
235
+ instX main_arg / opt_args # proc_statement X
236
+ instY main_arg / opt_args
237
+ instZ main_arg / opt_args
238
+ END
239
+ ```
240
+
241
+ * COMMAND
242
+ + PROC command name
243
+ * proc_opts
244
+ + This parameter can be refered from any instructions in this block. In other words, this can be seen as global settings of this PROC block.
245
+ + Internally, this parameter is managed by RBridge::ParamManager.
246
+ * proc_statement line
247
+ + Each line consists of instruction, main argument and optional arguments. Main argument and optional arguments are separated by slash(/).
248
+ + Internally, each line is converted into an R function, and its return value is managed by RBridge::ResultManager. (Whether the result is stored or not can be changed in PROC setting.)
249
+ + inst
250
+ + PROC instruction name. Instruction names are associated with R's function names.
251
+ + main_arg
252
+ + Main argument. Value specified in main_arg is passed to R function's argument.
253
+ + How main argument part is parsed varies on each instruction. This is defined in main_arg_and_how_to_treat variable in setting.
254
+ + opt_args
255
+ + Optional arguments. Values specified in opt_args are also passed to R function's argument.
256
+ + opt_args part consists of (a) key-value(s) or key(s).
257
+ + Internally, this argument parsing is conducted by methods in STSBlockParseProcOpts.
258
+
259
+
260
+ ## About plotting device
261
+
262
+ R outputs graphics to various programs called devices. When using R interactively, graphics are usually output to a window by default. StatSailr uses such a default device, and the device or the plotting window closes as the script execution finishes.
263
+
264
+ To keep the plotting result, it is currently recommended to copy the device graphics to some file. dev.copy() does this work. For such PROCs that have plot related instructions, dev.copy instruction are provided. dev.copy can save the graphic on the current graphics device to a file.
265
+
266
+ ```
267
+ // Example
268
+
269
+ PROC PLOT data=mtcars
270
+ scatter cyl carb // This instruction creates scatter plot and displays it on a device (window).
271
+ dev.copy png / file="./myplot.png" // This instruction copies graphics on the device to myplot.png file.
272
+ END
273
+ ```
274
+
275
+
276
+ ## License
277
+
278
+ The gem is available as open source under the terms of the [GPL v3 License](https://www.gnu.org/licenses/gpl-3.0.en.html).
279
+
280
+
281
+ ## Contact
282
+
283
+ Your feedback is welcome.
284
+
285
+ Maintainer: Toshi Umehara toshi@niceume.com
286
+
287
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "statsailr"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/example/blank.slr ADDED
@@ -0,0 +1,3 @@
1
+
2
+
3
+
@@ -0,0 +1,5 @@
1
+ READ builtin="mtcars"
2
+
3
+ PROC CAT data=mtcars
4
+ crosstable cyl carb / missing.include = T
5
+ END
@@ -0,0 +1,10 @@
1
+ // comment
2
+ /*
3
+ multipe line comments
4
+ */
5
+
6
+ Read builtin = "mtcars"
7
+
8
+ READ file = "./iris.csv" as = iris_csv sep = ","
9
+
10
+
data/example/iris.csv ADDED
@@ -0,0 +1,151 @@
1
+ "","Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","Species"
2
+ "1",5.1,3.5,1.4,0.2,"setosa"
3
+ "2",4.9,3,1.4,0.2,"setosa"
4
+ "3",4.7,3.2,1.3,0.2,"setosa"
5
+ "4",4.6,3.1,1.5,0.2,"setosa"
6
+ "5",5,3.6,1.4,0.2,"setosa"
7
+ "6",5.4,3.9,1.7,0.4,"setosa"
8
+ "7",4.6,3.4,1.4,0.3,"setosa"
9
+ "8",5,3.4,1.5,0.2,"setosa"
10
+ "9",4.4,2.9,1.4,0.2,"setosa"
11
+ "10",4.9,3.1,1.5,0.1,"setosa"
12
+ "11",5.4,3.7,1.5,0.2,"setosa"
13
+ "12",4.8,3.4,1.6,0.2,"setosa"
14
+ "13",4.8,3,1.4,0.1,"setosa"
15
+ "14",4.3,3,1.1,0.1,"setosa"
16
+ "15",5.8,4,1.2,0.2,"setosa"
17
+ "16",5.7,4.4,1.5,0.4,"setosa"
18
+ "17",5.4,3.9,1.3,0.4,"setosa"
19
+ "18",5.1,3.5,1.4,0.3,"setosa"
20
+ "19",5.7,3.8,1.7,0.3,"setosa"
21
+ "20",5.1,3.8,1.5,0.3,"setosa"
22
+ "21",5.4,3.4,1.7,0.2,"setosa"
23
+ "22",5.1,3.7,1.5,0.4,"setosa"
24
+ "23",4.6,3.6,1,0.2,"setosa"
25
+ "24",5.1,3.3,1.7,0.5,"setosa"
26
+ "25",4.8,3.4,1.9,0.2,"setosa"
27
+ "26",5,3,1.6,0.2,"setosa"
28
+ "27",5,3.4,1.6,0.4,"setosa"
29
+ "28",5.2,3.5,1.5,0.2,"setosa"
30
+ "29",5.2,3.4,1.4,0.2,"setosa"
31
+ "30",4.7,3.2,1.6,0.2,"setosa"
32
+ "31",4.8,3.1,1.6,0.2,"setosa"
33
+ "32",5.4,3.4,1.5,0.4,"setosa"
34
+ "33",5.2,4.1,1.5,0.1,"setosa"
35
+ "34",5.5,4.2,1.4,0.2,"setosa"
36
+ "35",4.9,3.1,1.5,0.2,"setosa"
37
+ "36",5,3.2,1.2,0.2,"setosa"
38
+ "37",5.5,3.5,1.3,0.2,"setosa"
39
+ "38",4.9,3.6,1.4,0.1,"setosa"
40
+ "39",4.4,3,1.3,0.2,"setosa"
41
+ "40",5.1,3.4,1.5,0.2,"setosa"
42
+ "41",5,3.5,1.3,0.3,"setosa"
43
+ "42",4.5,2.3,1.3,0.3,"setosa"
44
+ "43",4.4,3.2,1.3,0.2,"setosa"
45
+ "44",5,3.5,1.6,0.6,"setosa"
46
+ "45",5.1,3.8,1.9,0.4,"setosa"
47
+ "46",4.8,3,1.4,0.3,"setosa"
48
+ "47",5.1,3.8,1.6,0.2,"setosa"
49
+ "48",4.6,3.2,1.4,0.2,"setosa"
50
+ "49",5.3,3.7,1.5,0.2,"setosa"
51
+ "50",5,3.3,1.4,0.2,"setosa"
52
+ "51",7,3.2,4.7,1.4,"versicolor"
53
+ "52",6.4,3.2,4.5,1.5,"versicolor"
54
+ "53",6.9,3.1,4.9,1.5,"versicolor"
55
+ "54",5.5,2.3,4,1.3,"versicolor"
56
+ "55",6.5,2.8,4.6,1.5,"versicolor"
57
+ "56",5.7,2.8,4.5,1.3,"versicolor"
58
+ "57",6.3,3.3,4.7,1.6,"versicolor"
59
+ "58",4.9,2.4,3.3,1,"versicolor"
60
+ "59",6.6,2.9,4.6,1.3,"versicolor"
61
+ "60",5.2,2.7,3.9,1.4,"versicolor"
62
+ "61",5,2,3.5,1,"versicolor"
63
+ "62",5.9,3,4.2,1.5,"versicolor"
64
+ "63",6,2.2,4,1,"versicolor"
65
+ "64",6.1,2.9,4.7,1.4,"versicolor"
66
+ "65",5.6,2.9,3.6,1.3,"versicolor"
67
+ "66",6.7,3.1,4.4,1.4,"versicolor"
68
+ "67",5.6,3,4.5,1.5,"versicolor"
69
+ "68",5.8,2.7,4.1,1,"versicolor"
70
+ "69",6.2,2.2,4.5,1.5,"versicolor"
71
+ "70",5.6,2.5,3.9,1.1,"versicolor"
72
+ "71",5.9,3.2,4.8,1.8,"versicolor"
73
+ "72",6.1,2.8,4,1.3,"versicolor"
74
+ "73",6.3,2.5,4.9,1.5,"versicolor"
75
+ "74",6.1,2.8,4.7,1.2,"versicolor"
76
+ "75",6.4,2.9,4.3,1.3,"versicolor"
77
+ "76",6.6,3,4.4,1.4,"versicolor"
78
+ "77",6.8,2.8,4.8,1.4,"versicolor"
79
+ "78",6.7,3,5,1.7,"versicolor"
80
+ "79",6,2.9,4.5,1.5,"versicolor"
81
+ "80",5.7,2.6,3.5,1,"versicolor"
82
+ "81",5.5,2.4,3.8,1.1,"versicolor"
83
+ "82",5.5,2.4,3.7,1,"versicolor"
84
+ "83",5.8,2.7,3.9,1.2,"versicolor"
85
+ "84",6,2.7,5.1,1.6,"versicolor"
86
+ "85",5.4,3,4.5,1.5,"versicolor"
87
+ "86",6,3.4,4.5,1.6,"versicolor"
88
+ "87",6.7,3.1,4.7,1.5,"versicolor"
89
+ "88",6.3,2.3,4.4,1.3,"versicolor"
90
+ "89",5.6,3,4.1,1.3,"versicolor"
91
+ "90",5.5,2.5,4,1.3,"versicolor"
92
+ "91",5.5,2.6,4.4,1.2,"versicolor"
93
+ "92",6.1,3,4.6,1.4,"versicolor"
94
+ "93",5.8,2.6,4,1.2,"versicolor"
95
+ "94",5,2.3,3.3,1,"versicolor"
96
+ "95",5.6,2.7,4.2,1.3,"versicolor"
97
+ "96",5.7,3,4.2,1.2,"versicolor"
98
+ "97",5.7,2.9,4.2,1.3,"versicolor"
99
+ "98",6.2,2.9,4.3,1.3,"versicolor"
100
+ "99",5.1,2.5,3,1.1,"versicolor"
101
+ "100",5.7,2.8,4.1,1.3,"versicolor"
102
+ "101",6.3,3.3,6,2.5,"virginica"
103
+ "102",5.8,2.7,5.1,1.9,"virginica"
104
+ "103",7.1,3,5.9,2.1,"virginica"
105
+ "104",6.3,2.9,5.6,1.8,"virginica"
106
+ "105",6.5,3,5.8,2.2,"virginica"
107
+ "106",7.6,3,6.6,2.1,"virginica"
108
+ "107",4.9,2.5,4.5,1.7,"virginica"
109
+ "108",7.3,2.9,6.3,1.8,"virginica"
110
+ "109",6.7,2.5,5.8,1.8,"virginica"
111
+ "110",7.2,3.6,6.1,2.5,"virginica"
112
+ "111",6.5,3.2,5.1,2,"virginica"
113
+ "112",6.4,2.7,5.3,1.9,"virginica"
114
+ "113",6.8,3,5.5,2.1,"virginica"
115
+ "114",5.7,2.5,5,2,"virginica"
116
+ "115",5.8,2.8,5.1,2.4,"virginica"
117
+ "116",6.4,3.2,5.3,2.3,"virginica"
118
+ "117",6.5,3,5.5,1.8,"virginica"
119
+ "118",7.7,3.8,6.7,2.2,"virginica"
120
+ "119",7.7,2.6,6.9,2.3,"virginica"
121
+ "120",6,2.2,5,1.5,"virginica"
122
+ "121",6.9,3.2,5.7,2.3,"virginica"
123
+ "122",5.6,2.8,4.9,2,"virginica"
124
+ "123",7.7,2.8,6.7,2,"virginica"
125
+ "124",6.3,2.7,4.9,1.8,"virginica"
126
+ "125",6.7,3.3,5.7,2.1,"virginica"
127
+ "126",7.2,3.2,6,1.8,"virginica"
128
+ "127",6.2,2.8,4.8,1.8,"virginica"
129
+ "128",6.1,3,4.9,1.8,"virginica"
130
+ "129",6.4,2.8,5.6,2.1,"virginica"
131
+ "130",7.2,3,5.8,1.6,"virginica"
132
+ "131",7.4,2.8,6.1,1.9,"virginica"
133
+ "132",7.9,3.8,6.4,2,"virginica"
134
+ "133",6.4,2.8,5.6,2.2,"virginica"
135
+ "134",6.3,2.8,5.1,1.5,"virginica"
136
+ "135",6.1,2.6,5.6,1.4,"virginica"
137
+ "136",7.7,3,6.1,2.3,"virginica"
138
+ "137",6.3,3.4,5.6,2.4,"virginica"
139
+ "138",6.4,3.1,5.5,1.8,"virginica"
140
+ "139",6,3,4.8,1.8,"virginica"
141
+ "140",6.9,3.1,5.4,2.1,"virginica"
142
+ "141",6.7,3.1,5.6,2.4,"virginica"
143
+ "142",6.9,3.1,5.1,2.3,"virginica"
144
+ "143",5.8,2.7,5.1,1.9,"virginica"
145
+ "144",6.8,3.2,5.9,2.3,"virginica"
146
+ "145",6.7,3.3,5.7,2.5,"virginica"
147
+ "146",6.7,3,5.2,2.3,"virginica"
148
+ "147",6.3,2.5,5,1.9,"virginica"
149
+ "148",6.5,3,5.2,2,"virginica"
150
+ "149",6.2,3.4,5.4,2.3,"virginica"
151
+ "150",5.9,3,5.1,1.8,"virginica"