Como filtrar tabela no modo organizacional

11

Por exemplo, quero filtrar a tabela que mostra a linha que contém apenas a sequência "USA" na coluna 3 e 4.

yuxuan
fonte

Respostas:

19

Você pode usar uma infinidade de soluções. Suponho que você queira produzir uma nova tabela com base em uma existente. Isso envolve a funcionalidade babel, na qual você define blocos de código que produzem a nova tabela. Os blocos de código podem estar em vários idiomas, e você ainda pode definir esse bloco de código para ser usado posteriormente normalmente nas fórmulas de tabela.

Estou mostrando aqui apenas um exemplo usando o emacs lisp. Você pode encontrar muitos outros exemplos na minha coleção de exemplos no 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 |

Agora, definimos uma função de filtro que produz uma nova tabela com os valores necessários.

  • Estou lendo na tabela anterior usando o argumento : var tbl = table1 na linha BEGIN.
  • Eu defino o valor a ser filtrado da mesma forma : var assign atribuindo val = "USA"
  • Observe que estou usando o argumento : colnames na linha BEGIN para preservar os títulos das colunas.
  • Filtrei apenas a coluna 4 nesses exemplos, para simplificar. Mas é trivial estender. Se você deseja a solução explícita, basta perguntar.
  # + NAME: meu filtro
  # + BEGIN_SRC elisp: var tbl = tabela1 val = "EUA": nomes de colunas y
    (loop cl para linha em tbl
          if (igual (enésima terceira linha) val)
          coletar linha no newtbl
          finalmente retorne newtbl)
  # + END_SRC

  # + RESULTADOS: meu filtro
  | col1 | col2 col3 col4 col5
  | ------ + ------ + ------ + ------ + ------ |
  | row4 | 8 JP EUA 20
  | row8 | 16 PL EUA 40

Também posso usar esta função com a sintaxe CALL do modo organizacional

  # + LIGAÇÃO: meu filtro (tbl = tabela1, val = "CN"): nomes de colunas y

  # + RESULTADOS:
  | col1 | col2 col3 col4 col5
  | ------ + ------ + ------ + ------ + ------ |
  | linha1 | 2 D CN 5
  | row7 | 14 D CN 35

Também demonstro aqui a abordagem SQLite, na qual uso seu requisito original de filtrar todas as linhas que contêm a sequência nas colunas 3 ou 4. Uma desvantagem menor da abordagem sqlite é que temos algum código padrão para ler na tabela e criar um banco de dados SQLite.

  # + NOME: my-filter2
  # + BEGIN_SRC sqlite: db table1.sqlite: var tbl = tabela1 val = "EUA": nomes de colunas sim
    soltar tabela se existir tabela1;
    criar tabela table1 (col1 VARCHAR, col2 INTEGER, col3 VARCHAR,
    col4 VARCHAR, col5 INTEGER);
    .import "$ tbl" table1
    selecione * da tabela1 onde col3 = '$ val' ou col4 = '$ val';
  # + END_SRC

  # + RESULTADOS:
  | col1 | col2 col3 col4 col5
  | ------ + ------ + ------ + ------ + ------ |
  | linha2 | 4 EUA PL 10
  | row4 | 8 JP EUA 20
  | row6 | 12 EUA JP 30
  | row8 | 16 PL EUA 40


  # + LIGAÇÃO: meu-filtro2 (tbl = tabela1, val = "CN"): nomes de colunas y

  # + RESULTADOS:
  | col1 | col2 col3 col4 col5
  | ------ + ------ + ------ + ------ + ------ |
  | linha1 | 2 D CN 5
  | linha3 | 6 CN D 15
  | row7 | 14 D CN 35
  | row9 | 18 CN D 45

Espero que tenha entendido sua pergunta corretamente e que os links o ajudem a encontrar outras variações de uma solução.

dfeich
fonte
Ótima solução. Com o sqlite e o gnuplot, vários gráficos de uma única tabela de origem podem ser gerados com grande economia.
Usuário Emacs
Obrigado pela ótima solução! BTW, no meu ambiente, tive que excluir a symbol-namefunção para ter sucesso na solução Emacs Lisp. Apenas para menção.
usar o seguinte comando
Obrigado. Só percebi agora que havia preparado meu exemplo original a partir de uma tabela produzida diretamente por um bloco src, usando os nomes de países como símbolos, de modo que o filtro recebeu símbolos e não seqüências de caracteres. Agora está corrigido.
precisa saber é
0

Eu uso q - Text como Data e 2 funções no meu library-of-babel( Exemplo Conf. ) Para fornecer uma interface fácil para consultar / juntar tabelas org-inline e .*svarquivos externos .

Sob o capô, q(via ) também usa , como a segunda abordagem do @dfeich, mas elimina a necessidade de um código clichê barulhento específico para cada tabela de origem individual. Ele só precisa ser instalado uma vez através do gerenciador de pacotes do sistema, geralmente no python-q-text-as-data.

Uma vez que sua biblioteca de babel esteja carregada com as 2 funções abaixo, você precisará apenas do exemplo #+Call:abaixo em seu arquivo organizacional para usar as 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 |

Isso cria uma linha de comando como SELECT $select FROM $from WHERE $where, com padrões para os parâmetros para selecionar todas as colunas stdinpara saída.

Os blocos de código a serem adicionados à sua biblioteca são:

** 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
fonte