Narrativas de datos sobre el uso racional de medicamentos: Construcción de la línea base

Por:

Yaneth Gil | Offray Luna

Proyecto Piamed fase 2

Licencia Creative Commons
Narrativas de datos sobre el uso racional de medicamentos: Construcción de la línea base por Yaneth Gil y Offray Luna se distribuye bajo una Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional.
Basada en una obra en http://beta.piamed.org/repos.fossil/uso-racional/home.

El siguiente documento es una narrativa de datos para construir un argumento que ayude al uso racional de medicamentos específicamente ARAS e IECAS (por las siglas para Antagonistas del Receptor de Angiotensina y Inhibidores de la Enzima Convertidora de Angiotensina, respectivamente). En esta se vinculan tanto texto como gráficas, algoritmos y consultas a bases de datos, para construir una línea base que nos permita resolver varias preguntas referidas a los hábitos de prescripción actuales.

Debido al creciente auge de las narrativa de datos pero su relativo desconocimiento en la forma como se producen y publican, creemos conveniente que este documento tenga un caracter tutorial y por tanto se muestran los pasos que progresivamente permiten la construcción de la narrativa desde elementos más básicos a otros más automatizados y complejos, para finalmente pasar a elementos más interpretativos y analíticos. Consecuentemente, hemos divido el documento en varias partes:

Hasta donde los autores tienen conocimiento, este es un documento nóvel en Iberoamérica, en el sentido de que, si bien se alinea con la tendencia mundial actual de construir narrativas de datos y liberar información para una mejor comprensión y gestión compartida de un mundo complejo, lo hace dentro del marco del proyecto Piamed, que se propuso la formulación y ejecución de un proyecto de innovación abierta y comunitaria de información para el acceso a medicamentos, y desde allí se ocupó de las labores administrativas, legales, tecnológicas, académicas, que permiten la construcción del presente documento, como uno de los 4 subproyectos claves del mismo. El proyecto realizó la recolección y curaduría de la información, la articulación a un marco legal que permite su liberación en el contexto colombiano dentro de una estrategia de Gobierno en línea y Open Data, la disposición de infraestructura tecnológica de software libre y de código abierto para su tratamiento, auditoría y reproducción, que integra en un único documento interactivo, diferentes actividades asociadas a la exploración e interpretación de los datos: como son la consulta de datos, visualización, exportación en versión pdf y publicación en línea. El documento y los datos que lo soportan ha sido liberado con una licencia abierta, de manera que permita a otros lectores, asumir también el papel de auditores y autores y formularse sus propios cuestionamientos y descubrimientos frente a la información.

Palabras clave: Narrativas de datos, uso racional de medicamentos, innovación abierta y comunitaria, Datos Abiertos, Gobierno en línea, Gobierno Abierto, Ciencia Abierta, Ciencia Reproducible.

Narrativas de datos y herramientas para ella

Supondremos que el lector ya tiene instalado el IPython Notebook, que es la herramienta con la que haremos la narrativa y nos servira para integrar otras, que iremos explicando en la medida en que avancemos en el documento. También supodremos que está trabajando en un entorno Unix como Mac o Gnu/Linux (Ubuntu, Debian, Arch), pues, si bien el documento puede ser leído desde cualquier navegador y existe soporte para las herramientas en Windows, la instalación y uso es más fluido en los anteriores sistemas operativos.

Empezaremos por agregar el sorpote para bases de datos usando el módulo IPython-SQL. Desde la consola de comandos ejecutamos:

    sudo pip install ipython-sql

Para probar que la instalación ha funcionado adecuadamente haremos una consulta pequeña en una base de datos minimalista que ya viene integrada con python (y por tanto con IPython), llamada sqlite, siguiendo el ejemplo de acá.

In [2]:
# cargamos la extensión de sql
%load_ext sql
The sql extension is already loaded. To reload it, use:
  %reload_ext sql

In [3]:
# Nos conectamos a una base de datos en sqlite
%sql sqlite://
Out[3]:
'Connected: None@None'
In [20]:
# Ahora creamos una tabla de pruebas pequeña
%sql \
CREATE TABLE escritor (nombres, apellidos, muerte); \
INSERT INTO escritor VALUES ('Gabriel', 'García Marquez', 2014); \
INSERT INTO escritor VALUES ('Bertold', 'Bretch', 1956);
(OperationalError) table escritor already exists u'CREATE TABLE escritor (nombres, apellidos, muerte);' ()

Vamos a ver la tabla creda

In [23]:
%sql select * from escritor
Done.

Out[23]:
nombres apellidos muerte
Gabriel García Marquez 2014
Bertold Bretch 1956

Exploración de bases de datos hospitalarias en Cundinamarca (Colombia)

Ahora que sabemos que el soporte para bases de datos funciona, haremos ya las consultas y conexiones a una base de datos preexistente en MySQL, que contiene la información curada y anonimizada de prescripción en 7 hospitales de Cundinamarca.

In [93]:
# Importamos los módulos de soporte para bases a datos desde Pandas
import pandas.io.sql as pdsql
import MySQLdb

# Importamos dataframe y pandas que nos permitirá trabajar con estructuras matriciales de datos
from pandas import DataFrame
import pandas as pd

# Importamos el soporte de graficación
from matplotlib import pyplot
# colocamos las gráficas dentro del notebook
%matplotlib inline

# Importamos el soporte para operaciones numéricas y arreglos vía numpy
import numpy as np

# Definimos el total de hospitales para este levantamiento
# de información, que es una constante
totalHospitales = 7

Si bien se espera liberar la información dentro de las estrategías de gobierno en línea y open data, por lo pronto los datos de ingreso a la base de datos ha sido almacenada en un archivo separado, de modo que sólo quienes tienen acceso a dicho archivo pueden hacer las consultas y acceder a la información. En la siguiente línea abrirmos ese archivo y lo evaluamos de modo tal que todos los datos queden almacenados en el diccionario de datos llamado datosIngreso.

In [21]:
datosIngreso = eval(open("ingresoDb.py", "r").read())
In [108]:
# Establecemos la conexión a la base de datos
conexion = MySQLdb.connect(host = datosIngreso["host"],
                           port = datosIngreso["port"],
                           user = datosIngreso["user"],
                           passwd = datosIngreso["password"],
                           db = datosIngreso["db"])
In [17]:
# Definamos unas consultas del número de pacientes (Población total) en
# cada uno de los hospitales
consultaSqlTotalPacientes = """
            SELECT COUNT(DISTINCT id_paciente) 
            FROM e_consolidado 
            WHERE fecha_folio_hc 
                BETWEEN '2013-10-01' AND '2014-03-31' 
                AND tipo_ingreso=1 
                AND institucion=1;
            """
In [18]:
# Seleccionemos los datos a partir de esta consulta 
totalPacientesHospital1 = pdsql.read_sql(consultaSqlTotalPacientes, conexion) 
totalPacientesHospital1
Out[18]:
COUNT(DISTINCT id_paciente)
0 10778

Ahora bien, esta consulta es para un sólo hospital, pero quisiéramos hacerla mucho más modular para que los disintintos hospitales puedan ser consultados más fácilmente. En ese caso es mejor convertir la consulta en una función.

In [112]:
def sqlTotalPacientesHospital(n):
    # Parte comun de la consulta
    comun = """
         SELECT COUNT(DISTINCT id_paciente) 
            FROM e_consolidado 
            WHERE fecha_folio_hc 
                BETWEEN '2013-10-01' AND '2014-03-31' 
                AND tipo_ingreso=1 
                AND institucion=
        """
    # Parte variable de la consulta
    hospital = n
    # Unimos la parte común y la variable para tener nuestro resultado final
    return comun + str(hospital) + ";"

Con esta nueva consulta parametrizada podemos también parametrizar la consulta desde pandas:

In [113]:
def totalPacientesHospital(n):
    return pdsql.read_sql(sqlTotalPacientesHospital(n), conexion)

Así para extractar el valor dentro la consulta que habíamos hecho antes, invocamos simplemente en:

In [15]:
totalPacientesHospital(1).ix[0,0]
Out[15]:
10778

y se tiene la ventaja de poder invocarla fácilmente para otro hospital:

In [114]:
totalPacientesHospital(2).ix[0,0]
Out[114]:
19062

e incluso podemos construir una estructura de datos que guarde la información para todos los hospitales:

