Spatial-R http://chengjun.github.io 2019-08-23T00:51:12+00:00 wangchj04@gmail.com 归因传染病动力学模型 http://spatial-r.github.io/cn/2019/01/CTModel/ 2019-01-15T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2019/01/CTModel

生态学角度去研究环境因素对传染病的影响,早已贯穿整个传染病研究史。我们不仅仅需从传染病本身去观测其传播特性,如传播力等,我们也关心传染病发生发展规律过程中的环境驱动因子。疾控事业的核心依然是寻找作用干预靶点进而促进健康(控制环境因素可能实施难度会较大)。如何更准确且有效地寻找传染病的环境驱动因子,这是一个牵扯了众多复杂过程的难题,尤其是针对非人传人传染病。但是路难走依然还是得继续,本研究在传染病动力学模型的基础上融入环境流行病学思想,构建了归因动力学模型(Causal tranmission model),用以探究人传人传染病(比如大部分呼吸道传染病和肠道传染病)可能的环境驱动因子。


别人怎么做


研究一个因素是否会对目标变量产生影响,我们可采取最简单的方法:线性回归,但简单的方法往往有其简单的局限性,对于线性回归而言,需保证因变量的生态性独立性。但对于传染病,下时点传染病的数量往往受到此时刻传染病数量的影响,故独立性这个先决条件难满足。故而,很多学者改用广义线性或者广义加性模型,这个确实可以有效摆脱数据独立性的限制,包括近年来新出的CCM算法,但是,这些方法“囫囵吞枣”般研究模式(不考虑传染病传播规律)得出来的结论往往让人“食之无味“,比如温度对传染病的效应在某个区域为正向的,但研究区域一换则效应也发生本质变化。在哲学中始终流传着一段话:我是谁,从哪儿来,最终回哪儿去。故最好的方式莫过于采用传染病动力学模型,既能充分考虑传染病传播特征,又能增加相关生物学假设来检验效应的有无及大小,何乐而不为?


我们缺什么


动力学模型主要是用以预测传染病的发生发展趋势及评估干预措施的效果,较少用以探究环境因素对传染病的影响。一方面是因为传染病动力学模型中未知参数过多会影响到目标参数求解,另一方面,目前主流算法对目标参数的求解需要较强的计算机资源支持。当然,随着近些年计算机能力的快速发展,各种类型的服务器及超级计算机相继问世,使得计算资源这个门槛已经不那么严重。但这些年看来,往往是软能力的缺乏,导致了环境因素与传染病间关系的研究一直没有较大突破。传染病研究,软能力更加侧重于传染病流行规律及其动力学模型内在意义的理解,这些知识将是准确探究环境因素与传染病关系的基石。


我们怎么做


建立一套合理的框架有效结合传染病动力学模型和环境流行病学相关知识,是给予环境因素与传染病关系合理解释的重要手段。既需结合环境流行病学和传染病动力学模型,那自然需要懂这两块内容所关注的靶点。环境流行病学关注的是关系强度滞后效应阈值效应;而动力学模型关注的是模型设定方式及其对实际疫情的反映程度。一个合格的动力学模型是既能符合传染病传播模式及其内在生物学特性,同时又能较好地与监测数据进行耦合。需要注意的是,动力学模型中所涉及的生物学过程,为环境流行病学相关理念的插入提供了很好的作用靶点。


作用靶点集


动力学模型会将目标人群认为多个状态,以SIR模型为例,目标人群被分为易感者,感染者和恢复者,其中易感者会受到一定程度感染力的作用而变成感染者,而感染者经过一个感染期后成为恢复者,恢复者获得终身免疫不再受该传染病影响。对于人传人传染病,环境因素只有两个靶点可以作用:作用病毒本身,影响了传播力和毒力;作用人群影响人群活动模式、人群免疫力。对于人群活动模式和传播力,可都归纳于传染力,因为气象因素对于人群活动模式的影响还是很有限,除非是相关极端气象因素如飓风等,人群活动模式不会有较大的变化。当然,我们研究组前段时间做的一个分析发现不同季节人群接触模式存在差别,但这个能否去解解传染病的季节性特征仍需进一步研究。而环境因素对病毒毒力和人群免疫力的影响,也可进行有效捆绑,目前还没有何种证据去支持气象因素可以影响病毒的毒力(病毒毒力主要由病毒本身决定),故此处可归纳为对人群免疫力的影响。因而,在归因动力学模型中我们将环境因素作用于传染病归纳为两个环节:1. 环境因素影响病毒感染力;2. 环境因素影响人群免疫力。这两个环节如何有效地嵌套到动力学模型框架中呢?


作用靶点嵌套


环境因素作用于感染力可直接嵌套在动力学模型中,因为传统的动力学模型中的感染力其实已是综合了多种环境效应对传染病感染力的影响,而此时我们要做的也只是将环境因素效应从这综合效应中剥离出来。而环境因素是如何改变人群免疫水平进而影响传染病传播的,是目前难点。正如上述提及的,环境因素影响人群免疫力会改变人群对于该病毒的易感性,同时也会影响人群感染该病毒后续一系列临床表征。为了更好地将效应剥离,我们做了一个很粗鲁的假设:环境因素并不会改变人群对病原体的易感性。这个假设可以这么理解:环境因素对人群易感性的影响相比于环境因素对病毒本身的存活及活力的影响要弱的多,故可将其忽略;另一个方面,在整个感染过程中,环境因素变化与否,人群对于病毒的清除能力并不会发生质变(对于免疫力的影响还未达到影响阈值水平),接触病毒后(来源于外界环境或直接来源于接触者)该感染的还是感染,该排毒的还是排毒。另一方面,环境因素改变人群免疫力会产生另一个现象:环境因素影响感染人群就诊比率,比如人群免疫力的下降会使得人体更易出现相关临床症状进而去医院就诊而被登记为病例,降低隐形感染率(1-报告率~隐形感染率)。这个假设可有效地嵌套到动力学模型耦合监测数据过程中(measure process)。


两个假设-两个靶点


综上所述,我们将环境因素作用于传染病传播演变过程中的两个环节:影响病毒的存活、繁殖等;影响人群免疫力进而影响出现临床症状而就诊的比例数。对于不管是SIR模型,还是SEIR模型,都可将两个假设嵌套到动力学模型框架里,也就是说这套假设具有普适性。同时需要注意的是:第一个假设会影响动力学模型的动态性(dynamic process),但第二个影响的仅仅是病例耦合(measure process),对动态传播过程没影响。这样设置最大的益处是方便参数求解。众所周知,若多个参数嵌套在动力学过程中,但耦合的只是动力学过程中病例数和实际监测病例数,这会使得参数的不确定性增大。换句话说,多种参数组合会得到同样的效果,哪组参数更嵌合实际自是无从知晓,因为再无其他信息可用以判断。当然,考虑到模型的稳定性及环境因素效应的可比性,我们会对模型进行相关调整,主要包括:环境因素的标准化;报告率设置为logistic形式;不同环境因素作用靶点设置(比如,环境流行病学大多探讨相对湿度而非绝对湿度对健康效应的影响。)


参数求解一:框架设置


有了模型框架和数据,接下来自然是去求解目标参数及其可信区间。目前主流思路是在隐马尔可夫模型的框架基础上,采用相关统计算法求解目标参数。之所以采用隐马尔可夫模型,这个和该模型独有特性有关。隐马尔可夫模型具有两大特性:1. 模型框架中有隐状态,也就是不可观测状态。对于SIR模型来说,人群中有多大比例是易感者,多大比例是感染者,在真实世界里难以获知;2. 马尔可夫特性,即t时刻的状态,只与上一时刻(t-1)该状态有关,而与其他时刻该状态无关。这两大特性都很好地满足了动力学模型中各状态的动态演变规律。对隐马尔可夫模型中参数求解,既可采用频率派的方法,如粒子滤波算法,也可采用贝叶斯方法,如偏蒙托卡洛算法。这些算法都已经集成在pomp程序包中,会R且懂C这即可调用。


