Dear all. I get that it may be a tad complicated, but if anyone sees at least a reference about how it may be done, please do share it here. Thanks a lot, in advance... :)
Edit 2026-01-07: added the missing ) and fixed the formatting
Here's how I would approach it:
#+STARTUP: noptag
#+TAGS:
#+TAGS: [ GT1 : tagA tagC tagD ]
#+TAGS: [ GT2 : tagB tagE ]
#+TAGS: [ GT3 : tagB tagC tagD ]
#+NAME: source
| tag | Q1 | Q2 |
|------+----+----|
| tagA | 9 | |
| tagB | 4 | 2 |
| tagC | 1 | 4 |
| tagD | | 5 |
| tagE | | 6 |
#+begin_src emacs-lisp
(defun my-sum-tag-groups (source)
(cons
(car source)
(mapcar
(lambda (tag-group)
(let ((tags (org--tags-expand-group (list (car tag-group)) org-tag-groups-alist nil)))
(cons
(car tag-group)
(seq-map-indexed
(lambda (colname i)
(apply
'+
(mapcar
(lambda (tag)
(let ((val (or (elt (assoc-default tag source) i) "0")))
(if (stringp val)
(string-to-number val)
(or val 0))))
tags)))
(cdr (car source))))))
org-tag-groups-alist)))
#+end_src
#+begin_src emacs-lisp :var source=source :colnames no :results table
(my-sum-tag-groups source)
#+end_src
#+RESULTS:
:results:
| tag | Q1 | Q2 |
| GT1 | 10 | 9 |
| GT2 | 4 | 8 |
| GT3 | 5 | 11 |
:end:
Dear @sachac (BTW, are you the legendary Sacha Chua?)
There was a parenthesis missing in the end, but it is working!!! :)))
I still have to understand the scope (does it works on the heading/ tree where it is called only, can I "point it" to a specific table, etc.) but it is a really great step forward.
And, as I wanted, it is short, simple, elegant, works perfectly and -specially- shows the power of elisp and how literate programming can be useful and powerful for reproducible research (this is part of my thesis).
I may continue with some questions, but it helps me a lot to learn.
Thank you so much! :D
Sorry for the late reply here too, and thanks for your e-mail! You've probably already figured out that you can change the :var in the second babel block to point to a different table (ex: :var source=another_table) named with #+NAME: . The tags you've defined with #+TAGS: are file-level, but it's possible to change the function so that it can take an optional argument with a tag hierarchy, so you can make your own structure.
Emacs
Our infinitely powerful editor.