Миллер: выбор столбцов на основе их последнего значения
Я обрабатываю файл TSV с сотней столбцов и хотел бы выбрать некоторые из них на основе их последних значений (т. е. значения в последней строке).
Например, со следующими данными (и я позволю вам представить еще 96 столбцов!):
Year An Ti Gi Na
2000 5 10 2 3
2010 3 2 5 7
2020 6 3 5 6
Я хотел бы выбрать все столбцы, значение которых в последней строке не менее 5 (и, что еще лучше, я хотел бы выбрать все столбцы, значение которых в последней строке не меньше значения строки Gi).
Итак, в конце концов я хотел бы получить следующий результат (столбец Ti отбрасывается, поскольку его значение в последней строке равно 3, что ниже нашего порога).
Year An Gi Na
2000 5 2 3
2010 3 5 7
2020 6 5 6
Есть ли у вас какие-либо идеи?
Спасибо!
2 ответа
Вы можете написать этот bash-скрипт
#!/bin/bash
gi_value=$(mlr --t2n tail -n 1 then cut -f Gi input.tsv)
gi_columns=$(mlr --t2n tail -n 1 then label 1 then reshape -r '^[a-zA-Z]' -o k,v then filter '$v >= '"$gi_value"'' then cut -f k then nest --ivar "," -f k input.tsv)
mlr --tsv cut -f Year,"$gi_columns" input.tsv
Сначала извлеките значение Gi
mlr --t2n tail -n 1 then cut -f Gi input.tsv
заселитьgi_value
вар с5
ценить.
Затем извлеките список столбцов последней строки, в которой значение >= 5.
mlr --t2n tail -n 1 \
then label 1 \
then reshape -r '^[a-zA-Z]' -o k,v \
then filter '$v >= '"$gi_value"'' \
then cut -f k \
then nest --ivar "," -f k input.tsv
Это дает вам результат.
Последний шаг – разрезатьAn,Gi,Na
столбцы:
mlr --tsv cut -f Year,"$gi_columns" input.tsv
Результат:
Year An Gi Na
2000 5 2 3
2010 3 5 7
2020 6 5 6
Вы можете использовать небольшую программу DSL для выбора/вырезания полей. Обратной стороной является то, что он загружает весь файл в ОЗУ (это то, что я наблюдал приmlr
текущая реализация):
mlr --tsv tac then put '
is_null(@m) { @m = apply($*, func(k,v) { return {k: v >= $Gi}; }); }
$* = select($*, func(k,v) { return @m[k]; });
' file.tsv
Year An Gi Na
2020 6 5 6
2010 3 5 7
2000 5 2 3
Примечание: порядок записей в выводе меняется на обратный, поэтому вы можете добавить еще одинtac
к цепочке для возврата исходного заказа:
mlr --tsv tac then put '...' then tac file.tsv