参数求解二:阈值效应


上述只说到最简单的情形:各环境因素作用靶点的方式是线性的。对于部分情形,线性方式可近似作为两者关系的表述,但对于某些环境因素如温度等,其对人体免疫力的影响是非线性的(一般认为是U型,温度过高或者过低都会降低人群免疫力)。对于这类存在阈值的作用情景,该如何在动力学模型框架下进行定量评估呢?首先,我们需要同时设定一个二次项和一次项系数,求解这两个系数的组合值(考虑到一次项和二次项系数会相互影响),若二次项系数不为0,则说明该环境因素对该靶点存在阈值;反之,则线性方式拟合也算最优。接下来,我们还需要从生物学角度去评估该环境因素对该作用靶点的效应是何种阈值形状:J型,U型还是V型。不同阈值形状所采用的计算方式并不一样,最简单的是V型,具体实现思路如下:假设该环境因素取值为[a,b],将其范围划分为10等分,分别对环境因素根据等分点进行V转换,再代入模型求解其参数值及似然值,参数值显著且似然值最大者所对应的点即为V型效应阈值。对于U型阈值则需在V型阈值的基础上增加组合参数值的求解:简而言之,低阈值和高阈值组合而成的那套参数出现了阈值特性才能将其认为是阈值点。当然,U型阈值相比于V型,会有一个很明显特性:V型转换后求解的各参数值会随着转换点的增大而降低,且在中间值处会使得参数值接近于0。


参数求解三:滞后效应


另一个需要关注则是滞后效应。滞后效应的评估带有点非合理性。由于归因动力学模型主要是针对周数据,因而环境因素不管是作用于病原体本身还是人群,滞后效应都极其有限,尤其对感染力。就理论机制而言,上周环境因素对本周病原体的生存及活力所产生的影响应该要远小于本周环境因素(病原体体外存活时间较短),同时环境因素在时间层面上呈现出来的自相关性会使得效应出现明显的归拢现象:本周环境因素对作用靶点的效应从整体上会是多个时点效应的总和。当然,突发的环境事件可能会改变此情形,但归因动力学模型评估的是综合效应,非特殊场景下的极端效应。故综上所述,我们一般将滞后效应设置在报告率这个靶点,而非感染力。具体而言,只需要将环境变量代入模型前进行滞后处理,参数求解而得的即为该环境因素的滞后效应。需要注意的是,在同一个作用靶点下,不要同时评估滞后效应和主效应,这样会导致滞后效应的不确定性增大。


相对危险度与归因百分比


公共卫生专家关心的是环境因素与结局变量的联系强度。正如前面提及的,传染病中存在隐性感染(不同传染病隐性感染比例不一致),所以环境因素与结局变量间的强度则可分为环境因素与感染病例数(RRp)及环境因素与监测病例数(RRt)。前者度量的是环境因素在动态过程中的作用,而后者,则反映的是环境因素在动态过程和耦合过程中的综合效应。当然,不管哪种,都需要注意在参数求解过程中我们对各环境因素所做的标化处理,因而此处得出的关联强度反映的是在均值基础上改变一个标准差所带来的效应。具体而言,RRt的计算可采用simulation的方式:设定环境因素为1进而计算总报告病例数,设定环境因素为0时计算总报告病例数,前者环境因素为均值增加一个标准差的发病风险,而后者则为环境因素为均值时的发病风险,前者除以后者则为在均值基础上改变一个标准差的相对危险度。考虑到模型结构中的随机性,将上述过程重复100次即可获得RRt的置信区间。


莫问英雄出处:何去何从


整个归因动力学模型的框架已介绍完毕,接下来则要探讨模型的优劣。众多模型中,不管是前面介绍的广义相加模型还是模型结构更为复杂的分布非线性滞后模型,又或者是几何模型如CCM,归因动力学模型具有如下优势:

  1. 传统模型只拟合的只是监测病例数,获取得到的只是该环境因素对监测病例效应,而非实际病例。在准确评估环境因素所产生的公共卫生效应时,应该考虑产生的总病例而非报告病例数。

  2. 某些环境因素对人体和病原体作用方式不一样,比如高温会降低病原体活性,但会降低人体免疫力而提升疾病报告率,这会使得传统方法估计温度总效应时存在很强的区域异质性,且无法解释。

  3. 分靶点的阈值效应,相比于传统方法中的单阈值,可更好地与实验室对比进而验证方法的可靠性,同时解释环境效应对传染病的区域异质性。

当然,归因动力学模型也存在诸多不足之处,1. 计算较为依赖计算资源,整套计算完成需要近几天甚至几周。2. 动力学模型去耦合传染病监测数据,比较依赖好的模型框架,比如SIRS模型简化成SIR模型,会使得参数求解变得异常曲折。一个能较好反映传染病特性的动力学模型框架是归因动力学模型的基础。3. 归因动力学模型将效应分割成作用人体和作用病原体两部分,但由于环境因素对人体免疫力的影响会改变其对病原体感染后的清除能力,因而环境因素作用于病原体的部分其实是作用于病原体和作用人体易感性的总和。

]]>
Animation in R (R与动画) http://spatial-r.github.io/cn/2018/07/Animation/ 2018-07-11T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2018/07/Animation

@写在这中秋前夜: 动起来


动画制作

近期有不少朋友一直在咨询如何用R来做动画(Animation)。制作动画,对于传染病工作者去发现传染病时空传播规律具有较大的价值。对其他学科而言,当时点较多时,通过动画来展现其分布趋势也是另有一番价值。当酷炫的动画穿插在你精美的PPT中时,是不是也要加个几个分啊?

简单而言之,动画可以将其理解为就是将多张静态图堆在一起,当然,不是随意堆砌,一般是根据某个类别属性(可以是时间点,也可以是城市等)。总体起来,动画制作包括两个步骤: 静态图制作及图形组装。静态图制作,这个就比较容易理解,毕竟R软件众多显著优势之一就是图形制作。对于图形组装,则可以依托谢益辉animation程序包程序包来实现。考虑到R软件中绘图系统的差异性, 我们可用基础绘图系统来绘制静态图,然后用animation程序包来封装。不过本人更加偏爱ggplot2绘图系统,它的伟大之处在于系统(妈妈再也不会担心改变图形某个属性是哪个函数控制了)和美观(比十八岁的美女还要美,你们信吗?). 正所谓条条道路通罗马, 而本文将要讲述的也是后者(好像我对美确实没什么抵抗力). 今晚的猪脚是gganimate程序包: extends the grammar of graphics as implemented by ggplot2 to include the description of animation, 一个可让你们体会图形制作和组装一步到位的酸爽.


程序包安装

gganimate程序包即可通过官网上下载,也可通过github(thomasp85)安装, 需要注意的是github版本一般会较早更新. 安装的具体代码如下:

  • 官网途径(因更新版本,官网途径已经失效):
    install.packages("gganimate")
    
  • Github途径: 需要先下载devtools程序包,然后用install_github函数进行安装:
    # install.packages('devtools')  
    devtools::install_github('thomasp85/gganimate')
    

主要函数

  • transition_*(): 定义动画是根据哪个变量进行”动”.
  • view_*(): 定义标尺的位置.
  • shadow_*(): 影子?定义点相继出现的方式.
  • enter_*()/exit_*(): 定义新数据产生和旧数据删除的方式.
  • ease_aes(): 美观定义(如何让整个动画看起来更舒适).

