Как выбрать минимальное значение, которое включает в себя экспоненциальное значение для каждого идентификатора на основе четвертого столбца? - PullRequest
0 голосов
/ 29 января 2020

Подскажите, пожалуйста, как выбрать строки с минимальным значением, включая экспоненциальный, на основе четвертого столбца и сгруппировать по первому столбцу в linux?

Исходный файл

ID,y,z,p-value
1,a,b,0.22
1,a,b,5e-10
1,a,b,1.2e-10
2,c,d,0.06
2,c,d,0.003
2,c,d,3e-7
3,e,f,0.002
3,e,f,2e-8
3,e,f,1.0

Файл, который я хочу, как показано ниже.

ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8

На самом деле это работало нормально, так что спасибо всем!

tail -n +2 original_file > txt sort -t, -k 4g txt | awk -F, '!visited[$1]++' | sort -k2,2 -k3,3 >> final_file

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Подход без awk, использующий GNU datama sh:

$ datamash -H -f -t, -g1 min 4 < input.txt | cut -d, -f1-4
ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8

(cut необходим, потому что с опцией -f datamash добавляет пятый столбец, который является дубликатом четвертого, без него будут просто отображаться значения первого и четвертого столбцов. Незначительное раздражение.)

Для этого требуется, чтобы ваши данные были отсортированы по первому столбцу, как в вашем образец.

0 голосов
/ 29 января 2020

Вы можете сделать это довольно легко в awk, просто сохранив текущую запись с минимальным полем 4 th для данного поля 1 st . Вы должны обработать вывод строки заголовка и сохранить первую запись, чтобы начать сравнение, что вы можете сделать, работая с первой записью NR==1 (или первой в каждом обработанном файле, FNR==1).

Вы можете сохранить первый минимум в массиве, проиндексированном первым полем, и сохранить исходную запись, содержащую значения, работающие с записью 2 nd . Тогда нужно просто проверить, не совпадает ли первое поле с последним, если это так, выведите минимальную запись для последней и продолжайте, пока у вас не кончатся записи. ( примечание: это предполагает, что первые поля появляются в порядке возрастания, как и в вашем файле) Затем вы используете правило END для вывода окончательной записи.

Вы можете поместить это вместе следующим образом:

awk -F, '
    FNR==1 {print; next}
    FNR==2 {rec=$0; m[$1]=$4; next}
    {
        if ($1 in m) {
            if ($4 < m[$1]) {
                rec=$0
                m[$1]=$4
            }
        }
        else {
            print rec
            rec=$0
            m[$1]=$4
        }
    }
END {
    print rec
}' file

(где ваши данные находятся в файле file)

Если ваше первое поле не в порядке возрастания, вам необходимо сохранить текущий минимум запись в массиве также. (например, превратить rec в массив, индексированный первым полем, содержащим итоговую запись в качестве значения). Затем вы отложите зацикливание обоих массивов до правила END для вывода минимальной записи для каждого первого поля.

Пример использования / Вывод

Вы можете обновить имя файла, совпадающее с именем файла, содержащим ваши данные, а затем для проверки все, что вам нужно сделать, это выбрать-скопировать выражение awk и вставить его средней мышью в xterm в каталоге, содержащем ваш file, например,

$ awk -F, '
>     FNR==1 {print; next}
>     FNR==2 {rec=$0; m[$1]=$4; next}
>     {
>         if ($1 in m) {
>             if ($4 < m[$1]) {
>                 rec=$0
>                 m[$1]=$4
>             }
>         }
>         else {
>             print rec
>             rec=$0
>             m[$1]=$4
>         }
>     }
> END {
>     print rec
> }' file
ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8

Посмотрите вещи и дайте мне знать, если у вас есть вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...