datamash
Статистика по столбцам из командной строки — суммы, средние, медианы, группировка
GNU datamash считает агрегаты по столбцам текстовых таблиц: сумму, среднее, минимум, медиану, число уникальных значений — по всему файлу или по группам. Там, где на awk пришлось бы писать программу с массивами, здесь хватает одного слова. В песочнице — версия 1.8.
Синтаксис
datamash [опции] операция столбец [операция столбец…] < файл
datamash [опции] -g столбец операция столбец… < файл
Читает только stdin. Столбцы нумеруются с 1; можно перечислять 1,3 и диапазоны 2-4. С заголовком (--header-in, -H) столбец можно указать по имени. Разделитель по умолчанию — табуляция, вывод — через тот же разделитель.
Опции
Ввод и вывод
| Опция | Что делает |
|---|---|
-W | разделитель — любая цепочка пробелов и табуляций |
-t ',' | разделитель — указанный символ |
--output-delimiter=';' | другой разделитель на выходе |
--header-in | первая строка ввода — заголовок, пропустить её |
--header-out | напечатать заголовок результата (sum(score), GroupBy(name) …) |
-H | то же, что --header-in --header-out |
-C | пропускать строки-комментарии (начинаются с # или ;) |
-R 2 (--round=2) | округлять результаты до 2 знаков |
--format='%.3f' | формат чисел в стиле printf |
--narm | пропускать значения NA и NaN |
--no-strict | разрешить строки с разным числом полей; --filler=X — чем заполнять недостающие (по умолчанию N/A) |
-z | строки разделены нулевым байтом |
Группировка
| Опция | Что делает |
|---|---|
-g 1 | группировать по столбцу 1 (можно -g 1,2) — считать агрегаты отдельно для каждого значения |
-s | отсортировать ввод перед группировкой — почти всегда нужен вместе с -g |
-i | сравнивать текст без учёта регистра (группировка и строковые операции) |
-f | печатать перед результатом всю входную строку — для построчных операций (round, md5 …) |
-c ';' | разделитель в списках collapse и unique (по умолчанию запятая) |
Операции
| Операция | Что считает |
|---|---|
count | число строк (в группе) |
sum / mean | сумма / среднее |
min / max / range | минимум / максимум / разность между ними |
absmin / absmax | минимум / максимум по модулю |
median / q1 / q3 / iqr | медиана / квартили / межквартильный размах |
perc:90 | 90-й перцентиль (perc без числа — 95-й) |
mode / antimode | самое частое / самое редкое значение |
sstdev / pstdev | стандартное отклонение выборки / генеральной совокупности |
svar / pvar | дисперсия выборки / генеральной совокупности |
geomean / harmmean | среднее геометрическое / гармоническое |
first / last | первое / последнее значение |
unique / countunique | список разных значений через запятую (отсортирован) / их число |
collapse | все значения группы через запятую, в исходном порядке |
rand | случайное значение из группы |
Целые таблицы: transpose — поменять строки и столбцы, reverse — обратить порядок столбцов, check — проверить, что во всех строках одинаковое число полей (check 3 col — ровно 3 столбца), crosstab 1,2 — сводная таблица по двум столбцам, rmdup 1 — убрать строки с повторяющимся значением столбца.
Построчные: round, floor, ceil, trunc, bin:10 (округлить вниз до кратного 10), md5, sha256, base64, debase64, basename, dirname, extname, getnum (вытащить число из строки), cut — применяются к каждой строке отдельно.
Примеры
printf 'dev\t30\nops\t25\ndev\t35\n' > data.tsv
# сумма и среднее второго столбца
datamash sum 2 mean 2 < data.tsv
# по группам первого столбца: сумма и число строк
datamash -s -g 1 sum 2 count 2 < data.tsv
# минимум, максимум, медиана, квартили
datamash min 2 max 2 median 2 q1 2 q3 2 < data.tsv
# значения, разделённые пробелами
printf 'x 1\ny 2\nx 3\n' | datamash -W -s -g 1 sum 2
# CSV с заголовком: пропустить его и вывести свой
printf 'name,score\na,1\nb,2\n' | datamash -t, --header-in sum 2
printf 'name,score\na,1\nb,2\n' | datamash -t, -H sum score
# список значений и число разных значений по группам
datamash -s -g 1 collapse 2 countunique 2 < data.tsv
# округление
datamash -R 2 sstdev 2 < data.tsv
# поменять строки и столбцы местами
datamash transpose < data.tsv
# проверить, что в каждой строке ровно 2 поля
datamash check 2 col < data.tsv
# сводная таблица: сколько строк для каждой пары значений
printf 'a x\na y\nb x\na x\n' | datamash -W -s crosstab 1,2
# удалить строки с повторяющимся значением первого столбца
printf 'a 1\na 2\nb 3\n' | datamash -W rmdup 1
# построчно: число из строки и округление
printf 'v12.7kg\n' | datamash getnum 1
printf '2.5\n3.7\n' | datamash round 1
Подводные камни
- Разделитель по умолчанию — табуляция. Для строки
x 1(через пробел) datamash видит одно поле и ругаетсяline 1 has only 1 fields. Добавь-Wили-t ' '. - Группировка работает только по соседним строкам, как uniq. Без
-sна несортированном вводе одна и та же группа выйдет несколько раз. Почти всегда пиши-s -g …. - Нечисловое значение — ошибка. На строке заголовка или на слове в числовом столбце datamash остановится с
invalid numeric value. Заголовок пропускай через--header-in;--narmпропускает толькоNA/NaN, а не произвольный текст. -t ' '— ровно один пробел. Два пробела подряд дают пустое поле. Для выровненного пробелами вывода нужен-W.- Порядок строк меняется. С
-sвывод отсортирован по ключу группы, а не идёт в порядке первого появления. - Дробные результаты печатаются с большим числом знаков (
4.0824829046386); округляй через-Rили--format. - Разные операции нельзя смешивать произвольно. Табличные (
transpose,check,rmdup…) пишутся одни; групповые и построчные в одной команде не сочетаются — datamash ответитconflicting operation.