(注意,此处只列出部分函数,正如作者所说的: extends the grammar of graphics as implemented by ggplot2, 所以,这个包所包含的应该是一整套关于动画绘制体系,而不仅仅只是几个函数.)


动画制作

首先,我们用程序包自带的例子给大家做一个演示:

library(ggplot2)  
library(gganimate)  
ggplot(mtcars, aes(factor(cyl), mpg)) + 
  geom_boxplot() + 
  # Here comes the gganimate code
  transition_states(
    gear,
    transition_length = 2,state_length = 1) 

大家可以看到, 相比与常规的ggplot2语法, 此处多了一个 transition_states的设置: 第一个参数states定义根据哪个变量(此处是gear)进行动画,第二(transition_length)和第三(state_length)分别定义了转变和状态变量停留的时间.

再来看一个例子:

library(gapminder)

ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop,
                                      colour = country)) +
  geom_point(alpha = 0.7, show.legend = FALSE) +
  scale_colour_manual(values = country_colors) +
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  facet_wrap(~continent) +
  # Here comes the gganimate specific bits
  labs(title = 'Year: {frame_time}', 
          x = 'GDP per capita', y = 'life expectancy') +
  transition_time(year) +
  ease_aes('linear')

如果玩过googleVis程序包的人应该对这个图形很熟,或者是听过汉斯罗斯林Ted演讲的人也会对这个似曾相识. 他曾担任世界卫生组织、联合国儿童基金会和其他援助机构的顾问, 当时用Trendalyzer来对全球发展的相关指标进行动态可视化, 相关视频见此处. (PS: 回想当年,本科毕业设计就是用R来实现这种动态图,可惜功底不够,只做了个交互式的)
回归正题, 上述代码与传统的ggplot2绘图系统语言相比,多了几个部分: transition_time, ease_aeslabs,各自定义了随时间改变的变量名称, 动画美观的方式(由离散形变量转变成连续型的,总要进行相应设置以及标签显示的规则(显示年份).


传染病动画

哈哈,好戏往往放在最后.那我们接下来看看如何用gganimate来对传染病暴发疫情数据进行动画. 其实如果说前面两个动画制作的方式您已经知晓了,那接下来的传染病数据的动画制作,其实也是很简单. 当然, 我们需要首先注意一点, 传染病点暴发数据, 往往具有空间属性(经纬度信息), 因此,最好的动画方式自然是将相关病例点描绘到地图上进行动态展示,也就是说,我们首先需要进行空间可视化.

空间可视化 难吗? 好像确实不难, 无非就是产生地图,然后把具有经纬度信息的点画上去,具体而言,我们可以看看如下代码:

library(gapminder)
library(rgdal)
GD<- readOGR("Data/guangdong.shp")
data10 <- read.csv("Data/animation.csv",header = T)

p = ggplot(GD)+
  geom_point(data= data10, aes(x = long, y = lat, colour=as.factor(type)), size=2) +
  geom_polygon( aes(x = long, y = lat, group =group), size=0.4,
                colour = "BLACK", fill = "transparent") +
  coord_map(project="conic", lat0 = 30) +
 theme_bw(base_size = 15) +
  # Here comes the gganimate specific bits
  lab(title = 'Disease in Guangdong Province in: {frame_time}', x = '', y = '') +
 transition_time(onset_date) +
  ease_aes('linear')

整个代码框架基本一致,相比之前多了geom_polygon和coord_map等函数去定义空间相关属性. 整个地图上描绘的点会随着onset_date这个变量进行改动, 因而你的原始数据中则必须含有onset_date这个变量. 其中data10这个数据框包含了三列: long, lat和onset_date, 分别表示病例发生的经度,纬度和发病时间. 当然, 你也可以用 shadow_mark函数将过去病例点重点标出.


动画保存

gganimate程序包默认产生的gif,动画保存的函数为anim_save:

`anim_save(filename = "test.gif", animation = last_animation())`

GIF可很好嵌入到PPT里去. 但有些时候,可能你更希望产生的动画能够以视频(MP4)的方式保存下来, 这个时候你可以用如下语句进行保存:

`anim_save(filename = "test.mp4", animation = last_animation())`

注意事项

  • 根据以往旧版本的经验, Window用户需下载imagemagick这个软件,同时”点点点”进行安装(即下一步下一步,全部可采用默认的方式), 最后在系统环境变量进行设置(某些电脑之前不设置好像也可以).

  • 某些Window用户, 其计算机名字取得有点任性,比如全部汉字啊, 又比如汉字加上上二次元文字啊. 这些在电脑读取系统环境变量(Path)时会认为是乱码,然后你会发现不管你下载R程序包也好,还是进行动画保存也好,遭遇各种BUGS. 所以, 请各位珍惜自己计算机名,取个高大上的可好?

  • Linux用户在安装gganimate程序包时候,可能会出现错误.我电脑(Ubantu16.04)遇到的问题是gifski包安装不了, 它也会有相关提示: sudo apt-get install cargo 即可, 不过这个貌似还蛮大(70M). 可参考如下两个网页: 网页一网页二. 另外,好像不安装cargo也可以,直接安装Rust,且必须保证版本大于1.28.

  • 新版本的gganimate程序包有很大的改动, 此次也是基于新版本进行测试, 虽然目前整个体系还不是很完善,但是勉强还是够用的. 若各位看管不急,可以坐等开发者将整个project做完后再去测试.

]]>
我未曾对世界说 http://spatial-r.github.io/cn/2018/07/Soul/ 2018-07-11T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2018/07/Soul

我从未对世间任何一人说起


我从未对世间任何一人说起,
你的到来,或是你的离去,
就如同这城墙外静谧的黑夜,
风吹叶落,却始终望不到边.


我从未对世间任何一人说起,
漫漫长夜里,是谁在忐忑地呐喊,
它跳跃着,翻滚着,呐喊着,
桀骜的灵魂,成为了一个小丑.


我从未对世间任何一人说起,
当无尽的黑夜遮住我的双眼时,
我未曾抗拒,却始终相信,
灵魂深处的灯,终究会被点亮.


]]>
时空多成分模型 http://spatial-r.github.io/cn/2015/09/Spatial-temporal-Multicomponent-Model/ 2015-09-13T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/09/Spatial-temporal-Multicomponent-Model Welocome to the surveillance project again! 这是一篇针对Surveillance程序包中时空多成分模型( Spatial-temporal Multicomponent Model)的文章。时空多成分模型是surveillance程序包提供的四大分析模块之一(Outbreaks detection, Endemic-epidemic Spatio-temporal Point Process Intensity Model, SIR event history of a fixed populationSpatial-temporal Multicomponent Model),自去年10月份开始接触,期间走了很多弯路(学习过程),故将相关教训在此文中分享,希望对时空流行病学感兴趣的朋友能够尽快熟悉该模型并能应用于自己的数据。英文功底不错的建议阅读该程序包的英文说明文档。如果您发现此文中的错误,也恳请留言指出,在此特表感谢。


模型综述

