Jak mogę filtrować tabelę w trybie org

11

Na przykład chcę filtrować tabelę, która pokazuje, że zawiera wiersz zawierający tylko ciąg „USA” w kolumnach 3 i 4.

Yuxuan
źródło

Odpowiedzi:

19

Możesz użyć wielu rozwiązań. Zakładam, że chcesz stworzyć nowy stół w oparciu o istniejący. Obejmuje to funkcjonalność babel, w której definiujesz bloki kodu, które tworzą nową tabelę. Bloki kodu mogą być w wielu językach, a nawet można zdefiniować taki blok kodu, który będzie później używany normalnie w formułach tabel.

Pokazuję tutaj tylko przykład użycia emacs lisp. Wiele innych przykładów można znaleźć w mojej kolekcji przykładów na 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 |

Teraz definiujemy funkcję filtrowania, która tworzy nową tabelę z wymaganymi wartościami.

  • Czytam w poprzedniej tabeli za pomocą argumentu : var tbl = table1 w wierszu BEGIN.
  • Definiuję wartość do filtrowania w ten sam sposób : przypisanie var przez ustawienie val = „USA”
  • Zauważ, że używam argumentu : colnames w wierszu BEGIN, aby zachować nagłówki kolumn.
  • Dla uproszczenia filtruję tylko kolumnę 4 w tych przykładach. Ale rozszerzenie jest banalne. Jeśli chcesz jednoznacznego rozwiązania, po prostu zapytaj.
  # + NAZWA: mój filtr
  # + BEGIN_SRC elisp: var tbl = table1 val = "USA": colnames y
    (pętla cl dla wiersza w tbl
          if (równa (n-ty 3 wiersz) val)
          zbierz wiersz do newtbl
          w końcu zwróć newtbl)
  # + END_SRC

  # + WYNIKI: mój filtr
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | wiersz4 | 8 | JP | USA | 20 |
  | wiersz 8 | 16 | PL | USA | 40 |

Mogę również użyć tej funkcji ze składnią CALL trybu org

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

  # + WYNIKI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | wiersz 1 | 2 | D | CN | 5 |
  | wiersz7 | 14 | D | CN | 35 |

Pokazuję tutaj również podejście SQLite, w którym używam twojego pierwotnego wymogu filtrowania wszystkich wierszy zawierających ciąg albo w kolumnach 3 lub 4. Małą wadą podejścia sqlite jest to, że mamy trochę kodu podstawki do odczytania w tabeli i utworzenia SQLite DB.

  # + NAZWA: my-filter2
  # + BEGIN_SRC sqlite: db table1.sqlite: var tbl = table1 val = "USA": nazwy kolorów tak
    upuść tabelę, jeśli istnieje table1;
    utwórz tabelę table1 (col1 VARCHAR, col2 INTEGER, col3 VARCHAR,
    col4 VARCHAR, col5 INTEGER);
    .import Tabela „$ tbl” 1
    wybierz * z tabeli 1, gdzie col3 = „$ val” lub col4 = „$ val”;
  # + END_SRC

  # + WYNIKI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | wiersz 2 | 4 | USA | PL | 10 |
  | wiersz4 | 8 | JP | USA | 20 |
  | wiersz 6 | 12 | USA | JP | 30 |
  | wiersz 8 | 16 | PL | USA | 40 |


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

  # + WYNIKI:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | wiersz 1 | 2 | D | CN | 5 |
  | wiersz 3 | 6 | CN | D | 15 |
  | wiersz7 | 14 | D | CN | 35 |
  | wiersz 9 | 18 | CN | D | 45 |

Mam nadzieję, że dobrze zrozumiałem twoje pytanie i że linki pomagają znaleźć inne warianty rozwiązania.

dfeich
źródło
Świetne rozwiązanie. Dzięki sqlite i gnuplot można generować wiele wykresów z jednej tabeli źródłowej z wielką ekonomią.
Użytkownik Emacsa,
Dziękujemy za świetne rozwiązanie! BTW, w moim środowisku musiałem usunąć symbol-namefunkcję, aby odnieść sukces w rozwiązaniu Emacs Lisp. Tylko na wzmiankę.
RUserPassing Do
Dzięki. Dopiero teraz zdałem sobie sprawę, że przygotowałem swój oryginalny przykład ze tabeli utworzonej bezpośrednio przez blok src, używając nazw krajów jako symboli, więc filtr był tak naprawdę przekazywanymi symbolami, a nie łańcuchami. To jest teraz poprawione.
dfeich
0

Używam q - Text jako danych i 2 funkcji w moim library-of-babel( Conf-Example ), aby zapewnić łatwy interfejs do przeszukiwania / dołączania tabel wewnętrznych i .*svplików zewnętrznych .

Pod maską q(przez ) używa również , podobnie jak drugie podejście z @dfeich, ale eliminuje potrzebę hałaśliwego kodu bojlera specyficznego dla każdej tabeli źródłowej. Trzeba go tylko raz zainstalować za pomocą menedżera pakietów systemowych, zwykle w python-q-text-as-data.

Kiedy twoja biblioteka babel zostanie załadowana 2 poniższymi funkcjami, potrzebujesz tylko #+Call:podobnej poniżej w pliku org, aby korzystać z zapytań SQL.

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

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

Tworzy to wiersz polecenia SELECT $select FROM $from WHERE $where, z domyślnymi parametrami, z których wybierane są wszystkie kolumny stdindo wyświetlenia.

Bloki kodu do dodania do biblioteki to:

** 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
źródło