Как я могу отфильтровать таблицу в режиме орг

11

Например, я хочу отфильтровать таблицу, которая показывает строку, которая содержит только строку «США» в столбцах 3 и 4.

Yuxuan
источник

Ответы:

19

Вы можете использовать множество решений. Я предполагаю, что вы хотите создать новую таблицу на основе существующей. Это включает в себя функции Babel, где вы определяете блоки кода, которые создают новую таблицу. Блоки кода могут быть на многих языках, и вы даже можете определить такой блок кода, который впоследствии будет использоваться обычно в формулах таблиц.

Я показываю здесь только пример использования emacs lisp. Вы можете найти много других примеров в моей коллекции примеров на 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 |

Теперь мы определяем функцию фильтра, которая создает новую таблицу с необходимыми значениями.

  • Я читаю в предыдущей таблице, используя аргумент : var tbl = table1 в строке BEGIN.
  • Я определяю значение, которое будет отфильтровано таким же образом : присваивание var путем установки val = "USA"
  • Обратите внимание, что я использую аргумент : colnames в строке BEGIN, чтобы сохранить заголовки столбцов.
  • Для простоты я фильтрую только столбец 4 в этих примерах. Но это тривиально расширить. Если вы хотите явного решения, просто спросите.
  # + NAME: my-filter
  # + BEGIN_SRC elisp: var tbl = table1 val = "USA": colnames y
    (cl-loop для строки в табл.
          if (равно (nth 3 строка) val)
          собрать строку в newtbl
          наконец вернуть ньютбл)
  # + END_SRC

  # + РЕЗУЛЬТАТЫ: my-filter
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | row4 | 8 | JP | США | 20 |
  | row8 | 16 | PL | США | 40 |

Я также могу использовать эту функцию с синтаксисом CALL режима org

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

  # + РЕЗУЛЬТАТЫ:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | row1 | 2 | D | CN | 5 |
  | row7 | 14 | D | CN | 35 |

Здесь я также демонстрирую подход SQLite, в котором я использую исходное требование фильтрации всех строк, содержащих строку, в столбцах 3 или 4. Небольшой недостаток подхода sqlite заключается в том, что у нас есть некоторый шаблонный код для чтения в таблице и создания БД SQLite.

  # + ИМЯ: my-filter2
  # + BEGIN_SRC sqlite: db table1.sqlite: var tbl = table1 val = "USA": имена столбцов да
    удалить таблицу, если существует table1;
    создать таблицу table1 (col1 VARCHAR, col2 INTEGER, col3 VARCHAR,
    col4 VARCHAR, col5 INTEGER);
    .import "$ tbl" table1
    выберите * из таблицы 1, где col3 = '$ val' или col4 = '$ val';
  # + END_SRC

  # + РЕЗУЛЬТАТЫ:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | row2 | 4 | США | PL | 10 |
  | row4 | 8 | JP | США | 20 |
  | row6 | 12 | США | JP | 30 |
  | row8 | 16 | PL | США | 40 |


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

  # + РЕЗУЛЬТАТЫ:
  | col1 | col2 | col3 | col4 | col5 |
  | ------ + ------ + ------ + ------ + ------ |
  | row1 | 2 | D | CN | 5 |
  | row3 | 6 | CN | D | 15 |
  | row7 | 14 | D | CN | 35 |
  | row9 | 18 | CN | D | 45 |

Надеюсь, что я правильно понял ваш вопрос и что ссылки помогут вам найти другие варианты решения.

dfeich
источник
Отличное решение. С помощью sqlite и gnuplot можно создать несколько графиков из одной исходной таблицы с большой экономией.
Emacs User
Спасибо за отличное решение! Кстати, в моей среде мне пришлось удалить symbol-nameфункцию, чтобы добиться успеха в решении Emacs Lisp. Просто для упоминания.
RUserPassingBy
Спасибо. Я только сейчас понял, что подготовил свой исходный пример из таблицы, созданной непосредственно блоком src, используя названия стран в качестве символов, поэтому фильтр фактически представлял собой символы, а не строки. Сейчас это исправлено.
dfeich
0

Я использую q-Text в качестве данных и две функции в моем library-of-babel( Conf-Example ), чтобы обеспечить простой интерфейс для запроса / объединения встроенных в org таблиц и внешних .*svфайлов.

Под капотом q(через ) также используется , как и второй подход из @dfeich, но устраняется необходимость в зашумленном шаблонном коде, специфичном для каждой отдельной исходной таблицы. Он просто должен быть установлен один раз через системный менеджер пакетов, обычно в python-q-text-as-data.

После того, как ваша библиотека babel загружена двумя приведенными ниже функциями, #+Call:для использования SQL-запросов вам потребуется только то, что показано ниже в вашем org-файле.

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

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

Это создает командную строку SELECT $select FROM $from WHERE $whereс параметрами по умолчанию для выбора всех столбцов stdinдля вывода.

Блоки кода для добавления в вашу библиотеку:

** 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
Алекс Страгиес
источник