时空多成分模型(Spatial-temporal Multicomponent Model)的简约版最初由Held et al. (2005)提出,并应用于麻疹疫情中[PS: 基于浙江省麻疹疫情已写了篇类似的文章,已投中华流行病学杂志]。Leonhard Held et al.(2006)在“A two-componet model for counts of infectious disease”一文中构建了随机双成分(相互独立)模型,包括局部特性成分(Endemic Component)和时间流行成分(Epidemic Component),其中局部特性成分控制季节效应的影响,时间流行成分同时考虑了疾病疫情的时间相关性和暴发影响。该模型假设时序数据服从Generalised Branching Process with Immigration, 并分别对甲肝和乙肝进行了拟合。在surveillance程序包中,基础模型中将时序数据分为三个成分:局部特性成分(Endemic component, end)、时间自相关成分(Autoregressive component,ar)和空间流行成分(Epidemic component, ne),并在公式中分别用$ν_(i,t)$、$λ_(i,t)$和$ϕ_(i,t)$表示。其中局部特性成分反映疫情的本地风险情况,时间自相关成分反映的是过去时段疫情在时间维度上产生的影响,而空间流行成分反映的是邻近单元对目标单元产生的影响(可根据多种空间权重矩阵来定义邻近)。具体的公式如下:

$γ_0$、$α_0$ 和 $β_0$分别代表了三成分的截距,$γ_i$、$α_i$ 和 $β_i$ 分别代表三成分的随机效应,都服从均值为0的正态分布;γ、α 和 β分别代表了协变量 $z_(i,t)^T$、$μ_(i,t)^T$ 和 $x_(i,t)^T$ 对局部特性成分、时间自相关成分和空间流行成分的作用强度。其中协变量$z_(i,t)^T$在本研究中包含了季节效应${∑_(s=1)^S[κ_s sina(τ_s t)+δ_s cosa(τ_s t)]}$,其中S代表周期数,$τ_s=2πs/freq$。


模型优点

surveillance程序包中的时空多成分模型相关优点主要体现在如下几个方面:

  1. 空间权重:多种方式定义研究单元的邻近性
  2. 协变量纳入:自变量反映局部和时序关系
  3. 随机效应:考虑区域的空间异质性

空间权重对空间分析影响较大,其设置方式是空间分析中老生常谈的话题。surveillance程序包除提高基本的空间权重矩阵外(如一阶queen邻近等,具体见spdep程序包),还提供Power-law算法,能更好模拟传染病远距离传播的特性(在一定距离范围内快速递减)。

协变量纳入不仅可在控制其他效应后准确度量协变量和结局变量之间的关系,也能较高地提高模型拟合度(AIC)。协变量一般纳入局部特性成分或时间自相关成分,借以反映其在局部疫情风险和时序效果上的影响,当然,将协变量得系数恒设为1进而转变成offset。不管何种方式,都可以借助AIC值来选择最优拟合模型,尽管有研究表明将易感人群比例值纳入时间自相关成分效果较佳(见此文)。

随机效应在协变量不能完全反映研究单元的空间异质性时,能显著提高模型的预测力。时空多成分模型中纳入随机效应最初由M. Paul and Held L(2010)提出,极大提高了模型的适用度。对于传染病大疫情的监测数据,无法观测的空间异质性主要体现在underreporting。针对不同研究单元不同成分随机效应的可视化,可为卫生决策者提供较好的干预措施,若某区域麻疹的局部特性成分较大,则说明麻疹疫情的本地风险较大,进一步巩固本地免疫屏障则显得尤为重要。


具体实例


STS数据

surveillance程序包中提供hhh4函数来拟合时空多成分模型,其所需的数据格式为sts(surveillance time series)。sts数据需包括以下几个部分:疫情数据人口数据空间邻阶数据,地图数据或和协变量数据。可借助new函数生成sts数据,示例代码如下:

measlesWeserEms <- new("sts", start = c(2013, 1), freq =365, epoch = 1:nrow(dat.final),
                observed = dat.final, neighbourhood = weserems_nbOrder,
               map = dat.zj, populationFrac = populationFrac)

此处,我的数据是逐日数据,因而freq设置为365,dat,final是疫情数据,dat.zj是地图数据,populationFrac是人口比例数据(研究单元人口占总研究单元人口数的百分比)。此处一定需注意各个数据集之间匹配问题,也就是变量名一定要一致(重要的事情不说三遍!!!)。对于空间邻阶文件,可通过spdep程序包中的poly2adjmatnbOrder函数来生成,但需注意孤立区域,如浙江省的洞头县尽管从地图属性是孤立的,但考虑传染病的扩散特性,还是将其设置为与乐清市相邻。

数据可视化

对于sts数据,surveillance程序包提供了一系列简约的方式来进行数据可视化(时间和空间)。考虑到数据保密性,此处,仅利用程序包自带的measlesWeserEms数据集来实现数据可视化和模型拟合。时间序列可视化的部分代码如下:

library(surveillance)
data(measlesWeserEms)
measlesWeserEms15 <- measlesWeserEms[, colSums(observed(measlesWeserEms)) > 6]
plot(measlesWeserEms15, type =observed ~ time | unit, legend.opts = NULL)

你可以调节type参数的值,如“observed ~ time”或“observed ~ unit”等来达到不同的可视化效果,需要注意的是其采用spplot和lattice绘图系统,若想调节图形相关参数的可查阅程序包的帮助文档。当然,也可以用ggplot2和gridExtra程序包,分别实现数据可视化和图形组合(推荐之至)。

模型拟合

此处先拟合基础模型,其包括三成分,其中各研究单元的人口比例值作为offset结合地域面积来反映人口密度,局部特性成分控制季节效应,时间流行成分和空间流行成分(一阶邻近)都只包括截距项。为控制研究区域疫情的过度离散特性,采用负二项分布(NegBin1)进行拟合,当然也可以选择泊松分布(Possion)。相关代码如下:

measlesModel_basic <- list( 
end = list(f = addSeason2formula(~1 + t, period = measlesWeserEms@freq),offset = population(measlesWeserEms)), 
ar = list(f = ~1),ne = list(f = ~1, weights = neighbourhood(measlesWeserEms) == 1), family = "NegBin1")
measlesFit_basic <- hhh4(stsObj = measlesWeserEms, control = measlesModel_basic)
summary(measlesFit_basic, idx2Exp = 1:4, amplitudeShift = TRUE, maxEV = TRUE)
## 
## Call: 
## hhh4(stsObj = measlesWeserEms, control = measlesModel_basic)
## 
## Coefficients:
##                       Estimate   Std. Error
## exp(ar.1)              0.645403   0.079270 
## exp(ne.1)              0.015805   0.004200 
## exp(end.1)             1.080248   0.278839 
## exp(end.t)             1.001185   0.004264 
## end.A(2 * pi * t/52)   1.164231   0.192124 
## end.s(2 * pi * t/52)  -0.634360   0.133500 
## overdisp               2.013839   0.285441 
## 
## Epidemic dominant eigenvalue:  0.72 
## 
## Log-likelihood:   -971.72 
## AIC:              1957.44 
## BIC:              1995.72 
## 
## Number of units:        17 
## Number of time points:  103

summary函数中idx2Exp是一个简单系数转换参数,此处是将系数中的ar.1,ne.1,end.1和end.t转换成其对数值,至于为什么要转换,看看基础模型的公式即可知。Epidemic dominant eigenvalue表示疾病发病率中空间流行成分百分值,更进一步的可视化形式如下:

districts2plot <- names(which(colSums(observed(measlesWeserEms)) > 20))
plot(measlesFit_basic, type = "fitted", units = districts2plot, hide0s = TRUE)

对于上图的解读可以从如下方面进行:三种颜色条纹分别代表局部特性成分、时间自相关成分和空间流行成分(需注意的是,此图中作者将Epidemic理解成spatiotemporal,似乎也是有一定道理)。总体而言,这六个研究单元的麻疹疫情主要是受先前麻疹疫情的影响,麻疹疫情出现后,没及时发现并及时进行相应处理。区域单元03453在2002年上半年疫情受邻近区域的影响较大。

纳入协变量

对于疫苗针对传染病而言,相关疫苗覆盖率对传染病疫情的传播具有重要影响。因此,此处易感人群比例作为协变量纳入基础模型,至于纳入何种成分中,且看AIC值。相关代码如下:

