Notxor tiene un blog

Defenestrando la vida


Tablas en org-mode: cómo tener una hoja de cálculo en modo texto.

Una forma muy habitual de ordenar la información que nos llega es meterla en una tabla. Si cogemos datos al azar y podemos organizar una tabla con ellos nos facilitará el acceso a ellos en posteriores ocasiones. En esto se basan la mayoría de las aplicaciones que gestionan información, como las bases de datos --que se suelen ordenar en tablas--, o las hojas de cálculo --que realizan cálculos con información ordenada en filas y columnas: tablas--.

En org-mode el fichero puede contener también ese tipo de información guardada y ordenada en filas y columnas. No sólo contener tablas, sino también hacer cálculos dentro de ellas. Pero vamos por pasos.

Crear tablas

Crear una tabla es muy sencillo. en un párrafo nuevo podemos teclear una cabecera separada por caracteres |. Por ejemplo, en un párrafo nuevo escribimos lo siguiente:

|Nombre|Apellidos|Teléfono|
|-

Cuando lo hayamos hecho, estando el cursor inmediatamente detrás del último guión se pulsa <TAB> y la tabla aparece. Cada vez que pulsemos <TAB> el cursor saltará a la siguiente celda en la misma línea y cada vez que pulsemos <RET> saltaremos a la siguiente línea. Si cambia el ancho de columna se reajustará toda la tabla al hacerlo.

En ocasiones tenemos datos que queremos tabular. Si los tenemos ordenados en una lista separada por comas (CSV) podemos tabular toda la información. Por ejemplo:

Perico,de los Palotes,123456789
Fulanito,de Tal,987654321

Nos dará como resultado:

| Perico   | de los Palotes | 123456789 |
| Fulanito | de Tal         | 987654321 |

Para ello debemos marcar las líneas que deseamos convertir en tabla y pulsamos C-c |. La misma combinación de teclas pulsada en cualquier otro sitio nos preguntará por la distribución de una tabla nueva. Por ejemplo, C-c |<RET>2x2<RET> creará una tabla vacía de dos por dos.

También se puede cambiar el orden de las columnas si te sitúas en una columna pulsas M-<dcha> o M-<izda>. Igualmente, se pueden mover la filas pulsando M-<arriba> o M-<abajo>.

Además, se pueden añadir columnas pulsando M-S-<dcha> y eliminarlas con M-S-<izda>. O crear filas con M-S-<abajo> o eliminarlas con M-S-<arriba>.

Ancho de columna y alineamiento

Normalmente, el ancho de columna lo calcula directamente emacs, pero también podemos forzarlo en algunas ocasiones insertando en la primera fila una cadena de formato con el ancho, por ejemplo:

|   |                                                                    |
|---+--------------------------------------------------------------------|
| 1 | Uno                                                                |
| 2 | Dos                                                                |
| 3 | tres                                                               |
| 4 | Esta es una entrada demasiado larga para que entre en una columna. |
|---+--------------------------------------------------------------------|

se convierte en

|   |            |
|---+------------|
|   | <10>       |
| 1 | Uno        |
| 2 | Dos        |
| 3 | tres       |
| 4 | Esta es => |
|---+------------|