In [115]:
pacientesPorHospital = {}
for i in range(1,totalHospitales + 1): 
    pacientesPorHospital[i] = totalPacientesHospital(i).ix[0,0]
pacientesPorHospital
Out[115]:
{1: 10778, 2: 19062, 3: 3515, 4: 27594, 5: 8997, 6: 8321, 7: 9366}

A partir del anterior diccionario podemos definir un dataframe que nos da ciertas facilidades de consulta y graficación:

In [116]:
dfPacientesPorHospital = DataFrame(pacientesPorHospital, index=[0])
dfPacientesPorHospital.plot(kind='bar', stacked=False, title= u'Pacientes por hospital')
Out[116]:
<matplotlib.axes.AxesSubplot at 0x7f660d311650>
In [17]:
## Se define la totalidad de pacientes por Sexo de acuerdo a la siguiente convención:
## 1 Hombre
## 2 Mujer

sqlPacientesPorSexo = """
    SELECT sexo, 
    COUNT(DISTINCT id_paciente)
    FROM e_consolidado
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
    AND institucion = '1'
    AND tipo_ingreso = '1'
    GROUP BY sexo;"""
In [18]:
# Seleccionemos los datos a partir de esta consulta 
totalPacientesPorSexoHospital1 = pdsql.read_sql(sqlPacientesPorSexo, conexion) 
totalPacientesPorSexoHospital1 
Out[18]:
sexo COUNT(DISTINCT id_paciente)
0 1 4562
1 2 6216

2 rows × 2 columns

In [19]:
# Automatizamos la consulta para que use variables para la institución en lugar de valores fijos
def sqlTotalPacientesPorSexoHospital(n):
    # Parte comun de la consulta
    comun = """
         SELECT sexo, 
         COUNT(DISTINCT id_paciente)
         FROM e_consolidado
         WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
           AND institucion = '%i'
           AND tipo_ingreso = '1'
         GROUP BY sexo;"""
    # Unimos la parte común y la variable para tener nuestro resultado final
    return comun %(n)

De esta manera podemos definir una consulta que nos retorne los pacientes por hospital, agrupados por sexo:

In [15]:
def totalPacientesPorSexoHospital(n):
    return pdsql.read_sql(sqlTotalPacientesPorSexoHospital(n), conexion) 
In [51]:
pacientesPorSexoHospital = {}
for i in range(1,totalHospitales + 1): 
    pacientesPorSexoHospital[i] = totalPacientesPorSexoHospital(i)
# pacientesPorSexoHospital
In [24]:
# Consolidado Pacientes Por Sexo- Tenemos que dividir esto en dos
# ciclos disintos e integrarlos al final. No sabemos si es una limitación
# de pandas (PREGUNTAR en stackoverflow). 
dfPacientesPorSexoHospital1 = pacientesPorSexoHospital[1]
for i in range(2,4):
    dfPacientesPorSexoHospital1 = pd.merge(dfPacientesPorSexoHospital1, pacientesPorSexoHospital[i], on='sexo', how='outer')
dfPacientesPorSexoHospital2 = pacientesPorSexoHospital[4]
for i in range(5,8):
    dfPacientesPorSexoHospital2 = pd.merge(dfPacientesPorSexoHospital2, pacientesPorSexoHospital[i], on='sexo', how='outer')
dfPacientesPorSexoHospital = pd.merge(dfPacientesPorSexoHospital1, dfPacientesPorSexoHospital2, on='sexo', how='outer')
dfPacientesPorSexoHospital
Out[24]:
sexo COUNT(DISTINCT id_paciente)_x_x COUNT(DISTINCT id_paciente)_y_x COUNT(DISTINCT id_paciente) COUNT(DISTINCT id_paciente)_x_y COUNT(DISTINCT id_paciente)_y_y COUNT(DISTINCT id_paciente)_x_y COUNT(DISTINCT id_paciente)_y_y
0 1 4562 7935 1327 10716 3130 3021 3886
1 2 6216 11130 2188 16878 5867 5300 5481

2 rows × 8 columns

Ya que tenemos el data frame que guarda nuestros consolidados, vamos a extraer los datos, de modo que podamos manipularlos de manera más discreta y enviarselos, por ejemplo a los gráficos que haremos a partir de ellos.

