fat_table 0.9.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-with-dbs.yml +180 -0
- data/.gitignore +4 -1
- data/.rubocop.yml +9 -2
- data/.simplecov +2 -0
- data/.yardopts +4 -5
- data/CHANGELOG.md +303 -0
- data/CHANGELOG.org +145 -0
- data/Gemfile +5 -7
- data/README.md +2961 -0
- data/README.org +1234 -914
- data/Rakefile +5 -0
- data/bin/ft_console +1 -0
- data/fat_table.gemspec +2 -0
- data/lib/{ext → core_ext}/array.rb +2 -0
- data/lib/core_ext/numeric_string.rb +196 -0
- data/lib/core_ext.rb +4 -0
- data/lib/fat_table/column.rb +5 -1
- data/lib/fat_table/convert.rb +2 -0
- data/lib/fat_table/footer.rb +1 -1
- data/lib/fat_table/formatters/formatter.rb +26 -52
- data/lib/fat_table/formatters/latex_formatter.rb +2 -2
- data/lib/fat_table/table.rb +8 -8
- data/lib/fat_table/version.rb +1 -1
- data/lib/fat_table.rb +51 -26
- metadata +11 -14
- data/examples/create_trans.sql +0 -14
- data/examples/quick.pdf +0 -0
- data/examples/quick.png +0 -0
- data/examples/quick.ppm +0 -0
- data/examples/quick.tex +0 -8
- data/examples/quick_small.png +0 -0
- data/examples/quicktable.tex +0 -123
- data/examples/trades.db +0 -0
- data/examples/trans.csv +0 -13
- /data/{lib/fat_table/formatters → data}/xcolors.txt +0 -0
data/README.org
CHANGED
|
@@ -2,43 +2,31 @@
|
|
|
2
2
|
#+OPTIONS: toc:4
|
|
3
3
|
#+LATEX_HEADER: \usepackage[margin=0.75in]{geometry}
|
|
4
4
|
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
|
|
5
|
-
#+PROPERTY: header-args:ruby :colnames no :session readme :hlines yes :exports both
|
|
6
|
-
#+PROPERTY: header-args:sh :exports code
|
|
7
5
|
#+STARTUP: inlineimages
|
|
6
|
+
#+PROPERTY: header-args:ruby :results value :colnames no :hlines yes :exports both :dir "./"
|
|
7
|
+
#+PROPERTY: header-args:ruby :wrap example :session fat_table_session
|
|
8
|
+
#+PROPERTY: header-args:ruby+ :prologue "$:.unshift('./lib') unless $:.first == './lib'; require 'fat_table'" :eval yes
|
|
9
|
+
#+PROPERTY: header-args:sh :exports code :eval no
|
|
10
|
+
#+PROPERTY: header-args:bash :exports code :eval no
|
|
8
11
|
|
|
9
|
-
#+begin_comment
|
|
10
|
-
Notes on producing this README.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
#+end_comment
|
|
18
|
-
|
|
19
|
-
#+BEGIN_COMMENT
|
|
20
|
-
This is for markdown output:
|
|
21
|
-
|
|
22
|
-
[](https://travis-ci.org/ddoherty03/fat_table)
|
|
23
|
-
|
|
24
|
-
The following is for org.
|
|
25
|
-
#+END_COMMENT
|
|
26
|
-
|
|
27
|
-
[[https://travis-ci.org/ddoherty03/fat_table.svg?branch=master]]
|
|
13
|
+
#+BEGIN_EXPORT markdown
|
|
14
|
+
[](
|
|
15
|
+
https://github.com/ddoherty03/fat_table/actions/workflows/ruby-with-dbs.yml
|
|
16
|
+
)
|
|
17
|
+
#+END_EXPORT
|
|
28
18
|
|
|
29
19
|
* Version
|
|
30
|
-
#+begin_src ruby
|
|
31
|
-
require 'fat_table'
|
|
20
|
+
#+begin_src ruby
|
|
32
21
|
"Current version is: #{FatTable::VERSION}"
|
|
33
22
|
#+end_src
|
|
34
23
|
|
|
35
24
|
#+RESULTS:
|
|
36
|
-
#+
|
|
37
|
-
Current version is: 0.
|
|
38
|
-
#+
|
|
25
|
+
#+begin_example
|
|
26
|
+
Current version is: 1.0.0
|
|
27
|
+
#+end_example
|
|
39
28
|
|
|
40
29
|
* Introduction
|
|
41
|
-
|
|
42
30
|
~FatTable~ is a gem that treats tables as a data type. It provides methods for
|
|
43
31
|
constructing tables from a variety of sources, building them row-by-row,
|
|
44
32
|
extracting rows, columns, and cells, and performing aggregate operations on
|
|
@@ -79,10 +67,90 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
|
|
|
79
67
|
- [[#quick-start][Quick Start]]
|
|
80
68
|
- [[#a-word-about-the-examples][A Word About the Examples]]
|
|
81
69
|
- [[#anatomy-of-a-table][Anatomy of a Table]]
|
|
70
|
+
- [[#columns][Columns]]
|
|
71
|
+
- [[#type-keywords-arguments][Type Keywords Arguments]]
|
|
72
|
+
- [[#headers][Headers]]
|
|
73
|
+
- [[#groups][Groups]]
|
|
82
74
|
- [[#constructing-tables][Constructing Tables]]
|
|
75
|
+
- [[#empty-tables][Empty Tables]]
|
|
76
|
+
- [[#without-headers][Without Headers]]
|
|
77
|
+
- [[#with-headers][With Headers]]
|
|
78
|
+
- [[#forcing-string-type][Forcing String Type]]
|
|
79
|
+
- [[#from-csv-or-org-mode-files-or-strings][From CSV or Org Mode files or strings]]
|
|
80
|
+
- [[#from-arrays-of-arrays][From Arrays of Arrays]]
|
|
81
|
+
- [[#in-ruby-code][In Ruby Code]]
|
|
82
|
+
- [[#in-emacs-org-files][In Emacs Org Files]]
|
|
83
|
+
- [[#from-arrays-of-hashes][From Arrays of Hashes]]
|
|
84
|
+
- [[#from-sql-queries][From SQL queries]]
|
|
85
|
+
- [[#marking-groups-in-input][Marking Groups in Input]]
|
|
86
|
+
- [[#manually][Manually]]
|
|
87
|
+
- [[#when-reading-in-tables][When Reading in Tables]]
|
|
83
88
|
- [[#accessing-parts-of-tables][Accessing Parts of Tables]]
|
|
89
|
+
- [[#rows][Rows]]
|
|
90
|
+
- [[#columns-1][Columns]]
|
|
91
|
+
- [[#cells][Cells]]
|
|
92
|
+
- [[#other-table-attributes][Other table attributes]]
|
|
84
93
|
- [[#operations-on-tables][Operations on Tables]]
|
|
94
|
+
- [[#example-input-tables][Example Input Tables]]
|
|
95
|
+
- [[#select][Select]]
|
|
96
|
+
- [[#selecting-existing-columns-also-of-omni][Selecting Existing Columns (Also of :omni)]]
|
|
97
|
+
- [[#copying-and-renaming-existing-columns][Copying and Renaming Existing Columns.]]
|
|
98
|
+
- [[#adding-new-computed-columns][Adding New Computed Columns]]
|
|
99
|
+
- [[#adding-constant-strings-and-other-types-in-select][Adding Constant Strings and Other Types in select]]
|
|
100
|
+
- [[#custom-instance-variables-and-hooks][Custom Instance Variables and Hooks]]
|
|
101
|
+
- [[#argument-order-and-boundaries][Argument Order and Boundaries]]
|
|
102
|
+
- [[#where][Where]]
|
|
103
|
+
- [[#order_by][Order_by]]
|
|
104
|
+
- [[#order_with][Order_with]]
|
|
105
|
+
- [[#group_by][Group_by]]
|
|
106
|
+
- [[#join][Join]]
|
|
107
|
+
- [[#join-types][Join Types]]
|
|
108
|
+
- [[#join-expressions][Join Expressions]]
|
|
109
|
+
- [[#join-examples][Join Examples]]
|
|
110
|
+
- [[#inner-joins][Inner Joins]]
|
|
111
|
+
- [[#left-and-right-joins][Left and Right Joins]]
|
|
112
|
+
- [[#full-join][Full Join]]
|
|
113
|
+
- [[#cross-join][Cross Join]]
|
|
114
|
+
- [[#set-operations][Set Operations]]
|
|
115
|
+
- [[#unions][Unions]]
|
|
116
|
+
- [[#intersections][Intersections]]
|
|
117
|
+
- [[#set-differences-with-except][Set Differences with Except]]
|
|
118
|
+
- [[#uniq-aka-distinct][Uniq (aka Distinct)]]
|
|
119
|
+
- [[#remove-groups-with-degroup][Remove groups with degroup!]]
|
|
85
120
|
- [[#formatting-tables][Formatting Tables]]
|
|
121
|
+
- [[#available-formatter-output-targets][Available Formatter Output Targets]]
|
|
122
|
+
- [[#output-media][Output Media]]
|
|
123
|
+
- [[#examples][Examples]]
|
|
124
|
+
- [[#to-text][To Text]]
|
|
125
|
+
- [[#to-org][To Org]]
|
|
126
|
+
- [[#to-term][To Term]]
|
|
127
|
+
- [[#to-latex][To LaTeX]]
|
|
128
|
+
- [[#to-aoa-array-of-arrays][To AoA (Array of Arrays)]]
|
|
129
|
+
- [[#to-aoh-array-of-hashes][To AoH (Array of Hashes)]]
|
|
130
|
+
- [[#formatting-directives][Formatting Directives]]
|
|
131
|
+
- [[#all-types-as-strings][All Types as Strings]]
|
|
132
|
+
- [[#numeric][Numeric]]
|
|
133
|
+
- [[#datetime][DateTime]]
|
|
134
|
+
- [[#boolean][Boolean]]
|
|
135
|
+
- [[#nilclass][NilClass]]
|
|
136
|
+
- [[#the-format-and-format_for-methods][The ~format~ and ~format_for~ methods]]
|
|
137
|
+
- [[#table-locations][Table Locations]]
|
|
138
|
+
- [[#location-priority][Location priority]]
|
|
139
|
+
- [[#type-and-column-priority][Type and Column priority]]
|
|
140
|
+
- [[#footers][Footers]]
|
|
141
|
+
- [[#adding-footers][Adding Footers]]
|
|
142
|
+
- [[#dynamic-labels][Dynamic Labels]]
|
|
143
|
+
- [[#aggregators][Aggregators]]
|
|
144
|
+
- [[#footer-objects][Footer objects]]
|
|
145
|
+
- [[#footer-examples][Footer Examples]]
|
|
146
|
+
- [[#built-in-aggregators][Built-in Aggregators]]
|
|
147
|
+
- [[#string-aggregators][String Aggregators]]
|
|
148
|
+
- [[#ruby-objects][Ruby Objects]]
|
|
149
|
+
- [[#lambdas][Lambdas]]
|
|
150
|
+
- [[#invoking-formatters][Invoking Formatters]]
|
|
151
|
+
- [[#by-instantiating-a-formatter][By Instantiating a Formatter]]
|
|
152
|
+
- [[#by-using-fattable-module-level-method-calls][By Using ~FatTable~ module-level method calls]]
|
|
153
|
+
- [[#by-calling-methods-on-table-objects][By Calling Methods on Table Objects]]
|
|
86
154
|
- [[#development][Development]]
|
|
87
155
|
- [[#contributing][Contributing]]
|
|
88
156
|
|
|
@@ -93,16 +161,28 @@ Add this line to your application's Gemfile:
|
|
|
93
161
|
gem 'fat_table'
|
|
94
162
|
#+END_SRC
|
|
95
163
|
|
|
164
|
+
#+RESULTS:
|
|
165
|
+
#+begin_example
|
|
166
|
+
true
|
|
167
|
+
#+end_example
|
|
168
|
+
|
|
96
169
|
Or, something like this in your gemspec file:
|
|
97
170
|
#+begin_SRC ruby :exports code
|
|
98
171
|
gem.add_runtime_dependency 'fat_table'
|
|
99
172
|
#+end_SRC
|
|
100
173
|
|
|
174
|
+
#+RESULTS:
|
|
175
|
+
#+begin_example
|
|
176
|
+
false
|
|
177
|
+
#+end_example
|
|
178
|
+
|
|
101
179
|
And then execute:
|
|
102
180
|
#+BEGIN_SRC sh
|
|
103
181
|
$ bundle
|
|
104
182
|
#+END_SRC
|
|
105
183
|
|
|
184
|
+
#+RESULTS:
|
|
185
|
+
|
|
106
186
|
** Manually install
|
|
107
187
|
Or install it yourself as:
|
|
108
188
|
|
|
@@ -110,6 +190,8 @@ Or install it yourself as:
|
|
|
110
190
|
$ gem install fat_table
|
|
111
191
|
#+END_SRC
|
|
112
192
|
|
|
193
|
+
#+RESULTS:
|
|
194
|
+
|
|
113
195
|
** Require
|
|
114
196
|
Somewhere in your code, make sure that =FatTable= is required:
|
|
115
197
|
#+begin_src ruby :exports code :results silent
|
|
@@ -152,11 +234,11 @@ compund key, select all columns but add a column, :ref, for the row number,
|
|
|
152
234
|
and finally re-order the columns with a final select.
|
|
153
235
|
|
|
154
236
|
#+BEGIN_SRC ruby :results silent :exports code
|
|
155
|
-
table = FatTable.from_aoa(data)
|
|
156
|
-
.where('shares > 2000')
|
|
157
|
-
.order_by(:date, :code)
|
|
237
|
+
table = FatTable.from_aoa(data)
|
|
238
|
+
.where('shares > 2000')
|
|
239
|
+
.order_by(:date, :code)
|
|
158
240
|
.select(:date, :code, :shares,
|
|
159
|
-
:price, :ok, ref: '@row')
|
|
241
|
+
:price, :ok, ref: '@row')
|
|
160
242
|
.select(:ref, :date, :code,
|
|
161
243
|
:shares, :price, :ok)
|
|
162
244
|
#+END_SRC
|
|
@@ -203,50 +285,41 @@ We can format the table constructed above.
|
|
|
203
285
|
end
|
|
204
286
|
#+END_SRC
|
|
205
287
|
|
|
288
|
+
#+RESULTS:
|
|
206
289
|
#+begin_example
|
|
207
|
-
|
|
208
|
-
|
|
|
209
|
-
|
|
210
|
-
|
|
|
211
|
-
|
|
|
212
|
-
|
|
213
|
-
|
|
|
214
|
-
|
|
215
|
-
|
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
219
|
-
|
|
|
220
|
-
|
|
221
|
-
|
|
|
222
|
-
|
|
223
|
-
|
|
|
224
|
-
|
|
225
|
-
|
|
|
226
|
-
|
|
227
|
-
|
|
|
228
|
-
|
|
229
|
-
| 11 | 2013-05-29 | S | 6,686.0 | 24.5802 | Y |
|
|
230
|
-
+---------+------------+------+-------------+----------+----+
|
|
231
|
-
| Avg | | | 6,315.8 | 24.7019 | |
|
|
232
|
-
+---------+------------+------+-------------+----------+----+
|
|
233
|
-
| 12 | 2013-05-30 | S | 2,808.5 | 25.0471 | Y |
|
|
234
|
-
+---------+------------+------+-------------+----------+----+
|
|
235
|
-
| Avg | | | 2,808.5 | 25.0471 | |
|
|
236
|
-
+---------+------------+------+-------------+----------+----+
|
|
237
|
-
| Average | | | 85,009.9 | $23.0428 | |
|
|
238
|
-
+---------+------------+------+-------------+----------+----+
|
|
239
|
-
| Total | | | 1,020,119.1 | | |
|
|
240
|
-
+=========+============+======+=============+==========+====+
|
|
290
|
+
+============+======+=============+=============+==========+=========+====+
|
|
291
|
+
| Date | Code | Raw | Shares | Price | Info | Ok |
|
|
292
|
+
+------------+------+-------------+-------------+----------+---------+----+
|
|
293
|
+
| 2013-05-29 | S | 15700.0000 | 6,601.9 | $24.7790 | ENTITY3 | N |
|
|
294
|
+
| 2013-05-02 | P | 118186.4000 | 118,186.4 | 11.8500 | ENTITY1 | Y |
|
|
295
|
+
| 2013-05-20 | S | 12000.0000 | 5,046.0 | 28.2804 | ENTITY3 | N |
|
|
296
|
+
| 2013-05-23 | S | 8000.0000 | 3,364.0 | 27.1083 | ENTITY3 | Y |
|
|
297
|
+
| 2013-05-23 | S | 39906.0000 | 16,780.5 | 25.1749 | ENTITY3 | Y |
|
|
298
|
+
| 2013-05-20 | S | 85000.0000 | 35,742.5 | 28.3224 | ENTITY3 | Y |
|
|
299
|
+
| 2013-05-02 | P | 795546.2000 | 795,546.2 | 1.1850 | ENTITY1 | Y |
|
|
300
|
+
| 2013-05-29 | S | 13459.0000 | 5,659.5 | 24.7464 | ENTITY3 | Y |
|
|
301
|
+
| 2013-05-20 | S | 33302.0000 | 14,003.5 | 28.6383 | ENTITY3 | Y |
|
|
302
|
+
| 2013-05-29 | S | 15900.0000 | 6,685.10 | 24.5802 | ENTITY3 | Y |
|
|
303
|
+
| 2013-05-30 | S | 6679.0000 | 2,808.5 | 25.0471 | ENTITY3 | Y |
|
|
304
|
+
| 2013-05-23 | S | 23054.0000 | 9,694.2 | 26.8015 | ENTITY3 | N |
|
|
305
|
+
+------------+------+-------------+-------------+----------+---------+----+
|
|
306
|
+
| Avg | | | 85,009.9 | 23.0428 | | |
|
|
307
|
+
+------------+------+-------------+-------------+----------+---------+----+
|
|
308
|
+
| Average | | | 85,009.9 | $23.0428 | | |
|
|
309
|
+
+------------+------+-------------+-------------+----------+---------+----+
|
|
310
|
+
| Total | | | 1,020,119.1 | | | |
|
|
311
|
+
+============+======+=============+=============+==========+=========+====+
|
|
241
312
|
#+end_example
|
|
242
313
|
|
|
314
|
+
|
|
243
315
|
For the text format above, we were wasting our breath specifying bold styling
|
|
244
316
|
since there is no way to make that happen in plain ASCII text. But with
|
|
245
317
|
LaTeX, bold is doable. The output of the following code block is being
|
|
246
|
-
written to a file =
|
|
247
|
-
simple wrapper file, =
|
|
318
|
+
written to a file =spec/example_files/quicktable.tex= which is then
|
|
319
|
+
=\included=-ed in a simple wrapper file, =spec/example_files/quick.tex=
|
|
320
|
+
so it can be compiled by LaTeX.
|
|
248
321
|
|
|
249
|
-
#+BEGIN_SRC ruby :results file :file "
|
|
322
|
+
#+BEGIN_SRC ruby :results file :file "spec/example_files/quicktable.tex"
|
|
250
323
|
table.to_latex do |fmt|
|
|
251
324
|
fmt.gfooter('Avg', shares: :avg, price: :avg)
|
|
252
325
|
fmt.avg_footer(:price, :shares)
|
|
@@ -260,26 +333,32 @@ simple wrapper file, =examples/quick.tex= so it can be compiled by LaTeX.
|
|
|
260
333
|
end
|
|
261
334
|
#+END_SRC
|
|
262
335
|
|
|
263
|
-
#+
|
|
264
|
-
|
|
265
|
-
|
|
336
|
+
#+RESULTS:
|
|
337
|
+
#+begin_example
|
|
338
|
+
[[file:spec/example_files/quicktable.tex]]
|
|
339
|
+
#+end_example
|
|
340
|
+
|
|
341
|
+
[[file:spec/example_files/quicktable.tex]]
|
|
266
342
|
|
|
267
343
|
These commands run pdflatex on the result twice to get the table aligned
|
|
268
344
|
properly.
|
|
269
345
|
#+begin_src sh :results silent
|
|
270
|
-
cd
|
|
346
|
+
cd spec/example_files
|
|
271
347
|
pdflatex quick.tex
|
|
272
348
|
pdflatex quick.tex
|
|
273
349
|
#+end_src
|
|
274
350
|
|
|
275
351
|
And we convert the =PDF= into a smaller image for display:
|
|
276
352
|
#+begin_src sh :results verbatim
|
|
277
|
-
cd
|
|
353
|
+
cd spec/example_files
|
|
278
354
|
pdftoppm -png quick.pdf >quick.png
|
|
279
|
-
|
|
355
|
+
magick quick.png -resize 600x800 quick_small.png
|
|
280
356
|
#+end_src
|
|
281
357
|
|
|
282
|
-
|
|
358
|
+
#+RESULTS:
|
|
359
|
+
|
|
360
|
+
[[file:spec/example_files/quick_small.png]]
|
|
361
|
+
|
|
283
362
|
|
|
284
363
|
** A Word About the Examples
|
|
285
364
|
When you install the ~fat_table~ gem, you have access to a program ~ft_console~,
|
|
@@ -374,6 +453,7 @@ no value) or be capable of being coerced to the column's type. Otherwise,
|
|
|
374
453
|
~FatTable~ raises an ~IncompatibleTypeError~ exception.
|
|
375
454
|
|
|
376
455
|
*** Type Keywords Arguments
|
|
456
|
+
|
|
377
457
|
All of the table constructors allow you to set the type for a column in
|
|
378
458
|
advance by adding keyword arguments to the end of the contructor arguments
|
|
379
459
|
where the keyword is a header symbol and the value is a string designating one
|
|
@@ -392,7 +472,7 @@ The type string can be anything that starts with 'dat', 'num', 'boo', or
|
|
|
392
472
|
that is, it remains open for automatic typing.
|
|
393
473
|
|
|
394
474
|
The strictness of requiring all items to be of the same type can be relaxed by
|
|
395
|
-
declaring a column to be "tolerant." You can do so by adding a
|
|
475
|
+
declaring a column to be "tolerant." You can do so by adding a =~= to the end
|
|
396
476
|
of a keyword type specifier in the table constructor. In the above example,
|
|
397
477
|
if we wanted to allow strings to be mixed up with the numeric prices, we would
|
|
398
478
|
use the following:
|
|
@@ -493,10 +573,20 @@ Column, ~:a~ and ~:b~ will have type Numeric, column ~:c~ will have type
|
|
|
493
573
|
have an open type. Notice that dates in the input can be wrapped in brackets as
|
|
494
574
|
in org-mode time stamps.
|
|
495
575
|
|
|
496
|
-
#+BEGIN_SRC ruby
|
|
576
|
+
#+BEGIN_SRC ruby
|
|
497
577
|
tab.to_text
|
|
498
578
|
#+END_SRC
|
|
499
579
|
|
|
580
|
+
#+RESULTS:
|
|
581
|
+
#+begin_example
|
|
582
|
+
+========+========+============+===+===+
|
|
583
|
+
| A | B | C | D | E |
|
|
584
|
+
+--------+--------+------------+---+---+
|
|
585
|
+
| 1 | 2 | 2017-01-21 | F | |
|
|
586
|
+
| 3.1400 | 2.1700 | 2016-01-21 | T | |
|
|
587
|
+
+========+========+============+===+===+
|
|
588
|
+
#+end_example
|
|
589
|
+
|
|
500
590
|
#+begin_EXAMPLE
|
|
501
591
|
+======+======+============+===+===+
|
|
502
592
|
| A | B | C | D | E |
|
|
@@ -519,6 +609,17 @@ for which no key was give are assigned ~nil~ as well:
|
|
|
519
609
|
tab.to_text
|
|
520
610
|
#+END_SRC
|
|
521
611
|
|
|
612
|
+
#+RESULTS:
|
|
613
|
+
#+begin_example
|
|
614
|
+
+========+========+============+===+===+=========+
|
|
615
|
+
| A | B | C | D | E | F |
|
|
616
|
+
+--------+--------+------------+---+---+---------+
|
|
617
|
+
| 1 | 2 | 2017-01-21 | F | | |
|
|
618
|
+
| 3.1400 | 2.1700 | 2016-01-21 | T | | |
|
|
619
|
+
| 3/5 | | | | | 335/113 |
|
|
620
|
+
+========+========+============+===+===+=========+
|
|
621
|
+
#+end_example
|
|
622
|
+
|
|
522
623
|
#+begin_EXAMPLE
|
|
523
624
|
+======+======+============+===+===+=========+
|
|
524
625
|
| A | B | C | D | E | F |
|
|
@@ -536,22 +637,37 @@ Alternatively, you can specify the headers at the outset, in which case,
|
|
|
536
637
|
headers in added rows that do not match any of the initial headers cause new
|
|
537
638
|
columns to be created:
|
|
538
639
|
|
|
539
|
-
#+BEGIN_SRC ruby
|
|
640
|
+
#+BEGIN_SRC ruby :results raw
|
|
540
641
|
require 'fat_table'
|
|
541
642
|
tab = FatTable.new(:a, 'b', 'C', :d)
|
|
542
643
|
tab.headers
|
|
543
644
|
#+END_SRC
|
|
544
645
|
|
|
646
|
+
#+RESULTS:
|
|
647
|
+
#+begin_example
|
|
648
|
+
[:a, :b, :c, :d]
|
|
649
|
+
#+end_example
|
|
650
|
+
|
|
545
651
|
#+begin_EXAMPLE
|
|
546
652
|
[:a, :b, :c, :d]
|
|
547
653
|
#+end_EXAMPLE
|
|
548
654
|
|
|
549
|
-
#+begin_src ruby
|
|
655
|
+
#+begin_src ruby
|
|
550
656
|
tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '' }
|
|
551
657
|
tab << { a: 3.14, b: 2.17, c: '[2016-01-21 Thu]', d: 'Y', e: nil }
|
|
552
658
|
tab.to_text
|
|
553
659
|
#+end_src
|
|
554
660
|
|
|
661
|
+
#+RESULTS:
|
|
662
|
+
#+begin_example
|
|
663
|
+
+========+========+============+===+===+
|
|
664
|
+
| A | B | C | D | E |
|
|
665
|
+
+--------+--------+------------+---+---+
|
|
666
|
+
| 1 | 2 | 2017-01-21 | F | |
|
|
667
|
+
| 3.1400 | 2.1700 | 2016-01-21 | T | |
|
|
668
|
+
+========+========+============+===+===+
|
|
669
|
+
#+end_example
|
|
670
|
+
|
|
555
671
|
#+begin_EXAMPLE
|
|
556
672
|
+======+======+============+===+===+
|
|
557
673
|
| A | B | C | D | E |
|
|
@@ -572,7 +688,7 @@ appearance. Think, for example, of zip codes. As mentioned above, when a
|
|
|
572
688
|
table is contructed, you can designate a 'String' type for a column by
|
|
573
689
|
using a keyword parameter.
|
|
574
690
|
|
|
575
|
-
#+begin_src ruby
|
|
691
|
+
#+begin_src ruby
|
|
576
692
|
require 'fat_table'
|
|
577
693
|
tab = FatTable.new(:a, 'b!', 'C', :d, :zip, zip: 'str')
|
|
578
694
|
tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '', zip: 18552 }
|
|
@@ -583,6 +699,19 @@ using a keyword parameter.
|
|
|
583
699
|
tab.to_text
|
|
584
700
|
#+end_src
|
|
585
701
|
|
|
702
|
+
#+RESULTS:
|
|
703
|
+
#+begin_example
|
|
704
|
+
+========+========+============+===+=============+===+
|
|
705
|
+
| A | B | C | D | Zip | E |
|
|
706
|
+
+--------+--------+------------+---+-------------+---+
|
|
707
|
+
| 1 | 2 | 2017-01-21 | F | 18552 | |
|
|
708
|
+
| 3.1400 | 2.1700 | 2016-01-21 | T | | |
|
|
709
|
+
| | | | | 01879--7884 | |
|
|
710
|
+
| | | | | 90210 | |
|
|
711
|
+
| | | | | | |
|
|
712
|
+
+========+========+============+===+=============+===+
|
|
713
|
+
#+end_example
|
|
714
|
+
|
|
586
715
|
#+begin_EXAMPLE
|
|
587
716
|
+===+===+============+===+=============+===+
|
|
588
717
|
| A | B | C | D | Zip | E |
|
|
@@ -599,7 +728,7 @@ In addition, at any time after creating a table, you can force the String type
|
|
|
599
728
|
on any number of columns with the ~force_string!~ method. When you do so, all
|
|
600
729
|
exisiting items in the column are converted to strings with the #to_s method.
|
|
601
730
|
|
|
602
|
-
#+begin_src ruby
|
|
731
|
+
#+begin_src ruby
|
|
603
732
|
tab = FatTable.new(:a, 'b', 'C', :d, :zip)
|
|
604
733
|
tab << { a: 1, b: 2, c: "<2017-01-21>", d: 'f', e: '', zip: 18552 }
|
|
605
734
|
tab << { a: 3.14, b: 2.17, c: '[2016-01-21 Thu]', d: 'Y', e: nil }
|
|
@@ -610,6 +739,19 @@ exisiting items in the column are converted to strings with the #to_s method.
|
|
|
610
739
|
tab.to_text
|
|
611
740
|
#+end_src
|
|
612
741
|
|
|
742
|
+
#+RESULTS:
|
|
743
|
+
#+begin_example
|
|
744
|
+
+========+========+============+===+=======+===+
|
|
745
|
+
| A | B | C | D | Zip | E |
|
|
746
|
+
+--------+--------+------------+---+-------+---+
|
|
747
|
+
| 1 | 2 | 2017-01-21 | F | 18552 | |
|
|
748
|
+
| 3.1400 | 2.1700 | 2016-01-21 | T | | |
|
|
749
|
+
| | | | | 01879 | |
|
|
750
|
+
| | | | | 66210 | |
|
|
751
|
+
| | | | | 90210 | |
|
|
752
|
+
+========+========+============+===+=======+===+
|
|
753
|
+
#+end_example
|
|
754
|
+
|
|
613
755
|
#+begin_EXAMPLE
|
|
614
756
|
+======+======+============+===+=======+===+
|
|
615
757
|
| A | B | C | D | Zip | E |
|
|
@@ -633,11 +775,11 @@ followed by ~|-~. Only the first table in an ~.org~ file is read.
|
|
|
633
775
|
For both ~.csv~ and ~.org~ files, the first row in the table is taken as the
|
|
634
776
|
header row, and the headers are converted to symbols as described above.
|
|
635
777
|
|
|
636
|
-
#+BEGIN_SRC ruby
|
|
637
|
-
|
|
638
|
-
|
|
778
|
+
#+BEGIN_SRC ruby :results silent
|
|
779
|
+
tab1 = FatTable.from_csv_file('~/data.csv')
|
|
780
|
+
tab2 = FatTable.from_org_file('~/project.org')
|
|
639
781
|
|
|
640
|
-
|
|
782
|
+
csv_body = <<-EOS
|
|
641
783
|
Ref,Date,Code,RawShares,Shares,Price,Info
|
|
642
784
|
1,2006-05-02,P,5000,5000,8.6000,2006-08-09-1-I
|
|
643
785
|
2,2006-05-03,P,5000,5000,8.4200,2006-08-09-1-I
|
|
@@ -647,15 +789,15 @@ header row, and the headers are converted to symbols as described above.
|
|
|
647
789
|
6,2006-05-12,P,2000,2000,6.7400,2006-08-09-1-I
|
|
648
790
|
EOS
|
|
649
791
|
|
|
650
|
-
|
|
792
|
+
tab3 = FatTable.from_csv_string(csv_body)
|
|
651
793
|
|
|
652
|
-
|
|
794
|
+
org_body = <<-EOS
|
|
653
795
|
.* Smith Transactions
|
|
654
796
|
:PROPERTIES:
|
|
655
797
|
:TABLE_EXPORT_FILE: smith.csv
|
|
656
798
|
:END:
|
|
657
799
|
|
|
658
|
-
|
|
800
|
+
,#+TBLNAME: smith_tab
|
|
659
801
|
| Ref | Date | Code | Raw | Shares | Price | Info |
|
|
660
802
|
|-----+------------+------+---------+--------+----------+---------|
|
|
661
803
|
| 29 | 2013-05-02 | P | 795,546 | 2,609 | 1.18500 | ENTITY1 |
|
|
@@ -676,7 +818,7 @@ header row, and the headers are converted to symbols as described above.
|
|
|
676
818
|
.* Another Heading
|
|
677
819
|
EOS
|
|
678
820
|
|
|
679
|
-
|
|
821
|
+
tab4 = FatTable.from_org_string(org_body)
|
|
680
822
|
#+END_SRC
|
|
681
823
|
|
|
682
824
|
*** From Arrays of Arrays
|
|
@@ -691,15 +833,15 @@ ending it with a '~'.
|
|
|
691
833
|
aoa = [
|
|
692
834
|
['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
|
|
693
835
|
[1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ENTITY1', 'T'],
|
|
694
|
-
[2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ENTITY1', 'T'],
|
|
836
|
+
[2, '2013-05-02', 'P', '118_186.40', 118_186.4, 11.8500, 'ENTITY1', 'T'],
|
|
695
837
|
[7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ENTITY3', 'F'],
|
|
696
838
|
[8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ENTITY3', 'T'],
|
|
697
839
|
[9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ENTITY3', 'T'],
|
|
698
|
-
[10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ENTITY3',
|
|
840
|
+
[10, Date.parse('2013-05-23'), 'S', 8000.00, 3364.00, 27.1083, 'ENTITY3', true],
|
|
699
841
|
[11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ENTITY3', 'F'],
|
|
700
|
-
[12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ENTITY3', 'T'],
|
|
842
|
+
['12', '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ENTITY3', 'T'],
|
|
701
843
|
[13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ENTITY3', 'T'],
|
|
702
|
-
[14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ENTITY3',
|
|
844
|
+
[14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ENTITY3', false],
|
|
703
845
|
[15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ENTITY3', 'T'],
|
|
704
846
|
[16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ENTITY3', 'T'] ]
|
|
705
847
|
|
|
@@ -707,20 +849,22 @@ ending it with a '~'.
|
|
|
707
849
|
#+END_SRC
|
|
708
850
|
|
|
709
851
|
#+RESULTS:
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
|
714
|
-
|
|
|
715
|
-
|
|
|
716
|
-
|
|
|
717
|
-
|
|
|
718
|
-
|
|
|
719
|
-
|
|
|
720
|
-
|
|
|
721
|
-
|
|
|
722
|
-
|
|
|
723
|
-
|
|
|
852
|
+
#+begin_example
|
|
853
|
+
| Ref | Date | Code | Raw | Shares | Price | Info | Bool |
|
|
854
|
+
|-----+------------+------+-------------+-------------+---------+---------+------|
|
|
855
|
+
| 1 | 2013-05-02 | P | 795546.2000 | 795546.2000 | 1.1850 | ENTITY1 | T |
|
|
856
|
+
| 2 | 2013-05-02 | P | 118186.4000 | 118186.4000 | 11.8500 | ENTITY1 | T |
|
|
857
|
+
| 7 | 2013-05-20 | S | 12000.0000 | 5046.0000 | 28.2804 | ENTITY3 | F |
|
|
858
|
+
| 8 | 2013-05-20 | S | 85000.0000 | 35742.5000 | 28.3224 | ENTITY3 | T |
|
|
859
|
+
| 9 | 2013-05-20 | S | 33302.0000 | 14003.4900 | 28.6383 | ENTITY3 | T |
|
|
860
|
+
| 10 | 2013-05-23 | S | 8000.0000 | 3364.0000 | 27.1083 | ENTITY3 | T |
|
|
861
|
+
| 11 | 2013-05-23 | S | 23054.0000 | 9694.2100 | 26.8015 | ENTITY3 | F |
|
|
862
|
+
| 12 | 2013-05-23 | S | 39906.0000 | 16780.4700 | 25.1749 | ENTITY3 | T |
|
|
863
|
+
| 13 | 2013-05-29 | S | 13459.0000 | 5659.5100 | 24.7464 | ENTITY3 | T |
|
|
864
|
+
| 14 | 2013-05-29 | S | 15700.0000 | 6601.8500 | 24.7790 | ENTITY3 | F |
|
|
865
|
+
| 15 | 2013-05-29 | S | 15900.0000 | 6685.9500 | 24.5802 | ENTITY3 | T |
|
|
866
|
+
| 16 | 2013-05-30 | S | 6679.0000 | 2808.5200 | 25.0471 | ENTITY3 | T |
|
|
867
|
+
#+end_example
|
|
724
868
|
|
|
725
869
|
Notice that the values can either be ruby objects, such as the Integer ~85_000~,
|
|
726
870
|
or strings that can be parsed into one of the permissible column types.
|
|
@@ -806,7 +950,7 @@ to a Hash with the ~#to_h~ method, so you can use an array of your own objects
|
|
|
806
950
|
to initialize a table, provided that you define a suitable ~#to_h~ method for
|
|
807
951
|
the objects' class.
|
|
808
952
|
|
|
809
|
-
#+BEGIN_SRC ruby
|
|
953
|
+
#+BEGIN_SRC ruby
|
|
810
954
|
aoh = [
|
|
811
955
|
{ ref: 'T001', date: '2016-11-01', code: 'P', price: '7.7000', shares: 100 },
|
|
812
956
|
{ ref: 'T002', date: '2016-11-01', code: 'P', price: 7.7500, shares: 200 },
|
|
@@ -825,9 +969,31 @@ aoh = [
|
|
|
825
969
|
{ ref: 'T015', date: '2016-11-02', code: 'P', price: 7.7500, shares: 500 },
|
|
826
970
|
{ ref: 'T016', date: '2016-11-02', code: 'P', price: 8.2500, shares: 100 }
|
|
827
971
|
]
|
|
828
|
-
tab = FatTable.from_aoh(aoh)
|
|
972
|
+
tab = FatTable.from_aoh(aoh).to_aoa
|
|
829
973
|
#+END_SRC
|
|
830
974
|
|
|
975
|
+
#+RESULTS:
|
|
976
|
+
#+begin_example
|
|
977
|
+
| Ref | Date | Code | Price | Shares |
|
|
978
|
+
|------+------------+------+--------+--------|
|
|
979
|
+
| T001 | 2016-11-01 | P | 7.7000 | 100 |
|
|
980
|
+
| T002 | 2016-11-01 | P | 7.7500 | 200 |
|
|
981
|
+
| T003 | 2016-11-01 | P | 7.5000 | 800 |
|
|
982
|
+
| T004 | 2016-11-01 | S | 7.5500 | 6811 |
|
|
983
|
+
| T005 | 2025-12-28 | S | 7.5000 | 4000 |
|
|
984
|
+
| T006 | 2016-11-01 | S | 7.6000 | 1000 |
|
|
985
|
+
| T007 | 2016-11-01 | S | 7.6500 | 200 |
|
|
986
|
+
| T008 | 2016-11-01 | P | 7.6500 | 2771 |
|
|
987
|
+
| T009 | 2016-11-01 | P | 7.6000 | 9550 |
|
|
988
|
+
| T010 | 2016-11-01 | P | 7.5500 | 3175 |
|
|
989
|
+
| T011 | 2016-11-02 | P | 7.4250 | 100 |
|
|
990
|
+
| T012 | 2016-11-02 | P | 7.5500 | 4700 |
|
|
991
|
+
| T013 | 2016-11-02 | P | 7.3500 | 53100 |
|
|
992
|
+
| T014 | 2016-11-02 | P | 7.4500 | 5847 |
|
|
993
|
+
| T015 | 2016-11-02 | P | 7.7500 | 500 |
|
|
994
|
+
| T016 | 2016-11-02 | P | 8.2500 | 100 |
|
|
995
|
+
#+end_example
|
|
996
|
+
|
|
831
997
|
Notice, again, that the values can either be ruby objects, such as ~Date.today~,
|
|
832
998
|
or strings that can be parsed into one of the permissible column types.
|
|
833
999
|
|
|
@@ -842,41 +1008,62 @@ you are accessing a Postgres database, you must install the ~pg~ gem with
|
|
|
842
1008
|
$ gem install pg
|
|
843
1009
|
#+end_src
|
|
844
1010
|
|
|
845
|
-
|
|
1011
|
+
#+RESULTS:
|
|
1012
|
+
|
|
1013
|
+
You must first call ~FatTable.connect~ to set the database parameters to be
|
|
1014
|
+
used for the queries.
|
|
1015
|
+
|
|
1016
|
+
The arguments to ~connect~ are simply passed on to ~sequel~'s connect method, so
|
|
1017
|
+
any set of arguments that work for it should work for ~connect~. Alternatively,
|
|
1018
|
+
you can build the ~Sequel~ connection directly with ~Sequel.connect~ or with
|
|
1019
|
+
adapter-specific ~Sequel~ connection methods and let ~FatTable~ know to use that
|
|
1020
|
+
connection:
|
|
846
1021
|
|
|
847
1022
|
#+BEGIN_SRC ruby
|
|
848
1023
|
# This automatically requires sequel.
|
|
849
1024
|
FatTable.connect(adapter: 'sqlite',
|
|
850
|
-
database: '
|
|
1025
|
+
database: 'spec/example_files/trades2.db')
|
|
851
1026
|
tab = FatTable.from_sql('select * from trans;').to_text
|
|
852
1027
|
#+END_SRC
|
|
853
1028
|
|
|
1029
|
+
#+RESULTS:
|
|
854
1030
|
#+begin_example
|
|
855
|
-
|
|
856
|
-
| Date | Code | Raw
|
|
857
|
-
|
|
858
|
-
| 2013-05-29 | S | 15700.
|
|
859
|
-
| 2013-05-02 | P | 118186.
|
|
860
|
-
| 2013-05-20 | S | 12000.
|
|
861
|
-
| 2013-05-23 | S | 8000.
|
|
862
|
-
| 2013-05-23 | S | 39906.
|
|
863
|
-
| 2013-05-20 | S | 85000.
|
|
864
|
-
| 2013-05-02 | P | 795546.
|
|
865
|
-
| 2013-05-29 | S | 13459.
|
|
866
|
-
| 2013-05-20 | S | 33302.
|
|
867
|
-
| 2013-05-29 | S | 15900.
|
|
868
|
-
| 2013-05-30 | S | 6679.
|
|
869
|
-
| 2013-05-23 | S | 23054.
|
|
870
|
-
|
|
1031
|
+
+============+======+=============+=============+=========+=========+====+
|
|
1032
|
+
| Date | Code | Raw | Shares | Price | Info | Ok |
|
|
1033
|
+
+------------+------+-------------+-------------+---------+---------+----+
|
|
1034
|
+
| 2013-05-29 | S | 15700.0000 | 6601.8500 | 24.7790 | ENTITY3 | F |
|
|
1035
|
+
| 2013-05-02 | P | 118186.4000 | 118186.4000 | 11.8500 | ENTITY1 | T |
|
|
1036
|
+
| 2013-05-20 | S | 12000.0000 | 5046.0000 | 28.2804 | ENTITY3 | F |
|
|
1037
|
+
| 2013-05-23 | S | 8000.0000 | 3364.0000 | 27.1083 | ENTITY3 | T |
|
|
1038
|
+
| 2013-05-23 | S | 39906.0000 | 16780.4700 | 25.1749 | ENTITY3 | T |
|
|
1039
|
+
| 2013-05-20 | S | 85000.0000 | 35742.5000 | 28.3224 | ENTITY3 | T |
|
|
1040
|
+
| 2013-05-02 | P | 795546.2000 | 795546.2000 | 1.1850 | ENTITY1 | T |
|
|
1041
|
+
| 2013-05-29 | S | 13459.0000 | 5659.5100 | 24.7464 | ENTITY3 | T |
|
|
1042
|
+
| 2013-05-20 | S | 33302.0000 | 14003.4900 | 28.6383 | ENTITY3 | T |
|
|
1043
|
+
| 2013-05-29 | S | 15900.0000 | 6685.9500 | 24.5802 | ENTITY3 | T |
|
|
1044
|
+
| 2013-05-30 | S | 6679.0000 | 2808.5200 | 25.0471 | ENTITY3 | T |
|
|
1045
|
+
| 2013-05-23 | S | 23054.0000 | 9694.2100 | 26.8015 | ENTITY3 | F |
|
|
1046
|
+
+============+======+=============+=============+=========+=========+====+
|
|
871
1047
|
#+end_example
|
|
872
1048
|
|
|
873
|
-
The
|
|
874
|
-
any set of arguments that work for it should work for ~connect~. Alternatively,
|
|
875
|
-
you can build the ~Sequel~ connection directly with ~Sequel.connect~ or with
|
|
876
|
-
adapter-specific ~Sequel~ connection methods and let ~FatTable~ know to use that
|
|
877
|
-
connection:
|
|
1049
|
+
The same connection can be queries multiple times:
|
|
878
1050
|
|
|
879
1051
|
#+BEGIN_SRC ruby
|
|
1052
|
+
tab = FatTable.from_sql('select * from trans where info = "ENTITY1";')
|
|
1053
|
+
tab.to_text
|
|
1054
|
+
#+END_SRC
|
|
1055
|
+
|
|
1056
|
+
#+RESULTS:
|
|
1057
|
+
#+begin_example
|
|
1058
|
+
+============+======+=============+=============+=========+=========+====+
|
|
1059
|
+
| Date | Code | Raw | Shares | Price | Info | Ok |
|
|
1060
|
+
+------------+------+-------------+-------------+---------+---------+----+
|
|
1061
|
+
| 2013-05-02 | P | 118186.4000 | 118186.4000 | 11.8500 | ENTITY1 | T |
|
|
1062
|
+
| 2013-05-02 | P | 795546.2000 | 795546.2000 | 1.1850 | ENTITY1 | T |
|
|
1063
|
+
+============+======+=============+=============+=========+=========+====+
|
|
1064
|
+
#+end_example
|
|
1065
|
+
|
|
1066
|
+
#+BEGIN_SRC ruby :eval no
|
|
880
1067
|
FatTable.db = Sequel.connect('postgres://user:password@localhost/dbname')
|
|
881
1068
|
FatTable.db = Sequel.ado(conn_string: 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=drive:\path\filename.accdb')
|
|
882
1069
|
#+END_SRC
|
|
@@ -890,14 +1077,12 @@ called again.
|
|
|
890
1077
|
|
|
891
1078
|
*** Marking Groups in Input
|
|
892
1079
|
**** Manually
|
|
893
|
-
|
|
894
1080
|
At any point, you can add a boundary to a table by invokong the
|
|
895
1081
|
~mark_boundary~ method. Without an argument, it adds the boundary to the end
|
|
896
1082
|
of the table; with a numeric argument, ~n~, it adds the boundary after row
|
|
897
1083
|
~n~.
|
|
898
1084
|
|
|
899
1085
|
**** When Reading in Tables
|
|
900
|
-
|
|
901
1086
|
~FatTable~ tables has a concept of "groups" of rows that play a role in many of
|
|
902
1087
|
the methods for operating on them as explained [[Groups][below]].
|
|
903
1088
|
|
|
@@ -920,7 +1105,6 @@ beginning with something like ~|---~. The ~.from_org_...~ functions always
|
|
|
920
1105
|
recognizes hlines in the input, so it takes no ~hlines:~ keyword parameter.
|
|
921
1106
|
|
|
922
1107
|
** Accessing Parts of Tables
|
|
923
|
-
|
|
924
1108
|
*** Rows
|
|
925
1109
|
A ~FatTable~ table is an Enumerable, yielding each row of the table as a Hash
|
|
926
1110
|
keyed on the header symbols. The method ~Table#rows~ returns an Array of the
|
|
@@ -940,7 +1124,7 @@ all the items of the table's ~:ref~ column.
|
|
|
940
1124
|
The two forms of indexing can be combined, in either order, to access
|
|
941
1125
|
individual cells of the table:
|
|
942
1126
|
|
|
943
|
-
#+BEGIN_SRC ruby
|
|
1127
|
+
#+BEGIN_SRC ruby :eval no
|
|
944
1128
|
tab[13] # => Hash of the 14th row
|
|
945
1129
|
tab[:date] # => Array of all Dates in the :date column
|
|
946
1130
|
tab[13][:date] # => The Date in the 14th row
|
|
@@ -950,7 +1134,7 @@ individual cells of the table:
|
|
|
950
1134
|
*** Other table attributes
|
|
951
1135
|
Here is a quick rundown of other table attributes that you can access:
|
|
952
1136
|
|
|
953
|
-
#+BEGIN_SRC ruby
|
|
1137
|
+
#+BEGIN_SRC ruby :eval no
|
|
954
1138
|
tab.headers # => an Array of the headers in symbol form
|
|
955
1139
|
tab.types # => a Hash mapping headers to column types
|
|
956
1140
|
tab.type(head) # => return the type of the column for the given head
|
|
@@ -964,26 +1148,31 @@ Here is a quick rundown of other table attributes that you can access:
|
|
|
964
1148
|
|
|
965
1149
|
You should note that what the ~.types~ and ~.type(head)~ methods return is a
|
|
966
1150
|
string naming the "type" assigned by ~FatTable~. All of them are also the
|
|
967
|
-
names of Ruby classes except
|
|
1151
|
+
names of Ruby classes except for 'Boolean' a class that doesn't exist in Ruby.
|
|
968
1152
|
The value ~true~ is a member of the ~TrueClass~ and ~false~ a member of the
|
|
969
1153
|
~FalseClass~. So for ~FatTable~ to provide a column of type 'Boolean'
|
|
970
1154
|
requires it to synthesize the type from these Ruby classes.
|
|
971
1155
|
|
|
972
|
-
#+begin_src ruby
|
|
1156
|
+
#+begin_src ruby :results raw
|
|
973
1157
|
tab.types
|
|
974
1158
|
#+end_src
|
|
975
1159
|
|
|
976
|
-
#+
|
|
977
|
-
|
|
978
|
-
|
|
1160
|
+
#+RESULTS:
|
|
1161
|
+
#+begin_example
|
|
1162
|
+
{date: "DateTime", code: "String", raw: "Numeric", shares: "Numeric", price: "Numeric", info: "String", ok: "Boolean"}
|
|
1163
|
+
#+end_example
|
|
979
1164
|
|
|
980
|
-
#+begin_src ruby
|
|
981
|
-
puts "Column :
|
|
1165
|
+
#+begin_src ruby :results output
|
|
1166
|
+
puts "Column :shares says its type is '#{tab.type(:shares)}' and that is a #{tab[:shares][0].class}"
|
|
982
1167
|
#+end_src
|
|
983
1168
|
|
|
984
|
-
#+
|
|
985
|
-
|
|
986
|
-
|
|
1169
|
+
#+RESULTS:
|
|
1170
|
+
#+begin_example
|
|
1171
|
+
=> false
|
|
1172
|
+
Column :shares says its type is 'Numeric' and that is a BigDecimal
|
|
1173
|
+
=> nil
|
|
1174
|
+
:org_babel_ruby_eoe
|
|
1175
|
+
#+end_example
|
|
987
1176
|
|
|
988
1177
|
** Operations on Tables
|
|
989
1178
|
Once you have one or more tables, you will likely want to perform operations on
|
|
@@ -1070,58 +1259,113 @@ EOS
|
|
|
1070
1259
|
#+END_SRC
|
|
1071
1260
|
|
|
1072
1261
|
Rendering ~tab1~ into Emacs org-mode:
|
|
1073
|
-
#+BEGIN_SRC ruby
|
|
1262
|
+
#+BEGIN_SRC ruby
|
|
1074
1263
|
tab1 = FatTable.from_org_string(tab1_str)
|
|
1264
|
+
tab1.to_aoa
|
|
1075
1265
|
#+END_SRC
|
|
1076
1266
|
|
|
1267
|
+
#+RESULTS:
|
|
1268
|
+
#+begin_example
|
|
1269
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
1270
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1271
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1272
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
1273
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1274
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1275
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1276
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
1277
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
1278
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
1279
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
1280
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
1281
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
1282
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
1283
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1284
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
1285
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1286
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
1287
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
1288
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
1289
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1290
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
1291
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
1292
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1293
|
+
#+end_example
|
|
1294
|
+
|
|
1295
|
+
|
|
1077
1296
|
Rendering ~tab2~ into Emacs org-mode:
|
|
1078
1297
|
|
|
1079
|
-
#+BEGIN_SRC ruby
|
|
1298
|
+
#+BEGIN_SRC ruby
|
|
1080
1299
|
tab2 = FatTable.from_org_string(tab2_str)
|
|
1300
|
+
tab2.to_aoa
|
|
1081
1301
|
#+END_SRC
|
|
1082
1302
|
|
|
1303
|
+
#+RESULTS:
|
|
1304
|
+
#+begin_example
|
|
1305
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
1306
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
1307
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1308
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1309
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
1310
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
1311
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
1312
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
1313
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
1314
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
1315
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
1316
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
1317
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
1318
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
1319
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1320
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
1321
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
1322
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
1323
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
1324
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
1325
|
+
#+end_example
|
|
1326
|
+
|
|
1083
1327
|
*** Select
|
|
1084
1328
|
With the ~select~ method, you can select columns to appear in the output
|
|
1085
1329
|
table, rearrange their order, and create new columns that are a function of
|
|
1086
1330
|
other columns.
|
|
1087
1331
|
|
|
1088
1332
|
**** Selecting Existing Columns (Also of :omni)
|
|
1089
|
-
|
|
1090
1333
|
Here we select three existing columns by simply passing header symbols in the
|
|
1091
1334
|
order we want them to appear in the output. Thus, one use of =select= is to
|
|
1092
1335
|
filter and permute the order of existing columns. The =select= method preserves
|
|
1093
1336
|
any group boundaries present in the input table.
|
|
1094
1337
|
|
|
1095
|
-
#+BEGIN_SRC ruby
|
|
1338
|
+
#+BEGIN_SRC ruby
|
|
1096
1339
|
tab1.select(:price, :ref, :shares).to_aoa
|
|
1097
1340
|
#+END_SRC
|
|
1098
1341
|
|
|
1099
|
-
#+
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
|
1104
|
-
|
|
|
1105
|
-
|
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
|
1109
|
-
|
|
|
1110
|
-
|
|
|
1111
|
-
|
|
|
1112
|
-
|
|
|
1113
|
-
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
| 7.
|
|
1117
|
-
|
|
|
1118
|
-
|
|
|
1119
|
-
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
|
1123
|
-
|
|
|
1124
|
-
|
|
1342
|
+
#+RESULTS:
|
|
1343
|
+
#+begin_example
|
|
1344
|
+
| Price | Ref | Shares |
|
|
1345
|
+
|--------+------+--------|
|
|
1346
|
+
| 7.7000 | T001 | 100 |
|
|
1347
|
+
| 7.7500 | T002 | 200 |
|
|
1348
|
+
| 7.5000 | T003 | 800 |
|
|
1349
|
+
| 7.5000 | T003 | 800 |
|
|
1350
|
+
|--------+------+--------|
|
|
1351
|
+
| 7.5500 | T004 | 6811 |
|
|
1352
|
+
| 7.5000 | T005 | 4000 |
|
|
1353
|
+
| 7.6000 | T006 | 1000 |
|
|
1354
|
+
| 7.6000 | T006 | 1000 |
|
|
1355
|
+
| 7.6500 | T007 | 200 |
|
|
1356
|
+
| 7.6500 | T008 | 2771 |
|
|
1357
|
+
| 7.6000 | T009 | 9550 |
|
|
1358
|
+
|--------+------+--------|
|
|
1359
|
+
| 7.5500 | T010 | 3175 |
|
|
1360
|
+
| 7.4250 | T011 | 100 |
|
|
1361
|
+
| 7.5500 | T012 | 4700 |
|
|
1362
|
+
| 7.5500 | T012 | 4700 |
|
|
1363
|
+
| 7.3500 | T013 | 53100 |
|
|
1364
|
+
|--------+------+--------|
|
|
1365
|
+
| 7.4500 | T014 | 5847 |
|
|
1366
|
+
| 7.7500 | T015 | 500 |
|
|
1367
|
+
| 8.2500 | T016 | 100 |
|
|
1368
|
+
#+end_example
|
|
1125
1369
|
|
|
1126
1370
|
It can be tedious to type the names of all the columns in a ~select~
|
|
1127
1371
|
statement, so ~FatTable~ recognizes the special column name ~:omni~. If the
|
|
@@ -1132,79 +1376,79 @@ non-existent column unless you happen to have a column named ~:omni~ in your
|
|
|
1132
1376
|
table, which is not advisable. You can add hash arguments after ~:omni~ but
|
|
1133
1377
|
you cannot add additional column names:
|
|
1134
1378
|
|
|
1135
|
-
#+BEGIN_SRC ruby
|
|
1379
|
+
#+BEGIN_SRC ruby
|
|
1136
1380
|
tab1.select(:omni, cost: 'shares * price').to_aoa
|
|
1137
1381
|
#+END_SRC
|
|
1138
1382
|
|
|
1139
|
-
#+
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
|
1144
|
-
|
|
|
1145
|
-
| T003 | 2016-11-01 | P |
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
|
1149
|
-
|
|
|
1150
|
-
| T006 | 2016-11-01 | S |
|
|
1151
|
-
|
|
|
1152
|
-
|
|
|
1153
|
-
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
|
1157
|
-
|
|
|
1158
|
-
| T012 | 2016-11-02 | P |
|
|
1159
|
-
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
|
1163
|
-
|
|
|
1164
|
-
|
|
1383
|
+
#+RESULTS:
|
|
1384
|
+
#+begin_example
|
|
1385
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp | Cost |
|
|
1386
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1387
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 | 770.0000 |
|
|
1388
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 | 1550.0000 |
|
|
1389
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 | 6000.0000 |
|
|
1390
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 | 6000.0000 |
|
|
1391
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1392
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 | 51423.0500 |
|
|
1393
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 | 30000.0000 |
|
|
1394
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 | 7600.0000 |
|
|
1395
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 | 7600.0000 |
|
|
1396
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 | 1530.0000 |
|
|
1397
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 | 21198.1500 |
|
|
1398
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 | 72580.0000 |
|
|
1399
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1400
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 | 23971.2500 |
|
|
1401
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 | 742.5000 |
|
|
1402
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 | 35485.0000 |
|
|
1403
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 | 35485.0000 |
|
|
1404
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 | 390285.0000 |
|
|
1405
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1406
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 | 43560.1500 |
|
|
1407
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 | 3875.0000 |
|
|
1408
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 | 825.0000 |
|
|
1409
|
+
#+end_example
|
|
1165
1410
|
|
|
1166
1411
|
**** Copying and Renaming Existing Columns.
|
|
1167
|
-
|
|
1168
1412
|
After the list of selected column names in the call to ~select~, you can add
|
|
1169
1413
|
any number of hash-like arguments. You can use these to add a copy of an
|
|
1170
1414
|
existing column. By calling select again, you can include only the copied
|
|
1171
1415
|
column, in effect renaming it. For example, if you want ~tab1~ but with ~:ref~
|
|
1172
1416
|
changed to ~:id~, just add an argument to define the new ~:id~ column:
|
|
1173
1417
|
|
|
1174
|
-
#+BEGIN_SRC ruby
|
|
1418
|
+
#+BEGIN_SRC ruby
|
|
1175
1419
|
tab1.select(:omni, id: :ref).
|
|
1176
1420
|
select(:id, :date, :code, :price, :shares).to_aoa
|
|
1177
1421
|
#+END_SRC
|
|
1178
1422
|
|
|
1179
|
-
#+
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
|
1184
|
-
|
|
|
1185
|
-
| T003 | 2016-11-01 | P |
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
|
1189
|
-
|
|
|
1190
|
-
| T006 | 2016-11-01 | S |
|
|
1191
|
-
|
|
|
1192
|
-
|
|
|
1193
|
-
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
|
1197
|
-
|
|
|
1198
|
-
| T012 | 2016-11-02 | P |
|
|
1199
|
-
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
|
1203
|
-
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
**** Adding New Columns
|
|
1423
|
+
#+RESULTS:
|
|
1424
|
+
#+begin_example
|
|
1425
|
+
| Id | Date | Code | Price | Shares |
|
|
1426
|
+
|------+------------+------+--------+--------|
|
|
1427
|
+
| T001 | 2016-11-01 | P | 7.7000 | 100 |
|
|
1428
|
+
| T002 | 2016-11-01 | P | 7.7500 | 200 |
|
|
1429
|
+
| T003 | 2016-11-01 | P | 7.5000 | 800 |
|
|
1430
|
+
| T003 | 2016-11-01 | P | 7.5000 | 800 |
|
|
1431
|
+
|------+------------+------+--------+--------|
|
|
1432
|
+
| T004 | 2016-11-01 | S | 7.5500 | 6811 |
|
|
1433
|
+
| T005 | 2016-11-01 | S | 7.5000 | 4000 |
|
|
1434
|
+
| T006 | 2016-11-01 | S | 7.6000 | 1000 |
|
|
1435
|
+
| T006 | 2016-11-01 | S | 7.6000 | 1000 |
|
|
1436
|
+
| T007 | 2016-11-01 | S | 7.6500 | 200 |
|
|
1437
|
+
| T008 | 2016-11-01 | P | 7.6500 | 2771 |
|
|
1438
|
+
| T009 | 2016-11-01 | P | 7.6000 | 9550 |
|
|
1439
|
+
|------+------------+------+--------+--------|
|
|
1440
|
+
| T010 | 2016-11-01 | P | 7.5500 | 3175 |
|
|
1441
|
+
| T011 | 2016-11-02 | P | 7.4250 | 100 |
|
|
1442
|
+
| T012 | 2016-11-02 | P | 7.5500 | 4700 |
|
|
1443
|
+
| T012 | 2016-11-02 | P | 7.5500 | 4700 |
|
|
1444
|
+
| T013 | 2016-11-02 | P | 7.3500 | 53100 |
|
|
1445
|
+
|------+------------+------+--------+--------|
|
|
1446
|
+
| T014 | 2016-11-02 | P | 7.4500 | 5847 |
|
|
1447
|
+
| T015 | 2016-11-02 | P | 7.7500 | 500 |
|
|
1448
|
+
| T016 | 2016-11-02 | P | 8.2500 | 100 |
|
|
1449
|
+
#+end_example
|
|
1207
1450
|
|
|
1451
|
+
**** Adding New Computed Columns
|
|
1208
1452
|
More interesting is that ~select~ can take hash-like keyword arguments after
|
|
1209
1453
|
the symbol arguments to create new columns in the output as functions of other
|
|
1210
1454
|
columns. For each hash-like parameter, the keyword given must be a symbol,
|
|
@@ -1224,104 +1468,160 @@ variables are set the number of the current row and group number respectively.
|
|
|
1224
1468
|
For example, if we want to rename the ~traded_on~ column to ~:date~ and add a
|
|
1225
1469
|
new column to compute the cost of shares, we could do the following:
|
|
1226
1470
|
|
|
1227
|
-
#+BEGIN_SRC ruby
|
|
1471
|
+
#+BEGIN_SRC ruby
|
|
1228
1472
|
tab1.select(:ref, :price, :shares, traded_on: :date, cost: 'price * shares').to_aoa
|
|
1229
1473
|
#+END_SRC
|
|
1230
1474
|
|
|
1231
|
-
#+
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
|
1236
|
-
|
|
|
1237
|
-
| T003 |
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
|
1241
|
-
|
|
|
1242
|
-
| T006 |
|
|
1243
|
-
|
|
|
1244
|
-
|
|
|
1245
|
-
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
|
1249
|
-
|
|
|
1250
|
-
| T012 |
|
|
1251
|
-
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
|
1255
|
-
|
|
|
1256
|
-
|
|
1475
|
+
#+RESULTS:
|
|
1476
|
+
#+begin_example
|
|
1477
|
+
| Ref | Price | Shares | Traded On | Cost |
|
|
1478
|
+
|------+--------+--------+------------+-------------|
|
|
1479
|
+
| T001 | 7.7000 | 100 | 2016-11-01 | 770.0000 |
|
|
1480
|
+
| T002 | 7.7500 | 200 | 2016-11-01 | 1550.0000 |
|
|
1481
|
+
| T003 | 7.5000 | 800 | 2016-11-01 | 6000.0000 |
|
|
1482
|
+
| T003 | 7.5000 | 800 | 2016-11-01 | 6000.0000 |
|
|
1483
|
+
|------+--------+--------+------------+-------------|
|
|
1484
|
+
| T004 | 7.5500 | 6811 | 2016-11-01 | 51423.0500 |
|
|
1485
|
+
| T005 | 7.5000 | 4000 | 2016-11-01 | 30000.0000 |
|
|
1486
|
+
| T006 | 7.6000 | 1000 | 2016-11-01 | 7600.0000 |
|
|
1487
|
+
| T006 | 7.6000 | 1000 | 2016-11-01 | 7600.0000 |
|
|
1488
|
+
| T007 | 7.6500 | 200 | 2016-11-01 | 1530.0000 |
|
|
1489
|
+
| T008 | 7.6500 | 2771 | 2016-11-01 | 21198.1500 |
|
|
1490
|
+
| T009 | 7.6000 | 9550 | 2016-11-01 | 72580.0000 |
|
|
1491
|
+
|------+--------+--------+------------+-------------|
|
|
1492
|
+
| T010 | 7.5500 | 3175 | 2016-11-01 | 23971.2500 |
|
|
1493
|
+
| T011 | 7.4250 | 100 | 2016-11-02 | 742.5000 |
|
|
1494
|
+
| T012 | 7.5500 | 4700 | 2016-11-02 | 35485.0000 |
|
|
1495
|
+
| T012 | 7.5500 | 4700 | 2016-11-02 | 35485.0000 |
|
|
1496
|
+
| T013 | 7.3500 | 53100 | 2016-11-02 | 390285.0000 |
|
|
1497
|
+
|------+--------+--------+------------+-------------|
|
|
1498
|
+
| T014 | 7.4500 | 5847 | 2016-11-02 | 43560.1500 |
|
|
1499
|
+
| T015 | 7.7500 | 500 | 2016-11-02 | 3875.0000 |
|
|
1500
|
+
| T016 | 8.2500 | 100 | 2016-11-02 | 825.0000 |
|
|
1501
|
+
#+end_example
|
|
1257
1502
|
|
|
1258
1503
|
The parameter ~traded_on: :date~ caused the ~:date~ column of the input table
|
|
1259
1504
|
to be renamed ~:traded_on~, and the parameter ~cost: 'price * shares'~ created
|
|
1260
|
-
a new column, ~:cost~, as the product of values in the ~:price~ and
|
|
1261
|
-
columns.
|
|
1505
|
+
a new computed column, ~:cost~, as the product of values in the ~:price~ and
|
|
1506
|
+
~:shares~ columns.
|
|
1262
1507
|
|
|
1263
1508
|
The order of the columns in the result tables is the same as the order of the
|
|
1264
1509
|
parameters to the ~select~ method. So, you can re-order the columns with a
|
|
1265
1510
|
second, chained call to ~select~:
|
|
1266
1511
|
|
|
1267
|
-
#+BEGIN_SRC ruby
|
|
1512
|
+
#+BEGIN_SRC ruby
|
|
1268
1513
|
tab1.select(:ref, :price, :shares, traded_on: :date, cost: 'price * shares').
|
|
1269
1514
|
select(:ref, :traded_on, :price, :shares, :cost).to_aoa
|
|
1270
1515
|
#+END_SRC
|
|
1271
1516
|
|
|
1272
|
-
#+
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
|
1277
|
-
|
|
|
1278
|
-
| T003 | 2016-11-01 |
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
|
1282
|
-
|
|
|
1283
|
-
| T006 | 2016-11-01 |
|
|
1284
|
-
|
|
|
1285
|
-
|
|
|
1286
|
-
|
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
|
1290
|
-
|
|
|
1291
|
-
| T012 | 2016-11-02 |
|
|
1292
|
-
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
|
1296
|
-
|
|
|
1297
|
-
|
|
1517
|
+
#+RESULTS:
|
|
1518
|
+
#+begin_example
|
|
1519
|
+
| Ref | Traded On | Price | Shares | Cost |
|
|
1520
|
+
|------+------------+--------+--------+-------------|
|
|
1521
|
+
| T001 | 2016-11-01 | 7.7000 | 100 | 770.0000 |
|
|
1522
|
+
| T002 | 2016-11-01 | 7.7500 | 200 | 1550.0000 |
|
|
1523
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | 6000.0000 |
|
|
1524
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | 6000.0000 |
|
|
1525
|
+
|------+------------+--------+--------+-------------|
|
|
1526
|
+
| T004 | 2016-11-01 | 7.5500 | 6811 | 51423.0500 |
|
|
1527
|
+
| T005 | 2016-11-01 | 7.5000 | 4000 | 30000.0000 |
|
|
1528
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | 7600.0000 |
|
|
1529
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | 7600.0000 |
|
|
1530
|
+
| T007 | 2016-11-01 | 7.6500 | 200 | 1530.0000 |
|
|
1531
|
+
| T008 | 2016-11-01 | 7.6500 | 2771 | 21198.1500 |
|
|
1532
|
+
| T009 | 2016-11-01 | 7.6000 | 9550 | 72580.0000 |
|
|
1533
|
+
|------+------------+--------+--------+-------------|
|
|
1534
|
+
| T010 | 2016-11-01 | 7.5500 | 3175 | 23971.2500 |
|
|
1535
|
+
| T011 | 2016-11-02 | 7.4250 | 100 | 742.5000 |
|
|
1536
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | 35485.0000 |
|
|
1537
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | 35485.0000 |
|
|
1538
|
+
| T013 | 2016-11-02 | 7.3500 | 53100 | 390285.0000 |
|
|
1539
|
+
|------+------------+--------+--------+-------------|
|
|
1540
|
+
| T014 | 2016-11-02 | 7.4500 | 5847 | 43560.1500 |
|
|
1541
|
+
| T015 | 2016-11-02 | 7.7500 | 500 | 3875.0000 |
|
|
1542
|
+
| T016 | 2016-11-02 | 8.2500 | 100 | 825.0000 |
|
|
1543
|
+
#+end_example
|
|
1298
1544
|
|
|
1299
1545
|
**** Adding Constant Strings and Other Types in select
|
|
1300
|
-
|
|
1301
1546
|
Because ~select~'s hash-like parameters evaluate a string as a ruby
|
|
1302
1547
|
expression, as just described, it must provide a way to set a new column to a
|
|
1303
1548
|
string literal. To indicate that a string should be inserted literally, add a
|
|
1304
1549
|
~:~ as the first non-blank character in the string. This will supress
|
|
1305
1550
|
evaluation and insert the remainder of the string in the named column.
|
|
1306
1551
|
|
|
1307
|
-
#+BEGIN_SRC ruby
|
|
1552
|
+
#+BEGIN_SRC ruby
|
|
1308
1553
|
tab1.select(:ref, :price, :shares, traded_on: :date, cost: ':the price of freedom').
|
|
1309
1554
|
select(:ref, :traded_on, :price, :shares, :cost).to_aoa
|
|
1310
1555
|
#+END_SRC
|
|
1311
1556
|
|
|
1557
|
+
#+RESULTS:
|
|
1558
|
+
#+begin_example
|
|
1559
|
+
| Ref | Traded On | Price | Shares | Cost |
|
|
1560
|
+
|------+------------+--------+--------+----------------------|
|
|
1561
|
+
| T001 | 2016-11-01 | 7.7000 | 100 | the price of freedom |
|
|
1562
|
+
| T002 | 2016-11-01 | 7.7500 | 200 | the price of freedom |
|
|
1563
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | the price of freedom |
|
|
1564
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | the price of freedom |
|
|
1565
|
+
|------+------------+--------+--------+----------------------|
|
|
1566
|
+
| T004 | 2016-11-01 | 7.5500 | 6811 | the price of freedom |
|
|
1567
|
+
| T005 | 2016-11-01 | 7.5000 | 4000 | the price of freedom |
|
|
1568
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | the price of freedom |
|
|
1569
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | the price of freedom |
|
|
1570
|
+
| T007 | 2016-11-01 | 7.6500 | 200 | the price of freedom |
|
|
1571
|
+
| T008 | 2016-11-01 | 7.6500 | 2771 | the price of freedom |
|
|
1572
|
+
| T009 | 2016-11-01 | 7.6000 | 9550 | the price of freedom |
|
|
1573
|
+
|------+------------+--------+--------+----------------------|
|
|
1574
|
+
| T010 | 2016-11-01 | 7.5500 | 3175 | the price of freedom |
|
|
1575
|
+
| T011 | 2016-11-02 | 7.4250 | 100 | the price of freedom |
|
|
1576
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | the price of freedom |
|
|
1577
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | the price of freedom |
|
|
1578
|
+
| T013 | 2016-11-02 | 7.3500 | 53100 | the price of freedom |
|
|
1579
|
+
|------+------------+--------+--------+----------------------|
|
|
1580
|
+
| T014 | 2016-11-02 | 7.4500 | 5847 | the price of freedom |
|
|
1581
|
+
| T015 | 2016-11-02 | 7.7500 | 500 | the price of freedom |
|
|
1582
|
+
| T016 | 2016-11-02 | 8.2500 | 100 | the price of freedom |
|
|
1583
|
+
#+end_example
|
|
1584
|
+
|
|
1312
1585
|
This sets the ~:cost~ column to the string constant 'the price of freedom' for
|
|
1313
1586
|
the whole table.
|
|
1314
1587
|
|
|
1315
1588
|
You can set a column to a constant of any of the acceptable types, ~Numeric~,
|
|
1316
1589
|
~Date~, ~DateTime~, true, false, or nil.
|
|
1317
1590
|
|
|
1318
|
-
#+BEGIN_SRC ruby
|
|
1591
|
+
#+BEGIN_SRC ruby
|
|
1319
1592
|
tab1.select(:ref, :price, :shares, traded_on: :date, cost: Math::PI, today: Date.today).
|
|
1320
1593
|
select(:ref, :traded_on, :price, :shares, :cost, :today).to_aoa
|
|
1321
1594
|
#+END_SRC
|
|
1322
1595
|
|
|
1323
|
-
|
|
1596
|
+
#+RESULTS:
|
|
1597
|
+
#+begin_example
|
|
1598
|
+
| Ref | Traded On | Price | Shares | Cost | Today |
|
|
1599
|
+
|------+------------+--------+--------+--------+------------|
|
|
1600
|
+
| T001 | 2016-11-01 | 7.7000 | 100 | 3.1416 | 2025-12-28 |
|
|
1601
|
+
| T002 | 2016-11-01 | 7.7500 | 200 | 3.1416 | 2025-12-28 |
|
|
1602
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | 3.1416 | 2025-12-28 |
|
|
1603
|
+
| T003 | 2016-11-01 | 7.5000 | 800 | 3.1416 | 2025-12-28 |
|
|
1604
|
+
|------+------------+--------+--------+--------+------------|
|
|
1605
|
+
| T004 | 2016-11-01 | 7.5500 | 6811 | 3.1416 | 2025-12-28 |
|
|
1606
|
+
| T005 | 2016-11-01 | 7.5000 | 4000 | 3.1416 | 2025-12-28 |
|
|
1607
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | 3.1416 | 2025-12-28 |
|
|
1608
|
+
| T006 | 2016-11-01 | 7.6000 | 1000 | 3.1416 | 2025-12-28 |
|
|
1609
|
+
| T007 | 2016-11-01 | 7.6500 | 200 | 3.1416 | 2025-12-28 |
|
|
1610
|
+
| T008 | 2016-11-01 | 7.6500 | 2771 | 3.1416 | 2025-12-28 |
|
|
1611
|
+
| T009 | 2016-11-01 | 7.6000 | 9550 | 3.1416 | 2025-12-28 |
|
|
1612
|
+
|------+------------+--------+--------+--------+------------|
|
|
1613
|
+
| T010 | 2016-11-01 | 7.5500 | 3175 | 3.1416 | 2025-12-28 |
|
|
1614
|
+
| T011 | 2016-11-02 | 7.4250 | 100 | 3.1416 | 2025-12-28 |
|
|
1615
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | 3.1416 | 2025-12-28 |
|
|
1616
|
+
| T012 | 2016-11-02 | 7.5500 | 4700 | 3.1416 | 2025-12-28 |
|
|
1617
|
+
| T013 | 2016-11-02 | 7.3500 | 53100 | 3.1416 | 2025-12-28 |
|
|
1618
|
+
|------+------------+--------+--------+--------+------------|
|
|
1619
|
+
| T014 | 2016-11-02 | 7.4500 | 5847 | 3.1416 | 2025-12-28 |
|
|
1620
|
+
| T015 | 2016-11-02 | 7.7500 | 500 | 3.1416 | 2025-12-28 |
|
|
1621
|
+
| T016 | 2016-11-02 | 8.2500 | 100 | 3.1416 | 2025-12-28 |
|
|
1622
|
+
#+end_example
|
|
1324
1623
|
|
|
1624
|
+
**** Custom Instance Variables and Hooks
|
|
1325
1625
|
As the above examples demonstrate, the instance variables ~@row~ and ~@group~
|
|
1326
1626
|
are available when evaluating expressions that add new columns. You can also set
|
|
1327
1627
|
up your own instance variables as well for keeping track of things that cross
|
|
@@ -1342,18 +1642,19 @@ shows the cumulative cost after each transaction in our example table. The
|
|
|
1342
1642
|
following example uses the ~ivars:~ and ~before_hook:~ parameters to keep track
|
|
1343
1643
|
of the running cost of shares, then formats the table.
|
|
1344
1644
|
|
|
1345
|
-
#+BEGIN_SRC ruby
|
|
1346
|
-
tab = tab1.select(:ref, :price, :shares, traded_on: :date,
|
|
1347
|
-
cost: 'price * shares', cumulative: '@total_cost',
|
|
1348
|
-
ivars: { total_cost: 0 },
|
|
1645
|
+
#+BEGIN_SRC ruby
|
|
1646
|
+
tab = tab1.select(:ref, :price, :shares, traded_on: :date,
|
|
1647
|
+
cost: 'price * shares', cumulative: '@total_cost',
|
|
1648
|
+
ivars: { total_cost: 0 },
|
|
1349
1649
|
before_hook: '@total_cost += price * shares')
|
|
1350
1650
|
FatTable.to_aoa(tab) do |f|
|
|
1351
1651
|
f.format(price: '0.4', shares: '0.0,', cost: '0.2,', cumulative: '0.2,')
|
|
1352
1652
|
end
|
|
1353
1653
|
#+END_SRC
|
|
1354
1654
|
|
|
1355
|
-
#+
|
|
1356
|
-
|
|
1655
|
+
#+RESULTS:
|
|
1656
|
+
#+begin_example
|
|
1657
|
+
| Ref | Price | Shares | Traded On | Cost | Cumulative |
|
|
1357
1658
|
|------+--------+--------+------------+------------+------------|
|
|
1358
1659
|
| T001 | 7.7000 | 100 | 2016-11-01 | 770.00 | 770.00 |
|
|
1359
1660
|
| T002 | 7.7500 | 200 | 2016-11-01 | 1,550.00 | 2,320.00 |
|
|
@@ -1377,10 +1678,9 @@ of the running cost of shares, then formats the table.
|
|
|
1377
1678
|
| T014 | 7.4500 | 5,847 | 2016-11-02 | 43,560.15 | 735,780.10 |
|
|
1378
1679
|
| T015 | 7.7500 | 500 | 2016-11-02 | 3,875.00 | 739,655.10 |
|
|
1379
1680
|
| T016 | 8.2500 | 100 | 2016-11-02 | 825.00 | 740,480.10 |
|
|
1380
|
-
#+
|
|
1681
|
+
#+end_example
|
|
1381
1682
|
|
|
1382
1683
|
**** Argument Order and Boundaries
|
|
1383
|
-
|
|
1384
1684
|
Notice that ~select~ can take any number of arguments but all the symbol
|
|
1385
1685
|
arguments must come first followed by all the hash-like keyword arguments,
|
|
1386
1686
|
including the special arguments for instance variables and hooks.
|
|
@@ -1403,20 +1703,22 @@ table has only a single group.
|
|
|
1403
1703
|
Here we select only those even-numbered rows where either of the two boolean
|
|
1404
1704
|
fields is true:
|
|
1405
1705
|
|
|
1406
|
-
#+BEGIN_SRC ruby
|
|
1407
|
-
|
|
1408
|
-
.to_aoa
|
|
1706
|
+
#+BEGIN_SRC ruby
|
|
1707
|
+
tab1.where('@row.even? && (g10 || qp10)').to_term
|
|
1409
1708
|
#+END_SRC
|
|
1410
1709
|
|
|
1411
|
-
#+
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1710
|
+
#+RESULTS:
|
|
1711
|
+
#+begin_example
|
|
1712
|
+
╒══════╤════════════╤══════╤════════╤═════╤══════╤════════╤══════╤═══════╤════════╤════════╕
|
|
1713
|
+
│ Ref │ Date │ Code │ Price │ G10 │ QP10 │ Shares │ Lp │ Qp │ Iplp │ Ipqp │
|
|
1714
|
+
├──────┼────────────┼──────┼────────┼─────┼──────┼────────┼──────┼───────┼────────┼────────┤
|
|
1715
|
+
│ T002 │ 2016-11-01 │ P │ 7.7500 │ T │ F │ 200 │ 28 │ 172 │ 0.2453 │ 0.1924 │
|
|
1716
|
+
│ T003 │ 2016-11-01 │ P │ 7.5000 │ F │ T │ 800 │ 112 │ 688 │ 0.2453 │ 0.1924 │
|
|
1717
|
+
│ T006 │ 2016-11-01 │ S │ 7.6000 │ F │ T │ 1000 │ 143 │ 857 │ 0.2453 │ 0.1924 │
|
|
1718
|
+
│ T010 │ 2016-11-01 │ P │ 7.5500 │ F │ T │ 3175 │ 451 │ 2724 │ 0.2453 │ 0.1924 │
|
|
1719
|
+
│ T013 │ 2016-11-02 │ P │ 7.3500 │ T │ T │ 53100 │ 7656 │ 45444 │ 0.2453 │ 0.1924 │
|
|
1720
|
+
╘══════╧════════════╧══════╧════════╧═════╧══════╧════════╧══════╧═══════╧════════╧════════╛
|
|
1721
|
+
#+end_example
|
|
1420
1722
|
|
|
1421
1723
|
*** Order_by
|
|
1422
1724
|
You can sort a table on any number of columns with ~order_by~. The ~order_by~
|
|
@@ -1429,36 +1731,36 @@ All columns of the input table are included in the output.
|
|
|
1429
1731
|
|
|
1430
1732
|
Let's sort our table first by ~:code~, then in reverse order of ~:date~.
|
|
1431
1733
|
|
|
1432
|
-
#+BEGIN_SRC ruby
|
|
1433
|
-
tab1.order_by(:code, :date!)
|
|
1434
|
-
.to_aoa
|
|
1734
|
+
#+BEGIN_SRC ruby
|
|
1735
|
+
tab1.order_by(:code, :date!).to_aoa
|
|
1435
1736
|
#+END_SRC
|
|
1436
1737
|
|
|
1437
|
-
#+
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
|
1442
|
-
| T012 | 2016-11-02 | P |
|
|
1443
|
-
|
|
|
1444
|
-
|
|
|
1445
|
-
|
|
|
1446
|
-
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
|
1450
|
-
|
|
|
1451
|
-
| T003 | 2016-11-01 | P |
|
|
1452
|
-
|
|
|
1453
|
-
|
|
|
1454
|
-
|
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
|
1458
|
-
|
|
|
1459
|
-
| T006 | 2016-11-01 | S |
|
|
1460
|
-
|
|
|
1461
|
-
|
|
1738
|
+
#+RESULTS:
|
|
1739
|
+
#+begin_example
|
|
1740
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
1741
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1742
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1743
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
1744
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
1745
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
1746
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
1747
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
1748
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1749
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1750
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
1751
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
1752
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1753
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
1754
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
1755
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
1756
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
1757
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
1758
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
1759
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
1760
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
1761
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
1762
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
1763
|
+
#+end_example
|
|
1462
1764
|
|
|
1463
1765
|
The interesting thing about ~order_by~ is that, while it ignores groups in its
|
|
1464
1766
|
input, it adds group boundaries in the output table at those rows where the sort
|
|
@@ -1473,48 +1775,49 @@ optional trailing ~!~ to indicate reverse sort. The resulting table has an
|
|
|
1473
1775
|
additional column called ~:sort_key~ with the expression evaluated for each
|
|
1474
1776
|
row, and the table is sorted as with ~order_by~ on that column.
|
|
1475
1777
|
|
|
1476
|
-
#+BEGIN_SRC ruby
|
|
1778
|
+
#+BEGIN_SRC ruby
|
|
1477
1779
|
tab1.order_with('price * shares').to_aoa
|
|
1478
1780
|
#+END_SRC
|
|
1479
1781
|
|
|
1480
|
-
#+
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
| T003 | 2016-11-01 | P |
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
| T006 | 2016-11-01 | S |
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
| T012 | 2016-11-02 | P |
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1782
|
+
#+RESULTS:
|
|
1783
|
+
#+begin_example
|
|
1784
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp | Sort Key |
|
|
1785
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1786
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 | 742.5000 |
|
|
1787
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1788
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 | 770.0000 |
|
|
1789
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1790
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 | 825.0000 |
|
|
1791
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1792
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 | 1530.0000 |
|
|
1793
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1794
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 | 1550.0000 |
|
|
1795
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1796
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 | 3875.0000 |
|
|
1797
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1798
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 | 6000.0000 |
|
|
1799
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 | 6000.0000 |
|
|
1800
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1801
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 | 7600.0000 |
|
|
1802
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 | 7600.0000 |
|
|
1803
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1804
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 | 21198.1500 |
|
|
1805
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1806
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 | 23971.2500 |
|
|
1807
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1808
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 | 30000.0000 |
|
|
1809
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1810
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 | 35485.0000 |
|
|
1811
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 | 35485.0000 |
|
|
1812
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1813
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 | 43560.1500 |
|
|
1814
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1815
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 | 51423.0500 |
|
|
1816
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1817
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 | 72580.0000 |
|
|
1818
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------+-------------|
|
|
1819
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 | 390285.0000 |
|
|
1820
|
+
#+end_example
|
|
1518
1821
|
|
|
1519
1822
|
*** Group_by
|
|
1520
1823
|
Like ~order_by~, ~group_by~ takes a set of parameters of column header symbols,
|
|
@@ -1530,29 +1833,29 @@ For example, let's summarize the ~trades~ table by ~:code~ and ~:price~ again,
|
|
|
1530
1833
|
and determine total shares, average price, and a few other features of each
|
|
1531
1834
|
group:
|
|
1532
1835
|
|
|
1533
|
-
#+BEGIN_SRC ruby
|
|
1836
|
+
#+BEGIN_SRC ruby
|
|
1534
1837
|
tab1.group_by(:code, :date, price: :avg,
|
|
1535
1838
|
shares: :sum, lp: :sum, qp: :sum,
|
|
1536
|
-
qp10: :all?)
|
|
1537
|
-
.to_aoa { |f| f.format(avg_price: '0.5R') }
|
|
1839
|
+
qp10: :all?).to_aoa { |f| f.format(avg_price: '0.5R') }
|
|
1538
1840
|
#+END_SRC
|
|
1539
1841
|
|
|
1540
|
-
#+
|
|
1541
|
-
|
|
1842
|
+
#+RESULTS:
|
|
1843
|
+
#+begin_example
|
|
1844
|
+
| Code | Date | Avg Price | Sum Shares | Sum Lp | Sum Qp | All QP10 |
|
|
1542
1845
|
|------+------------+-----------+------------+--------+--------+----------|
|
|
1543
1846
|
| P | 2016-11-01 | 7.60714 | 17396 | 2473 | 14923 | F |
|
|
1544
1847
|
| P | 2016-11-02 | 7.61786 | 69047 | 9945 | 59102 | F |
|
|
1545
1848
|
| S | 2016-11-01 | 7.58000 | 13011 | 1852 | 11159 | F |
|
|
1546
|
-
#+
|
|
1849
|
+
#+end_example
|
|
1547
1850
|
|
|
1548
1851
|
After the grouping column parameters, ~:code~ and ~:date~, there are several
|
|
1549
|
-
hash-like "aggregating" parameters where the key is the column to aggregate
|
|
1550
|
-
the value is a symbol for one of several aggregating methods that
|
|
1551
|
-
~FatTable::Column~ objects understand. For example, the ~:avg~ method is
|
|
1552
|
-
to the :price column so that the output shows the average price in
|
|
1553
|
-
The ~:shares~, ~:lp~, and ~:qp~ columns are summed, and the
|
|
1554
|
-
applied to one of the boolean fields, that is, it is
|
|
1555
|
-
in that column are ~true~.
|
|
1852
|
+
hash-like "aggregating" parameters where the key is the column to aggregate
|
|
1853
|
+
and the value is a symbol for one of several aggregating methods that
|
|
1854
|
+
~FatTable::Column~ objects understand. For example, the ~:avg~ method is
|
|
1855
|
+
applied to the :price column so that the output shows the average price in
|
|
1856
|
+
each group. The ~:shares~, ~:lp~, and ~:qp~ columns are summed, and the
|
|
1857
|
+
~:all?~ aggregate is applied to one of the boolean fields, that is, it is
|
|
1858
|
+
~true~ if all of the values in that column are ~true~.
|
|
1556
1859
|
|
|
1557
1860
|
Note that the column names in the output of the aggregated columns have the
|
|
1558
1861
|
name of the aggregating method pre-pended to the column name.
|
|
@@ -1603,7 +1906,6 @@ implicit ~order_by~ on the grouping columns is collapsed into a single row.
|
|
|
1603
1906
|
|
|
1604
1907
|
*** Join
|
|
1605
1908
|
**** Join Types
|
|
1606
|
-
|
|
1607
1909
|
So far, all the operations have operated on a single table. ~FatTable~ provides
|
|
1608
1910
|
several ~join~ methods for combining two tables, each of which takes as
|
|
1609
1911
|
parameters (1) a second table and (2) except in the case of ~cross_join~, zero
|
|
@@ -1640,7 +1942,6 @@ for inclusion in the joined output table.
|
|
|
1640
1942
|
M~ rows.
|
|
1641
1943
|
|
|
1642
1944
|
**** Join Expressions
|
|
1643
|
-
|
|
1644
1945
|
For each of the join types, if no join expressions are given, the tables will be
|
|
1645
1946
|
joined on columns having the same column header in both tables, and the join
|
|
1646
1947
|
condition is satisfied when all the values in those columns are equal. If the
|
|
@@ -1668,12 +1969,11 @@ local variables within the expression, but the instance variables ~@row~ and
|
|
|
1668
1969
|
~@group~ are not.
|
|
1669
1970
|
|
|
1670
1971
|
**** Join Examples
|
|
1671
|
-
|
|
1672
1972
|
The following examples are taken from the [[https://www.tutorialspoint.com/postgresql/postgresql_using_joins.htm][Postgresql tutorial]], with some slight
|
|
1673
1973
|
modifications. The examples will use the following two tables, which are also
|
|
1674
1974
|
available in ~ft_console~ as ~@tab_a~ and ~@tab_b~:
|
|
1675
1975
|
|
|
1676
|
-
#+BEGIN_SRC ruby :
|
|
1976
|
+
#+BEGIN_SRC ruby :results silent
|
|
1677
1977
|
tab_a_str = <<-EOS
|
|
1678
1978
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
1679
1979
|
|----+-------+-----+------------+--------+------------|
|
|
@@ -1697,145 +1997,153 @@ available in ~ft_console~ as ~@tab_a~ and ~@tab_b~:
|
|
|
1697
1997
|
#+END_SRC
|
|
1698
1998
|
|
|
1699
1999
|
Here is ~tab_a~:
|
|
1700
|
-
#+begin_src ruby
|
|
2000
|
+
#+begin_src ruby
|
|
1701
2001
|
tab_a = FatTable.from_org_string(tab_a_str)
|
|
1702
2002
|
tab_a.to_aoa
|
|
1703
2003
|
#+end_src
|
|
1704
2004
|
|
|
1705
|
-
#+
|
|
1706
|
-
|
|
2005
|
+
#+RESULTS:
|
|
2006
|
+
#+begin_example
|
|
2007
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
1707
2008
|
|----+-------+-----+------------+--------+------------|
|
|
1708
|
-
|
|
|
1709
|
-
|
|
|
1710
|
-
|
|
|
1711
|
-
|
|
|
1712
|
-
|
|
|
1713
|
-
|
|
|
1714
|
-
|
|
|
2009
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
|
2010
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
2011
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
2012
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
2013
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
|
2014
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
2015
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
1715
2016
|
| 10 | James | 45 | Texas | 5000 | |
|
|
1716
|
-
#+
|
|
2017
|
+
#+end_example
|
|
1717
2018
|
|
|
1718
2019
|
And ~tab_b~:
|
|
1719
|
-
#+begin_src ruby
|
|
2020
|
+
#+begin_src ruby
|
|
1720
2021
|
tab_b = FatTable.from_org_string(tab_b_str)
|
|
1721
2022
|
tab_b.to_aoa
|
|
1722
2023
|
#+end_src
|
|
1723
2024
|
|
|
1724
|
-
#+
|
|
2025
|
+
#+RESULTS:
|
|
2026
|
+
#+begin_example
|
|
1725
2027
|
| Id | Dept | Emp Id |
|
|
1726
2028
|
|----+-------------+--------|
|
|
1727
|
-
|
|
|
1728
|
-
|
|
|
1729
|
-
|
|
|
1730
|
-
#+
|
|
2029
|
+
| 1 | IT Billing | 1 |
|
|
2030
|
+
| 2 | Engineering | 2 |
|
|
2031
|
+
| 3 | Finance | 7 |
|
|
2032
|
+
#+end_example
|
|
1731
2033
|
|
|
1732
2034
|
***** Inner Joins
|
|
1733
2035
|
With no join expression arguments, the tables are joined when their sole common
|
|
1734
2036
|
field, ~:id~, is equal in both tables. The result is the natural join of the
|
|
1735
2037
|
two tables.
|
|
1736
2038
|
|
|
1737
|
-
#+BEGIN_SRC ruby
|
|
2039
|
+
#+BEGIN_SRC ruby
|
|
1738
2040
|
tab_a.join(tab_b).to_aoa
|
|
1739
2041
|
#+END_SRC
|
|
1740
2042
|
|
|
1741
|
-
#+
|
|
1742
|
-
|
|
2043
|
+
#+RESULTS:
|
|
2044
|
+
#+begin_example
|
|
2045
|
+
| Id | Name | Age | Address | Salary | Join Date | Dept | Emp Id |
|
|
1743
2046
|
|----+-------+-----+------------+--------+------------+-------------+--------|
|
|
1744
|
-
|
|
|
1745
|
-
|
|
|
1746
|
-
|
|
|
1747
|
-
#+
|
|
2047
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | IT Billing | 1 |
|
|
2048
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | Finance | 7 |
|
|
2049
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | Engineering | 2 |
|
|
2050
|
+
#+end_example
|
|
1748
2051
|
|
|
1749
2052
|
But the natural join joined employee IDs in the first table and department IDs
|
|
1750
2053
|
in the second table. To correct this, we need to explicitly state the columns we
|
|
1751
2054
|
want to join on in each table by disambiguating them with ~_a~ and ~_b~
|
|
1752
2055
|
suffixes:
|
|
1753
2056
|
|
|
1754
|
-
#+BEGIN_SRC ruby
|
|
2057
|
+
#+BEGIN_SRC ruby
|
|
1755
2058
|
tab_a.join(tab_b, :id_a, :emp_id_b).to_aoa
|
|
1756
2059
|
#+END_SRC
|
|
1757
2060
|
|
|
1758
|
-
#+
|
|
1759
|
-
|
|
2061
|
+
#+RESULTS:
|
|
2062
|
+
#+begin_example
|
|
2063
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept |
|
|
1760
2064
|
|----+-------+-----+------------+--------+------------+------+-------------|
|
|
1761
|
-
|
|
|
1762
|
-
|
|
|
1763
|
-
#+
|
|
2065
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing |
|
|
2066
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering |
|
|
2067
|
+
#+end_example
|
|
1764
2068
|
|
|
1765
2069
|
Instead of using the disambiguated column names as symbols, we could also use a
|
|
1766
2070
|
string containing a ruby expression. Within the expression, the column names
|
|
1767
2071
|
should be treated as local variables:
|
|
1768
2072
|
|
|
1769
|
-
#+BEGIN_SRC ruby
|
|
2073
|
+
#+BEGIN_SRC ruby
|
|
1770
2074
|
tab_a.join(tab_b, 'id_a == emp_id_b').to_aoa
|
|
1771
2075
|
#+END_SRC
|
|
1772
2076
|
|
|
1773
|
-
#+
|
|
1774
|
-
|
|
2077
|
+
#+RESULTS:
|
|
2078
|
+
#+begin_example
|
|
2079
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept | Emp Id |
|
|
1775
2080
|
|----+-------+-----+------------+--------+------------+------+-------------+--------|
|
|
1776
|
-
|
|
|
1777
|
-
|
|
|
1778
|
-
#+
|
|
2081
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing | 1 |
|
|
2082
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering | 2 |
|
|
2083
|
+
#+end_example
|
|
1779
2084
|
|
|
1780
2085
|
***** Left and Right Joins
|
|
1781
2086
|
In left join, all the rows of ~tab_a~ are included in the output, augmented by
|
|
1782
2087
|
the matching columns of ~tab_b~ and augmented with nils where there is no match:
|
|
1783
2088
|
|
|
1784
|
-
#+BEGIN_SRC ruby
|
|
2089
|
+
#+BEGIN_SRC ruby
|
|
1785
2090
|
tab_a.left_join(tab_b, 'id_a == emp_id_b').to_aoa
|
|
1786
2091
|
#+END_SRC
|
|
1787
2092
|
|
|
1788
|
-
#+
|
|
1789
|
-
|
|
2093
|
+
#+RESULTS:
|
|
2094
|
+
#+begin_example
|
|
2095
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept | Emp Id |
|
|
1790
2096
|
|----+-------+-----+------------+--------+------------+------+-------------+--------|
|
|
1791
|
-
|
|
|
1792
|
-
|
|
|
1793
|
-
|
|
|
1794
|
-
|
|
|
1795
|
-
|
|
|
1796
|
-
|
|
|
1797
|
-
|
|
|
2097
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing | 1 |
|
|
2098
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | | | |
|
|
2099
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 | | | |
|
|
2100
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 | | | |
|
|
2101
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering | 2 |
|
|
2102
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 | | | |
|
|
2103
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 | | | |
|
|
1798
2104
|
| 10 | James | 45 | Texas | 5000 | | | | |
|
|
1799
|
-
#+
|
|
2105
|
+
#+end_example
|
|
1800
2106
|
|
|
1801
2107
|
In a right join, all the rows of ~tab_b~ are included in the output, augmented
|
|
1802
2108
|
by the matching columns of ~tab_a~ and augmented with nils where there is no
|
|
1803
2109
|
match:
|
|
1804
2110
|
|
|
1805
|
-
#+BEGIN_SRC ruby
|
|
2111
|
+
#+BEGIN_SRC ruby
|
|
1806
2112
|
tab_a.right_join(tab_b, 'id_a == emp_id_b').to_aoa
|
|
1807
2113
|
#+END_SRC
|
|
1808
2114
|
|
|
1809
|
-
#+
|
|
1810
|
-
|
|
2115
|
+
#+RESULTS:
|
|
2116
|
+
#+begin_example
|
|
2117
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept | Emp Id |
|
|
1811
2118
|
|----+-------+-----+------------+--------+------------+------+-------------+--------|
|
|
1812
|
-
|
|
|
1813
|
-
|
|
|
1814
|
-
| | | | | | |
|
|
1815
|
-
#+
|
|
2119
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing | 1 |
|
|
2120
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering | 2 |
|
|
2121
|
+
| | | | | | | 3 | Finance | 7 |
|
|
2122
|
+
#+end_example
|
|
1816
2123
|
|
|
1817
2124
|
***** Full Join
|
|
1818
2125
|
A full join combines the effects of a left join and a right join. All the rows
|
|
1819
2126
|
from both tables are included in the output augmented by columns of the other
|
|
1820
2127
|
table where the join expression is satisfied and augmented with nils otherwise.
|
|
1821
2128
|
|
|
1822
|
-
#+BEGIN_SRC ruby
|
|
2129
|
+
#+BEGIN_SRC ruby
|
|
1823
2130
|
tab_a.full_join(tab_b, 'id_a == emp_id_b').to_aoa
|
|
1824
2131
|
#+END_SRC
|
|
1825
2132
|
|
|
1826
|
-
#+
|
|
1827
|
-
|
|
2133
|
+
#+RESULTS:
|
|
2134
|
+
#+begin_example
|
|
2135
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept | Emp Id |
|
|
1828
2136
|
|----+-------+-----+------------+--------+------------+------+-------------+--------|
|
|
1829
|
-
|
|
|
1830
|
-
|
|
|
1831
|
-
|
|
|
1832
|
-
|
|
|
1833
|
-
|
|
|
1834
|
-
|
|
|
1835
|
-
|
|
|
2137
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing | 1 |
|
|
2138
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | | | |
|
|
2139
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 | | | |
|
|
2140
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 | | | |
|
|
2141
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering | 2 |
|
|
2142
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 | | | |
|
|
2143
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 | | | |
|
|
1836
2144
|
| 10 | James | 45 | Texas | 5000 | | | | |
|
|
1837
|
-
| | | | | | |
|
|
1838
|
-
#+
|
|
2145
|
+
| | | | | | | 3 | Finance | 7 |
|
|
2146
|
+
#+end_example
|
|
1839
2147
|
|
|
1840
2148
|
***** Cross Join
|
|
1841
2149
|
Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
|
@@ -1843,38 +2151,39 @@ Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
|
|
1843
2151
|
~N~ rows and ~tab_b~ has ~M~ rows, the output table will have ~N * M~ rows.
|
|
1844
2152
|
So be careful lest you consume all your computer's memory.
|
|
1845
2153
|
|
|
1846
|
-
#+BEGIN_SRC ruby
|
|
2154
|
+
#+BEGIN_SRC ruby
|
|
1847
2155
|
tab_a.cross_join(tab_b).to_aoa
|
|
1848
2156
|
#+END_SRC
|
|
1849
2157
|
|
|
1850
|
-
#+
|
|
1851
|
-
|
|
2158
|
+
#+RESULTS:
|
|
2159
|
+
#+begin_example
|
|
2160
|
+
| Id | Name | Age | Address | Salary | Join Date | Id B | Dept | Emp Id |
|
|
1852
2161
|
|----+-------+-----+------------+--------+------------+------+-------------+--------|
|
|
1853
|
-
|
|
|
1854
|
-
|
|
|
1855
|
-
|
|
|
1856
|
-
|
|
|
1857
|
-
|
|
|
1858
|
-
|
|
|
1859
|
-
|
|
|
1860
|
-
|
|
|
1861
|
-
|
|
|
1862
|
-
|
|
|
1863
|
-
|
|
|
1864
|
-
|
|
|
1865
|
-
|
|
|
1866
|
-
|
|
|
1867
|
-
|
|
|
1868
|
-
|
|
|
1869
|
-
|
|
|
1870
|
-
|
|
|
1871
|
-
|
|
|
1872
|
-
|
|
|
1873
|
-
|
|
|
1874
|
-
| 10 | James | 45 | Texas | 5000 | |
|
|
1875
|
-
| 10 | James | 45 | Texas | 5000 | |
|
|
1876
|
-
| 10 | James | 45 | Texas | 5000 | |
|
|
1877
|
-
#+
|
|
2162
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 1 | IT Billing | 1 |
|
|
2163
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 2 | Engineering | 2 |
|
|
2164
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 | 3 | Finance | 7 |
|
|
2165
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | 1 | IT Billing | 1 |
|
|
2166
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | 2 | Engineering | 2 |
|
|
2167
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 | 3 | Finance | 7 |
|
|
2168
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 | 1 | IT Billing | 1 |
|
|
2169
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 | 2 | Engineering | 2 |
|
|
2170
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 | 3 | Finance | 7 |
|
|
2171
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 | 1 | IT Billing | 1 |
|
|
2172
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 | 2 | Engineering | 2 |
|
|
2173
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 | 3 | Finance | 7 |
|
|
2174
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 1 | IT Billing | 1 |
|
|
2175
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 2 | Engineering | 2 |
|
|
2176
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 | 3 | Finance | 7 |
|
|
2177
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 | 1 | IT Billing | 1 |
|
|
2178
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 | 2 | Engineering | 2 |
|
|
2179
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 | 3 | Finance | 7 |
|
|
2180
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 | 1 | IT Billing | 1 |
|
|
2181
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 | 2 | Engineering | 2 |
|
|
2182
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 | 3 | Finance | 7 |
|
|
2183
|
+
| 10 | James | 45 | Texas | 5000 | | 1 | IT Billing | 1 |
|
|
2184
|
+
| 10 | James | 45 | Texas | 5000 | | 2 | Engineering | 2 |
|
|
2185
|
+
| 10 | James | 45 | Texas | 5000 | | 3 | Finance | 7 |
|
|
2186
|
+
#+end_example
|
|
1878
2187
|
|
|
1879
2188
|
*** Set Operations
|
|
1880
2189
|
~FatTable~ can perform several set operations on pairs of tables. In order for
|
|
@@ -1886,66 +2195,67 @@ We'll use the following two set-compatible tables in the examples. They each
|
|
|
1886
2195
|
have some duplicates and some group boundaries so you can see the effect of the
|
|
1887
2196
|
set operations on duplicates and groups.
|
|
1888
2197
|
|
|
1889
|
-
#+BEGIN_SRC ruby
|
|
2198
|
+
#+BEGIN_SRC ruby
|
|
1890
2199
|
tab1.to_aoa
|
|
1891
2200
|
#+END_SRC
|
|
1892
2201
|
|
|
1893
|
-
#+
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
|
1898
|
-
|
|
|
1899
|
-
| T003 | 2016-11-01 | P |
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
|
1903
|
-
|
|
|
1904
|
-
| T006 | 2016-11-01 | S |
|
|
1905
|
-
|
|
|
1906
|
-
|
|
|
1907
|
-
|
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
|
1911
|
-
|
|
|
1912
|
-
| T012 | 2016-11-02 | P |
|
|
1913
|
-
|
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
|
1917
|
-
|
|
|
1918
|
-
|
|
2202
|
+
#+RESULTS:
|
|
2203
|
+
#+begin_example
|
|
2204
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2205
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2206
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2207
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2208
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2209
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2210
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2211
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2212
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2213
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2214
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2215
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2216
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2217
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2218
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2219
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2220
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2221
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2222
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2223
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2224
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2225
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2226
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2227
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2228
|
+
#+end_example
|
|
1919
2229
|
|
|
1920
|
-
#+BEGIN_SRC ruby
|
|
2230
|
+
#+BEGIN_SRC ruby
|
|
1921
2231
|
tab2.to_aoa
|
|
1922
2232
|
#+END_SRC
|
|
1923
2233
|
|
|
1924
|
-
#+
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
| T003 | 2016-11-01 | P |
|
|
1929
|
-
|
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
| T018 | 2016-11-01 | S | 7.
|
|
1933
|
-
|
|
|
1934
|
-
|
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
|
1938
|
-
| T015 | 2016-11-02 | P |
|
|
1939
|
-
|
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
|
1943
|
-
|
|
|
1944
|
-
| T021 | 2017-01-23 | P |
|
|
1945
|
-
|
|
2234
|
+
#+RESULTS:
|
|
2235
|
+
#+begin_example
|
|
2236
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2237
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2238
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2239
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2240
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
2241
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2242
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2243
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2244
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2245
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2246
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2247
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2248
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2249
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2250
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2251
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2252
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
2253
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
2254
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2255
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2256
|
+
#+end_example
|
|
1946
2257
|
|
|
1947
2258
|
**** Unions
|
|
1948
|
-
|
|
1949
2259
|
Two tables that are set-compatible can be combined with the ~union~ or
|
|
1950
2260
|
~union_all~ methods so that the rows of both tables appear in the output. In the
|
|
1951
2261
|
output table, the headers of the receiver table are used. You can use ~select~
|
|
@@ -1956,292 +2266,297 @@ Any group boundaries in the input tables are destroyed by ~union~ but are
|
|
|
1956
2266
|
preserved by ~union_all~. In addition, ~union_all~ (but not ~union~) adds a
|
|
1957
2267
|
group boundary between the rows of the two input tables.
|
|
1958
2268
|
|
|
1959
|
-
#+BEGIN_SRC ruby
|
|
2269
|
+
#+BEGIN_SRC ruby
|
|
1960
2270
|
tab1.union(tab2).to_aoa
|
|
1961
2271
|
#+END_SRC
|
|
1962
2272
|
|
|
1963
|
-
#+
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
|
1968
|
-
|
|
|
1969
|
-
|
|
|
1970
|
-
|
|
|
1971
|
-
|
|
|
1972
|
-
|
|
|
1973
|
-
|
|
|
1974
|
-
|
|
|
1975
|
-
|
|
|
1976
|
-
|
|
|
1977
|
-
|
|
|
1978
|
-
|
|
|
1979
|
-
|
|
|
1980
|
-
|
|
|
1981
|
-
|
|
|
1982
|
-
|
|
|
1983
|
-
|
|
|
1984
|
-
|
|
|
1985
|
-
|
|
|
1986
|
-
|
|
|
1987
|
-
|
|
2273
|
+
#+RESULTS:
|
|
2274
|
+
#+begin_example
|
|
2275
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2276
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2277
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2278
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2279
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2280
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2281
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2282
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2283
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2284
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2285
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2286
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2287
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2288
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2289
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2290
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2291
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2292
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2293
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
2294
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2295
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
2296
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
2297
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2298
|
+
#+end_example
|
|
1988
2299
|
|
|
1989
|
-
#+BEGIN_SRC ruby
|
|
2300
|
+
#+BEGIN_SRC ruby
|
|
1990
2301
|
tab1.union_all(tab2).to_aoa
|
|
1991
2302
|
#+END_SRC
|
|
1992
2303
|
|
|
1993
|
-
#+
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
|
1998
|
-
|
|
|
1999
|
-
| T003 | 2016-11-01 | P |
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
|
2003
|
-
|
|
|
2004
|
-
| T006 | 2016-11-01 | S |
|
|
2005
|
-
|
|
|
2006
|
-
|
|
|
2007
|
-
|
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
|
2011
|
-
|
|
|
2012
|
-
| T012 | 2016-11-02 | P |
|
|
2013
|
-
|
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
|
2017
|
-
|
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
| T003 | 2016-11-01 | P |
|
|
2021
|
-
|
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
| T018 | 2016-11-01 | S | 7.
|
|
2025
|
-
|
|
|
2026
|
-
|
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
|
2030
|
-
| T015 | 2016-11-02 | P |
|
|
2031
|
-
|
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
|
2035
|
-
|
|
|
2036
|
-
| T021 | 2017-01-23 | P |
|
|
2037
|
-
|
|
2304
|
+
#+RESULTS:
|
|
2305
|
+
#+begin_example
|
|
2306
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2307
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2308
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2309
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2310
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2311
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2312
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2313
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2314
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2315
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2316
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2317
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2318
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2319
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2320
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2321
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2322
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2323
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2324
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2325
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2326
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2327
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2328
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2329
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2330
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2331
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2332
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2333
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
2334
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2335
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2336
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2337
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2338
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2339
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2340
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2341
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2342
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2343
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2344
|
+
|------+------------+------+--------+-----+------+--------+-------+-------+--------+--------|
|
|
2345
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
2346
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
2347
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2348
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2349
|
+
#+end_example
|
|
2038
2350
|
|
|
2039
2351
|
**** Intersections
|
|
2040
|
-
|
|
2041
2352
|
The ~intersect~ method returns a table having only rows common to both tables,
|
|
2042
2353
|
eliminating any duplicate rows in the result.
|
|
2043
2354
|
|
|
2044
|
-
#+BEGIN_SRC ruby
|
|
2355
|
+
#+BEGIN_SRC ruby
|
|
2045
2356
|
tab1.intersect(tab2).to_aoa
|
|
2046
2357
|
#+END_SRC
|
|
2047
2358
|
|
|
2048
|
-
#+
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
|
2053
|
-
|
|
|
2054
|
-
|
|
|
2055
|
-
|
|
|
2056
|
-
|
|
|
2057
|
-
|
|
2359
|
+
#+RESULTS:
|
|
2360
|
+
#+begin_example
|
|
2361
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2362
|
+
|------+------------+------+--------+-----+------+--------+-----+------+--------+--------|
|
|
2363
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2364
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2365
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2366
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2367
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2368
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2369
|
+
#+end_example
|
|
2058
2370
|
|
|
2059
2371
|
With ~intersect_all~, all the rows of the first table, including duplicates, are
|
|
2060
2372
|
included in the result if they also occur in the second table. However,
|
|
2061
2373
|
duplicates in the second table do not appear.
|
|
2062
2374
|
|
|
2063
|
-
#+BEGIN_SRC ruby
|
|
2375
|
+
#+BEGIN_SRC ruby
|
|
2064
2376
|
tab1.intersect_all(tab2).to_aoa
|
|
2065
2377
|
#+END_SRC
|
|
2066
2378
|
|
|
2067
|
-
#+
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
| T003 | 2016-11-01 | P |
|
|
2072
|
-
| T006 | 2016-11-01 | S |
|
|
2073
|
-
|
|
|
2074
|
-
|
|
|
2075
|
-
|
|
|
2076
|
-
|
|
|
2077
|
-
|
|
2078
|
-
#+END_EXAMPLE
|
|
2379
|
+
#+RESULTS:
|
|
2380
|
+
#+begin_example
|
|
2381
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2382
|
+
|------+------------+------+--------+-----+------+--------+-----+------+--------+--------|
|
|
2383
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2384
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2385
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2386
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2387
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2388
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2389
|
+
#+end_example
|
|
2079
2390
|
|
|
2080
2391
|
As a result, it makes a difference which table is the receiver of the
|
|
2081
2392
|
~intersect_all~ method call and which is the argument. In other words, order of
|
|
2082
2393
|
operation matters.
|
|
2083
2394
|
|
|
2084
|
-
#+BEGIN_SRC ruby
|
|
2395
|
+
#+BEGIN_SRC ruby
|
|
2085
2396
|
tab2.intersect_all(tab1).to_aoa
|
|
2086
2397
|
#+END_SRC
|
|
2087
2398
|
|
|
2088
|
-
#+
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
| T003 | 2016-11-01 | P |
|
|
2093
|
-
| T006 | 2016-11-01 | S |
|
|
2094
|
-
| T007 | 2016-11-01 | S |
|
|
2095
|
-
| T014 | 2016-11-02 | P |
|
|
2096
|
-
| T015 | 2016-11-02 | P |
|
|
2097
|
-
|
|
|
2098
|
-
|
|
2099
|
-
#+END_EXAMPLE
|
|
2399
|
+
#+RESULTS:
|
|
2400
|
+
#+begin_example
|
|
2401
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2402
|
+
|------+------------+------+--------+-----+------+--------+-----+------+--------+--------|
|
|
2403
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2404
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2405
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2406
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2407
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2408
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2409
|
+
#+end_example
|
|
2100
2410
|
|
|
2101
2411
|
**** Set Differences with Except
|
|
2102
|
-
|
|
2103
2412
|
You can use the ~except~ method to delete from a table any rows that occur in
|
|
2104
2413
|
another table, that is, compute the set difference between the tables.
|
|
2105
2414
|
|
|
2106
|
-
#+BEGIN_SRC ruby
|
|
2415
|
+
#+BEGIN_SRC ruby
|
|
2107
2416
|
tab1.except(tab2).to_aoa
|
|
2108
2417
|
#+END_SRC
|
|
2109
2418
|
|
|
2110
|
-
#+
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
|
2115
|
-
|
|
|
2116
|
-
|
|
|
2117
|
-
|
|
|
2118
|
-
|
|
|
2119
|
-
|
|
|
2120
|
-
|
|
|
2121
|
-
|
|
|
2122
|
-
|
|
|
2123
|
-
|
|
2419
|
+
#+RESULTS:
|
|
2420
|
+
#+begin_example
|
|
2421
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2422
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2423
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2424
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2425
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2426
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2427
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2428
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2429
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2430
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2431
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2432
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2433
|
+
#+end_example
|
|
2124
2434
|
|
|
2125
2435
|
Like subtraction, though, the order of operands matters with set difference
|
|
2126
2436
|
computed by ~except~.
|
|
2127
2437
|
|
|
2128
|
-
#+BEGIN_SRC ruby
|
|
2438
|
+
#+BEGIN_SRC ruby
|
|
2129
2439
|
tab2.except(tab1).to_aoa
|
|
2130
2440
|
#+END_SRC
|
|
2131
2441
|
|
|
2132
|
-
#+
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
|
2137
|
-
|
|
|
2138
|
-
|
|
|
2139
|
-
|
|
|
2140
|
-
|
|
2442
|
+
#+RESULTS:
|
|
2443
|
+
#+begin_example
|
|
2444
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2445
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2446
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
2447
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2448
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
2449
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
2450
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2451
|
+
#+end_example
|
|
2141
2452
|
|
|
2142
2453
|
As with ~intersect_all~, ~except_all~ includes any duplicates in the first,
|
|
2143
2454
|
receiver table, but not those in the second, argument table.
|
|
2144
2455
|
|
|
2145
|
-
#+BEGIN_SRC ruby
|
|
2456
|
+
#+BEGIN_SRC ruby
|
|
2146
2457
|
tab1.except_all(tab2).to_aoa
|
|
2147
2458
|
#+END_SRC
|
|
2148
2459
|
|
|
2149
|
-
#+
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
|
2154
|
-
|
|
|
2155
|
-
|
|
|
2156
|
-
|
|
|
2157
|
-
|
|
|
2158
|
-
|
|
|
2159
|
-
|
|
|
2160
|
-
|
|
|
2161
|
-
| T012 | 2016-11-02 | P |
|
|
2162
|
-
|
|
|
2163
|
-
|
|
2460
|
+
#+RESULTS:
|
|
2461
|
+
#+begin_example
|
|
2462
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2463
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2464
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2465
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2466
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2467
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2468
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2469
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2470
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2471
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2472
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2473
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2474
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2475
|
+
#+end_example
|
|
2164
2476
|
|
|
2165
2477
|
And, of course, the order of operands matters here as well.
|
|
2166
2478
|
|
|
2167
|
-
#+BEGIN_SRC ruby
|
|
2479
|
+
#+BEGIN_SRC ruby
|
|
2168
2480
|
tab2.except_all(tab1).to_aoa
|
|
2169
2481
|
#+END_SRC
|
|
2170
2482
|
|
|
2171
|
-
#+
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
|
2176
|
-
| T018 | 2016-11-01 | S | 7.
|
|
2177
|
-
|
|
|
2178
|
-
|
|
|
2179
|
-
|
|
|
2180
|
-
| T021 | 2017-01-23 | P |
|
|
2181
|
-
|
|
2483
|
+
#+RESULTS:
|
|
2484
|
+
#+begin_example
|
|
2485
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2486
|
+
|------+------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
|
2487
|
+
| T017 | 2016-11-01 | P | 8.3000 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
|
2488
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2489
|
+
| T018 | 2016-11-01 | S | 7.1520 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
|
2490
|
+
| T019 | 2017-01-15 | S | 8.7500 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
|
2491
|
+
| T020 | 2017-01-19 | S | 8.2500 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
|
2492
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2493
|
+
| T021 | 2017-01-23 | P | 7.1600 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
|
2494
|
+
#+end_example
|
|
2182
2495
|
|
|
2183
2496
|
*** Uniq (aka Distinct)
|
|
2184
2497
|
The ~uniq~ method takes no arguments and simply removes any duplicate rows from
|
|
2185
2498
|
the input table. The ~distinct~ method is an alias for ~uniq~. Any groups in
|
|
2186
2499
|
the input table are lost.
|
|
2187
2500
|
|
|
2188
|
-
#+BEGIN_SRC ruby
|
|
2501
|
+
#+BEGIN_SRC ruby
|
|
2189
2502
|
tab1.uniq.to_aoa
|
|
2190
2503
|
#+END_SRC
|
|
2191
2504
|
|
|
2192
|
-
#+
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
|
2197
|
-
|
|
|
2198
|
-
|
|
|
2199
|
-
|
|
|
2200
|
-
|
|
|
2201
|
-
|
|
|
2202
|
-
|
|
|
2203
|
-
|
|
|
2204
|
-
|
|
|
2205
|
-
|
|
|
2206
|
-
|
|
|
2207
|
-
|
|
|
2208
|
-
|
|
|
2209
|
-
|
|
|
2210
|
-
|
|
|
2211
|
-
|
|
2505
|
+
#+RESULTS:
|
|
2506
|
+
#+begin_example
|
|
2507
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2508
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2509
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2510
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2511
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2512
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2513
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2514
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2515
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2516
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2517
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2518
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2519
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2520
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2521
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2522
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2523
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2524
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2525
|
+
#+end_example
|
|
2212
2526
|
|
|
2213
2527
|
*** Remove groups with degroup!
|
|
2214
2528
|
Finally, it is sometimes helpful to remove any group boundaries from a table.
|
|
2215
2529
|
You can do this with ~.degroup!~, which, together with ~force_string!~, are
|
|
2216
2530
|
the only operations that mutate their receiver tables.
|
|
2217
2531
|
|
|
2218
|
-
#+BEGIN_SRC ruby
|
|
2532
|
+
#+BEGIN_SRC ruby
|
|
2219
2533
|
tab1.degroup!.to_aoa
|
|
2220
2534
|
#+END_SRC
|
|
2221
2535
|
|
|
2222
|
-
#+
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
|
2227
|
-
|
|
|
2228
|
-
| T003 | 2016-11-01 | P |
|
|
2229
|
-
|
|
|
2230
|
-
|
|
|
2231
|
-
|
|
|
2232
|
-
| T006 | 2016-11-01 | S |
|
|
2233
|
-
|
|
|
2234
|
-
|
|
|
2235
|
-
|
|
|
2236
|
-
|
|
|
2237
|
-
|
|
|
2238
|
-
|
|
|
2239
|
-
| T012 | 2016-11-02 | P |
|
|
2240
|
-
|
|
|
2241
|
-
|
|
|
2242
|
-
|
|
|
2243
|
-
|
|
|
2244
|
-
|
|
2536
|
+
#+RESULTS:
|
|
2537
|
+
#+begin_example
|
|
2538
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | Lp | Qp | Iplp | Ipqp |
|
|
2539
|
+
|------+------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
|
2540
|
+
| T001 | 2016-11-01 | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2541
|
+
| T002 | 2016-11-01 | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2542
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2543
|
+
| T003 | 2016-11-01 | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
|
2544
|
+
| T004 | 2016-11-01 | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
|
2545
|
+
| T005 | 2016-11-01 | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
|
2546
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2547
|
+
| T006 | 2016-11-01 | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
|
2548
|
+
| T007 | 2016-11-01 | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
|
2549
|
+
| T008 | 2016-11-01 | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
|
2550
|
+
| T009 | 2016-11-01 | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
|
2551
|
+
| T010 | 2016-11-01 | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
|
2552
|
+
| T011 | 2016-11-02 | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2553
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2554
|
+
| T012 | 2016-11-02 | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
|
2555
|
+
| T013 | 2016-11-02 | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
|
2556
|
+
| T014 | 2016-11-02 | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
|
2557
|
+
| T015 | 2016-11-02 | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
|
2558
|
+
| T016 | 2016-11-02 | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
|
2559
|
+
#+end_example
|
|
2245
2560
|
|
|
2246
2561
|
** Formatting Tables
|
|
2247
2562
|
Besides creating and operating on tables, you may want to display the resulting
|
|
@@ -2289,11 +2604,12 @@ that, unlike to ~to_org~ formatter shown below, the intersections of lines are
|
|
|
2289
2604
|
represented by a ~+~ character. Embelishments such as color, bold, and so
|
|
2290
2605
|
forth are ignored.
|
|
2291
2606
|
|
|
2292
|
-
#+BEGIN_SRC ruby
|
|
2607
|
+
#+BEGIN_SRC ruby
|
|
2293
2608
|
tab_a.to_text
|
|
2294
2609
|
#+end_SRC
|
|
2295
2610
|
|
|
2296
|
-
#+
|
|
2611
|
+
#+RESULTS:
|
|
2612
|
+
#+begin_example
|
|
2297
2613
|
+====+=======+=====+============+========+============+
|
|
2298
2614
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2299
2615
|
+----+-------+-----+------------+--------+------------+
|
|
@@ -2306,10 +2622,9 @@ forth are ignored.
|
|
|
2306
2622
|
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
2307
2623
|
| 10 | James | 45 | Texas | 5000 | |
|
|
2308
2624
|
+====+=======+=====+============+========+============+
|
|
2309
|
-
#+
|
|
2625
|
+
#+end_example
|
|
2310
2626
|
|
|
2311
2627
|
***** To Org
|
|
2312
|
-
|
|
2313
2628
|
This formatter is designed to format tables in a manner consistent with the
|
|
2314
2629
|
way tables are drawn within Emacs Org Mode. It also uses nothing by ASCII
|
|
2315
2630
|
characters to draw the table, but, the intersections of lines are represented
|
|
@@ -2318,37 +2633,38 @@ ignored. When working in Org Mode, note that Emacs will convert an Array of
|
|
|
2318
2633
|
Arrays into an Org Mode table, so when constructing tables programmatically,
|
|
2319
2634
|
it may be better to use the =to_aoa= formatter shown below.
|
|
2320
2635
|
|
|
2321
|
-
#+begin_SRC ruby
|
|
2636
|
+
#+begin_SRC ruby
|
|
2322
2637
|
tab_a.to_org
|
|
2323
2638
|
#+end_SRC
|
|
2324
2639
|
|
|
2325
|
-
#+
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
|
2331
|
-
|
|
|
2332
|
-
|
|
|
2333
|
-
|
|
|
2334
|
-
|
|
|
2335
|
-
|
|
|
2336
|
-
|
|
|
2337
|
-
|
|
2338
|
-
|
|
2640
|
+
#+RESULTS:
|
|
2641
|
+
#+begin_example
|
|
2642
|
+
|----+-------+-----+------------+--------+------------------|
|
|
2643
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
2644
|
+
|----+-------+-----+------------+--------+------------------|
|
|
2645
|
+
| 1 | Paul | 32 | California | 20000 | [2001-07-13 Fri] |
|
|
2646
|
+
| 3 | Teddy | 23 | Norway | 20000 | [2007-12-13 Thu] |
|
|
2647
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | [2007-12-13 Thu] |
|
|
2648
|
+
| 5 | David | 27 | Texas | 85000 | [2007-12-13 Thu] |
|
|
2649
|
+
| 2 | Allen | 25 | Texas | | [2005-07-13 Wed] |
|
|
2650
|
+
| 8 | Paul | 24 | Houston | 20000 | [2005-07-13 Wed] |
|
|
2651
|
+
| 9 | James | 44 | Norway | 5000 | [2005-07-13 Wed] |
|
|
2652
|
+
| 10 | James | 45 | Texas | 5000 | |
|
|
2653
|
+
|----+-------+-----+------------+--------+------------------|
|
|
2654
|
+
#+end_example
|
|
2339
2655
|
|
|
2340
2656
|
***** To Term
|
|
2341
|
-
|
|
2342
2657
|
When outputting to a terminal or other device that can interpret ANSI
|
|
2343
2658
|
characters and escape codes, you can use this formatter to get a prettier
|
|
2344
2659
|
table. It also allows embelishments such as color and text styles to the
|
|
2345
2660
|
extent the device supports it.
|
|
2346
2661
|
|
|
2347
|
-
#+begin_SRC ruby
|
|
2662
|
+
#+begin_SRC ruby
|
|
2348
2663
|
tab_a.to_term
|
|
2349
2664
|
#+end_SRC
|
|
2350
2665
|
|
|
2351
|
-
#+
|
|
2666
|
+
#+RESULTS:
|
|
2667
|
+
#+begin_example
|
|
2352
2668
|
╒════╤═══════╤═════╤════════════╤════════╤════════════╕
|
|
2353
2669
|
│ Id │ Name │ Age │ Address │ Salary │ Join Date │
|
|
2354
2670
|
├────┼───────┼─────┼────────────┼────────┼────────────┤
|
|
@@ -2361,19 +2677,19 @@ extent the device supports it.
|
|
|
2361
2677
|
│ 9 │ James │ 44 │ Norway │ 5000 │ 2005-07-13 │
|
|
2362
2678
|
│ 10 │ James │ 45 │ Texas │ 5000 │ │
|
|
2363
2679
|
╘════╧═══════╧═════╧════════════╧════════╧════════════╛
|
|
2364
|
-
#+
|
|
2680
|
+
#+end_example
|
|
2365
2681
|
|
|
2366
2682
|
***** To LaTeX
|
|
2367
|
-
|
|
2368
2683
|
This formatter outputs a table in the form suitable for inclusion in a LaTeX
|
|
2369
2684
|
document using the ~logtable~ package. Natualy it allows embelishments such
|
|
2370
2685
|
as color and text styles to the full extent of LaTeX's formatting prowess.
|
|
2371
2686
|
|
|
2372
|
-
#+begin_SRC ruby
|
|
2687
|
+
#+begin_SRC ruby
|
|
2373
2688
|
tab_b.to_latex
|
|
2374
2689
|
#+end_SRC
|
|
2375
2690
|
|
|
2376
|
-
#+
|
|
2691
|
+
#+RESULTS:
|
|
2692
|
+
#+begin_example
|
|
2377
2693
|
\begin{longtable}{lll}
|
|
2378
2694
|
Id&
|
|
2379
2695
|
Dept&
|
|
@@ -2389,29 +2705,27 @@ Engineering&
|
|
|
2389
2705
|
Finance&
|
|
2390
2706
|
7\\
|
|
2391
2707
|
\end{longtable}
|
|
2392
|
-
#+
|
|
2708
|
+
#+end_example
|
|
2393
2709
|
|
|
2394
2710
|
***** To AoA (Array of Arrays)
|
|
2395
|
-
|
|
2396
|
-
#+begin_SRC ruby :wrap EXAMPLE
|
|
2711
|
+
#+begin_SRC ruby :results verbatim
|
|
2397
2712
|
tab_b.to_aoa
|
|
2398
2713
|
#+end_SRC
|
|
2399
2714
|
|
|
2400
|
-
#+
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
#+
|
|
2715
|
+
#+RESULTS:
|
|
2716
|
+
#+begin_example
|
|
2717
|
+
[["Id", "Dept", "Emp Id"], nil, ["1", "IT Billing", "1"], ["2", "Engineering", "2"], ["3", "Finance", "7"]]
|
|
2718
|
+
#+end_example
|
|
2404
2719
|
|
|
2405
2720
|
***** To AoH (Array of Hashes)
|
|
2406
|
-
|
|
2407
|
-
#+begin_SRC ruby :wrap EXAMPLE
|
|
2721
|
+
#+begin_SRC ruby :results verbatim
|
|
2408
2722
|
tab_b.to_aoh
|
|
2409
2723
|
#+end_SRC
|
|
2410
2724
|
|
|
2411
|
-
#+
|
|
2412
|
-
|
|
2413
|
-
{:id
|
|
2414
|
-
#+
|
|
2725
|
+
#+RESULTS:
|
|
2726
|
+
#+begin_example
|
|
2727
|
+
[{id: "1", dept: "IT Billing", emp_id: "1"}, {id: "2", dept: "Engineering", emp_id: "2"}, {id: "3", dept: "Finance", emp_id: "7"}]
|
|
2728
|
+
#+end_example
|
|
2415
2729
|
|
|
2416
2730
|
*** Formatting Directives
|
|
2417
2731
|
The formatting methods explained in the next section all take formatting
|
|
@@ -2424,7 +2738,6 @@ order, so '$R,' and ',$R' are equivalent.
|
|
|
2424
2738
|
Here is a list of all the formatting directives that apply to each cell type:
|
|
2425
2739
|
|
|
2426
2740
|
**** All Types as Strings
|
|
2427
|
-
|
|
2428
2741
|
For a string element, or any an element of any type (since these are applied
|
|
2429
2742
|
after the element has been converted to a String), the following instructions
|
|
2430
2743
|
are valid.
|
|
@@ -2453,7 +2766,6 @@ columns of a given type, it can be countermanded in formatting directives for
|
|
|
2453
2766
|
particular columns.
|
|
2454
2767
|
|
|
2455
2768
|
**** Numeric
|
|
2456
|
-
|
|
2457
2769
|
For a numeric element, all the instructions valid for string are available, in
|
|
2458
2770
|
addition to the following:
|
|
2459
2771
|
|
|
@@ -2477,17 +2789,16 @@ For example, the directive 'R5.0c[blue]' would right-align the numeric
|
|
|
2477
2789
|
element, pad it on the left with zeros, and color it blue.
|
|
2478
2790
|
|
|
2479
2791
|
**** DateTime
|
|
2480
|
-
|
|
2481
2792
|
For a ~DateTime~, all the instructions valid for string are available, in
|
|
2482
2793
|
addition to the following:
|
|
2483
2794
|
|
|
2484
|
-
- d[fmt] :: apply the format to a ~Date~ or a
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2795
|
+
- d[fmt] :: apply the format to a ~Date~ or a ~DateTime~ that is a whole day,
|
|
2796
|
+
that is that has no or zero hour, minute, and second components, where fmt
|
|
2797
|
+
is a valid format string for ~Date#strftime~, otherwise, the datetime will
|
|
2798
|
+
be formatted as an ISO 8601 string, YYYY-MM-DD.
|
|
2488
2799
|
- D[fmt] :: apply the format to a datetime that has at least a non-zero hour
|
|
2489
|
-
|
|
2490
|
-
|
|
2800
|
+
component where fmt is a valid format string for Date#strftime, otherwise,
|
|
2801
|
+
the datetime will be formatted as an ISO 8601 string, YYYY-MM-DD HH:MM:SS.
|
|
2491
2802
|
|
|
2492
2803
|
For example, 'c[pink]d[%b %-d, %Y]C', would format a date element like 'Sep
|
|
2493
2804
|
22, 1957', center it, and color it pink.
|
|
@@ -2511,7 +2822,6 @@ render a true boolean as ~Yeppers~ colored green on pink and render a false
|
|
|
2511
2822
|
boolean as ~Nope~ colored red on pink. See [[https://www.youtube.com/watch?v=oLdFFD8II8U][Yeppers]] for additional information.
|
|
2512
2823
|
|
|
2513
2824
|
**** NilClass
|
|
2514
|
-
|
|
2515
2825
|
By default, ~nil~ elements are rendered as blank cells, but you can make them
|
|
2516
2826
|
visible with the following, and in that case, all the formatting instructions
|
|
2517
2827
|
valid for strings are also available:
|
|
@@ -2522,7 +2832,6 @@ For example, you might want to use 'n[-]Cc[purple]' to make nils visible as a
|
|
|
2522
2832
|
centered purple hyphen.
|
|
2523
2833
|
|
|
2524
2834
|
*** The ~format~ and ~format_for~ methods
|
|
2525
|
-
|
|
2526
2835
|
Formatters take only two kinds of methods, those that attach footers to a
|
|
2527
2836
|
table, which are discussed in the next section, and those that specify
|
|
2528
2837
|
formatting for table cells, which are the subject of this section.
|
|
@@ -2546,7 +2855,7 @@ formatting for numerics in general and calls for the ~:id~ column to be padded
|
|
|
2546
2855
|
to three digits with zeros on the left (the '3.0' part) and to be centered
|
|
2547
2856
|
(the 'C' part).
|
|
2548
2857
|
|
|
2549
|
-
#+BEGIN_SRC ruby
|
|
2858
|
+
#+BEGIN_SRC ruby
|
|
2550
2859
|
tab_a.to_text do |f|
|
|
2551
2860
|
# Note: blat: is silently ignored
|
|
2552
2861
|
f.format(numeric: '0.0,R', id: '3.0C', blat: 'B')
|
|
@@ -2555,7 +2864,8 @@ to three digits with zeros on the left (the '3.0' part) and to be centered
|
|
|
2555
2864
|
end
|
|
2556
2865
|
#+END_SRC
|
|
2557
2866
|
|
|
2558
|
-
#+
|
|
2867
|
+
#+RESULTS:
|
|
2868
|
+
#+begin_example
|
|
2559
2869
|
+=====+=======+=====+============+========+============+
|
|
2560
2870
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2561
2871
|
+-----+-------+-----+------------+--------+------------+
|
|
@@ -2568,7 +2878,7 @@ to three digits with zeros on the left (the '3.0' part) and to be centered
|
|
|
2568
2878
|
| 009 | James | 44 | Norway | 5,000 | 2005-07-13 |
|
|
2569
2879
|
| 010 | James | 45 | Texas | 5,000 | |
|
|
2570
2880
|
+=====+=======+=====+============+========+============+
|
|
2571
|
-
#+
|
|
2881
|
+
#+end_example
|
|
2572
2882
|
|
|
2573
2883
|
In the example, the ~format~ method affects the whole table. Its ~numeric:~
|
|
2574
2884
|
directive affected the ~:age~ and ~:salary~ columns because their types are
|
|
@@ -2639,13 +2949,14 @@ be applied to all column types. Likewise, since all columns may contain nils,
|
|
|
2639
2949
|
the ~NilClass:~ type applies to nils in all columns regardless of the column's
|
|
2640
2950
|
type.
|
|
2641
2951
|
|
|
2642
|
-
#+BEGIN_SRC ruby
|
|
2952
|
+
#+BEGIN_SRC ruby
|
|
2643
2953
|
tab_a.to_text do |f|
|
|
2644
2954
|
f.format(string: 'R', id: '3.0C', nil: 'Cn[-]', salary: 'n[N/A]')
|
|
2645
2955
|
end
|
|
2646
2956
|
#+END_SRC
|
|
2647
2957
|
|
|
2648
|
-
#+
|
|
2958
|
+
#+RESULTS:
|
|
2959
|
+
#+begin_example
|
|
2649
2960
|
+=====+=======+=====+============+========+============+
|
|
2650
2961
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2651
2962
|
+-----+-------+-----+------------+--------+------------+
|
|
@@ -2653,12 +2964,12 @@ type.
|
|
|
2653
2964
|
| 003 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
2654
2965
|
| 004 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
2655
2966
|
| 005 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
2656
|
-
| 002 | Allen | 25 | Texas |
|
|
2967
|
+
| 002 | Allen | 25 | Texas | N/A | 2005-07-13 |
|
|
2657
2968
|
| 008 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
2658
|
-
| 009 | James | 44 | Norway |
|
|
2659
|
-
| 010 | James | 45 | Texas |
|
|
2969
|
+
| 009 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
2970
|
+
| 010 | James | 45 | Texas | 5000 | - |
|
|
2660
2971
|
+=====+=======+=====+============+========+============+
|
|
2661
|
-
#+
|
|
2972
|
+
#+end_example
|
|
2662
2973
|
|
|
2663
2974
|
The ~string: 'R'~ directive causes all the cells to be right-aligned except
|
|
2664
2975
|
~:id~ which specifies centering for the ~:id~ column only. The ~n[N/A]~
|
|
@@ -2667,7 +2978,6 @@ but not for other nils, such as in the last row of the ~:join_date~ column.
|
|
|
2667
2978
|
|
|
2668
2979
|
*** Footers
|
|
2669
2980
|
**** Adding Footers
|
|
2670
|
-
|
|
2671
2981
|
You can call the ~foot~, ~gfoot~, ~footer,~ or ~gfooter~, methods on
|
|
2672
2982
|
~Formatter~ objects to add footers and group footers. Note that all of these
|
|
2673
2983
|
methods return a ~Footer~ object that can be accessed to extract the computed
|
|
@@ -2725,7 +3035,6 @@ There are also a number of convenience methods for adding common footers:
|
|
|
2725
3035
|
columns with the label 'Group Maximum'.
|
|
2726
3036
|
|
|
2727
3037
|
**** Dynamic Labels
|
|
2728
|
-
|
|
2729
3038
|
Most of the time, you will want a fixed string as the label. However,
|
|
2730
3039
|
especially in the case of a group footer, you might want a dynamically
|
|
2731
3040
|
contructed label. You can use a proc or lambda for a label, and it will be
|
|
@@ -2734,32 +3043,33 @@ parameter, the footer object itself. This allows you to make the label a
|
|
|
2734
3043
|
function of other footer values, for example, you could make the label
|
|
2735
3044
|
include the most recent year from the date column:
|
|
2736
3045
|
|
|
2737
|
-
#+begin_src ruby
|
|
3046
|
+
#+begin_src ruby :eval no
|
|
2738
3047
|
fmtr.foot(label: -> (f) { "Average (latest year #{f.column(:date).max.year})" },
|
|
2739
3048
|
temp: :avg)
|
|
2740
3049
|
#+end_src
|
|
2741
3050
|
|
|
2742
|
-
In the case of a group footer, the lambda or proc may take either one or
|
|
3051
|
+
In the case of a group footer, the lambda or proc may take either one or two parameters.
|
|
2743
3052
|
If it takes one, the parameter is simply the 0-based number of the group:
|
|
2744
3053
|
|
|
2745
|
-
#+begin_src ruby
|
|
3054
|
+
#+begin_src ruby :eval no
|
|
2746
3055
|
fmtr.gfoot(label: -> (k) { "Group #{(k+1).to_roman} Average" }, temp: :avg)
|
|
2747
3056
|
#+end_src
|
|
3057
|
+
|
|
2748
3058
|
This would format the label with a roman numeral (assuming you defined a
|
|
2749
3059
|
method to do so) for the group number.
|
|
2750
3060
|
|
|
2751
3061
|
If it takes two arguments, the second argument is the footer itself, as with
|
|
2752
3062
|
non-group footers:
|
|
2753
3063
|
|
|
2754
|
-
#+begin_src ruby
|
|
3064
|
+
#+begin_src ruby :eval no
|
|
2755
3065
|
fmtr.gfoot(label: -> (k, f) { "Year #{f.column(:date, k).max.year} Group #{(k+1).to_roman} Average" },
|
|
2756
3066
|
temp: :avg)
|
|
2757
3067
|
#+end_src
|
|
3068
|
+
|
|
2758
3069
|
This would add the group's year to label, assuming the :date column of the
|
|
2759
3070
|
footer's table had the same year for each item in the group.
|
|
2760
3071
|
|
|
2761
3072
|
**** Aggregators
|
|
2762
|
-
|
|
2763
3073
|
When adding a footer with the above methods, you can specify an aggregator for
|
|
2764
3074
|
each column named in the ~agg_cols~ parameter. There are several candidates
|
|
2765
3075
|
for what you can use for an aggregator:
|
|
@@ -2775,7 +3085,7 @@ for what you can use for an aggregator:
|
|
|
2775
3085
|
In the case of datetime columns, these aggrgators convert the dates to
|
|
2776
3086
|
julian date numbers, perform the calculation, then convert the result back
|
|
2777
3087
|
to a datetime object.
|
|
2778
|
-
Apart from the built-in
|
|
3088
|
+
Apart from the built-in aggregators, you could define your own by opening the
|
|
2779
3089
|
FatTable::Column class and adding a suitable instance method. In that
|
|
2780
3090
|
case, the symbol could also refer to the method you defined.
|
|
2781
3091
|
- String :: using a string as an aggrgegator can result in:
|
|
@@ -2804,7 +3114,6 @@ for what you can use for an aggregator:
|
|
|
2804
3114
|
itself.
|
|
2805
3115
|
|
|
2806
3116
|
**** Footer objects
|
|
2807
|
-
|
|
2808
3117
|
Each of the methods for adding a footer to a ~Formatter~ returns a ~Footer~ object
|
|
2809
3118
|
that you can query for attributes of the generated footer, including accessing
|
|
2810
3119
|
their computed values. Here are the accessors available on a
|
|
@@ -2827,32 +3136,33 @@ their computed values. Here are the accessors available on a
|
|
|
2827
3136
|
~k~ to specify which group to access in the case of a group footer.
|
|
2828
3137
|
|
|
2829
3138
|
**** Footer Examples
|
|
2830
|
-
|
|
2831
3139
|
As a reminder, here is the table, ~tab_a~ defined earlier:
|
|
2832
3140
|
|
|
2833
|
-
#+BEGIN_SRC ruby
|
|
3141
|
+
#+BEGIN_SRC ruby
|
|
2834
3142
|
tab_a.to_aoa
|
|
2835
3143
|
#+END_SRC
|
|
2836
3144
|
|
|
2837
|
-
#+
|
|
2838
|
-
|
|
3145
|
+
#+RESULTS:
|
|
3146
|
+
#+begin_example
|
|
3147
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
2839
3148
|
|----+-------+-----+------------+--------+------------|
|
|
2840
|
-
|
|
|
2841
|
-
|
|
|
2842
|
-
|
|
|
2843
|
-
|
|
|
2844
|
-
|
|
|
2845
|
-
|
|
|
2846
|
-
|
|
|
3149
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
|
3150
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
3151
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
3152
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
3153
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
|
3154
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
3155
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
2847
3156
|
| 10 | James | 45 | Texas | 5000 | |
|
|
2848
|
-
#+
|
|
3157
|
+
#+end_example
|
|
2849
3158
|
|
|
2850
3159
|
***** Built-in Aggregators
|
|
2851
3160
|
You can add a footer compute the average of the given columns. You may be
|
|
2852
3161
|
surprised that you can average a set of dates, but ~:avg~ simply converts the
|
|
2853
3162
|
dates to Julian numbers, averages that, then converts the result back to a
|
|
2854
3163
|
date.
|
|
2855
|
-
|
|
3164
|
+
|
|
3165
|
+
#+BEGIN_SRC ruby
|
|
2856
3166
|
tab_a.to_text do |f|
|
|
2857
3167
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]')
|
|
2858
3168
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
@@ -2860,7 +3170,8 @@ date.
|
|
|
2860
3170
|
end
|
|
2861
3171
|
#+END_SRC
|
|
2862
3172
|
|
|
2863
|
-
#+
|
|
3173
|
+
#+RESULTS:
|
|
3174
|
+
#+begin_example
|
|
2864
3175
|
+=========+=======+=====+============+========+=============+
|
|
2865
3176
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2866
3177
|
+---------+-------+-----+------------+--------+-------------+
|
|
@@ -2877,14 +3188,15 @@ date.
|
|
|
2877
3188
|
+---------+-------+-----+------------+--------+-------------+
|
|
2878
3189
|
| Tally | | 8 | | | |
|
|
2879
3190
|
+=========+=======+=====+============+========+=============+
|
|
2880
|
-
#+
|
|
3191
|
+
#+end_example
|
|
2881
3192
|
|
|
2882
3193
|
***** String Aggregators
|
|
2883
3194
|
If the string is convertible into its columns's type, it will be converted to
|
|
2884
3195
|
that type; otherwise, it will be placed in the footer literally. This example
|
|
2885
3196
|
also shows how the values from one footer might be used in composing another
|
|
2886
3197
|
footer.
|
|
2887
|
-
|
|
3198
|
+
|
|
3199
|
+
#+BEGIN_SRC ruby
|
|
2888
3200
|
tab_a.to_text do |f|
|
|
2889
3201
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]')
|
|
2890
3202
|
avg_ft = f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
@@ -2900,7 +3212,8 @@ footer.
|
|
|
2900
3212
|
end
|
|
2901
3213
|
#+END_SRC
|
|
2902
3214
|
|
|
2903
|
-
#+
|
|
3215
|
+
#+RESULTS:
|
|
3216
|
+
#+begin_example
|
|
2904
3217
|
+=============+=======+=====+============+========+====================+
|
|
2905
3218
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2906
3219
|
+-------------+-------+-----+------------+--------+--------------------+
|
|
@@ -2923,14 +3236,14 @@ footer.
|
|
|
2923
3236
|
+-------------+-------+-----+------------+--------+--------------------+
|
|
2924
3237
|
| Comment | | | | | We're overspending |
|
|
2925
3238
|
+=============+=======+=====+============+========+====================+
|
|
2926
|
-
#+
|
|
3239
|
+
#+end_example
|
|
2927
3240
|
|
|
2928
3241
|
***** Ruby Objects
|
|
2929
3242
|
You can make the aggregator an normal ruby object, in which case it is just
|
|
2930
3243
|
inserted into the footer at the requested location. If its type is the same
|
|
2931
3244
|
as the column type, it participates in the formatting for that type and
|
|
2932
3245
|
column.
|
|
2933
|
-
#+BEGIN_SRC ruby
|
|
3246
|
+
#+BEGIN_SRC ruby
|
|
2934
3247
|
tab_a.to_text do |f|
|
|
2935
3248
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
2936
3249
|
f.footer('Report Date', age: :count, join_date: Date.today)
|
|
@@ -2938,7 +3251,8 @@ column.
|
|
|
2938
3251
|
end
|
|
2939
3252
|
#+END_SRC
|
|
2940
3253
|
|
|
2941
|
-
#+
|
|
3254
|
+
#+RESULTS:
|
|
3255
|
+
#+begin_example
|
|
2942
3256
|
+=============+=======+=====+============+========+=============+
|
|
2943
3257
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2944
3258
|
+-------------+-------+-----+------------+--------+-------------+
|
|
@@ -2953,12 +3267,12 @@ column.
|
|
|
2953
3267
|
+-------------+-------+-----+------------+--------+-------------+
|
|
2954
3268
|
| Average | | 31 | | 31,429 | 29-DEC-2005 |
|
|
2955
3269
|
+-------------+-------+-----+------------+--------+-------------+
|
|
2956
|
-
| Report Date | | 8 | | |
|
|
3270
|
+
| Report Date | | 8 | | | 28-DEC-2025 |
|
|
2957
3271
|
+=============+=======+=====+============+========+=============+
|
|
2958
|
-
#+
|
|
3272
|
+
#+end_example
|
|
2959
3273
|
|
|
2960
3274
|
But it can be any type. Here we pick a lottery winner from the employee ids.
|
|
2961
|
-
#+BEGIN_SRC ruby
|
|
3275
|
+
#+BEGIN_SRC ruby
|
|
2962
3276
|
tab_a.to_text do |f|
|
|
2963
3277
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
2964
3278
|
winner_id = tab_a.column(:id).items.sample
|
|
@@ -2967,7 +3281,8 @@ But it can be any type. Here we pick a lottery winner from the employee ids.
|
|
|
2967
3281
|
end
|
|
2968
3282
|
#+END_SRC
|
|
2969
3283
|
|
|
2970
|
-
#+
|
|
3284
|
+
#+RESULTS:
|
|
3285
|
+
#+begin_example
|
|
2971
3286
|
+================+=======+=====+============+========+=============+
|
|
2972
3287
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
2973
3288
|
+----------------+-------+-----+------------+--------+-------------+
|
|
@@ -2982,9 +3297,9 @@ But it can be any type. Here we pick a lottery winner from the employee ids.
|
|
|
2982
3297
|
+----------------+-------+-----+------------+--------+-------------+
|
|
2983
3298
|
| Average | | 31 | | 31,429 | 29-DEC-2005 |
|
|
2984
3299
|
+----------------+-------+-----+------------+--------+-------------+
|
|
2985
|
-
| Lottery Winner | | 8 | | |
|
|
3300
|
+
| Lottery Winner | | 8 | | | 9 |
|
|
2986
3301
|
+================+=======+=====+============+========+=============+
|
|
2987
|
-
#+
|
|
3302
|
+
#+end_example
|
|
2988
3303
|
|
|
2989
3304
|
***** Lambdas
|
|
2990
3305
|
Perhaps the most flexible form of aggregator is a lambda form. They can take
|
|
@@ -3007,7 +3322,7 @@ the things accessible with the footers, including the items in the current
|
|
|
3007
3322
|
column, through the ~f.items(c)~ accessor.
|
|
3008
3323
|
|
|
3009
3324
|
Compute the summ of the squares if the items in the ~:age~ column:
|
|
3010
|
-
#+BEGIN_SRC ruby
|
|
3325
|
+
#+BEGIN_SRC ruby
|
|
3011
3326
|
tab_a.to_text do |f|
|
|
3012
3327
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]')
|
|
3013
3328
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
@@ -3015,7 +3330,8 @@ Compute the summ of the squares if the items in the ~:age~ column:
|
|
|
3015
3330
|
end
|
|
3016
3331
|
#+END_SRC
|
|
3017
3332
|
|
|
3018
|
-
#+
|
|
3333
|
+
#+RESULTS:
|
|
3334
|
+
#+begin_example
|
|
3019
3335
|
+=========+=======+=====+============+========+=============+
|
|
3020
3336
|
| Id | Name | Age | Address | Salary | Join Date |
|
|
3021
3337
|
+---------+-------+-----+------------+--------+-------------+
|
|
@@ -3030,13 +3346,13 @@ Compute the summ of the squares if the items in the ~:age~ column:
|
|
|
3030
3346
|
+---------+-------+-----+------------+--------+-------------+
|
|
3031
3347
|
| Average | | 31 | | 31,429 | 29-DEC-2005 |
|
|
3032
3348
|
+---------+-------+-----+------------+--------+-------------+
|
|
3033
|
-
| SSQ | |
|
|
3349
|
+
| SSQ | | 810 | | | |
|
|
3034
3350
|
+=========+=======+=====+============+========+=============+
|
|
3035
|
-
#+
|
|
3351
|
+
#+end_example
|
|
3036
3352
|
|
|
3037
3353
|
Group the table according to the employee's year of joining, then compute the
|
|
3038
3354
|
summ of the squares if the ages in each group:
|
|
3039
|
-
#+BEGIN_SRC ruby
|
|
3355
|
+
#+BEGIN_SRC ruby
|
|
3040
3356
|
tab_a.order_with('join_date.year').to_text do |f|
|
|
3041
3357
|
f.format(numeric: '0.0R,', datetime: 'd[%v]D[%v]', sort_key: '0.0~,')
|
|
3042
3358
|
f.footer('Average', age: :avg, salary: :avg, join_date: :avg)
|
|
@@ -3045,7 +3361,8 @@ summ of the squares if the ages in each group:
|
|
|
3045
3361
|
end
|
|
3046
3362
|
#+END_SRC
|
|
3047
3363
|
|
|
3048
|
-
#+
|
|
3364
|
+
#+RESULTS:
|
|
3365
|
+
#+begin_example
|
|
3049
3366
|
+===========+=======+=====+============+========+=============+==========+
|
|
3050
3367
|
| Id | Name | Age | Address | Salary | Join Date | Sort Key |
|
|
3051
3368
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
|
@@ -3071,9 +3388,9 @@ summ of the squares if the ages in each group:
|
|
|
3071
3388
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
|
3072
3389
|
| Average | | 31 | | 31,429 | 29-DEC-2005 | |
|
|
3073
3390
|
+-----------+-------+-----+------------+--------+-------------+----------+
|
|
3074
|
-
| Total SSQ | |
|
|
3391
|
+
| Total SSQ | | 810 | | | | |
|
|
3075
3392
|
+===========+=======+=====+============+========+=============+==========+
|
|
3076
|
-
#+
|
|
3393
|
+
#+end_example
|
|
3077
3394
|
|
|
3078
3395
|
*** Invoking Formatters
|
|
3079
3396
|
As the examples show, one way to invoke the formatting methods is simply to
|
|
@@ -3082,40 +3399,41 @@ call one of the ~to_xxx~ methods directly on a table, which will yield a
|
|
|
3082
3399
|
convenient way to do it. But there are a few other ways.
|
|
3083
3400
|
|
|
3084
3401
|
**** By Instantiating a Formatter
|
|
3085
|
-
|
|
3086
3402
|
You can instantiate a ~XXXFormatter~ object and feed it a table as a
|
|
3087
3403
|
parameter. There is a Formatter subclass for each target output medium, for
|
|
3088
3404
|
example, ~AoaFormatter~ will produce a ruby array of arrays. You can then call
|
|
3089
3405
|
the ~output~ method on the ~XXXFormatter~.
|
|
3090
3406
|
|
|
3091
|
-
#+BEGIN_SRC ruby
|
|
3407
|
+
#+BEGIN_SRC ruby
|
|
3092
3408
|
FatTable::AoaFormatter.new(tab_a).output
|
|
3093
3409
|
#+END_SRC
|
|
3094
3410
|
|
|
3095
|
-
#+
|
|
3096
|
-
|
|
3411
|
+
#+RESULTS:
|
|
3412
|
+
#+begin_example
|
|
3413
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3097
3414
|
|----+-------+-----+------------+--------+------------|
|
|
3098
|
-
|
|
|
3099
|
-
|
|
|
3100
|
-
|
|
|
3101
|
-
|
|
|
3102
|
-
|
|
|
3103
|
-
|
|
|
3104
|
-
|
|
|
3415
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
|
3416
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
3417
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
3418
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
3419
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
|
3420
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
3421
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
3105
3422
|
| 10 | James | 45 | Texas | 5000 | |
|
|
3106
|
-
#+
|
|
3423
|
+
#+end_example
|
|
3107
3424
|
|
|
3108
3425
|
The ~XXXFormatter.new~ method yields the new instance to any block given, and
|
|
3109
3426
|
you can call methods on it to affect the formatting of the output:
|
|
3110
3427
|
|
|
3111
|
-
#+BEGIN_SRC ruby
|
|
3428
|
+
#+BEGIN_SRC ruby
|
|
3112
3429
|
FatTable::AoaFormatter.new(tab_a) do |f|
|
|
3113
3430
|
f.format(numeric: '0.0,R', id: '3.0C')
|
|
3114
3431
|
end.output
|
|
3115
3432
|
#+END_SRC
|
|
3116
3433
|
|
|
3117
|
-
#+
|
|
3118
|
-
|
|
3434
|
+
#+RESULTS:
|
|
3435
|
+
#+begin_example
|
|
3436
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3119
3437
|
|-----+-------+-----+------------+--------+------------|
|
|
3120
3438
|
| 001 | Paul | 32 | California | 20,000 | 2001-07-13 |
|
|
3121
3439
|
| 003 | Teddy | 23 | Norway | 20,000 | 2007-12-13 |
|
|
@@ -3125,44 +3443,45 @@ you can call methods on it to affect the formatting of the output:
|
|
|
3125
3443
|
| 008 | Paul | 24 | Houston | 20,000 | 2005-07-13 |
|
|
3126
3444
|
| 009 | James | 44 | Norway | 5,000 | 2005-07-13 |
|
|
3127
3445
|
| 010 | James | 45 | Texas | 5,000 | |
|
|
3128
|
-
#+
|
|
3446
|
+
#+end_example
|
|
3129
3447
|
|
|
3130
3448
|
**** By Using ~FatTable~ module-level method calls
|
|
3131
|
-
|
|
3132
3449
|
The ~FatTable~ module provides a set of methods of the form ~to_aoa~, ~to_text~,
|
|
3133
3450
|
etc., to access a ~Formatter~ without having to create an instance yourself.
|
|
3134
3451
|
Without a block, they apply the default formatting to the table and call the
|
|
3135
3452
|
~.output~ method automatically:
|
|
3136
3453
|
|
|
3137
|
-
#+BEGIN_SRC ruby
|
|
3454
|
+
#+BEGIN_SRC ruby
|
|
3138
3455
|
FatTable.to_aoa(tab_a)
|
|
3139
3456
|
#+END_SRC
|
|
3140
3457
|
|
|
3141
|
-
#+
|
|
3142
|
-
|
|
3458
|
+
#+RESULTS:
|
|
3459
|
+
#+begin_example
|
|
3460
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3143
3461
|
|----+-------+-----+------------+--------+------------|
|
|
3144
|
-
|
|
|
3145
|
-
|
|
|
3146
|
-
|
|
|
3147
|
-
|
|
|
3148
|
-
|
|
|
3149
|
-
|
|
|
3150
|
-
|
|
|
3462
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
|
3463
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
3464
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
3465
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
3466
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
|
3467
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
3468
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
3151
3469
|
| 10 | James | 45 | Texas | 5000 | |
|
|
3152
|
-
#+
|
|
3470
|
+
#+end_example
|
|
3153
3471
|
|
|
3154
3472
|
With a block, these methods yield a ~Formatter~ instance on which you can call
|
|
3155
3473
|
formatting and footer methods. The ~.output~ method is called on the ~Formatter~
|
|
3156
3474
|
automatically after the block:
|
|
3157
3475
|
|
|
3158
|
-
#+BEGIN_SRC ruby
|
|
3476
|
+
#+BEGIN_SRC ruby
|
|
3159
3477
|
FatTable.to_aoa(tab_a) do |f|
|
|
3160
3478
|
f.format(numeric: '0.0,R', id: '3.0C')
|
|
3161
3479
|
end
|
|
3162
3480
|
#+END_SRC
|
|
3163
3481
|
|
|
3164
|
-
#+
|
|
3165
|
-
|
|
3482
|
+
#+RESULTS:
|
|
3483
|
+
#+begin_example
|
|
3484
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3166
3485
|
|-----+-------+-----+------------+--------+------------|
|
|
3167
3486
|
| 001 | Paul | 32 | California | 20,000 | 2001-07-13 |
|
|
3168
3487
|
| 003 | Teddy | 23 | Norway | 20,000 | 2007-12-13 |
|
|
@@ -3172,53 +3491,54 @@ automatically after the block:
|
|
|
3172
3491
|
| 008 | Paul | 24 | Houston | 20,000 | 2005-07-13 |
|
|
3173
3492
|
| 009 | James | 44 | Norway | 5,000 | 2005-07-13 |
|
|
3174
3493
|
| 010 | James | 45 | Texas | 5,000 | |
|
|
3175
|
-
#+
|
|
3494
|
+
#+end_example
|
|
3176
3495
|
|
|
3177
3496
|
**** By Calling Methods on Table Objects
|
|
3178
|
-
|
|
3179
3497
|
Finally, as in many of the examples, you can call methods such as ~to_aoa~,
|
|
3180
3498
|
~to_text~, etc., directly on a Table:
|
|
3181
3499
|
|
|
3182
|
-
#+BEGIN_SRC ruby
|
|
3500
|
+
#+BEGIN_SRC ruby
|
|
3183
3501
|
tab_a.to_aoa
|
|
3184
3502
|
#+END_SRC
|
|
3185
3503
|
|
|
3186
|
-
#+
|
|
3187
|
-
|
|
3504
|
+
#+RESULTS:
|
|
3505
|
+
#+begin_example
|
|
3506
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3188
3507
|
|----+-------+-----+------------+--------+------------|
|
|
3189
|
-
|
|
|
3190
|
-
|
|
|
3191
|
-
|
|
|
3192
|
-
|
|
|
3193
|
-
|
|
|
3194
|
-
|
|
|
3195
|
-
|
|
|
3508
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
|
3509
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
|
3510
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
|
3511
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
|
3512
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
|
3513
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
|
3514
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
|
3196
3515
|
| 10 | James | 45 | Texas | 5000 | |
|
|
3197
|
-
#+
|
|
3516
|
+
#+end_example
|
|
3198
3517
|
|
|
3199
|
-
And you can supply a block to them
|
|
3518
|
+
And you can supply a block to them to specify formatting or footers:
|
|
3200
3519
|
|
|
3201
|
-
#+BEGIN_SRC ruby
|
|
3520
|
+
#+BEGIN_SRC ruby
|
|
3202
3521
|
tab_a.to_aoa do |f|
|
|
3203
|
-
f.format(numeric: '0.0,R', id: '3.0C')
|
|
3522
|
+
f.format(numeric: '$0.0,R', id: '3.0C')
|
|
3204
3523
|
f.sum_footer(:salary, :age)
|
|
3205
3524
|
end
|
|
3206
3525
|
#+END_SRC
|
|
3207
3526
|
|
|
3208
|
-
#+
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
|
3213
|
-
|
|
|
3214
|
-
|
|
|
3215
|
-
|
|
|
3216
|
-
|
|
|
3217
|
-
|
|
|
3218
|
-
|
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3527
|
+
#+RESULTS:
|
|
3528
|
+
#+begin_example
|
|
3529
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
|
3530
|
+
|-------+-------+------+------------+----------+------------|
|
|
3531
|
+
| 001 | Paul | $32 | California | $20,000 | 2001-07-13 |
|
|
3532
|
+
| 003 | Teddy | $23 | Norway | $20,000 | 2007-12-13 |
|
|
3533
|
+
| 004 | Mark | $25 | Rich-Mond | $65,000 | 2007-12-13 |
|
|
3534
|
+
| 005 | David | $27 | Texas | $85,000 | 2007-12-13 |
|
|
3535
|
+
| 002 | Allen | $25 | Texas | | 2005-07-13 |
|
|
3536
|
+
| 008 | Paul | $24 | Houston | $20,000 | 2005-07-13 |
|
|
3537
|
+
| 009 | James | $44 | Norway | $5,000 | 2005-07-13 |
|
|
3538
|
+
| 010 | James | $45 | Texas | $5,000 | |
|
|
3539
|
+
|-------+-------+------+------------+----------+------------|
|
|
3540
|
+
| Total | | $245 | | $220,000 | |
|
|
3541
|
+
#+end_example
|
|
3222
3542
|
|
|
3223
3543
|
* Development
|
|
3224
3544
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|