Limitando la columna es más difícil modificar el contenido que no cabe en el ancho estipulado. Para hacerlo de una manera cómoda, viene al rescate la combinación de teclas C-c `, que abrirá una ventana donde se puede editar el contenido cómodamente.

Además del ancho, se puede establecer la alineación añadiendo al número un prefijo de una letra: <r10> alineará la columna a la derecha, <c10> la centrará y <l10> la alineará a la izquierda.

Haciendo cálculos con las tablas.

Los cálculos recuerdan mucho a como funciona una hoja de cálculo. Una celda está determinada por una fila y una columna. En las hojas de cálculo, desde los tiempos del «Lotus 123», las columnas se nombran con una letra y las filas con un número, de forma que la primera celda de la primera columna se llama A1 y la segunda A2. En las tablas de org-mode las filas se marcan con el signo @ y un número y las columnas con el signo $ y un número. Es decir, una celda se nombra como @FILA$COLUMNA. Pero si tienes dudas de qué celda es, simplemente te puedes situar en ella y pulsar C-c ?.

Además en las fórmulas se pueden utilizar números relativos. Por ejemplo, @-1 se refiere a la fila anterior a la actual o @+2 a la fila posterior a la siguiente. Pero para acostumbrarse a todas estas cosas lo mejor es utilizarlo.

Calculando

Para no alargarme mucho, voy a utilizar una tabla que viene en la documentación de org-mode. Pero lo voy a hacer paso a paso poniendo los resultados intermedios para mostrar cómo lo utilizo yo.

Escribo:

|N|N^2|N^3|N^4|~sqrt(n)~|~sqrt[4](N)~|
|-

y pulso <TAB> obteniendo

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
|   |     |     |     |           |              |

La tabla se ha creado y está vacía, a parte de la cabecera. La única fila que hay no tiene contenido. En el ejemplo hay una fila especial que marca grupos de columnas para dibujar líneas verticales

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | <   |     | >   | <         | >            |

Cuando el primer campo contiene únicamente un carácter /, los siguientes campos marcan con < el inicio de un grupo de columnas y con > el final de un grupo. Si el grupo está formado por una sola columna se puede utilizar <> para marcar a la vez el inicio y el final de un grupo de columnas. Al exportar el documento se dibujarán las líneas que separan los grupos.

Pero vamos con los cálculos. Introduzco el primer número y la primera fórmula que calcularemos en la segunda columna.

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | <   |     | >   | <         | >            |
| 1 | :=$1^2 |     |     |           |              |

Para introducir la fórmula he utilizado la combinación := a continuación le indico que tome el valor de la columna anterior con $1 y lo elevo al cuadrado con el operador ^. Al pulsar <RET> el resultado se muestra es:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | <   |     | >   | <         | >            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2

como se puede ver donde he escrito la fórmula ha aparecido el resultado del cálculo y la fórmula se guarda en una línea de comando #+TBLFM:, y en ella aparece que la celda @3$2 se calcula con el valor de la columna anterior $1 elevado al cuadrado $1^2. Como el valor lo vamos a querer utilizar en filas sucesivas podemos eliminar @3 que identifica la línea y así se tratará en toda la columna. En las hojas de cálculo hay que copiar explícitamente la fórmula a cada celda. Aquí, quedaría como sigue:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | <   |     | >   | <         | >            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: $2=$1^2

Vamos con las siguientes columnas:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | <   |     | >   | <         | >            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2::$3=$1^3::$4=$1^4

Como se puede apreciar cada fórmula se separa de la anterior con un doble carácter :. Me he detenido en esa columna para explicar que al introducir fórmulas podemos utilizar cualquier fórmula matemática que esté soportada por el modo calc de emacs. En este caso sqrt para calcular raíces cuadradas.

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |         1 |            1 |
|   |     |     |     |           |              |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))

Ya he introducido la primera línea y las fórmulas que calculan cada celda de ella. También se pueden introducir fórmulas en elisp. Las fórmulas deben ir marcadas con un apóstrofe. Las fórmulas elisp devuelven por defecto cadenas, por lo que si queremos que sea tratado como un número se debe marcar un N. Por ejemplo, si queremos sumar dos columnas la fórmula tendrá el formato '(+ $1 $2);N.

Pero seguiré con la tabla. Más valores para la columna N.

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |     |     |     |           |              |
| 3 |     |     |     |           |              |
| 4 |     |     |     |           |              |
|---+-----+-----+-----+-----------+--------------|
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))

Es hora de calcular toda la tabla. Coloco el cursor en la línea #+TBLFM: y pulso C-c C-c. El resultado:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |   4 |   8 |  16 | 1.4142136 |    1.1892071 |
| 3 |   9 |  27 |  81 | 1.7320508 |    1.3160740 |
| 4 |  16 |  64 | 256 |         2 |    1.4142136 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))

¿Se puede hacer algo con el formato de los resultados? Algunas columnas no tienen decimales y otras tienen siete. Pero sí, se puede dar un poco de formato añadiendo un flag %.4f detrás de la fórmula que queremos ajustar, separándolo con un carácter ;. Por ejemplo:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |   4 |   8 |  16 | 1.4142136 |    1.1892071 |
| 3 |   9 |  27 |  81 | 1.7320508 |    1.3160740 |
| 4 |  16 |  64 | 256 |         2 |    1.4142136 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1);%.4f::$6=sqrt(sqrt($1));%.5f

Volvemos a pulsar C-c C-c sobre la línea de fórmulas y el resultado es:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |    1.0000 |      1.00000 |
| 2 |   4 |   8 |  16 |    1.4142 |      1.18921 |
| 3 |   9 |  27 |  81 |    1.7321 |      1.31607 |
| 4 |  16 |  64 | 256 |    2.0000 |      1.41421 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1);%.4f::$6=sqrt(sqrt($1));%.5f

La tabla, tal y como queda en el documento es la siguiente:

N N^2 N^3 N^4 sqrt(n) sqrt[4](N)
1 1 1 1 1.0000 1.00000
2 4 8 16 1.4142 1.18921
3 9 27 81 1.7321 1.31607
4 16 64 256 2.0000 1.41421

Comentarios