In [101]:
listaPacientesPorSexoHospital = np.array(dfPacientesPorSexoHospital.get_values()).tolist()
totalHombres = listaPacientesPorSexoHospital[0][1:8]
totalMujeres = listaPacientesPorSexoHospital[1][1:8]
In [102]:
# Basados en: http://people.duke.edu/~ccc14/pcfb/numpympl/MatplotlibBarPlots.html#simple-bar-plot

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

## the data
N = totalHospitales
menMeans = totalHombres
womenMeans = totalMujeres

## necessary variables
ind = np.arange(N)                # the x locations for the groups
width = 0.35                      # the width of the bars

## the bars
rects1 = ax.bar(ind, menMeans, width,
                color='black')

rects2 = ax.bar(ind+width, womenMeans, width,
                    color='red')

# axes and labels
ax.set_xlim(-width,len(ind)+width)
ax.set_ylim(0,20000)
ax.set_ylabel(u'Número de pacientes')
ax.set_title(u'Número de pacientes agrupados por sexo')
xTickMarks = ['Hospital '+str(i) for i in range(1,8)]
ax.set_xticks(ind+width)
xtickNames = ax.set_xticklabels(xTickMarks)
plt.setp(xtickNames, rotation=45, fontsize=10)

## add a legend
ax.legend( (rects1[0], rects2[0]), ('Hombres', 'Mujeres') )

plt.show()
In [45]:
In [20]:
## Consultas médicas por mes

totalConsultasporMes = """
    SELECT MONTH(fecha_folio_hc),YEAR(fecha_folio_hc), COUNT(DISTINCT CONCAT(fecha_folio_hc,id_paciente)) 
    FROM e_consolidado 
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
    AND institucion ='1' 
    AND tipo_ingreso ='1' 
    GROUP BY MONTH(fecha_folio_hc),YEAR(fecha_folio_hc)
    ORDER BY YEAR(fecha_folio_hc);"""
In [21]:
totalConsultasporMesHospital1 = pdsql.read_sql(totalConsultasporMes, conexion) 
totalConsultasporMesHospital1
Out[21]:
MONTH(fecha_folio_hc) YEAR(fecha_folio_hc) COUNT(DISTINCT CONCAT(fecha_folio_hc,id_paciente))
0 10 2013 4632
1 11 2013 4048
2 12 2013 4096
3 1 2014 4604
4 2 2014 4590
5 3 2014 5387

6 rows × 3 columns

In []:
#automatizar
In [106]:
## Los medicamentos antihipertensivos identificados en los hospitales se han agrupado 
## por grupo farmacológico. La siguiente consulta tiene como objetivo identificar 
## cuantos estan en tratamiento con cada grupo farmacológico

pacientesporGrupoAntihipertensivo = """

    SELECT Antihipertensivo, COUNT(DISTINCT id_paciente)
    FROM e_consolidado 
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
    AND institucion ='1' 
    AND tipo_ingreso ='1'
    AND Antihipertensivo <>'' 
    GROUP BY Antihipertensivo;"""
In [109]:
dfPacientesGrupoAntihipertensivoHospital1 = pdsql.read_sql(pacientesporGrupoAntihipertensivo, conexion) 
dfPacientesGrupoAntihipertensivoHospital1
Out[109]:
Antihipertensivo COUNT(DISTINCT id_paciente)
0 AA 36
1 AB 92
2 ARA 660
3 BB 288
4 CA 354
5 DU 572
6 IECA 541

7 rows × 2 columns

In [110]:
# Gráfica de torta. Base tomada de: 
# http://matplotlib.org/1.2.1/examples/pylab_examples/pie_demo.html
"""
Make a pie chart - see
http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring.

This example shows a basic pie chart with labels optional features,
like autolabeling the percentage, offsetting a slice with "explode",
adding a shadow, and changing the starting angle.

"""


# make a square figure and axes
figure(1, figsize=(6,6))
ax = axes([0.1, 0.1, 0.8, 0.8])

# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]
explode=(0, 0.05, 0, 0)

pie(fracs, explode=explode, labels=labels,
                autopct='%1.1f%%', shadow=True, startangle=90)
                # The default startangle is 0, which would start
                # the Frogs slice on the x-axis.  With startangle=90,
                # everything is rotated counter-clockwise by 90 degrees,
                # so the plotting starts on the positive y-axis.

