¿Cómo puedo filtrar la tabla en modo org?

11

Por ejemplo, quiero filtrar la tabla para que muestre la fila que solo contiene la cadena "EE. UU." En las columnas 3 y 4.

yuxuan
fuente

Respuestas:

19

Puedes usar una multitud de soluciones. Supongo que desea producir una nueva tabla basada en una existente. Esto implica la funcionalidad de babel donde define bloques de código que producen la nueva tabla. Los bloques de código pueden estar en muchos idiomas, e incluso puede definir dicho bloque de código para que luego se use normalmente en fórmulas de tabla.

Estoy mostrando aquí solo un ejemplo usando emacs lisp. Puede encontrar muchos más ejemplos en mi colección de ejemplos en github: https://github.com/dfeich/org-babel-examples

 *table filter

  #+NAME: table1
  | col1  | col2 | col3 | col4 | col5 |
  |-------+------+------+------+------|
  | row0  |    0 | CH   | CH   |    0 |
  | row1  |    2 | D    | CN   |    5 |
  | row2  |    4 | USA  | PL   |   10 |
  | row3  |    6 | CN   | D    |   15 |
  | row4  |    8 | JP   | USA  |   20 |
  | row5  |   10 | PL   | PL   |   25 |
  | row6  |   12 | USA  | JP   |   30 |
  | row7  |   14 | D    | CN   |   35 |
  | row8  |   16 | PL   | USA  |   40 |
  | row9  |   18 | CN   | D    |   45 |
  | row10 |   20 | CH   | CH   |   50 |

Ahora definimos una función de filtro que produce una nueva tabla con los valores requeridos.

  • Estoy leyendo en la tabla anterior usando el argumento : var tbl = table1 en la línea BEGIN.
  • Defino el valor que se filtrará en el mismo : asignación de var configurando val = "USA"
  • Observe que estoy usando el argumento : colnames en la línea BEGIN para preservar los encabezados de columna.
  • Solo filtro la columna 4 en estos ejemplos, por simplicidad. Pero es trivial extender. Si desea la solución explícita, solo pregunte.
  # + NOMBRE: mi-filtro
  # + BEGIN_SRC elisp: var tbl = table1 val = "EE. UU.": Colnames y
    (cl-loop para fila en tbl
          if (igual (nth 3 fila) val)
          recoger fila en newtbl
          finalmente regrese newtbl)
  # + END_SRC

  # + RESULTADOS: my-filter
  El | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  El | fila4 | 8 | JP | Estados Unidos | 20 |
  El | fila8 | 16 PL | Estados Unidos | 40 |

También puedo usar esta función con la sintaxis CALL del modo org.

  # + CALL: my-filter (tbl = table1, val = "CN"): colnames y

  # + RESULTADOS:
  El | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  El | fila1 | 2 | D | CN | 5 |
  El | fila7 | 14 D | CN | 35

También demuestro aquí el enfoque SQLite donde utilizo su requisito original de filtrar todas las filas que contienen la cadena en las columnas 3 o 4. Un inconveniente menor del enfoque sqlite es que tenemos un código repetitivo para leer en la tabla y crear una base de datos SQLite.

  # + NOMBRE: my-filter2
  # + BEGIN_SRC sqlite: db table1.sqlite: var tbl = table1 val = "USA": colnames yes
    descartar tabla si existe tabla1;
    crear tabla tabla1 (col1 VARCHAR, col2 INTEGER, col3 VARCHAR,
    col4 VARCHAR, col5 INTEGER);
    .import "$ tbl" table1
    seleccione * de la tabla1 donde col3 = '$ val' o col4 = '$ val';
  # + END_SRC

  # + RESULTADOS:
  El | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  El | fila2 | 4 | Estados Unidos | PL | 10 |
  El | fila4 | 8 | JP | Estados Unidos | 20 |
  El | fila6 | 12 | Estados Unidos | JP | 30
  El | fila8 | 16 PL | Estados Unidos | 40 |


  # + CALL: my-filter2 (tbl = table1, val = "CN"): colnames y

  # + RESULTADOS:
  El | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  El | fila1 | 2 | D | CN | 5 |
  El | fila3 | 6 | CN | D | 15 |
  El | fila7 | 14 D | CN | 35
  El | fila9 | 18 CN | D | 45 |

Espero haber entendido su pregunta correctamente y que los enlaces lo ayuden a encontrar otras variaciones de una solución.

dfeich
fuente
Gran solución Con sqlite y gnuplot, se pueden generar múltiples gráficos de una sola tabla fuente con gran economía.
Usuario de Emacs
¡Gracias por una gran solución! Por cierto, en mi entorno, tuve que eliminar la symbol-namefunción para tener éxito en la solución Emacs Lisp. Solo por mencionar.
RUserPassingBy
Gracias. Ahora me di cuenta de que había preparado mi ejemplo original a partir de una tabla producida directamente por un bloque src utilizando los nombres de los países como símbolos, por lo que el filtro en realidad era símbolos y no cadenas. Ahora está corregido.
dfeich
0

Uso q - Texto como datos y 2 funciones en mi library-of-babel( Conf-Example ) para proporcionar una interfaz fácil para consultar / unir tablas org-inline y .*svarchivos externos .

Debajo del capó, q(a través de ) también usa , como el segundo enfoque de @dfeich, pero elimina la necesidad de un código repetitivo ruidoso específico para cada tabla fuente individual. Solo necesita instalarse una vez a través del administrador de paquetes del sistema, generalmente en python-q-text-as-data.

Una vez que su biblioteca de babel esté cargada con las 2 funciones a continuación, solo necesita una #+Call:similar en su archivo org para usar consultas SQL.

#+CALL: Q[:stdin table1](where="col4=='USA'")

#+RESULTS:
| col1 | col2 | col3 | col4 | col5 |
|------+------+------+------+------|
| row4 |    8 | JP   | USA  |   20 |
| row8 |   16 | PL   | USA  |   40 |

Esto construye una línea de comando como SELECT $select FROM $from WHERE $where, con los valores predeterminados para los parámetros para seleccionar todas las columnas de la stdinsalida.

Los bloques de código para agregar a su biblioteca son:

** Add a header Row to tables
#+name: addhdr
#+begin_src emacs-lisp :var tbl=""
(cons (car tbl) (cons 'hline (cdr tbl)))
#+end_src

** Filtering with SQL
#+NAME: Q
#+HEADER: :results value table
#+HEADER: :var callOptsStd="-H -O -t" callOpts=""
#+HEADER: :post addhdr(*this*)
#+BEGIN_SRC shell :stdin Ethers :var select="*" from="-" where="1"
q $callOptsStd $callOpts "Select $select from $from where $where"
#+END_SRC
Alex Stragies
fuente