Учитывая размер ввода, который вы хотите выполнить потоковая обработка , а R не подходит для такой обработки, поэтому здесь мы используем простую программу gawk. gawk доступен в Rtools на Windows и изначально поставляется с большинством систем UNIX / Linux.
При первом проходе программа gawk создает ассоциативный массив disease
от заболевания поле, то есть второе поле ввода. Предположительно число заболеваний намного меньше, чем длина файла, так что это, вероятно, вписывается в память.
Затем за второй проход он считывает каждую группу записей, соответствующих пациенту, предполагая, что все записи для пациента являются последовательными Для каждого пациента он выводит одну строку с идентификатором пациента и последовательностью 0 и 1, так что i-й указывает на отсутствие или наличие i-го заболевания.
FNR == 1 { next } # skip header on both passes
# first pass - create disease array
FNR == NR {
disease[$2] = 0;
next;
}
# second pass - create and output flattened records
{
if ($1 != prevkey && FNR > 2) {
printf("%s ", prevkey);
for(d in disease) printf("%d ", disease[d]);
printf("\n");
for(d in disease) disease[d] = 0;
}
disease[$2] = 1;
prevkey = $1;
}
END {
if (FNR == NR) for(d in disease) {
print d;
} else {
printf("%s ", prevkey);
for(d in disease) printf("%d ", disease[d]);
printf("\n");
}
}
Если мы поместим вышеуказанный код gawk в model_mat .awk, тогда мы можем запустить его следующим образом - обратите внимание, что файл должен быть указан дважды - один раз для каждого из двух проходов:
gawk -f model_mat.awk disease.txt disease.txt
Выходные данные следующие, где мы предполагаем, что это требуется чтобы каждое заболевание было обозначено 1, если оно присутствует, или 0, если нет.
1111111111 1 1 1 1 1 1
1111111112 1 1 0 1 0 0
1111111113 1 0 0 0 1 0
Если мы запустим его только с одним аргументом blood.txt, тогда он будет выполнять только первый проход, а затем в конце перечислить болезни без дубликатов:
gawk -f model_mat.awk disease.txt
, что дает:
DISEASE:1
DISEASE:2
DISEASE:3
DISEASE:4
DISEASE:5
DISEASE:6
Список болезней
Альтернативой для перечисления болезней является UNIX конвейер, который перечисляет болезни без дубликатов и сортирует их. sed удаляет заголовок, cut занимает третье разделенное пробелами поле (это третье, потому что между двумя полями два пробела) и сортирует его по уникальным элементам.
sed 1d disease.txt | cut -f 3 -d " " | sort -u > diseases-sorted.txt
Сортировка и объединение
Утилита сортировки GNU может сортировать и объединять файлы, размер которых превышает объем памяти, и имеет параллельную опцию, чтобы ускорить ее. Также см. Бесплатную утилиту cmsort (только Windows).
csvfix
Ниже приведены некоторые сценарии, использующие бесплатную утилиту командной строки csvfix . Вам может потребоваться изменить кавычки в зависимости от процессора / оболочки командной строки, который вы используете, и вам нужно будет поместить каждый из них в одну строку или, соответственно, экранировать новую строку (backsla sh для bash, окружность для Windows cmd) , Для наглядности мы показали, что каждый конвейер распределен по отдельным строкам.
Первый конвейер ниже создает список заболеваний в одну колонку в болезнь-list.txt. Первая команда csvfix в нем удаляет заголовок, вторая команда csvfix извлекает второе поле (т.е. удаляет идентификатор пациента), а последняя команда csvfix уменьшает его до уникальных заболеваний.
Второй приведенный ниже конвейер создает файл с один ряд на пациента с идентификатором пациента, за которым следуют заболевания для этого пациента. Первая команда csvfix удаляет заголовок, вторая преобразует его в формат csv, а последняя команда csvfix выравнивает его.
csvfix remove -if "$line == 1" -smq disease.txt |
csvfix read_dsv -s " " -cm -f 2 |
csvfix uniq -smq > disease-list.txt
csvfix remove -if "$line == 1" -smq disease.txt |
csvfix read_dsv -s " " -cm -f 1,2 |
csvfix flatten -smq > flat.txt