title('Raining Hogs and Dogs', bbox={'facecolor':'0.8', 'pad':5})

show()
In []:
#automatizar
In [48]:
## Calculamos el total de médicos por institución durante el periodo
## (Octubre de 2013 a Marzo de 2014)

medicosPeriodo = """
    SELECT COUNT(DISTINCT medico) 
    FROM e_consolidado 
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
        AND institucion ='1' 
        AND tipo_ingreso ='1';"""
In [49]:
medicosPeriodoHospital1 = pdsql.read_sql(medicosPeriodo, conexion) 
medicosPeriodoHospital1
Out[49]:
COUNT(DISTINCT medico)
0 54

1 rows × 1 columns

In [51]:
#Sin embargo se identifica que existen especialidades no médicas en la 
#base de datos, dado que otros profesionales de la salud también utilizan
#la historia clínica, por tanto se deben identificar cuales son esas 
#profesiones distintas para excluirlas del conteo

Especialidades = """
    SELECT DISTINCT especialidad 
    FROM e_consolidado
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
        AND tipo_ingreso = '1'
        AND especialidad <>'';"""
In [52]:
diferentesEspecialidadesdb = pdsql.read_sql(Especialidades, conexion) 
diferentesEspecialidadesdb
Out[52]:
especialidad
0 MEDICINA INTERNA
1 MEDICINA GENERAL
2 ORTOPEDIA Y TRAUMATOLOGIA
3 ODONTOLOGIA
4 MEDICINA DE URGENCIAS Y DOMICILIARIA
5 CIRUGIA GENERAL
6 GINECOLOGIA Y OBSTETRICIA
7 ECOGRAFIA OBSTETRICA
8 PSIQUIATRIA
9 ESPIROMETRIA PRE Y POST BRONCODILACION
10 PEDIATRIA
11 MEDICO HOSPITALARIO
12 ENFERMERA JEFE
13 GASTROENTEROLOGIA Y ENDOSCOPIA DIGESTIVA
14 OPTOMETRIA
15 UROLOGIA
16 CIRUGIA PLASTICA
17 OTORRINOLARINGOLOGIA
18 ENFERMERIA JEFE
19 ECOGRAFIAS
20 COLPOSOCPIAS
21 ODONTOLOGIA PEDIATRICA
22 OFTALMOLOGIA
23 MEDICO FAMILIAR
24 FISIATRIA Y ELECTROMIOGRAFIAS ...
25 NEUROCIRUGIA ...
26 ANESTESIOLOGIA ...
27 CUIDADOS INTENSIVOS Y REANIMACION
28 CUIDADOS INTERMEDIOS ...
29 DERMATOLOGIA ...
30 CARDIOLOGIA ...
31 CIRUGIA ORAL Y MAXILOFACIAL ...
32 ATENCION PROMOCION Y PREVENCION ...
33 ENDODONCIA ...
34 GASTROENTEROLOGIA ...
35 COLPOSCOPIAS ...
36 GINECOLOGIA
37 ECOGRAFIAS OBSTETRICA ...
38 NUTRICION ...
39 ODONTOLOGIA INTEGRAL DEL ADULTO ...
40 ECOGRAFIAS UROLOGICAS ...
41 CONTROL PRENATAL ...
42 CRECIMIENTO Y DESARROLLO ...
43 NEONATOLOGIA ...
44 RETINOLOGIA ...
45 URODINAMIAS
46 NASOFIBROBRONCOSCOPIA
47 ENFERMERIA EN HOSPITALIZACION
48 TELECONSULTA
49 OBSTETRICIA
50 CARDIOLOGIA PEDIATRICA ...
51 CIRUGIA ORTOPEDICA Y TRAUMATOLOGIA ...
52 ENFERMERIA PROMOCION Y PREVENCION ...
53 CONTROL POST-QX ORTOPEDIA ...
54 PROMOCION Y PREVENCION
55 CIRUGIA MAXILOFACIAL ...
56 ENFERMERIA ...
57 ANESTESIOLOGIA Y REANIMACION ...
58 HIGIENISTA ORAL ...
59 AUXILIAR DE ENFERMERIA

60 rows × 1 columns