Sprop <- matrix(1 - measlesWeserEms@map@data$vacc1.2004, byrow = TRUE,
nrow = nrow(measlesWeserEms), ncol = ncol(measlesWeserEms))
Soptions <- c("unchanged", "Soffset", "Scovar")
SmodelGrid <- expand.grid(end = Soptions, ar = Soptions)
row.names(SmodelGrid) <- do.call("paste", c(SmodelGrid, list(sep = "|")))
measlesFits_vacc <- apply(X = SmodelGrid, MARGIN = 1, FUN = function (options) {
 updatecomp <- function (comp, option)
 switch(option, "unchanged" = list(),
 "Soffset" = list(offset = comp$offset * Sprop),
 "Scovar" = list(f = update(comp$f, ~. + log(Sprop))))
 update(measlesFit_basic,
 end = updatecomp(measlesFit_basic$control$end, options[1]),
 ar = updatecomp(measlesFit_basic$control$ar, options[2]),
 data = list(Sprop = Sprop))
 })

AIC.list <- function (object, ..., k = 2){
if (is.null(names(object))) stop("the list of models must have names")
 eval(as.call(c(lapply(c("AIC", names(object)), as.name), list(k = k))),
 envir = object)
 }
aics_vacc <- AIC(measlesFits_vacc);aics_vacc[order(aics_vacc[, "AIC"]), ]
##                     df      AIC
## `Scovar|unchanged`   8 1917.071
## `Scovar|Scovar`      9 1919.070
## `Soffset|unchanged`  7 1922.114
## `Soffset|Scovar`     8 1924.020
## `Scovar|Soffset`     8 1934.478
## `Soffset|Soffset`    7 1936.990
## unchanged|unchanged  7 1957.442
## `unchanged|Scovar`   8 1958.959
## `unchanged|Soffset`  7 1966.933

由AIC值可知,当易感人群比例这个变量纳入局部特性成分时模拟拟合度最好,这个也很好理解,本地免疫屏障影响着麻疹疫情的本地风险水平。当然,选择模型时候仍需结合专业知识。

Power-law

在基础模型中,我们假定麻疹疫情只会在具有共同边际的研究单元间传播,且传播系数都一致。考虑到人群的流动性,基础模型明显具有局限性。结合相关协变量,我们同时考虑研究区域的人口百分比(人越多,远距离传播的可能性就越大)和多阶传播(多阶相邻和Power-law)。相关代码如下:

measlesFit_vacc <- measlesFits_vacc[["Scovar|unchanged"]]
measlesFit_nepop <- update(measlesFit_vacc,
    ne = list(f = ~log(pop)), data = list(pop = population(measlesWeserEms)))
measlesFit_np2 <- update(measlesFit_nepop,
    ne = list(weights = W_np(maxlag = 2)))
measlesFit_powerlaw <- update(measlesFit_nepop,
    ne = list(weights = W_powerlaw(maxlag = 5)))
summary(measlesFit_powerlaw, idx2Exp = 1:5, amplitudeShift = TRUE, maxEV = TRUE)
## 
## Call: 
## hhh4(stsObj = object$stsObj, control = control)
## 
## Coefficients:
##                       Estimate   Std. Error
## exp(ar.1)               0.59314    0.06982 
## exp(ne.1)              44.52223   55.10724 
## exp(ne.log(pop))        9.89295    4.96028 
## exp(end.1)            474.78153  406.32394 
## exp(end.t)              1.00383    0.00440 
## end.A(2 * pi * t/52)    1.10678    0.19405 
## end.s(2 * pi * t/52)   -0.43513    0.15135 
## end.log(Sprop)          2.32578    0.32256 
## neweights.d             4.10214    1.05496 
## overdisp                1.60779    0.23055 
## 
## Epidemic dominant eigenvalue:  0.77 
## 
## Log-likelihood:   -931.03 
## AIC:              1882.06 
## BIC:              1936.74 
## 
## Number of units:        17 
## Number of time points:  103

通过定义不同形式的空间权重矩阵,可较好地度量传染病的空间蔓延规律,尤其是在人口流动或是交通数据缺乏的情况下。 当然,如果你有相关数据,直接修改weights参数即可。

Random effect

对于政府决策者,不仅要知道整个研究区域内传染病的时空传播特性,还需要知晓其在区域间的传播异质性,以便采取相应措施来防控传染病。另一方面,很多影响传染病传播的因素较难度量,而随机效应则是解决这类不确定问题的利器。我们在power-law模型的基础上构建三个成分的随机效应,具体代码如下:

measlesFit_ri <- update(measlesFit_powerlaw,
 end = list(f = update(formula(measlesFit_powerlaw)$end, ~ . + ri() - 1)),
 ar = list(f = update(formula(measlesFit_powerlaw)$ar, ~ . + ri() - 1)),
 ne = list(f = update(formula(measlesFit_powerlaw)$ne, ~ . + ri() - 1)))
## [1] "iteration limit reached without convergence (10)"
## Update of variance parameters in iteration  5  unreliable
head(ranef(measlesFit_ri, tomatrix = TRUE))
##       ar.ri(iid)  ne.ri(iid) end.ri(iid)
## 03401  0.0000000 -0.05673057  -1.0044596
## 03402  1.2234776  0.04311721   1.5263983
## 03403 -0.8272548  1.55877779  -0.6198755
## 03404 -0.3772432 -0.50126451  -1.1188042
## 03405  0.0000000 -0.09105187  -1.2822860
## 03451 -0.5241670 -0.11345751   0.4959956
for (comp in c("end","ar", "ne")) {
print(plot(measlesFit_ri, type = "ri", component = comp, xlim = c(6.6,8.8),
 labels = list(cex = 0.6), at = seq(-1.7, 1.7, length.out = 15)))
}

通过这三图分别代表局部特性成分、时间自相关成分和空间流行成分的随机效应,可知03460和03457区域的局部特性成分较大,03454和03457区域的时间自相关成分较大,0.453和03452的空间流行成分较大,故相应措施应运而生:针对03460和03457区域,需加强本地麻疹免疫屏障建设来降低麻疹的本地风险;针对03454和03457区域,则需加强麻疹疫情的应急处置工作,及时控制疫情发展;针对0.453和03452区域则需控制其周边区域麻疹疫情对目标区域的影响。


##结语

本文比较粗糙地介绍了时空多成分模型在R中的实现步骤及相关注意事项,当然,你还可以对模型进行扩展。接下来打算基于shiny来开发时空多成分模型的app,也是作为大疫情数据分析平台的一部分。若有什么问题,请及时联系张兵: Spatial-R,谢谢!

]]>
基于斜分类树的空间聚集性探测 http://spatial-r.github.io/cn/2015/07/SPODT-IN-R/ 2015-07-01T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/07/SPODT-IN-R 空间聚集丛探测常用方法

流行病学中一个较为常见的问题就是探测疾病的空间聚集丛, 包括热点(hot spot)或冷点(cold spot), 主要分为全局性探测(Globe Detection),局部性(Local detection)探测和焦点探测(Force Decetion)。全局性探测的方法有样方分析法(Quadrat analysis), 最近邻分析法(Nearest neighbor analysis), Ripley’s K 函数法, Cuzick-Edwards法, 全局空间自相关分析法(Global spatial autocorrelation analysis)和 Tango最大超额事件检验法;局部性探测的分析方法有空间扫描统计量(Spatial scan statistic), Besag-Newell法, 聚集性评价排列组合法局部空间自相关法;焦点探测的分析方法主要为Stone检验法, Lawson-Waller得分检验法Diggle检验,各个方法的描述可参考Here1, Here2


