Некоторым кажется, что разработчики BI делают магию. Например, как в нашем сегодняшнем примере – анализируют данные, которых в факт-таблицах нет. Заинтриговал? Значит, теперь подробности =)

Учет пациентов

Предположим, что у нас есть частная клиника, которая ведет прием и госпитализацию пациентов. У клиники несколько источников данных и есть цель создать единый аналитический интерфейс для учета и прогнозирования, в том числе потока пациентов и их оплат.

В чем магия? По сути, у нас нет источника данных с повторными приемами пациентов, а есть только значения записей по приемам такого вида:

Имя пациента Дата приема Дата выписки
Пациент 1 1/1/2016 1/4/2016
Пациент 1 1/7/2016 1/10/2016
Пациент 1 1/30/2016 2/4/2016

Для владельца клиники в этих данных все очевидно. Пациент пришел 7 января, а затем пришел еще раз в конце того же месяца – 30 января. Но для разработчика нужна отдельная строка с четким указанием, что прием был повторным.

Получается, что в голове сотрудника повторный прием учтен, но в базе данных этих данных нет. Конечно, можно сделать дополнительный отчет с колонкой – повторный прием, первичный прием. Но нам нужен отчет более глубокий, поскольку нам нужно точно учитывать посещения каждого пациента, их количество, обратился ли человек с тем же диагнозом или другим.

ID Имя пациента Прием Выписка Тип пациента Диагноз
1 Пациент 1 1/1/2016 1/4/2016 Стационар 1
2 Пациент 1 1/7/2016 1/10/2016 Амбулаторно 2
3 Пациент 1 1/30/2016 2/4/2016 Стационар 1
4 Пациент 1 2/6/2016 2/10/2016 Стационар 2
5 Пациент 1 2/11/2016 2/16/2016 Стационар 1

Так, например, мы не хотим сравнивать визиты с разными диагнозами, а лишь, например, 2/11 с 2/4.

Как правило, в таблицах хранится код диагноза, согласно принятой системе медицинской учета:

ID ICD9_1 ICD9_2 ICD9_3 ICD9_4 ICD9_…. ICD9_25
1 491.1 023.2 33.5 V16.9 37.52

То есть у нас есть таблица с такими цифрами:

491.1, 491.20, 491.21, 491.22, 491.8, 491.9, 492.0, 492.8, 493.20, 493.21, 493.22, 494.0, 494.1, 496

А для дальнейшей классификации идут другие подкатегории:

33.51, 33.52, 37.51, 37.52, 37.53, 37.54, 37.62, 37.63′, 33.50, 33.6, 50.51, 50.59, 52.80, 52.82, 55.69′,’196.0, 196.1, 196.2, 196.3, 196.5, 196.6, 196.8, 196.9, 197.0, 197.1, 197.2, 197.3, 197.4, 197.5, 197.6, 197.7, 197.8, 198.0, 198.1, 198.2, 198.3, 198.4, 198.5, 198.6, 198.7, 198.81, 198.82, 198.89, 203.02, 203.12, 203.82, 204.02, 204.12, 204.22, 204.82, 204.92, 205.02, 205.12, 205.22, 205.82, 205.92, 206.02, 206.12, 206.22, 206.82, 206.92, 207.02, 207.12, 207.22, 207.82, 208.02, 208.12, 208.22, 208.82, 208.92, 480.3, 480.8, 996.80, 996.81, 996.82, 996.83, 996.84, 996.85, 996.86, 996.87, 996.89, V42.0, V42.1, V42.4, V42.6, V42.7, V42.81, V42.82, V42.83, V42.84, V42.89, V42.9, V43.21, V46.11

Итак, как же представить все это в Qlik?

Шаг 1

Если объединить коды диагнозов 15-25 в одно поле, то сравнить их будет проще и понять, какой назначить пациенту. Qlik поможет это сделать через скрипт загрузки и функцию Concatenate:

Шаг 2

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

Encounters:

Шаг 3

Далее предлагаю воспользоваться функцией “Previous”. Она позволяет посмотреть предыдущую строку. Если вы на второй строке, вы можете проверить значение первой строки. Вот как это работает:

IF(MRN = Previous(MRN),’Yes’, ‘No’) as [Inpatient IsReadmission Flag],

Если значение то же, что и в строке выше, тогда это повторный прием, иначе нет. Если нет, то это новый пациент.

Конечно, это упрощенная версия кода. Значение «да-нет» – хорошо для компьютера, а нам нужно читаемый вид для человека, поэтому используем функцию DUAL, что позволит иметь одно поле для значений и да, и нет.

IF(MRN = Previous(MRN),Dual(‘Yes’, 1),Dual(‘No’,0)) as [Inpatient IsReadmission Flag],

Благодаря этой функции, мы можем использовать такое выражение:

Sum([Inpatient IsReadmission Flag])

Итоговый скрипт выглядит следующим образом:

Назовем наши поля по-другому:

Аналогичный скрипт пишем для другого диагноза.

И то же мы делаем, когда нам нужно создать поля, которых нет в модели.

ReadmissionsFields

Дэшборд приема пациентов

В итоге у нас получился такой дэшборд:

ReadmissionsDashboard

readmissionsDashboard_MeasureForSum

Вот и все на сегодня. Хороших вам разработок!