跟着 mimic-code 探索 MIMIC 数据之 tutorials (一)
文章目录
SQL 算是学完了,结果回去看 mimic-code 发现大多数脚本根本看不懂!想起来小学做数学习题:
课本例题: 小明有 3 个苹果,吃了 1 个,请问小明还有几个苹果 ?
课后习题:小华前天买了 5 个橘子,昨天吃了 1 个梨,请问小红今天还剩下几个苹果?
我:卒 …..
没有办法,我就把 mimic-code 翻来覆去地看,看看有没有什么我能看懂的。果然,MIMIC 很良心的,mimic-code/tutorials/
里面就放了针对新人的几个简单的小课程,小课程搭配习题,答案也有,可以说是很好了。
一个个来看吧。
1. sql-intro
这个文档基本就是教我们 SQL 的了。基本上我就是泛泛地看了看。有几个值得记下来的:
How can we use temporary tables to help manage queries?
临时的表格可以用 WITH foo AS bar 这样的语法来存放。比如我们要得到从 patients
表格中得出年龄并做他用:
|
|
另一个办法是使用 materialised views,即物化视图:
|
|
CASE statement for if/else logic
CASE WHEN 是简单的逻辑判断语句。比如我们想对 icustays
中 ICU 住院时间长短 (los
) 分组:
|
|
Window functions
Window functions 中文好像翻译为窗口函数,这个窗口其实是艾滋病感染潜伏期窗口那个意思,在 Bowtie2 之类的 RNA-Seq 数据比对之类的软件计算比对质量的时候也会用到这个这个概念。 不知道为什么 SQLBolt 竟然没有涉及到 Window functions,感觉很实用的功能。
Window functions 和 Aggregate 很像,但是 Aggregate 是聚合,会按照我们要求对相同的行进行合并,而 Window functions 则不同。用例子来看会很清楚,比如我们想要对同一个病人多次住 ICU 进行编号。这种情况下直接用 GROUP BY subject_id
会直接把同一个病人信息合并到一行,而我们想要的是每个病人每次入 ICU 的信息仍然单独是一行,顺序通过 admission_time
进行编号。这里的 窗
就是 subject_id
,每个病人为一个处理单位,RANK()
生成顺序编号。 代码:
|
|
有了这样一个编号我们就可以很方便的筛选只住过一次 ICU 的病例了 (这个在文献里经常看到):
|
|
Multiple temporary views
多个临时视图,这个在 mimic-code 里简直不要太常见。
services
表格包含了病人接受治疗的情况(比如是在外科还是内科这种):
|
|
但是这个表格里没有 icustay_id
,我们只能通过 hadm_id
来 JOIN:
|
|
但是,这个过程其实中间是有一些猫腻的。INNER JOIN 是取交集的:
那么取完后的结果的行数肯定不多于之前的数据。但是我们看看我们的数据:
|
|
这个在我电脑上显示 78840
行,那我们再看 icustays
数据:
|
|
61532
行。哈哈,INNER JOIN 之后行数变多了,刺激!
下面很快给出了解释:
事实是,每个 hadm_id
可能对应了好几个 service 和好几个 icustay_id
,即一个病人院内转科和多次住 ICU 的情况。所以当通过 hadm_id
来 JOIN 两个表的时候,在 hadm_id
相同而 icustay_id
和 services
不同时每种组合都会在结果里作为单独的一行。专业的解释:
More technically, the first query joined two tables on non-unique keys: there may be multiple
hadm_id
with the same value in the services table, and there may be multiplehadm_id
with the same value in the admissions table. For example, if the services table hashadm_id = 100001
repeated N times, and the admissions table hashadm_id = 100001
repeated M times, then joining these two onhadm_id
will result in a table with NxM rows: one for every pair. With MIMIC, it is generally very bad practice to join two tables on non-unique columns: at least one of the tables should have unique values for the column, otherwise you end up with duplicate rows and the query results can be confusing.
所以最后,我们可以通过在 services
里对相同的 hadm_id
利用窗口函数排序,只留下第一个 service
记录,这样 hadm_id
也就变成了 unique key 了。
|
|
本来打算只写一点点做个笔记,没想到已经这么长了,那干脆分篇好了。
参考:
To be continued…
文章作者 Jackie
上次更新 2019-01-11 (6f12b47)