SPODT 简介

SPODT的全称是Spatial Oblique Decision Tree, 一种基于斜决策树(Oblique decision tree)的空间分类方法。对于空间流行病数据而言,这种非参回归方法通过递归方式在整个研究区域不断寻找阈值范围或者边界,使得不同区域内的差异尽可能大。相对于分类与回归树方法(Classification and regression tree, CART)而言,斜决策树可以将研究区域进行斜划分,而非局限的矩形(CART划分结果)。与上述局部性探测方法相比较,对该方法对边缘效应的敏感性要低很多。


方法介绍

总的说来,斜决策树是CART的改版,其函数形式如下:

其中$x_{i}$,$y_{i}$是位置点$i$的经纬度对于小区域最好采用欧几里德或地理坐标系统(注意:若不进行正确投影,可能会得到错误的结果)。$class_{j}$是将整个研究区域划分后形成的子区域个数$mz_{j}$是所有子区域内样点观测值的均值。所有不同区域间的边界线($s_{j}(x_{i}+y_{i})$)是基于平行坐标系的线性函数($ax_{i}+by_{i}+c=0$)这些边界线或是分割方向对每个位置点(也称为结点$\xi$)进行反复迭代,最终将区域划分为若干个子区域。当结点达到如下条件时,该区域不再增加样本点:

  1. 新的区域划分不再增加变异性,也就是说该区域内新增样本点时不会产生新变异。
  2. 结点的大小不能低于事先设定好的样本点大小(parent node)。
  3. 当划分子区域时两个子区域的大小不能低于子区域最小值(child node)。
  4. 达到分类树水平的最大值。

总的说来SPODT中提供了三个重要函数即spodt, spodt.tree, spodtSpatialLines,和test.spodt。spdot是核心函数,其中的weight, graft,level.max, min.parent, min.child和rtwo.min参数可详细控制斜分类树算法;spodt.tree和spodtSpatialLines是spdot后结果的可视化;test.spodt是采用蒙托卡罗模拟来检验分类的有效性。


例子

此处选择了Bandiagara区域分布在168个地点的300个儿童数据,观察该人群在2009年11月-12月中疟疾的发病情况来探测是否存在疟疾高风险区。该数据集为SPODT程序包自带,因而data函数带入即可。基础分析代码如下:

library(SPODT)  
data("dataMALARIA") ;coordinates(dataMALARIA) <- c("x", "y") 
proj4string(dataMALARIA) <- "+proj=longlat +datum=WGS84 +ellps=WGS84"  
dataMALARIA <- spTransform(dataMALARIA, CRS("+proj=merc +datum=WGS84 +ellps=WGS84"))
spodt.results <- spodt(z ~ 1, data = dataMALARIA, graft = 0.13,  
                       level.max = 7, min.parent = 25, min.child = 2, rtwo.min = 0.01)
spodt.tree(spodt.results)

上述即是SPODT分类树结果,设定好grapt参数值后,可得到6个子区域;其中$R_{global}^{2}$ (可通过spodt.results@R2获得)为0.49,表明疟疾发病风险中49%的差异可由空间效应来解释.

SSL.result <- spodtSpatialLines(spodt.results, dataMALARIA) 
plot(SSL.result) 
points(dataMALARIA, cex = log(dataMALARIA@data$z *3))

上述即是SPODT结果以地图的方式呈现,可发现中部地区存在一个疟疾发病的低风险区(发病风险在0.08[0.04-0.11]),而在其下方存在一个发病高风险区(发病风险为0.47[0.39-0.55])

]]>
R中关于heatmap的那些事 http://spatial-r.github.io/cn/2015/06/Heatmap-in-R/ 2015-06-26T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/06/Heatmap-in-R 因为有期待,所以就会有各种偶遇。— 记d3heatmap的出世。


那年故事

如果没有记错的话,最初接触heatmap是在2010年,当然,故事还得从R-blogger说起,在此,不得不再次强调下R-bloogger的作用,对于R的新手更是如此。 回归正题,R-blogger上第一篇关于heatmap的介绍在, 第二篇, 第三篇等等。不容否认,heatmap的出现,为矩阵数据框可视化开辟了一个新方向。


heatmap综述

Heatmap主要分为两大类,静态的(static)和交互式(interactive)。R中实现静态heatmap有很多程序包,如fheatmap, gapmap, heatmap3, heatmap.plus, mcheatmaps, NeatMap, pheatmap。 利用强大的ggplot2也可较好地实现heatmap,如这个这个。研究基因的童鞋,对heatmap一定不陌生,见 此文。当然,对于公共卫生领域的朋友,利用heatmap也可较好地实现数据可视化,如大疫情系统中的面板数据(panel data),多个城市或区县的逐日数据,用heatmap来呈现也是相当perfect的。

鉴于网上关于静态heatmap的文章已经很多(随便百度一下,总能出来那么几篇)。在此,我主要介绍交互式hetmap,主要是利用d3heatmaprCharts程序包。


d3heatmap

d3heatmap的介绍可见,毕竟是Rstudio出品,质量没得说,其除了实现最基本的heatmap功能外,还能:

  1. 点击横坐标或者坐标,进而实现类别高亮(highlight)。
  2. 对特定长或者宽的矩形实现放大(zoom in)。
  3. 可以在Rstudio中结合Markdownshiny使用(reproduced)。

废话少说,直接上示例,这个例子你同样可以在这篇博文中找到:

library(d3heatmap)
nba_players<-read.csv("ppg2008.csv",header=T,stringsAsFactors = F)
row.names(nba_players)<-nba_players$Name;nba_players$Name<-NULL
d3heatmap(nba_players, scale = "column",color = "Blues")

短短4行代码,轻松实现交互式heatmap,同时还赠送聚类分析结果,真的很实惠。 此处图形没有出现,正在找原因,你可以在这个网页看到,请点击: Here


rCharts

在没有d3heatmap前,rCharts是创造交互式heatmap唯一的方式。首先得感谢Stefan Wilhelm, 在他的博文中介绍了用R实现交互式heatmap的方法并且附上了详细的代码。其功能和d3heatmap相比,要弱(至于弱在什么地方,读者可自行体验),但终究是一种不错的方式。当数据超过1000行时,需重新定义turboThreshold参数,具体可见其博文。示例如下:

library(dplyr);library(rCharts);library(rjson)
#load("country.RData")
dat.f<-dat.f[1:910,];colnames(dat.f) <- c("y","x","value"); 
    map <- Highcharts$new()
    map$chart(zoomType = "x", type = 'heatmap')
    map$title(text='Sales per employee per weekday')
    map$series(name = 'Sales per employee',data = toJSONArray2(dat.f, json=FALSE))
    map$yAxis(categories = as.character(c(16071:16080)))
    map$xAxis(categories = as.character(c(1:91)))
    map$plotOptions(series=list(turboThreshold = 4000))
    map$addParams(colorAxis = list(min = 0,minColor='#FFFFFF',maxColor='#7cb5ec'))
    map$legend(align='right',layout='vertical',margin=0,verticalAlign='top',y=35,symbolHeight=320)
    map$tooltip(formatter = "#! function() { return '<b>' + this.series.xAxis.categories[this.point.x] + '</b> sold <br><b>' + this.point.value + '</b> items on <br><b>' + this.series.yAxis.categories[this.point.y] + '</b>'; } !#")
    map$addParams(height = 900, width=800, dom="heatmap")

