Ben
Ben

Reputation: 873

org table and named columns for babel processing

Data in an org table can be processed (row-by-row) in src blocks like so:

#+NAME: test-table
| a | b |
|---+---|
| 1 | 2 |
| 3 | 4 |

#+NAME: test-table-script
#+BEGIN_SRC emacs-lisp :var table=test-table
  (mapcar (lambda (x) (cadr x)) table)
#+END_SRC

#+RESULTS: test-table-script
| 2 | 4 |

In the example above, though, the table is only available through the table variable, and I have to pull the elements in each row/column out manually.

In the case that the original table has column names (as in the case above) is there a way to have the values columns of the table automatically bound to those variables (a and b in the example table) in a BEGIN_SRC block?

Upvotes: 1

Views: 908

Answers (1)

Mark Clements
Mark Clements

Reputation: 130

The following solution uses org-babel-get-colnames and cl-destructuring-bind. Note that the table colnames are strings and need to be interned. The example shows the original data with an additional column.

#+NAME: test-table-script
#+BEGIN_SRC emacs-lisp :var table=test-table :colnames no
  (require 'cl)
  (defmacro with-table (table expression)
    "Given an org table with colnames, evaluate an expression using the colnames.
Note: use ':colnames no' in the header -- this imports the colnames 
but does not export them."
    `(let* ((table-with-colnames (org-babel-get-colnames ,table))
        (names (loop for name in (cdr table-with-colnames)
             collect (if (stringp name) (intern name) name))))
       (funcall
    `(lambda (data)
           (mapcar (lambda (row)
                 (cl-destructuring-bind ,names row ,',expression))
               data))
    (car table-with-colnames))))

  ;; example to add a third column
  (cons '(a b c) (cons 'hline (with-table table (list a b (+ a b)))))
#+END_SRC

With output:

#+RESULTS: test-table-script
| a | b | c |
|---+---+---|
| 1 | 2 | 3 |
| 3 | 4 | 7 |

This approach could be readily extended to transform columns, either replacing values or adding a new column. The macro could also be improved through the addition of some gensym's.

Upvotes: 1

Related Questions