9

I am having a bit of trouble with code blocks that produce org tables to be later consumed by other code blocks. For example:

#+NAME: upper_air
#+BEGIN_SRC clojure :results output raw
  (clojure.pprint/print-table table)
#+END_SRC 

will produce

#+RESULTS: upper_air
|      :m | :degree | :meter/second |      :degC | :millibar |
|---------+---------+---------------+------------+-----------|
|  1545.0 |   175.0 |         12.36 |  15.400001 |     850.0 |
|  3162.0 |   265.0 |          6.69 |        4.8 |     700.0 |

but what I would really like is

#+TBLNAME: upper_air
|      :m | :degree | :meter/second |      :degC | :millibar |
|---------+---------+---------------+------------+-----------|
|  1545.0 |   175.0 |         12.36 |  15.400001 |     850.0 |
|  3162.0 |   265.0 |          6.69 |        4.8 |     700.0 |

(note #+RESULTS vs. #+TBLNAME) so that subsequently I can do something like

#+BEGIN_SRC ipython :session  :var data=upper_air
import numpy as np

arr = np.array(data)
p = arr[:,4]
#+END_SRC

With the #+RESULTS result, the second code block will interpret the data argument as a string instead of a data table and I will not be able to extract the data in a straightforward way. I could convert the ASCII data to a Python data structure 'manually', but I would prefer org handle it for me :-) Is there a way for either the first code block to output a #+TBLNAME instead of #+RESULTS? Alternatively, can the second code block coerce the argument as an org table instead of a string?

  • 2
    Normally, if a Babel source block is meant to produce a table, it generates a two-dimensional vector. If the Clojure code did that instead of generating a string, you wouldn't have to change anything in your code. Maybe try looking for a way to produce a vector in Clojure? – wvxvw Jul 30 '15 at 8:03
  • @wvxvw Thanks the comment. I guess I am a little confused here. I thought the entire point org mode is plain text. What you see is what you get. But you seem to be suggesting that the #+RESULTS block has some sort of data structure behind it which can be a String or some nested data structure. – Julien Chastang Jul 30 '15 at 17:22
  • 2
    Nope, that's not what I'm saying. I believe that clojure.pprint/print-table returns a string formatted as Org table, and since you set header argument to be output and raw, you get what you get. However, when you use it second time, Org doesn't read the resulting table, instead, it re-evaluates the Clojure block and feeds its result to the Python block. However, if the Clojure block produced a 2D array, you could change the result to be value and not raw for Org to format that result as a table, and you would get it as a 2D array in Python block. – wvxvw Jul 30 '15 at 19:09
  • @wvxvw Thanks again for helping me understand org-babel header arguments. After some experimentation, I can see what you describe does indeed seem to be the case, and I should be able to run with that. However, it appears I cannot I cannot use "richer"-style org-tables with hlines in particular as an intermediate format since these are strings and not data (e.g., Clojure nested vector) representations. At any rate, I have been super-happy with org-babel and consider it a superior alternative to Jupyter (if you are an emacs user, of course :-) ) Thanks again for your help. – Julien Chastang Jul 30 '15 at 21:46
6

You need to have your table block return an array (or vector or list, etc...) like this. You can get horizontal lines with None, or nil or whatever equivalent type in clojure.

#+NAME: upper_air
#+BEGIN_SRC python :results value
return [[":m", ":degree",":meter/second", ":degC", ":millibar"],
        None,
        [1545.0, 175.0, 12.36, 15.40001, 850.0],
        [3162.0, 265.0, 6.69, 4.8, 700.0]]

#+END_SRC

#+RESULTS: upper_air
|     :m | :degree | :meter/second |    :degC | :millibar |
|--------+---------+---------------+----------+-----------|
| 1545.0 |   175.0 |         12.36 | 15.40001 |     850.0 |
| 3162.0 |   265.0 |          6.69 |      4.8 |     700.0 | 


#+BEGIN_SRC python :results value  :var data=upper_air
import numpy as np

arr = np.array(data)
p = arr[:,4]
return p
#+END_SRC  

#+RESULTS:
| 850 | 700 |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.