此处我并没有将country这个数据集公开,但只要读者好好研究StefanWilhelm的那篇博文,实现交互式heatmap并不难,但考虑到d3heatmap程序包的强大,rCharts程序包仅仅只是作为一个辅助方式,所以,你懂的。

]]>
前瞻性暴发探测 http://spatial-r.github.io/cn/2015/06/Surveillance1/ 2015-06-03T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/06/Surveillance1 Welcome to surveillance Project! 这是一篇针对surveillance程序包相关方法的总结,有疑问请联系张兵: Spatial-R

Surveillance 程序包提供了一系列前瞻性爆发探测和回顾性的时空模型,主要适用的数据类型是时间序列频数、时序百分比和时序分类数据。


前瞻性暴发探测

Aberration Detection(Change-point detection, Outbreak Detection),我将其都翻译为暴发探测,但仔细推敲,各词组间含义差别还是有点大。具体如下:

  1. Aberration 原指光行差,是指同一瞬间运动中观测者所观测的天体视方向与静止观察者所观测到天体的真方向之差,通俗理解就是偏差。
  2. Change-Point 指在某一位置或时刻点,前后观测值遵循两个不同的模型。changepoint 程序包也提供了一系列变点探测的方法,主要依托于变点前后均值或和方差的差异性。
  3. Disease Outbreak 指在局限的区域范围和短时间内突然出现许多同类病例的现象,对于区域范围、时间范围和案例数目都没有确切定义,因而不同空间尺度下,可能会存在截然不同的疾病分布状态。

综上所述,用Aberration或Change-point来归纳surveillance程序包中的方法可能更加确切。同时也需注意,上述两种都是正向改变,也就是说个案数目应增多。

surveillance程序包以S4方式,按照STS(surveillance time series)格式编排数据(该数据格式的说明可参考此文)。很多文章都对传染病监测方法进行了介绍,包括若干已经成功应用于疾病预防控制中心常规监测系统中的方法,如rki,已成功应用于德国的Robert Koch Institute。总的说来,Salmon et.al 2014一文系统详细地介绍了目前异常值监测方法,主要分为单个异常点监测异常时段监测分类数据异常监测

异常点监测较为常规的方式是基于历史数据(in-control)来估计某个时刻的病例数,并与阈值想比较,若高于阈值,则将其定义为 out-control。通过比较每个时间点的in-control和out-control状态,即可获得相应变点。


单个异常点

单个异常点监测是监测系统中较为常见的方式,通俗地理解就是一段时序数据中在某个时间点发生了较为重要的改变。

  1. Method EARS: CDC异常检测系统中的早期方法,surveillance程序包中的 sarsC 可实现这个过程,更为详细地说明可参考Fricker,Hegler 和 Dunfee。当疾病历史数据较少时且数据较平稳时,此方法较合适,同时该程序包提供了C1C2C3方式来实现变点探测。但该方法没有考虑到疾病时序数据如过度离散、周期性、长期趋势和过往疾病暴发对现状的影响等特性,同时也没有对将来数据进行区间预测。
  2. Method Farrington: 该方法最初由Farrington在Farrington et.al. 1996 提出,Hohle和Mazick 2010一文中详细介绍了该方法,其主要基于广义线性或相加模型来探测异常值,而Noufaily et.al 2012在原方法的基础上,采用因子来校准季节性,同时当Anscombe残差大于2或者3时采用再加权进而有效改善了“低加权”现象(Down-weighting)。 FarringtonFlexible函数可实现该过程。
  3. Method Boda: 在FarringtonFlexible方法的基础上,boda (Bayesian Outbreak Detection Algorithm)采用成熟的贝叶斯广义线性或相加模型,通过惩罚样条函数(Penalized Spline)来校准长期和季节性趋势,并能即时调整以往暴发或以往疾病情况对当前个案数的影响。为了更好地获得参数的后验分布,boda采用Integrated Nested Laplace Approximaxion方法来逼近贝叶斯推断。

异常时段

时序中的异常时段由单个异常点组成,但其具体实现过程则完全不同于单个异常点监测。控制图(Control Chart)是实现异常时段监测常用方式,其来源于统计控制过程(Statistical process control)。然后需要注意的是,控制图并没有考虑到监测数据的过度离散和季节性特性,因而,Hohle 和 Paul 2008在传统监测方法上结合统计控制过程,有效地实现异常时段监测。surveillance中的 glrnb(负二项分布) 和 glrPois(Possion分布) 函数可实现这个过程。该程序包中其他函数如 cusumrogerson 等也可实现针对异常时段的监测,其效果与glrnb相比可参考Hohle 和 Paul 2008

在控制图中,以广义相加模型结合Possion 或 Negative binomial 分布来定义 in control 状态,而 out control 状态则由 in control 状态来反映。in control 状态的均值可由当前时刻点案例数和参数k获得(参数k可以事先设定或通过模型再估计获得),或是结合当前时刻点案例数和自相关成分综合反映。


分类数据

在公共卫生监测中,目标变量可能会是分为若干亚组(Categories)的时序数据,如在疫苗接种情况下,不同年龄层传染病的发病情况异常值监测。Chen 1978Reynods和Stoumbos 2000Rogerson和Yamada 2004 等文章强调了针对二分类时序数据异常值探测方法,这些方法都基于常规CUSUM方法,并没有考虑到时序数据过度离散的特性。Hohle 2010在上述方法的基础上,提出通过采用广义线性模型框架进而有效解决了基础SUSUM方法的缺陷(1,仅适用二分类时序数据;2,无法掌控过度离散特性),该方法可由surveillance程序包中的categoricalCUSUM 函数实现。

]]>
那年夏天 http://spatial-r.github.io/cn/2015/05/Summer-In-Hangzhou/ 2015-05-15T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/05/Summer-In-Hangzhou 试问闲愁都几许?一川烟草,满城风絮,梅子黄时雨。又是柳絮纷飞的季节,窗外之景,思绪在哪?哦,那年!

那年夏天,心在躁动

躁动的心境,其实也是一种享受。

虽然此时的内心并没有完全认同上述语句。

夏天和躁动如果能够划上一个等号,那我只适合生活在北极。

躁动的根本原因是无力扯开生命前那层薄纱—生命的不对等。


那年夏天,心在迷惘

世界万物,迷惘只是过程,不会是结果。

冒险和迷惘有时候是等同的。

其实自己真正需要的,往往要很多年以后才能明白。

“蓦然回首,那人却在灯火阑珊处”的大彻大悟终究来得晚,但迟与不迟,与个人有关。

如果说生活重在折腾,那么曾经的迷惘和无所适从,应该就是这段路程中最为深刻的记忆。


那年夏天,心在期待

还年轻,也庆幸自己还有梦。

理性和现实的对照,心中期待不断升华。

如果多年后我能对自己说,你所做的一切都是自己想要的,那时该多庆幸。

真实的人性中存在无尽的可能,所以,该谈恋爱就谈恋爱,该结婚就结婚。

总是在寻找人生的兴奋点,努力让灵魂变得热气腾腾: 窗外有风景吗?


那年夏天,心在成长

迷惘和期待,终究会推着你成长,不管愿不愿意。

成长的心境比结果更值得回味,若干年后想想总是如此。

因为留恋,所以扭着头慢慢前进,内心又如何?

所有我懂的,不过是对现实妥协,可我还是懂了。

如果下次我迷惘了,请记得为我鼓掌,那才是真正意义的成长。


内心腾开一片空地,等待,下一次躁动;等到,下一个那年!

]]>
时空统计模型(一):空间统计 http://spatial-r.github.io/cn/2015/01/Spatial-and-Spatial-temporal/ 2015-01-25T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2015/01/Spatial-and-Spatial-temporal 接触空间统计学已有近3年了,从毕设开始,得知R在空间统计方面的优势后,毅然扎进”Spatial”和”R”的世界里,Spatial-R的名称应运而生。我从不夸大空间统计学和R软件在我研究生时候的贡献,但自己对于这两样宝贝的热爱,却也不是其他东西能够比拟的。书呆子的生活自是如此,乐此不疲。

还是进入正题,这次主要讨论的主题是空间统计学和时空数据模型等,当然,全部是基于R来实现。因篇幅有限,在此只给大概思路,感兴趣的朋友可以进一步探讨(邮箱:zhangbing4502431@outlook.com)。


国际上已广泛建立了传染病的早期预警平台,但主要是针对症状监测,相比于传统的病例监测,症状监测可以更早期地探测到特定传染病的发生和发展趋势。我国已经建立较为完善的传染病病例监测系统(如传染病疫情信息网络直报系统,俗称“大疫情系统”),通过病例数据探索传染病传播过程中的异常,并及时采取相应的应对措施,可以有效降低传染病所带来的危害。


空间统计

空间统计其实是个很宽泛的概念,世间万物都有其空间属性,但并不代表都能用空间统计学去诠释。当然,也有很多原本不存在明显空间熟悉的事物,我们可以将其转换成或者理解成具有空间属性。这里所强调的,也就是不仅仅只有带有经纬度属性的事物才具备空间数据。

目前在公共卫生领域比较常见的两类是:点数据和面数据。点数据比如传染病的发病地点;面数据比如各个区县的发病总人数。针对点数据,主要是来探讨空间点格局分布进而探讨可能的热点区域;而面数据更多是建立空间回归模型,如空间滞后模型,空间杜宾模型等。当然,空间点数据也可以建立空间回归模型,空间权重的选择往往成为头疼的话题(多大的带宽或者阈值距离最合适)。面数据也可以用以探讨热点,但其揭示的热点往往有点泛(如整个区县是热点,公共卫生的意义并不大)。


热点探测

地方病、传染病及环境污染所致疾病均可表现出空间聚集性,而传染病在传播途径、流行机制等方面的特殊性决定了其病例的分布特征与其他疾病存在较大差异,其空间属性主要体现在空间自相关(空间依赖性)和空间异质性。空间自相关性表现为目标地区与邻近地区发病水平及特征较强,与距离远的地区差异大,空间异质性表现为不同地区因为其”位置”原因而存在差异。

公共卫生(Public Health)中较为常见的是病例个案(也就是点数据),记录着病例个案详细的地址信息。因而在热点探测时,需将详细地址信息转换成经纬度信息。因Google地图API被封,我们可以借助百度地图API,具体操作的方式可参考我的博文(点点)。

获取经纬度信息后,则可利用R中的DCluster程序包和Spatsta程序包分别进行热点探测(Cluster Dectecting)和点格局分析(Pattern Analysis)。热点探测也叫聚集性分析,主要包括全局检验和局部检验。顾名思义,全局检验是看疾病在整体或者全局水平上是否具有聚集性,而不管聚集点分布在何处;而局部检验则从底层去探讨和发现可能存在的局部热点。全局聚集性探测可采用KnoxRogerson 等方法,局部聚集性探测则可采用TurnbullBesag-Newell时空扫描 等方法。


全局性热点探测


Knox

Knox,最早也最为经典的全局检验方法(1964由统计学家E.G.Knox提出来,用以检验疾病的时空交互作用),能充分利用病例的时空信息,不需要人口学数据,计算简便。基本原理如下:

    病例两两配对,然后设定时间和空间临界值,以此标准来判断病例对间距离是"近"还是"远"。
    若时间和空间距离均为"近"的病例对与期望值的差异具有统计意义,则该区域内该病存在时空聚集性。

假设n个病例,则可配成N=n*(n-1)/2个病例对子,如果知道了每个个案的发病时间和发病位置,则可计算每个病例对之间的空间距离和时间距离。在定义了时间界值(t)和空间界值(s)后,Nt则为时间距离为近的病例对子总数,Ns则为空间距离较近的病例对子总数,X是时间距离和空间距离均为近的病例对子总数,也就是Knox方法的统计检验量,可得到如下的四格表:

时间距离 <s >s 合计
<t X b Nt
>t c d Nt1
合计 Ns NS1 n

统计推断方法包括

  • 卡方检验:样本量较大时,可采用卡方检验,对Knox方法而言,其本身要求设定的空间临界值足够小,因而X样本量偏小的情况较常见。
  • Possion估计法:当Nt和Ns相对于N来说较小时,X的方差接近于它的均数,此时可采用Possion估计法。但当Nt和Ns较大时,使用该方法进行推断时会有偏性。
  • 基于Possion分布的估计法:与Possion估计法相似,其以正态分布代替Possion分布,一般当u>20时,Possion分布近似正态分布。
  • Barton-David: 仍假设X服从正态分布,但当Ns和Nt较大时,仍能进行无偏推断。
  • 蒙特卡罗法:一种无偏的估计方法,目前较好地能够进行Knox检验。

时间、空间临界值的确定

  • 已知疾病信息,时间界值可按照设为其潜伏期天数,空间界值可设定为相邻农场的距离。
  • 未知疾病信息,可设置一系列时间界值和空间界值,分别对各个组合进行检验。需注意时间界值和空间界值的设定不能超过其所有病例对子的平均时间距离或平均空间距离(平均时间距离=所有病例对子的时间间隔之和/病例对子总数,平均空间距离=所有病例对子的空间距离之和/病例对子总和)

Rogerson

Rogerson,能对传染病的时空进行动态监测,可利用历史数据和不同传染病的危害程度来调整参数和报警界值,有效降低漏报和误报。基本原理如下:

    在Tango方法的基础上,将样本按n个单位进行分割,使得Zi呈正态或者接近正态。  

未完待续

]]>
美人鱼 http://spatial-r.github.io/cn/2014/08/mermaid/ 2014-08-03T00:00:00+00:00 Spatial-R http://spatial-r.github.io/cn/2014/08/mermaid

我是渔夫,
在日暮之时,映着夕阳,
渴望再次听一曲她的赞歌。


辽阔寂静的海边,有人在贮视,
那片他早已熟悉的区域.
他的思绪,浸润在海风中,
一直飘,一直飘…
直至消散在海天相接的地方,
他想,那地方,很美吧.


那天,天也是这般蓝,
蓝得只允许人去陶醉.
他,静静地望着夕阳,
望着夕阳在海天相接的地方点点消散.
蓦然,一丝乐符渗进他的耳际,
他的心,猛然地被拉紧.


是谁,在夕阳下如此轻柔地歌唱
是谁,在海边为他带来了如此动人的乐章
是谁,又是谁…
转身,从容却又那么迫不及待.
那是一条融在夕阳里的美人鱼,
一条他只能选择远望的美人鱼.


她,高贵地立在海面上,
忘我般演绎着一首生命的赞歌,
这,是他见过的最美的风景,
这,是他永生都忘记不了的记忆.
她,依旧在醉然地歌唱,
他,依旧在醉然地聆听.


多久,他不知道.
只是,歌声渐渐地飘渺,变淡,
最后,淡的他只能听见海风的呼啸.
他才觉悟地猛然抬头,
她,游走了,向着海天相交的地方,
向着那个他认为最美的地方.


天,依旧那么蓝.
等待着,伴随间歇有力的涛声.
尽管他并不知道,这一次,下一次,
她,是否会出现;
尽管他已经知道,很多次,很多次,
她,都没有出现.


夕阳隐没在海天的地方,
他,又望望了那片熟悉的区域,
默然间扎进了海中…


09年写的小诗,无意中想起,过去的岁月,总是这样让人放不下。渔夫是孤独的,但却一如既往地守着自己的梦,有梦的生活,是幸福的。

Drawing

]]>