原文Org tutorial on table lookup functions, 由 Jarmo Hurri 編輯示血,維護(hù)腋腮。本文只做學(xué)習(xí)之用宴卖。
序言
Org
提供三個(gè)不同的函數(shù)席纽,用于在表中執(zhí)行搜索和數(shù)據(jù)依賴的計(jì)算赖欣。 這些函數(shù)可以用于實(shí)現(xiàn)數(shù)組關(guān)聯(lián)屑彻,統(tǒng)計(jì)匹配單元格验庙,結(jié)果排名或分組數(shù)據(jù)。 以下示例將有助于開始使用這些功能社牲。
具有唯一鍵的關(guān)聯(lián)數(shù)組
查找最直接的用法是將 Org
表的一部分視為關(guān)聯(lián)數(shù)組:一個(gè)鍵可用于查找相應(yīng)的值粪薛。
假設(shè)你去斯堪的納維亞,并且想跟蹤你花了多少錢在旅途中搏恤。 你決定將所有金額轉(zhuǎn)換為歐元违寿。 在行程之前,你請(qǐng)記下大致匯率,如下表所示:
#+TBLNAME: rates
| currency | abbreviation | euros |
|-----------------+--------------+-------|
| euro | eur | 1 |
| Norwegian krone | nok | 0.14 |
| Swedish krona | sek | 0.12 |
| US dollar | usd | 0.77 |
接下來將使用函數(shù) org-lookup-first
和前面的匯率表格來自動(dòng)將不同貨幣的金額轉(zhuǎn)換成歐元挑社。 函數(shù) org-lookup-first
的簽名如下:
(org-lookup-first VAL S-LIST R-LIST &optional PREDICATE)
假定 PREDICATE
為 nil
陨界,在這種情況下使用默認(rèn)謂詞(predicate) equal
, 則該函數(shù)將在 S-LIST
中搜索 VAL
的第一個(gè)實(shí)例痛阻,并從 R-LIST
中的相應(yīng)位置返回一個(gè)值菌瘪。 在下表中,每筆金額分配了貨幣縮寫; 對(duì)于相應(yīng)的縮寫阱当,在匯率表格的第二列中進(jìn)行查找俏扩,然后從第三列返回相應(yīng)的匯率。 對(duì)于每一行只需要填充前四列; 第5列和第6列自動(dòng)計(jì)算產(chǎn)生弊添。 請(qǐng)注意豺撑,如果找不到鍵值茶行,則會(huì)出現(xiàn)錯(cuò)誤:在最后一行中,空鍵將被搜索。
| date | expense | sum | currency | rate | euros |
|-------+------------------+------+----------+--------+--------|
| 1.3. | flights | 324 | eur | 1 | 324 |
| 4.6. | books and maps | 243 | usd | 0.77 | 187.11 |
| 30.7. | rental car | 8300 | sek | 0.12 | 996. |
| 2.7. | hotel | 1150 | sek | 0.12 | 138. |
| 2.7. | lunch | 190 | sek | 0.12 | 22.8 |
| 3.7. | fishing licenses | 1400 | nok | 0.14 | 196. |
| 3.7. | gasoline | 340 | | #ERROR | #ERROR |
#+TBLFM: $5='(org-lookup-first $4 '(remote(rates,@2$2..@>$2)) '(remote(rates,@2$3..@>$3)))::$6=$5*$3
多個(gè)匹配優(yōu)先排序
教師的常見任務(wù)是從總分中分配考試成績(jī)对嚼。 這種分級(jí)的起點(diǎn)是具有等級(jí)邊界的表。 以下是一個(gè)這樣的表域携,其中行按照特定等級(jí)所需的下限的遞增排序巴帮。
#+TBLNAME: grade-boundaries
| lower bound | grade |
|-------------+-------|
| 0 | F |
| 10 | D |
| 20 | C |
| 30 | B |
| 40 | A |
使用函數(shù) org-lookup-last
和根據(jù)前面的 等級(jí)邊界
表來為學(xué)生分配成績(jī)。 函數(shù) org-lookup-last
的簽名與 org-lookup-first
的完全相同:
(org-lookup-last VAL S-LIST R-LIST &optional PREDICATE)
函數(shù) org-lookup-last
會(huì)搜索 S-LIST
中的最后一個(gè)匹配項(xiàng)瞬女,并從 R-LIST
中的相應(yīng)位置返回一個(gè)值窍帝。 用于分配等級(jí)的查找思想如下:假定學(xué)生的考試成績(jī)是33分。我們尋找學(xué)生的 marks 大于或等于下限的表中的最后一行; 在這種情況下诽偷,它是下邊界的行30坤学。學(xué)生的成績(jī)是第二列的相應(yīng)元素,在這種情況下是B.
因此报慕,給定學(xué)生的標(biāo)記數(shù)VAL深浮,找到下限S滿足 (>= VAL S)
的表等級(jí)邊界的第一列的最后一行。 因此眠冈,我們將使用 >=
作為 PREDICATE
來執(zhí)行匹配略号。 注意, VAL
和 S
按照它們?cè)?org-lookup-last
的簽名中的順序被分配給謂詞,其中 VAL
在 S-LIST
之前玄柠。 下表列出了從總 marks 到最終成績(jī)的轉(zhuǎn)換突梦。 注: 文字插值 L
表示表值的字面值插入到Elisp公式中,這是必須的羽利,因?yàn)橐恍┲凳菙?shù)字宫患,一些是符號(hào)。
| student | marks | grade |
|---------+-------+-------|
| X | 30 | B |
| Y | 29 | C |
| Z | 5 | F |
| W | 55 | A |
#+TBLFM: $3='(org-lookup-last $2 '(remote(grade-boundaries,@2$1..@>$1)) '(remote(grade-boundaries,@2$2..@>$2)) '>=);L
統(tǒng)計(jì)匹配單元格
函數(shù) org-lookup-all
不能在表等式中使用自己这弧,因?yàn)樗祷刂盗斜怼?但是娃闲,通過將函數(shù)與其他 elisp 函數(shù)相結(jié)合,可執(zhí)行強(qiáng)大的查找任務(wù)匾浪。
作為一個(gè)簡(jiǎn)單的例子皇帮,計(jì)算表中缺少值的數(shù)量。 函數(shù) org-lookup-all
的簽名與其他兩個(gè)查找函數(shù)的簽名完全相同:
(org-lookup-all VAL S-LIST R-LIST &optional PREDICATE)
數(shù)搜索 S-LIST
中的所有匹配項(xiàng)蛋辈,并從 R-LIST
中的相應(yīng)位置返回所有相應(yīng)的值属拾。 與org-lookup-first和org-lookup-last的情況一樣,如果 R-LIST
為nil冷溶,則直接返回 S-LIST
相應(yīng)匹配值渐白。 注意使用 E
標(biāo)志來保留范圍內(nèi)的空字段。 還要注意逞频,在這種情況下纯衍,以真正的二維范圍來進(jìn)行查找,這也是可能的
| group | round 1 | round 2 |
|-------+---------+---------|
| A | | 2.4 |
| B | 4.7 | 11 |
| C | | |
| D | 5 | |
| E | | 7.2 |
| F | 3.2 | 4.3 |
| G | | 4.4 |
| H | | 8 |
|-------+---------+---------|
| total | missing | 7 |
#+TBLFM: @>$3='(length(org-lookup-all "" '(@2$2..@-1$3) nil));E
排序結(jié)果
org-lookup-all
的另一個(gè)示例應(yīng)用是結(jié)果的自動(dòng)排序苗胀。 在下表中襟诸,總數(shù)越大越好。 請(qǐng)注意基协,Elisp表達(dá)式還自動(dòng)處理關(guān)聯(lián)關(guān)系歌亲。
| group | marks | rank |
|-------+-------+------|
| A | 22 | 2 |
| B | 22 | 2 |
| C | 14 | 4 |
| D | 28 | 1 |
| E | 9 | 5 |
#+TBLFM: $3='(+ 1 (length (org-lookup-all $2 '(@2$2..@>$2) nil '<)));N
統(tǒng)計(jì)原始數(shù)據(jù)的頻率
數(shù)據(jù)分析中的常見情況是對(duì)可視化的原始數(shù)據(jù)值進(jìn)行分類(分組)。 通常是通過統(tǒng)計(jì)在特定范圍內(nèi)的出現(xiàn)頻率來完成的堡掏。 可使用函數(shù) org-lookup-all
,結(jié)合其他 elisp 函數(shù)來執(zhí)行此任務(wù)刨疼。 此示例還顯示了如何使用表中的多個(gè)值構(gòu)建更復(fù)雜的查找規(guī)則泉唁。
考慮下表,不同組A-I的不同結(jié)果揩慕。
#+TBLNAME: raw-data
| group | result |
|-------+--------|
| A | 2.3 |
| B | 4.2 |
| C | 1.1 |
| D | 3.6 |
| E | 4.5 |
| F | 2.4 |
| G | 1.0 |
| H | 2.3 |
| I | 2.8 |
將結(jié)果分為不同的亭畜,并且相斥的類。 例如迎卤,屬于第一類的值在區(qū)間 [1拴鸵,1.9]
(包括端點(diǎn))中。 為了執(zhí)行這樣的分類,我們定義了以下兩參數(shù)謂詞函數(shù) in-interval
劲藐。 請(qǐng)注意八堡,此函數(shù)的第一個(gè)參數(shù)是一對(duì),其第一個(gè)元素是下限聘芜,第二個(gè)成員是該間隔的上限兄渺。
#+BEGIN_SRC emacs-lisp
(defun in-interval (bounds el)
(and (>= el (car bounds)) (<= el (cadr bounds))))
#+END_SRC
#+RESULTS:
: in-interval
使用這個(gè)謂詞函數(shù),我們可以構(gòu)造一個(gè)具有分類邊界和相應(yīng)頻率的表汰现。 請(qǐng)注意挂谍,函數(shù) org-lookup-all
的第一個(gè)參數(shù)是作為第一個(gè)參數(shù)傳遞給謂詞 in-interval
中的第一個(gè)參數(shù),是一對(duì)邊界瞎饲。
| lower bound | upper bound | frequency |
|-------------+-------------+-----------|
| 1 | 1.9 | 2 |
| 2 | 2.9 | 4 |
| 3 | 3.9 | 1 |
| 4 | 4.9 | 2 |
#+TBLFM: $3='(length (org-lookup-all '($1 $2) '(remote(raw-data,@2$2..@>$2)) nil 'in-interval));N
結(jié)論
Org 的 lookup
函數(shù)可用于大量不同的數(shù)據(jù)相關(guān)計(jì)算口叙。 例如,libreoffice或Excel用戶熟悉的以下電子表格操作都可以使用它們來實(shí)現(xiàn): HLOOKUP
嗅战, VLOOKUP
妄田, COUNTIF
, SUMIF
和 FREQUENCY
仗哨。