In [3]:
##Se realiza nuevamente la consulta excluyendo las especialidades
## no médicas (Enfermera jefe, Optometría, Enfermeria jefe, Odontología pediátrica, 
## Endodoncia, Nutrición, Odontología integral del adulto, Enfermeria en Hospitalización
##Enfermeria promocion y prevencion, Enfermeria, Higienista oral, Auxiliar de enfermeria

especialidadesMedicas = """
    SELECT COUNT(DISTINCT medico)
    FROM e_consolidado
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
        AND tipo_ingreso = '1'
        AND especialidad not REGEXP 'enferme|optome|odontol|endodon|nutric|higienis'
        AND institucion = '1';"""
In [4]:
medicosPeriodo = pdsql.read_sql(especialidadesMedicas, conexion) 
medicosPeriodo
Out[4]:
COUNT(DISTINCT medico)
0 50

1 rows × 1 columns

In []:
#automatizar
In [26]:
##Considerando que la consulta medicosPeriodo corresponde a la totalidad de medicos
##durante el periodo comprendido entre octubre de 2013 y marzo de 2014 calculamos 
## ahora la cantidad de medicos por mes para establecer el promedio de médicos de 
## la institución dado que existe alta rotación de personal

sqlMedicosPorMes = """
    SELECT MONTH(fecha_folio_hc), YEAR(fecha_folio_hc), 
    COUNT(DISTINCT medico)
    FROM e_consolidado
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
        AND tipo_ingreso = '1'
        AND especialidad not REGEXP 'enferme|optome|odontol|endodon|nutric|higienis'
        AND institucion = '1'
    GROUP BY MONTH(fecha_folio_hc), YEAR(fecha_folio_hc)
    ORDER BY YEAR(fecha_folio_hc);"""
In [27]:
totalMedicosPorMes = pdsql.read_sql(sqlMedicosPorMes, conexion) 
totalMedicosPorMes
Out[27]:
MONTH(fecha_folio_hc) YEAR(fecha_folio_hc) COUNT(DISTINCT medico)
0 10 2013 33
1 11 2013 34
2 12 2013 32
3 1 2014 34
4 2 2014 32
5 3 2014 35

6 rows × 3 columns

In []:
##Automatizar
In []:
## Seria conveniente poder estimar la rotación de medicos durante el periodo
In [28]:
##Establecemos la totalidad de médicos por especialidad. Esto nos ayudará a 
##definir cuales son los médicos que más prescriben antihipertensivos y así
##priorizar los grupos que requieren mayor intervención

sqlMedicosPorEspecialidad = """
    SELECT especialidad, 
    COUNT(DISTINCT medico)
    FROM e_consolidado
    WHERE fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31'
        AND tipo_ingreso = '1'
        AND especialidad not REGEXP 'enferme|optome|odontol|endodon|nutric|higienis'
        AND institucion = '1'
    GROUP BY especialidad
    ORDER BY especialidad;"""
In [29]:
totalMedicosPorEspecialidad = pdsql.read_sql(sqlMedicosPorEspecialidad , conexion) 
totalMedicosPorEspecialidad
Out[29]:
especialidad COUNT(DISTINCT medico)
0 ANESTESIOLOGIA Y REANIMACION ... 2
1 CARDIOLOGIA ... 1
2 CIRUGIA GENERAL ... 11
3 CIRUGIA MAXILOFACIAL ... 1
4 GASTROENTEROLOGIA Y ENDOSCOPIA DIGESTIVA ... 1
5 GINECOLOGIA Y OBSTETRICIA ... 4
6 MEDICINA GENERAL ... 24
7 MEDICINA INTERNA ... 5
8 ORTOPEDIA Y TRAUMATOLOGIA ... 2
9 OTORRINOLARINGOLOGIA ... 1
10 PEDIATRIA ... 1
11 PROMOCION Y PREVENCION 3
12 UROLOGIA ... 1

13 rows × 2 columns

In []:
##Automatizar
In []:
##Considerar las siguientes opciones: Agrupar por principales especialidades y otras o
##mostrar el detalle y agrupar las que corresponden a la misma pero cambia denominación
##entre hospitales
In [30]:
##Ahora identificamos la totalidad de pacientes con cada medicamento antihipertensivo

