Este problema tiene como objetivo guiarte en el desarrollo y anÔlisis de un modelo dinÔmico empleando el lenguaje de programación R. El objetivo es que te familiarices con las herramientas de anÔlisis en R y que inicies el desarrollo de tus propios modelos dinÔmicos. Para este efecto tomaremos como referencia el caso de la epidemia COVID-19, basÔndonos en el modelo bÔsico SIR, descrito por Sterman (2013) en el apartado 9.2.1.
Descripción del caso:
Para iniciar tomaremos como referencia el diagrama āstock-flowā de Sterman (2013) mostrado en la siguiente figura.
Como primer paso haremos un listado del tipo de variables en el modelo:
Variables de Estado (Stock variables)
Variables de flujo (flow variables)
Variables auxiliares endógenas (endogenous auxiliary variables)
ParÔmetros de simulación (variables en la frontera del sistema o exogenous auxiliary variables)
Esta clasificación es útil para organizar el espacio de trabajo en Rstudio.
Tutorial de modelado del caso en R:
Iniciaremos por definir este modelo dinÔmico como una función definida por el usuario siguiendo los siguientes pasos.
#Carga la librerĆa deSolve empleando la función library()
library("deSolve")
Declara el espacio de trabajo como una función definida por el usuario.
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
#Flow variables
#State (stock) variables
list(c())
})
}
Ahora agregaremos las variables de estado y los flujos asociadas a ellas. Iniciaremos con la variable de estado āPopulation Susceptible to COVIDā como se muestra en el chunk siguiente.
#Esta funcion se llena primero las variables de estado, luego las de flujo y finalmente las variables endógenas.
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
#Flow variables
#State (stock) variables
dpopulation.susceptible.to.COVID<-
list(c()) #Para que todo esté en un paquete grande ¿cuales son las variables que quiero responder en este modelo?
})
}
Nota que en R las variables no pueden ser nombradas con espacios. De manera que esta variable de estado es nombrada como: āpopulation.susceptible.to.COVIDā nota tambiĆ©n que las variables de estado son precedidas por el sĆmbolo diferencial ādā para indicar que esta es una variable de estado, la sintaxis completa es: ādpopulation.susceptible.to.COVIDā. DespuĆ©s de este paso habrĆ”s creado exitosamente la primera variable de estado del modelo.
Una prĆ”ctica muy recomendable es documentar tus modelos. En R puedes hacer esto empleando el sĆmbolo ā#ā y escribiendo delante de Ć©ste una breve descripción de la variable que estas representando. AdemĆ”s de describir la variable que estas creando es muy recomendable escribir tambiĆ©n las unidades de medición de tu variable. El siguiente chunk muestra un ejemplo:
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
#Flow variables
#State (stock) variables
#The population susceptible to COVID is equal to the
#population susceptible prior to the onset of the disease
#less all of those that have contracted it
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
#Esta linea indica que variables se imprimen como
#resultado de la integración del modelo, todas las
#variables de estado deben estar listadas
list(c())
})
}
Como se muestra en el stock-flow diagram, la variable āInfection.Rateā estĆ” conectada a la variable de estado como un flujo de salida (i.e.Ā outflow variable), esta estructura se modela como se muestra en el chunk anterior. Nota que esta variable de flujo afecta con signo negativo a la variable de estado. Este signo negativo especĆfica a esta variable de flujo como un flujo de salida.
Podemos seguir un proceso similar para modelar y documentar la segunda variable de estado āpopulation.infected.with.COVIDā como se muestra en la siguiente figura. Nota que en este caso la variable de flujo āInfection.Rateā es modelada como un flujo de entrada (i.e.Ā inflow variable) y por esta razón no se incluye un signo negativo y nota tambiĆ©n que la variable de estado āpopulation.infected.with.COVIDā es especificada precedida del signo diferencial ādā.
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
#Flow variables
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c())
})
}
Como se muestra en el stock-flow diagram, en este modelo solo existe una sola variable de flujo que estĆ” conectada a las variables de estado. Esta variable de flujo es determinada por dos variables auxiliares: āContacts between Infected and Uninfected Peopleā e āInfectivityā. Para este caso especificamos la variable de flujo āInfection.Rateā como la multiplicación simple de estas dos variables auxiliares tal como se muestra en la siguiente figura. Nota que al agregar esta nueva variable tambiĆ©n hemos incluido la documentación que describe esta variable y sus unidades de medición.
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
#Flow variables
Infection.Rate<-Infectivity*Contacts.bt.Infected.and.Uninfected.People #[people/time]
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c())
})
}
Al definir la variable de flujo āInfection.Rateā hemos agregado dos nuevas variables que debemos especificar. La variable āContacts between Infected and Uninfected Peopleā es una variable auxiliar endógena que es determinada por la variable āSusceptible Contactsā y la variable āProbability of Contact with Infected Personā esta interacción es especificada de la siguiente manera:
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
Contacts.bt.Infected.and.Uninfected.People<-Susceptible.Contacts*Probability.of.Contact.with.Infected #[people/time]
#Flow variables
Infection.Rate<-Infectivity*Contacts.bt.Infected.and.Uninfected.People #[people/time]
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c())
})
}
Al definir esta nueva variable hemos agregado dos nuevas variables auxiliares endógenas que debemos definir. La primera variable āSusceptible Contactsā es determinada por la variable de estado āPopulation Susceptible to COVIDā y por la variable āContact Frequencyā y es especificada como se muestra en la figura siguiente. Nota que en esta ocasión al emplear la variable de estado para definir otra variable endógena auxiliar no es necesario usar el sĆmbolo diferencial antes de la variable de estado.
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
Susceptible.Contacts<-population.susceptible.to.COVID*Contact.Frequency #[people/time]
Contacts.bt.Infected.and.Uninfected.People<-Susceptible.Contacts*Probability.of.Contact.with.Infected #[people/time]
#Flow variables
Infection.Rate<-Infectivity*Contacts.bt.Infected.and.Uninfected.People #[people/time]
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c())
})
}
La Ćŗltima variable endógena auxiliar por modelar es la variable āProbability of Contact with Infected Personā. De manera similar al caso anterior, esta variable es determinada por la variable de estado āpopulation infected with COVIDā dividida por la variable exógena auxiliar āTotal Populationā
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
Probability.of.Contact.with.Infected<-population.infected.with.COVID/Total.Population #dimensionless
Susceptible.Contacts<-population.susceptible.to.COVID*Contact.Frequency #[people/time]
Contacts.bt.Infected.and.Uninfected.People<-Susceptible.Contacts*Probability.of.Contact.with.Infected #[people/time]
#Flow variables
Infection.Rate<-Infectivity*Contacts.bt.Infected.and.Uninfected.People #[people/time]
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c())
})
}
Esto concluye la especificación de todos los elementos endógenos del modelo. El siguiente paso es especificar los valores de los parÔmetros (i.e. variables auxiliares exógenas), las condiciones iniciales de las variables de estado, el horizonte temporal de anÔlisis y el método de integración para la simulación.
En nuestro modelo hemos especificado tres parĆ”metros: āContact Frequencyā, āTotal Populationā e āInfectivityā.
En R podemos especificar los parÔmetros del modelo empleando un vector como se muestra en la siguiente figura. Nota que el nombre de los parÔmetros es idéntico al nombre empleando en la especificación descrita en los pasos anteriores. También nota que cada parÔmetro estÔ asociado a un valor numérico único para el cual correremos el modelo de simulación. Finalmente nota que para cada parÔmetro se especifican sus unidades de medición.
parameters<-c(Infectivity = 0.1, # [1] dimmensionless
Contact.Frequency = 2, # people/day
Total.Population = 350 ) #people)
De igual manera podemos emplear un vector en R para definir las condiciones iniciales de cada variable de estado, esto se muestra en la siguiente figura. Nuevamente el nombre de las variables de estado es idéntico al empleado en la especificación de la modelo y cada variable de estado es inicializada a un valor único.
InitialConditions <- c(population.susceptible.to.COVID = 349 ,
population.infected.with.COVID = 1)
Ahora es necesario especificar el vector de tiempo que serÔ usado para simular el modelo. Esta especificación se lleva a cabo como se muestra en la siguiente figura. Nota que para especificar este vector de tiempo empleamos la función seq(). Esta función crea una secuencia numérica y requiere tres parÔmetros: valor inicial, valor final e intervalo de crecimiento. En nuestro modelo dinÔmico estos tres parÔmetros representan el tiempo inicial de la simulación, el tiempo final de la simulación y la resolución temporal de la simulación. Nota que para cada parÔmetro hemos indicado la unidad de tiempo correspondiente.
times <- seq(0 , #initial time, days
120 , #end time, days
0.25 ) #time step, days
Aún no discutimos con detalle las propiedades de los diferentes métodos de integración que podemos emplear para simular nuestro modelo. Por lo pronto, para este ejercicio, elegiremos el método Runge-Kutta de Orden 4. El chunk siguiente muestra la forma de especificar este método de integración.
intg.method<-c("rk4")
El Ćŗltimo paso en el proceso de especificación del modelo es elegir las variables que serĆ”n āimpresasā por la simulación. Este es un paso muy importante ya que nos permite elegir las variables que deseamos analizar. La figura siguiente muestra la forma de especificar las variables a imprimir por el modelo. Nota que esto es especificado en la Ćŗltima lĆnea de código de la función contiene nuestro modelo dinĆ”mico. Nota tambiĆ©n que en este caso hemos elegido imprimir sólo las variables de estado y que ambas estĆ”n precedidas por el signo diferencial ādā y son concatenadas empleando la función c().
covid.epidemic <- function(t, state, parameters) {
with(as.list(c(state,parameters)), {
#Endogenous auxiliary variables
Probability.of.Contact.with.Infected<-population.infected.with.COVID/Total.Population #dimensionless
Susceptible.Contacts<-population.susceptible.to.COVID*Contact.Frequency #[people/time]
Contacts.bt.Infected.and.Uninfected.People<-Susceptible.Contacts*Probability.of.Contact.with.Infected #[people/time]
#Flow variables
Infection.Rate<-Infectivity*Contacts.bt.Infected.and.Uninfected.People #[people/time]
#State (stock) variables
dpopulation.susceptible.to.COVID<-(-1)*Infection.Rate #Stock units: People/time
dpopulation.infected.with.COVID<-Infection.Rate #Stock units: People/time
list(c(dpopulation.susceptible.to.COVID,
dpopulation.infected.with.COVID))
})
}
#el mismo orden que tengas en las variables de estado, tiene que ser el mismo que aparezca en la lista y en las condiciones iniciales (Āæcuantas personas ha infectadas y no infectadas?)
Esto concluye la especificación del modelo de simulación. El siguiente paso es ejecutar este código y llevar a cabo la simulación. Corre los chunks que contienen la librerĆa deSolve, los vectores que guardamos como parameters, InitialConditions, times e intg.method, y tambiĆ©n corre el chunk de la función covid.epidemic.
Una vez realizado esto, en la consola de R ya estĆ”n cargados tanto el modelo como todos los parĆ”metros necesarios para llevar a cabo la simulación, pero aĆŗn no hemos generado datos de la simulación. Para hacer esto, crearemos una base de datos āoutā que contiene los resultados de la simulación empleando la función āodeā. Nota que la función āodeā emplea como parĆ”metros de entrada condiciones iniciales de las variables de estado del modelo, el vector de tiempo, la función covid.epidemic que describe nuestro modelo, las variables exógenas (i.e.Ā parĆ”metros) y el mĆ©todo de integración. Todos estos elementos los hemos definido ya en los pasos anteriores.
#El cambio en las variable de estado a traƩs del tiempo (las 6 hrs que definimos)
out <- ode(y = InitialConditions,
times = times,
func = covid.epidemic,#aqui esta cargada la interacción entre las variables
parms = parameters,
method =intg.method )
Si has hecho esto correctamente verĆ”s un nuevo objeto llamado āoutā listado en el panel superior derecho.
El paso final es analizar grĆ”ficamente los resultados para esto emplea la función āplotā
plot(out,
col=c("blue"))
āāāāāāāāāāāāāāāāāāāāāāāāāTAREAāāāāāāāāāāāāāāāāāāāāā
Preguntas del caso:
4.1. Incluye tu modelo en un sólo chunk de código en el que se utilice la función plot para ver el comportamiento de las variables de estado.
GRAFICA 1:
4.2. ĀæQuĆ© sucede cuando inicializas la variable de estado āPopulation Infected with COVIDā en cero? Explica brevemente que origina el comportamiento que observas, emplea la estructura del modelo para cimentar tu argumentación.
Como nunca se inicia el ciclo de infectados nunca se va a vaciar la bañera. Es decir: cuando iniciamos la variable de estado en cero en el modelo, asumimos que no hay individuos infecciosos o recuperados al comienzo de la simulación. Esto significa que toda la población inicial es susceptible a la enfermedad. Entonces, sin individuos infecciosos iniciales, no hay transmisión de la enfermedad. Por lo tanto, la población susceptible permanece constante y no hay cambios en las poblaciones infecciosas o recuperadas.
GRAFICA 2:
4.3. ¿Cómo cambia la dinÔmica de comportamiento del modelo si inicializas esta variable de estado a un valor positivo diferente de cero?.
Iniciar con un valor positivo diferente de cero implica que hay un primer paciente que introduce la propagación de la enfermedad en el modelo. Esto lleva a un comportamiento donde la enfermedad se propaga, alcanza un pico y luego disminuye a medida que la población desarrolla inmunidad o se recupera (Como podemos ver en la grÔfica 1)
4.4. ĀæCómo cambia la dinĆ”mica del sistema si aumenta el valor del parĆ”metro āContact Frequencyā? ĀæEl valor de este parĆ”metro modifica el valor final de la variable de estado āPopulation Infected with COVIDā? Explica porque sĆ o porque no haciendo referencia a la estructura del modelo y a los resultados de la simulación.
El valor del parĆ”metro āContact Frequencyā no modifica el valor final de la variable de estado. Sin embargo, sĆ afecta la velocidad a la que se alcanza āPopulation Infected with COVIDā el valor final de la población recuperada
Esto se debe a que, en el modelo, la dinÔmica de la enfermedad estÔ determinada por la interacción entre susceptibles e infectados, y la recuperación es un proceso que eventualmente lleva a la desaparición de la enfermedad en la población.
4.5. ĀæCómo cambia el comportamiento del modelo si la variable de flujo āInfection Rateā cambia? Sigue los siguientes lineamientos para dar tu respuesta: Responde a esta pregunta describiendo brevemente los cambios que identificas al cambiar el valor de esta variable. Emplea un par de grĆ”ficos de comportamiento del modelo para dar soporte a tu respuesta.
Considerando que Infection Rate es la velocidad a la que las personas susceptibles se infectan al entrar en contacto con personas infectadas, entonces esta variable de flujo nos dice la rapidez con la que el COVID se propaga en la población.
Si esta variable aumenta, significa que la enfermedad se estĆ” propagando mĆ”s rĆ”pidamente. Esto puede pasar si las personas tienen mĆ”s contactos entre sĆ āContact Frequencyā o si el virus es mĆ”s contagioso āInfectivityā.
Si variable disminuye, significa que la enfermedad se estĆ” propagando mĆ”s lento. quizĆ” porque las personas tienen menos contactos entre sĆ.
Por lo que si bien āInfection Rateā afecta la velocidad y la cantidad de la propagación del COVID, no cambia que eventualmente, la población infectada tiende a cero ya que las personas se recuperan o mueren, y el COVID deja de propagarse cuando no hay suficientes personas susceptibles para infectarse.
GRĆFICA 3:
Por eso entonces en la GRAFICA 3 vemos que en la linea azul (cuando hay menos contacto humano) toma mas tiempo que la poblacion se infecte, pero eventualmente lo hace. Por el contrario vemos en la linea verde que cuando hay mucho contacto humano la enfermedad se propaga rapidamente.
4.6. El modelo que has desarrollado siguiendo el tutorial anterior es demasiado simple. Brevemente critica la formulación y estructura del modelo y lista las suposiciones del modelo que consideras son irrealistas.
El modelo es muy irrealista porque en la vida real la gente infectada no solo se queda infectada, puede morirse, reinfectar, volverse a hacer suseptible.
Para solucionarlo serĆa bueno agregar una tasa de mortalidad o el tiempo de duración de la enfermedad en los infectados.
En el punto anterior identificaste algunas suposiciones irrealistas. Las siguientes preguntas tienen como objetivo que explores que sucede cuando se expanda el modelo para atender sus limitaciones.
Hasta el momento hemos asumido que la población se mantiene infectada con el virus COVID de manera indefinida. En epidemiologia esto se conoce como el modelo SI (i.e. Susceptible-Infectious). El modelo SI es apropiado para representar enfermedades crónicas para las que no existe una cura. Sin embargo, en el caso de muchas enfermedades infecciosas, incluyendo COVID, viruela o influenza, las personas infectadas pueden recuperarse o en los casos mÔs lamentables morir.
El siguiente diagrama stock-flow expande la estructura del modelo base para describir el proceso de recuperación de la población infectada con COVID. Esta expansión del modelo en epidemiologĆa es conocida como el modelo SIR (i.e.Ā la āRā indica āRecoveryā, explicada en el apartado 9.2.2 del libro de Sterman (2013)). Sigue las instrucciones siguientes para expandir el modelo del tutorial.
El diagrama stock-flow muestra que debes agregar tres variables nuevas: una nueva variable de estado āPopulation Recovered from COVIDā, una nueva variable de flujo āRecovery Rateā (por simplicidad no distinguiremos entre los pacientes que se recuperan y aquellos que mueren) y un nuevo parĆ”metro āAverage Duration of Infectionā.
El parĆ”metro āAverage Duration of Infectionā indica el tiempo promedio (i.e.Ā en dĆas) que una persona permanece infectada con el virus COVID. Los epidemiólogos estiman que la fase de infección del COVID tiene una duración promedio de 7 a 21 dĆas. Emplea tu criterio para elegir el valor de este parĆ”metro.
Existen muchas formas de modelar la variable de flujo āRecovery Rateā pero la especificación empleada con mayor frecuencia es la siguiente: Recovery Rate=Population Infected with COVID/Average Duration of Infectivity
Para implementar exitosamente esta estructura en el modelo es necesario que especifiques que esta nueva variable de flujo afecta tambiĆ©n a la variable de estado existente āPopulation Infected with COVIDā de la siguiente manera (i.e.Ā sintaxis en R):
dpopulation.infected.with.COVID<-Infection.Rate - Recovery.Rate
TambiĆ©n es necesario agregar nueva variable de estado āPopulation Recovered from COVIDā, esto lo puedes lograr empleando la siguiente especificación:
dpopulation.recovered.from.COVID<- Recovery.Rate
Recuerda que al agregar una nueva variable de estado es necesario que indiques en el vector de condiciones iniciales el valor inicial de esta variable y tambiĆ©n indicar en la Ćŗltima lĆnea de código de la función ācovid.epidemicā que esta nueva variable de estado serĆ” impresa por la simulación:
list(c(dpopulation.susceptible.to.COVID, dpopulation.infected.with.COVID, dpopulation.recovered.from.COVID))
Emplea esta nueva versión del modelo para responder a las siguientes preguntas:
4.7. ¿De qué manera cambia el comportamiento de la epidemia una vez que agregas estas nuevas variables al modelo?
Cuando agregamos esas nuevas variables de recuperados y tasa de recuperación al modelo, introducimos un tercer grupo (personas que lograron curarse de la enfermedad y ya no pueden contagiarse ni contagiar a otros).
AsĆ, en este nuevo modelo SIR, los infectados se recuperan despuĆ©s de un tiempo (definido por la duración promedio de la infección). Esto significa que la enfermedad no dura para siempre y eventualmente desaparece.
Por otro lado, la curva de infectados crece rÔpidamente al principio, pero luego alcanza un pico y comienza a disminuir a medida que las personas se recuperan. Esto pasa porque la tasa de recuperación (el tiempo en que las personas tardan de curarse de la enfermedad) reduce el número de infectados.
Finalemnte, no todos se infectan ya que algunas personas se recuperan antes de que la enfermedad pueda contagiarse a todos los susceptibles. Esto significa que la epidemia termina antes de que toda la población se infecte (Tal como pasó en aquellos tiempos horribles de pandemiaā¦)
Estas explicaciones las podemos ver grÔficamente a continuación:
GRAFICA 4:
4.8. ĀæDescribe grĆ”ficamente y con un breve texto el efecto en el sistema de cambios (i.e.Ā incremento y decremento) de las siguientes variables: ācontact frequencyā y āinfectivityā? Enfatiza en las diferencias que percibes con respecto del comportamiento del modelo base.
En el modelo nuevo que estamos trabajando (SIR), donde reconocemos que existe la recuperación, trabajamos con parĆ”metros como āContact Frequencyā y āInfectivityā, que pueden variar porque no son parĆ”metros estĆ”ticos en la vida real⦠Sin embargo en el modelo los fijamos para simular diferentes escenarios. Por lo que NO estamos prediciendo un resultado exacto, sino explorando cómo se comporta el sistema dentro de ciertos lĆmites
TambiĆ©n es importante reconocer que dependiendo de las polĆticas que aplique el gobierno en turno que estĆ© enfrentando la epidemia (como el distanciamiento social o el uso de mascarillas) afectan directamente a variables como āContact Frequencyā o āInfectivityā reduciendo la probabilidad de transmisión y por lo tanto el sistema tambiĆ©n puede cambiar en su comportamiento.
Asi que si bien, mis resultados nos son 100% seguros,al menos nos da la posibilidad de definir algunos escenarios posibles.
A continuación se muestra grÔficamente lo que menciono de como pueden variar los escenarios:
GRAFICA 5: