用lisp在emacs org table中进行电子表格计算

一句话,绝对不比excel计算功能弱,当然图形方面是没有的。对于编程者来讲,用鼠标拖拽操作还是用lisp编写计算公式哪个更符合思考的习惯,我觉得是后者。我这里只介绍lisp计算公式,如果关注简单的Calc计算公式,可以参考官方文档


如何引用表格中其他字段

推荐写法,@row_index$col_index

可以用C-c } 显示或者隐藏row_index和col_index

比如:

技术分享


如何插入公式

首先将光标定位到要计算的cell,然后可以通过菜单,tbl->calculat->set column formular, 也可以使用组合键: C-c = 或者C-u C-c =

然后在mini buffer中输入公式,回车。结果会在表格下面出现公式:

* 测试表格

#+CAPTION: DAU统计
| 日期   | 新增  | 日活  | VV    |
|--------+-------+-------+-------|
| <6>    | <l5>  | <l5>  | <l5>  |
| /      | <     | >     |       |
| 2015-05-01 | 10    | 20    | 51    |
| 2015-05-04 | 11    | 22    | 68    |
|        |       |       |  119  |
#+TBLFM: @6$4=‘(+ @4$4 @5$4);N

注意,这里采用了lisp计算公式,前面要用单引号防止过早求值,后面需要加上;N,据说是N模式,我目前还不是很理解这个模式。


如何重新计算

C-u C-c * 可以对整个表格重新计算(光标必须停留在表格上), 结果如下:

#+CAPTION: DAU统计
| 日期   | 新增  | 日活  | VV    |
|--------+-------+-------+-------|
| <6>    | <l5>  | <l5>  | <l5>  |
| /      | <     | >     |       |
| 2015-05-01 | 10    | 20    | 50    |
| 2015-05-04 | 11    | 22    | 68    |
|        |       |       | 118   |
#+TBLFM: @6$4=‘(+ @4$4 @5$4);N



如何对某列求和

有一种不需要编写公式就可以对某列求和的方式,将光标定位到某个cell,然后按下C-c + ,就会看到mini buffer的提示,然后按下S-Insert 键,就自动出现了求和的值。比如:

#+CAPTION: DAU统计
| 日期   | 新增  | 日活  | VV    |
|--------+-------+-------+-------|
| <6>    | <l5>  | <l5>  | <l5>  |
| /      | <     | >     |       |
| 2015-05-01 | 10    | 20    | 50    |
| 2015-05-04 | 11    | 22    | 68    |
|        |     21  |   42    |    118   |

但是我还是觉得用lisp公式比较好,便于维护,因为一旦数据发生了变动,只需要重新计算一次表格即可。

#+CAPTION: DAU统计
| 日期   | 新增  | 日活  | VV    |
|--------+-------+-------+-------|
| <6>    | <l5>  | <l5>  | <l5>  |
| /      | <     | >     |       |
| 2015-05-01 | 10    | 20    | 49    |
| 2015-05-04 | 11    | 22    | 68    |
|        | 21    | 42    | 117   |
#+TBLFM: @6$2=‘(+ @4$2..@5$2);N::@6$3=‘(+ @4$3..@5$3);N::@6$4=‘(+ @4$4..@5$4);N

首先,这里有三个计算公式,中间使用::分隔开来

然后引用范围的fields值可以用..表示from..to的语义。

最后,每次修改任何一个值,直接重新计算该表即可。这个方式比较好。


上面的公式还可以优化,可以使用相对位置指定最后一行:

#+CAPTION: DAU统计
|   日期 | 新增  | 日活  | VV    | 转化率 |
|--------+-------+-------+-------+--------|
|    <6> | <l5>  | <l5>  | <l5>  |        |
|      / | <     | >     |       |        |
| 2015-05-01 | 11    | 20    | 42    |        |
| 2015-05-04 | 12    | 20    | 61    |        |
| 2015-05-05 | 19    | 19    | 80    |        |
|        | 42    | 59    | 183   |        |
#+TBLFM: @7$2=‘(+ @4$2..@-1$2);N::@7$3=‘(+ @4$3..@-1$3);N::@7$4=‘(+ @4$4..@-1$4);N

-1 表示在@7的前一行,因此可以在中间插入任意多行,公式只需要修改@7为正确行数,就能够正确计算。

除法

elisp的除法就是/, 当出线浮点数就作为浮点除法,如果都是整数,就整除。

#+CAPTION: DAU统计
|   日期 | 新增 | 日活 |    VV |             转化率 |
|--------+------+------+-------+--------------------|
|    <6> |      |      |       |                    |
|      / |    < |    > |       |                    |
| 2015-05-01 |   11 |   20 |    42 |                    |
| 2015-05-04 |   11 |   20 |    41 |                    |
| 2015-05-05 |   22 |   40 |    84 |                    |
| 2015-05-06 |   41 |   81 |  68.0 |                    |
|    All |   85 |  161 | 235.0 | 1.4596273291925466 |
#+TBLFM: @8$2=‘(+ @4$2..@-1$2);N::@8$3=‘(+ @4$3..@-1$3);N::@8$4=‘(+ @4$4..@-1$4);N::@8$5=‘(/ @8$4 @8$3);N



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。