sqlPacientesPorAntihipertensivo = """
     SELECT med_nombre, 
     COUNT(DISTINCT id_paciente) 
     FROM e_consolidado 
     WHERE antihipertensivo NOT LIKE '' 
         AND fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
         AND institucion = '1' 
         AND tipo_ingreso = '1'
    GROUP BY med_nombre;"""
In [31]:
totalPacientesPorAntihipertensivo = pdsql.read_sql(sqlPacientesPorAntihipertensivo , conexion) 
totalPacientesPorAntihipertensivo
Out[31]:
med_nombre COUNT(DISTINCT id_paciente)
0 AMLODIPINO TABLETA 5 MG 235
1 CAPTOPRIL TABLETA 25 MG 191
2 CAPTOPRIL TABLETA 50 MG 249
3 CLONIDINA TABLETA 0.150 MG 32
4 ENALAPRIL MALEATO TABLETA 20 MG 216
5 ENALAPRIL MALEATO TABLETA 5 MG 57
6 ESPIRONOLACTONA TABLETA 100 MG 11
7 ESPIRONOLACTONA TABLETA 25 MG 103
8 FUROSEMIDA SOLUCION INYECTABLE 20 MG/ 2ML 196
9 FUROSEMIDA TABLETA 40 MG 191
10 HIDROCLOROTIAZIDA TABLETA 25 MG 297
11 LOSARTAN POTASICO TABLETA 50 MG 656
12 LOSART�N X 100MG TABLETA 14
13 METILDOPA 250 MG TABLETA 4
14 METOPROLOL SOLUCION INYECTABLE 1 MG/ML 2
15 METOPROLOL TARTRATO TABLETA 100 MG 5
16 METOPROLOL TARTRATO TABLETA 50 MG 207
17 NIFEDIPINA CAPSULA DE LIBERACION PROGRAMADA 30 MG 82
18 NIFEDIPINO 10MG CAPSULAS 4
19 PRAZOSINA TABLETA 1 MG 92
20 PROPRANOLOL CLORHIDRATO TABLETA 40 MG 79
21 VERAPAMILO CLORHIDRATO TABLETA 120 MG 19
22 VERAPAMILO CLORHIDRATO TABLETA RECUBIERTA 80 MG 27

23 rows × 2 columns

In []:
##Afinamos la consulta para que nos agrupe por principio activo (ej: total de 
##pacientes con Enalapril, sin considerar concentración) y excluya inyectables
##dado que los medicamentos en esta presentación no son administrados de 
##manera ambulatoria

Calculo de DDD para cada uno de los medicamentos

In []:
##1-Extracción de la concentración de la columna medicamento

A continuacion se detallan otras variables marcadoras de prescripcion racional, relacionadas con el uso concomitante de ARA II e IECA e incluso el uso simultaneo de IECA. La formulacion concomitante de medicamentos que actuan sobre el mismo sistema, en este caso Bloqueadores del sistema Renina-Angiotensina corresponde a un problema relacionado con los medicamentos conocido comunmente como Duplicidad.

In []:
## Pacientes a quienes se les prescribieron 2 IECA (Captopril y Enalapril) de manera simultanea (en la misma fecha)
PacientesIECA_IECA = """
    SELECT COUNT(DISTINCT ec.id_paciente) 
    FROM e_consolidado AS ec
      JOIN (SELECT id_paciente, fecha_folio_hc 
            FROM e_consolidado 
            WHERE med_nombre LIKE '%capto%') AS t
    ON ec.id_paciente = t.id_paciente AND ec.fecha_folio_hc = t.fecha_folio_hc
    WHERE (ec.med_nombre LIKE '%enalap%' 
          AND ec.fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
          AND ec.tipo_ingreso=1 
          AND ec.institucion=1);"""
In []:
TotalPacientesIECA_IECA_Hospital1 = pdsql.read_sql(PacientesIECA_IECA, conexion)
TotalPacientesIECA_IECA_Hospital1 
In [14]:
def pacientesIECA_IECA(n):
    #Parte comun de la consulta
    comun = """
        SELECT COUNT(DISTINCT ec.id_paciente) 
        FROM e_consolidado 
        AS ec
        JOIN (SELECT id_paciente, fecha_folio_hc 
              FROM e_consolidado 
              WHERE med_nombre like '%capto%') 
              AS t

        ON ec.id_paciente = t.id_paciente AND ec.fecha_folio_hc = t.fecha_folio_hc
        WHERE (ec.med_nombre like '%enalap%' AND ec.fecha_folio_hc 
            BETWEEN '2013-10-01' AND '2014-03-31'
            AND ec.tipo_ingreso=1 AND ec.institucion=  """
    #Parte variable de la consulta
    hospital = n
    # Unimos la parte comun y la variable para tener nuestro resultado final
    return comun + str(hospital) + ") ;"
