Search code examples
pythonorg-modeorg-table

How to return multiple latex or org tables from an org-mode's source block?


My specific problem is that a lot of times I use python source blocks in org-mode to run the same statistical analysis on a lot of variables of a dataframe and then present them as latex tables. It becomes really tedious to do each analysis manually so I want to use a for loop:

#+begin_src python :exports results :session :results latex   
import pandas as pd   
df = pd.DataFrame({'a': [1, 2, 3, 4, 5],
                        'b': [9, 8, 7, 6, 5]})

for var in df.columns:
    df[var].value_counts().to_latex()
#+end_src

The problem is that it only returns the last value returned by the source block (last run of the for loop.

#+Results:
#+BEGIN_LaTeX
\begin{tabular}{lr}
\toprule
{} &  b \\
\midrule
7 &  1 \\
6 &  1 \\
5 &  1 \\
9 &  1 \\
8 &  1 \\
\bottomrule
\end{tabular}
#+END_LaTeX

So is there a way to actually get more than one latex or org table from a source block?

EDIT: Thinking on @dschwilk answer, what I would need is to return multiple #+Results blocks (one for every latex or org table) so that I may add text descriptions between them. Such as:

Description for table 1
#+RESULTS:
#+BEGIN_LaTeX
\begin{tabular}{lr}
\toprule
{} &  a \\
\midrule
5 &  1 \\
4 &  1 \\
3 &  1 \\
2 &  1 \\
1 &  1 \\
\bottomrule
\end{tabular}
#+END_LaTeX

Description for table 2    
#+RESULTS:
\begin{tabular}{lr}
\toprule
{} &  b \\
\midrule
7 &  1 \\
6 &  1 \\
5 &  1 \\
9 &  1 \\
8 &  1 \\
\bottomrule
\end{tabular}
#+END_LaTeX

Solution

  • I managed to get something close to what I want but I have to run multiple src_blocks (which I really wanted to avoid).

    I have a source block that creates all the tables and stores them on a list and make a new src_block for each table and return it.

    For example:

    #+begin_src python :exports results :session :results silent)
      import pandas as pd
      results_tables = []
      d = pd.DataFrame({'a': [1, 2, 3, 4, 5],
                        'b': [9, 8, 7, 6, 5]})
    
      for var in d.columns:
          results_tables.append(d[var].value_counts().to_latex())
    #+end_src
    
    #+RESULTS:
    #+begin_src python :exports results :session :results latex
    results_tables[0]
    #+end_src
    
    #+RESULTS:
    #+BEGIN_LaTeX
    \begin{tabular}{lr}
    \toprule
    {} &  a \\
    \midrule
    5 &  1 \\
    4 &  1 \\
    3 &  1 \\
    2 &  1 \\
    1 &  1 \\
    \bottomrule
    \end{tabular}
    #+END_LaTeX
    
    #+begin_src python :exports results :session :results latex
    results_tables[1]
    #+end_src
    
    #+RESULTS:
    #+BEGIN_LaTeX
    \begin{tabular}{lr}
    \toprule
    {} &  b \\
    \midrule
    7 &  1 \\
    6 &  1 \\
    5 &  1 \\
    9 &  1 \\
    8 &  1 \\
    \bottomrule
    \end{tabular}
    #+END_LaTeX