2

I found here in the org manual how to output from an org-babel source-code block to an org-mode table, namely through something like

#+header :results output table

I have had some trouble getting org-mode to interpret separator rows in output correctly, however, Here is an example

  #+name: stack_overflow_mve
  #+header: :exports results
  #+header: :results output table
  #+begin_src C++ :noweb yes :results output :flags -std=c++14 :includes '(<algorithm> <functional> <iostream> <cmath> <string.h> <stdio.h> <stdlib.h> <iomanip>)"
    double means   [] {0.23, 0.77,     2.05,    3.8,   6.35};
    double stddevs [] {0,    0.763675, 2.28184, 3.965, 6.65608};
    size_t total_count = sizeof(means) / sizeof(means[0]);
    std::cout << "count " << "mean " << "std_dev" << std::endl;
    std::cout << "-----|" << "----|" << "------|" << std::endl;
    for (size_t count = 0; count < total_count; ++count) {
        std::cout << count + 1      << " ";
        std::cout << means[count]   << " ";
        std::cout << stddevs[count] << " " << std::endl;
    }
  #+end_src

The code block above produces the following almost-table. As you can see, the separators on the second line are not correct. That incorrectness hinders my ability to feed the table to some later code blocks without manual intervention.

  #+RESULTS: stack_overflow_mve
  | count | mean |  std_dev |
  | ----- | ---- |   ------ |
  |     1 | 0.23 |        0 |
  |     2 | 0.77 | 0.763675 |
  |     3 | 2.05 |  2.28184 |
  |     4 |  3.8 |    3.965 |
  |     5 | 6.35 |  6.65608 |

If I put the cursor inside the table on the second line, replace the first space with a - and press TAB, org-mode corrects it to the following:

  | count | mean |  std_dev |
  |-------+------+----------|
  |     1 | 0.23 |        0 |
  |     2 | 0.77 | 0.763675 |
  |     3 | 2.05 |  2.28184 |
  |     4 |  3.8 |    3.965 |
  |     5 | 6.35 |  6.65608 |

Of course, I want to do that with my code so that my document is fully automated. Here are a bunch of attempts, each of which produces some hilariously differently wrong results:

//std::cout << "|-----+-----+-----|" << std::endl;
//std::cout << "|-----|-----|-----|" << std::endl;
//std::cout << "-----\t" << "---- \t" << "------" << std::endl;
//std::cout << "----- " << "---- " << "------ " << std::endl;
//std::cout << "------" << "-----" << "-------" << std::endl;

I was unable to find specific info in the org-manual about how to format separator lines correctly from org-babel code.

  • 1
    Have you tried the :colnames header argument? Some of the ob libraries support a list as an argument, i.e. :colnames '("count" "mean" "std_dev") in your case. – mutbuerger May 18 '17 at 16:02
3

Some (most?) ob libraries take a list as an argument for the :colnames header:

#+begin_src elisp :colnames '("Key" "Value")
(list '("a" 43) '("b" 87))
#+end_src

#+results:
| Key | Value |
|-----+-------|
| a   |    43 |
| b   |    87 |
  • Note that if there is an input table and an output table, then they must both have the same :colnames orgmode.org/manual/colnames.html#colnames . I don't know a solution for inputs and outputs that have different column names. – Reb.Cabin May 18 '17 at 19:42
0

I found an answer that addresses the following problem: with :colnames, an input table must have the same column names as the output table, lest you get an error like this

: error: cannot initialize an array element of type 'const char *' with an rvalue of type 'double'
const char* data_header[1] = {0.23};
                              ^~~~
1 error generated.

But :results output raw verbatim lets you format a table nicely. Here is a full example:

#+NAME: a_little_data
|  0.23 |
|  1.31 |
|  4.61 |
|  9.05 |
| 16.55 |

# nope! #+header: :colnames '("count" "mean" "stddev")
#+header: :results output raw verbatim
#+header: :flags=c++14
#+header: :includes '(<iostream> <cmath>)"
#+begin_src C++ :var data=a_little_data
    double sum    = 0;
    double sumsqr = 0;
    double * running_mean   = new double [data_rows];
    double * running_stddev = new double [data_rows];
    for (size_t i = 0; i < data_rows; ++i) {
        running_mean  [i] = 0;
        running_stddev[i] = 0;
    }
    for (size_t i = 0; i < data_rows; ++i) {
        size_t count = i + 1;
        sum += data[i][0];
        sumsqr += (data[i][0] * data[i][0]);
        running_mean[i] = (sum / count);
        double mean = running_mean[i];
        if (count != 1) {
            running_stddev[i] = std::sqrt
                ( (sumsqr - count * mean * mean) /
                  (count - 1) );
        }
    }
    std::cout << "| count " << "| mean " << "| stddev"  << std::endl;
    std::cout << "|--"  << std::endl;
    for (size_t i = 0; i < data_rows; ++i) {
        std::cout << "| " << i + 1             << " ";
        std::cout << "| " << running_mean[i]   << " ";
        std::cout << "| " << running_stddev[i] << " " << std::endl;
    }
    delete [] running_mean;
    delete [] running_stddev;
#+end_src

#+RESULTS:
| count | mean |   stddev |
|-------+------+----------|
|     1 | 0.23 |        0 |
|     2 | 0.77 | 0.763675 |
|     3 | 2.05 |  2.28184 |
|     4 |  3.8 |    3.965 |
|     5 | 6.35 |  6.65608 |

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.