In [15]:
def totalPacientesIECA_IECA_Hospital(n):
    return pdsql.read_sql(pacientesIECA_IECA(n),conexion)
In [16]:
totalPacientesIECA_IECA_Hospital(1)
Out[16]:
COUNT(DISTINCT ec.id_paciente)
0 29

1 rows × 1 columns

In [40]:
## Pacientes a quienes se les prescribió 1 IECA (Captopril o Enalapril) y 1 ARA 
##(Losartan o Losartan + Hidroclorotiazida) de manera simultanea (en la misma fecha)

PacientesIECA_ARA0 = """
    SELECT COUNT(DISTINCT ec.id_paciente) 
    FROM e_consolidado AS ec
      JOIN (SELECT id_paciente, fecha_folio_hc 
            FROM e_consolidado 
            WHERE med_nombre REGEXP 'capto|enalap') AS t
    ON ec.id_paciente = t.id_paciente AND ec.fecha_folio_hc = t.fecha_folio_hc
    WHERE (ec.med_nombre REGEXP 'losart' 
          AND ec.fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
          AND ec.tipo_ingreso=1 
          AND ec.institucion=1);"""
In [41]:
totalPacientesIECA_ARA0_Hospital1 = pdsql.read_sql(PacientesIECA_ARA0, conexion)
totalPacientesIECA_ARA0_Hospital1 
Out[41]:
COUNT(DISTINCT ec.id_paciente)
0 130

1 rows × 1 columns

In [17]:
## Pacientes a quienes se les prescribió 1 IECA (Captopril) y 1 ARA (Losartan o Losartan + Hidroclorotiazida) de manera simultanea (en la misma fecha)
PacientesIECA_ARA = """
    SELECT COUNT(DISTINCT ec.id_paciente) 
    FROM e_consolidado AS ec
      JOIN (SELECT id_paciente, fecha_folio_hc 
            FROM e_consolidado 
            WHERE med_nombre LIKE '%capto%') AS t
    ON ec.id_paciente = t.id_paciente AND ec.fecha_folio_hc = t.fecha_folio_hc
    WHERE (ec.med_nombre REGEXP 'losart' 
          AND ec.fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
          AND ec.tipo_ingreso=1 
          AND ec.institucion=1);"""
In [19]:
totalPacientesIECA_ARA_Hospital1 = pdsql.read_sql(PacientesIECA_ARA, conexion)
totalPacientesIECA_ARA_Hospital1 
Out[19]:
COUNT(DISTINCT ec.id_paciente)
0 109

1 rows × 1 columns

In [20]:
##automatizar
In [38]:
## Pacientes a quienes se les prescribió 1 IECA (Enalapril) y 1 ARA (Losartan o Losartan + Hidroclorotiazida) 
## de manera simultanea (en la misma fecha)

PacientesIECA_ARA2 = """
    SELECT COUNT(DISTINCT ec.id_paciente) 
    FROM e_consolidado AS ec
      JOIN (SELECT id_paciente, fecha_folio_hc 
            FROM e_consolidado 
            WHERE med_nombre LIKE '%enala%') AS t
    ON ec.id_paciente = t.id_paciente AND ec.fecha_folio_hc = t.fecha_folio_hc
    WHERE (ec.med_nombre REGEXP 'losart' 
          AND ec.fecha_folio_hc BETWEEN '2013-10-01' AND '2014-03-31' 
          AND ec.tipo_ingreso=1 
          AND ec.institucion=1);"""
In [39]:
totalPacientesIECA_ARA2_Hospital1 = pdsql.read_sql(PacientesIECA_ARA2, conexion)
totalPacientesIECA_ARA2_Hospital1
Out[39]:
COUNT(DISTINCT ec.id_paciente)
0 31

1 rows × 1 columns

Referencias Extra

Acá unos enlaces extra que sirvieron durante la elaboración de este documento.

In []: