Come posso filtrare la tabella in modalità org


11

Ad esempio, voglio filtrare la tabella in modo che mostri la riga che contiene solo la stringa "USA" nelle colonne 3 e 4.

Risposte:


19

Puoi usare una moltitudine di soluzioni. Presumo che tu voglia produrre una nuova tabella basata su una esistente. Ciò comporta la funzionalità babel in cui si definiscono blocchi di codice che producono la nuova tabella. I blocchi di codice possono essere in molte lingue e puoi persino definire un tale blocco di codice da utilizzare in seguito normalmente nelle formule di tabella.

Sto mostrando qui solo un esempio usando emacs lisp. Puoi trovare molti altri esempi nella mia raccolta di esempi su 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 |

Ora definiamo una funzione di filtro che produce una nuova tabella con i valori richiesti.

  • Sto leggendo nella tabella precedente usando l' argomento : var tbl = table1 nella riga BEGIN.
  • Definisco il valore da filtrare nello stesso : assegnazione var impostando val = "USA"
  • Si noti che sto usando l' argomento : colnames nella riga BEGIN per preservare le intestazioni di colonna.
  • Filtro solo la colonna 4 in questi esempi, per semplicità. Ma è banale estenderlo. Se vuoi la soluzione esplicita, basta chiedere.
  # + NAME: my-filter
  # + BEGIN_SRC elisp: var tbl = table1 val = "USA": nomi dei nomi y
    (cl-loop per riga in tbl
          if (uguale (ennesima riga) val)
          raccogliere la riga in newtbl
          finalmente torna newtbl)
  # + END_SRC

  # + RISULTATI: my-filter
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | riga4 | 8 | JP | USA | 20 |
  | riga8 | 16 | PL | USA | 40 |

Posso anche usare questa funzione con la sintassi CALL in modalità org

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

  # + RISULTATI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | riga1 | 2 | D | CN | 5 |
  | riga7 | 14 | D | CN | 35 |

Dimostro anche qui l'approccio SQLite in cui utilizzo il requisito originale di filtrare tutte le righe che contengono la stringa nelle colonne 3 o 4. Uno svantaggio dell'approccio sqlite è che abbiamo un codice boilerplate da leggere nella tabella e creare un DB SQLite.

  # + NAME: my-filter2
  # + BEGIN_SRC sqlite: db table1.sqlite: var tbl = table1 val = "USA": nomi utente sì
    drop table se esiste table1;
    crea tabella table1 (col1 VARCHAR, col2 INTEGER, col3 VARCHAR,
    col4 VARCHAR, col5 INTEGER);
    .import "$ tbl" tabella1
    seleziona * dalla tabella 1 dove col3 = '$ val' o col4 = '$ val';
  # + END_SRC

  # + RISULTATI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | riga2 | 4 | USA | PL | 10 |
  | riga4 | 8 | JP | USA | 20 |
  | riga6 | 12 | USA | JP | 30 |
  | riga8 | 16 | PL | USA | 40 |


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

  # + RISULTATI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | riga1 | 2 | D | CN | 5 |
  | riga3 | 6 | CN | D | 15 |
  | riga7 | 14 | D | CN | 35 |
  | riga9 | 18 | CN | D | 45 |

Spero di aver compreso correttamente la tua domanda e che i link ti aiutino a trovare altre varianti di una soluzione.


Ottima soluzione Con sqlite e gnuplot, è possibile generare più grafici da un'unica tabella di origine con grande economia.
Utente Emacs

Grazie per un'ottima soluzione! A proposito, nel mio ambiente, ho dovuto eliminare la symbol-namefunzione per avere successo nella soluzione Emacs Lisp. Solo per menzione.
RUserPassing dal

Grazie. Mi sono reso conto solo ora che avevo preparato il mio esempio originale da una tabella prodotta direttamente da un blocco src usando i nomi dei paesi come simboli, quindi il filtro era in realtà passato a simboli e non a stringhe. Ora è corretto.
dfeich,

0

Uso q - Text as Data e 2 funzioni nel mio library-of-babel( Conf-Example ) per fornire un'interfaccia semplice per interrogare / unire tabelle organizzate e .*svfile esterni .

Under the hood, q(tramite ) usa anche , come il secondo approccio di @dfeich, ma elimina la necessità di rumorosi codici boilerplate specifici per ogni singola tabella di origine. Deve solo essere installato una volta tramite il gestore dei pacchetti di sistema, di solito in python-q-text-as-data.

Una volta caricata la tua libreria di babel con le 2 funzioni seguenti, #+Call:per utilizzare le query SQL è necessario solo un like di seguito nel file org.

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

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

Questo crea una riga di comando simile SELECT $select FROM $from WHERE $where, con valori predefiniti per i parametri da cui selezionare tutte le colonne stdinper l'output.

I blocchi di codice da aggiungere alla tua libreria sono:

** 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.