Org-mode也有Excel一樣的LOOKUP

原文Org tutorial on table lookup functions, 由 Jarmo Hurri 編輯,維護。本文只做學習之用。

序言

Org 提供三個不同的函數,用于在表中執行搜索和數據依賴的計算。 這些函數可以用于實現數組關聯,統計匹配單元格,結果排名或分組數據。 以下示例將有助于開始使用這些功能。

具有唯一鍵的關聯數組

查找最直接的用法是將 Org 表的一部分視為關聯數組:一個鍵可用于查找相應的值。

假設你去斯堪的納維亞,并且想跟蹤你花了多少錢在旅途中。 你決定將所有金額轉換為歐元。 在行程之前,你請記下大致匯率,如下表所示:

 #+TBLNAME: rates
| currency        | abbreviation | euros |
|-----------------+--------------+-------|
| euro            | eur          |     1 |
| Norwegian krone | nok          |  0.14 |
| Swedish krona   | sek          |  0.12 |
| US dollar       | usd          |  0.77 |

接下來將使用函數 org-lookup-first 和前面的匯率表格來自動將不同貨幣的金額轉換成歐元。 函數 org-lookup-first 的簽名如下:

(org-lookup-first VAL S-LIST R-LIST &optional PREDICATE)

假定 PREDICATEnil ,在這種情況下使用默認謂詞(predicate) equal , 則該函數將在 S-LIST 中搜索 VAL 的第一個實例,并從 R-LIST 中的相應位置返回一個值。 在下表中,每筆金額分配了貨幣縮寫; 對于相應的縮寫,在匯率表格的第二列中進行查找,然后從第三列返回相應的匯率。 對于每一行只需要填充前四列; 第5列和第6列自動計算產生。 請注意,如果找不到鍵值,則會出現錯誤:在最后一行中,空鍵將被搜索。

|  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

多個匹配優先排序

教師的常見任務是從總分中分配考試成績。 這種分級的起點是具有等級邊界的表。 以下是一個這樣的表,其中行按照特定等級所需的下限的遞增排序。

 #+TBLNAME: grade-boundaries
| lower bound | grade |
|-------------+-------|
|           0 | F     |
|          10 | D     |
|          20 | C     |
|          30 | B     |
|          40 | A     |

使用函數 org-lookup-last 和根據前面的 等級邊界 表來為學生分配成績。 函數 org-lookup-last 的簽名與 org-lookup-first 的完全相同:

(org-lookup-last VAL S-LIST R-LIST &optional PREDICATE)

函數 org-lookup-last 會搜索 S-LIST 中的最后一個匹配項,并從 R-LIST 中的相應位置返回一個值。 用于分配等級的查找思想如下:假定學生的考試成績是33分。我們尋找學生的 marks 大于或等于下限的表中的最后一行; 在這種情況下,它是下邊界的行30。學生的成績是第二列的相應元素,在這種情況下是B.

因此,給定學生的標記數VAL,找到下限S滿足 (>= VAL S) 的表等級邊界的第一列的最后一行。 因此,我們將使用 >= 作為 PREDICATE 來執行匹配。 注意, VALS 按照它們在 org-lookup-last 的簽名中的順序被分配給謂詞,其中 VALS-LIST 之前。 下表列出了從總 marks 到最終成績的轉換。 注: 文字插值 L 表示表值的字面值插入到Elisp公式中,這是必須的,因為一些值是數字,一些是符號。

| 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

統計匹配單元格

函數 org-lookup-all 不能在表等式中使用自己,因為它返回值列表。 但是,通過將函數與其他 elisp 函數相結合,可執行強大的查找任務。

作為一個簡單的例子,計算表中缺少值的數量。 函數 org-lookup-all 的簽名與其他兩個查找函數的簽名完全相同:

(org-lookup-all VAL S-LIST R-LIST &optional PREDICATE)

數搜索 S-LIST 中的所有匹配項,并從 R-LIST 中的相應位置返回所有相應的值。 與org-lookup-first和org-lookup-last的情況一樣,如果 R-LIST 為nil,則直接返回 S-LIST 相應匹配值。 注意使用 E 標志來保留范圍內的空字段。 還要注意,在這種情況下,以真正的二維范圍來進行查找,這也是可能的

| 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

排序結果

org-lookup-all 的另一個示例應用是結果的自動排序。 在下表中,總數越大越好。 請注意,Elisp表達式還自動處理關聯關系。

| 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

統計原始數據的頻率

數據分析中的常見情況是對可視化的原始數據值進行分類(分組)。 通常是通過統計在特定范圍內的出現頻率來完成的。 可使用函數 org-lookup-all ,結合其他 elisp 函數來執行此任務。 此示例還顯示了如何使用表中的多個值構建更復雜的查找規則。

考慮下表,不同組A-I的不同結果。

 #+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 |

將結果分為不同的,并且相斥的類。 例如,屬于第一類的值在區間 [1,1.9] (包括端點)中。 為了執行這樣的分類,我們定義了以下兩參數謂詞函數 in-interval 。 請注意,此函數的第一個參數是一對,其第一個元素是下限,第二個成員是該間隔的上限。

#+BEGIN_SRC emacs-lisp
  (defun in-interval (bounds el)
    (and (>= el (car bounds)) (<= el (cadr bounds))))
#+END_SRC

#+RESULTS:
: in-interval

使用這個謂詞函數,我們可以構造一個具有分類邊界和相應頻率的表。 請注意,函數 org-lookup-all 的第一個參數是作為第一個參數傳遞給謂詞 in-interval 中的第一個參數,是一對邊界。

| 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

結論

Org 的 lookup 函數可用于大量不同的數據相關計算。 例如,libreoffice或Excel用戶熟悉的以下電子表格操作都可以使用它們來實現: HLOOKUPVLOOKUPCOUNTIFSUMIFFREQUENCY

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容