Author: Haoxiang Qi(齐浩翔)
Date: Feb 8, 2020
Data from: GuangchuangYu (Github), jianxu305 (Github)
R包获取数据
# R
# 需要先安装包remotes
library(remotes)
# remotes::install_github("GuangchuangYu/nCov2019") 按照github里的数据包 From: GuangchuangYu
library(nCov2019)
# 获取数据
x <- get_nCov2019()
x[] %>% head(3)## name confirm suspect dead heal
## 1 湖北 27100 0 780 1439
## 2 广东 1120 0 1 125
## 3 浙江 1075 0 0 173
## confirm suspect dead heal deadRate healRate date
## 1 41 0 1 0 2.4 0.0 01.13
## 2 41 0 1 0 2.4 0.0 01.14
## 3 41 0 2 5 4.9 12.2 01.15
数据处理
# Python
# 定义新函数:添加ticker
def convert_table(table):
output_table = pd.DataFrame()
for ticker in ["heal", "dead", "suspect", "confirm"]:
col = table >> select(ticker, "date") >> mutate(condition = ticker)
output_table = pd.concat([output_table, col.rename(columns={ticker:"number"})])
return output_table.replace(["heal", "dead", "suspect", "confirm"],
["治愈", "死亡", "疑似", "确诊"]).reset_index().drop(columns="index")
# 应用函数添加ticker
summary = convert_table(r.summary)
summary.head(3)## number date condition
## 0 0 01.13 治愈
## 1 0 01.14 治愈
## 2 5 01.15 治愈
可视化
# R
ggplot(py$summary, aes(x=as.Date(date, "%m.%d"), y=number, color=condition)) + # 谨记将日期由格式str转为date
geom_line(size=.8, alpha=.7) +
geom_point(aes(shape=condition)) +
geom_hline(yintercept = 10000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 20000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 30000, color='black', size=.8, alpha=.5, linetype="dotted") +
theme_classic() +
scale_x_date(date_labels = "%m/%d", breaks = "2 days") +
xlab("日期") +
ylab("人数") +
ggtitle("全国累计总人数趋势图") +
theme(text = element_text(family = "Source Han Sans CN")) 分析:
1. 可以非常明显的看出确诊人数和疑似人数仍然持上升趋势,其中确诊人数呈现近似指数增长,预计2月9日即突破4万确诊,形势依然不容乐观。
2. 全国治愈人数逐渐上升突破1542人,各地的物资医疗支援开始初见成效。
有兴趣的同学可以查看下面的使用R语言预测拐点的链接
https://openr.pzhao.org/zh/blog/ncovr-03/
数据处理
## number date condition
## 1 0 01.21 治愈
## 16 261 02.05 治愈
## 8 43 01.28 治愈
可视化
# R
ggplot(py$summary_new, aes(x=as.Date(date, "%m.%d"), y=number, color=condition)) +
geom_line(size=.8, alpha=.7) +
geom_point(aes(shape=condition)) +
geom_hline(yintercept = 2000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 4000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 6000, color='black', size=.8, alpha=.5, linetype="dotted") +
theme_classic() +
scale_x_date(date_labels = "%m/%d", breaks = "2 days") +
xlab("日期") +
ylab("人数") +
ggtitle("全国每日新增趋势图") +
theme(text = element_text(family = "Source Han Sans CN")) 分析:
1. 近几日新增疑似病例数量开始出现下降,但新增确诊病例并未出现大幅上升。这说明一方面可能因为确诊流程趋于完善,另一方面可能是疫情得到控制的先兆。
2. 得益于大量医务人员的不懈努力,新增治愈人数开始快速爬升。
数据处理
# Python
# 只选出疑似和确诊
filter = summary[summary.condition.isin(["疑似", "确诊"])].sort_values("date")
# 按日期聚合汇总并更改列名
total = filter.groupby("date").sum().reset_index().rename(columns={"number":"total"})
# 连结表并新建比例计算列
ratio_table = filter.merge(total, "left", on="date") >> mutate(ratio=X.number / X.total)
ratio_table.tail(3)## number date condition total ratio
## 51 27657 02.07 疑似 62255 0.444253
## 52 28942 02.08 疑似 66193 0.437237
## 53 37251 02.08 确诊 66193 0.562763
可视化
# R
ggplot(py$ratio_table %>% tail(-14), aes(x=as.Date(date, "%m.%d"), y=ratio, fill=condition)) +
geom_bar(stat="identity", alpha=.8) +
geom_hline(yintercept = 0.5, color='black', size=.8, alpha=.7, linetype="dotted") +
xlab("日期") +
ylab("占比") +
ggtitle("全国确诊/疑似百分比堆积图") +
theme_classic() +
scale_x_date(date_labels = "%m/%d", breaks = "2 days") +
theme(text = element_text(family = "Source Han Sans CN")) +
geom_text(aes(label=paste0(sprintf("%1.0f", ratio*100), "%")), position=position_stack(vjust=0.5), size=2.5) 分析:
1. 确诊人数占比近日出现上升,并于2月4日超过50%,说明确诊能力得到提升,感染人群容易被控制。
2. 确诊能力的提升使得更多处于潜伏期的人群能够被隔离,减少与未染病人群的接触,降低疫情扩大的可能。
R包的数据比较少,下面使用Python获取更多数据
# Python
# 有人帮我们把轮子造好了,这也是Python的好处之一,可以使用全世界的轮子
import utils # 一个从数仓下载数据并清洗的模块 From: jianxu305 (Github)
# 加载数据
cnov_data = utils.load_chinese_data() ## 最近更新于: 2020-02-09 08:34:27.166000
## 数据日期范围: 2020-01-24 to 2020-02-09
## 数据条目数: 26347
## The following dates are removed due to insufficient provinces reported: [datetime.date(2020, 2, 9)]
cnov_data.updateDate = cnov_data.updateDate.astype(str)
cnov_data.drop(columns="updateTime", inplace=True)
cnov_data.head(3)## provinceName cityName confirmed cured dead updateDate
## 25357 云南省 丽江市 1 0 0 2020-01-24
## 25355 云南省 昆明 3 0 0 2020-01-24
## 25356 云南省 西双版纳州 1 0 0 2020-01-24
数据处理
# Python
# 只选出最新日期数据
sort_data = cnov_data[cnov_data.updateDate == cnov_data.updateDate.max()]
# 选出除武汉外前10城市
sort_data = sort_data.sort_values("dead", ascending=False).head(11).tail(10)
# 手动添加GDP,人口数据
extra_data = pd.DataFrame({"cityName":list(sort_data.cityName),
"GDP":[2035, 1912, 1005, 1847, 591, 2082, 1011, 4064, 800, 4309],
"population":[750, 530, 108, 300, 161, 641, 222, 417, 156, 605]})
# 连结数据
sort_data = sort_data.merge(extra_data, "inner", on="cityName")
sort_data.head(3)## provinceName cityName confirmed cured dead updateDate GDP population
## 0 湖北省 黄冈 2041 105 36 2020-02-08 2035 750
## 1 湖北省 孝感 2313 42 26 2020-02-08 1912 530
## 2 湖北省 鄂州 569 33 20 2020-02-08 1005 108
可视化
# R
ggplot(py$sort_data, aes(x=population, y=GDP, color=cityName)) +
geom_point(aes(size=dead)) +
geom_text(aes(label=paste(cityName, dead)), family = "Source Han Sans CN", hjust=-.5, size=3) +
geom_abline(intercept=0, slope=6.5, color='red', size=.9, alpha=.5, linetype="dotted") +
xlim(100, 800) +
theme_classic() +
xlab("人口 (万)") +
ylab("GDP (亿)") +
ggtitle("人口-GDP-死亡数气泡关系图 (除武汉外死亡数前十城市)") +
scale_size_continuous(range=c(2,11)) +
annotate("text", x=530, y=3500, label="全国人均GDP分界线", alpha=.6, family="Source Han Sans CN", size=2.5) +
annotate("text", x=600, y=1200, label="未达全国人均GDP", alpha=.8, family="Source Han Sans CN", size=4) +
annotate("text", x=250, y=3000, label="超过全国人均GDP", alpha=.8, family="Source Han Sans CN", size=4) +
theme(text = element_text(family = "Source Han Sans CN")) 分析:
手动录入10座城市的GDP和人口数据,并加入全国人均GDP标准线,想探究目前富裕程度和死亡人数的关系。
1. 襄阳和宜昌作为湖北省老二老三,拥有较为优良的医疗条件,所以即便人口众多也能尽可能降低死亡数。
2. 就死亡数来看,可能黄冈和孝感对医疗力量的需求更大,应加大对这两座城市的救援力度。
数据处理
# Python
# 以省份和日期聚合数据获得省维度数据
province_data = cnov_data.groupby(["provinceName", "updateDate"]).sum().reset_index()
# 以日期聚合数据获得国家维度数据再求平均
china = cnov_data.groupby("updateDate").sum().reset_index() >> mutate(provinceName = "全国平均")
# 合并数据再只选出四省和全国平均
total = pd.concat([province_data, china], sort=False)
total = total.sort_values(["provinceName", "confirmed"], ascending=False)
total = total[total.provinceName.isin(["湖北省", "广东省", "浙江省", "河南省", "全国平均"])]
total.head(3)## provinceName updateDate confirmed cured dead
## 327 湖北省 2020-02-08 24953 1218 699
## 326 湖北省 2020-02-07 22112 867 618
## 325 湖北省 2020-02-06 19665 712 549
可视化
# R
# 新建治愈率计算列并选出三列
total <- py$total %>% mutate(cured_ratio = cured / confirmed * 100) %>% select(
"provinceName", "updateDate", "cured_ratio")
# 定义新函数:方便一次性画出四张图
plot_provinces <- function(info, flag_title, flag_title_x, flag_title_y)
{
# 传递参数进入theme以方便消除多余的标题
if (flag_title == TRUE)
title = element_blank()
else
title = element_text(size = 10, face = "bold")
if (flag_title_x == TRUE)
title_x = element_blank()
else
title_x = element_text(size = 8)
if (flag_title_y == TRUE)
title_y = element_blank()
else
title_y = element_text(size = 8)
if (info == "浙江省")
{mannul_colors = c("#E69F00", "#56B4E9")
mannul_shapes = c(16, 17)}
else
{mannul_colors = c("#56B4E9", "#E69F00")
mannul_shapes = c(17, 16)}
ggplot(total %>% filter(provinceName == info | provinceName == "全国平均"), aes(
x=as.Date(updateDate, "%Y-%m-%d"), y=cured_ratio, color=provinceName)) +
geom_line(size=.7, alpha=.5) +
geom_point(aes(shape=provinceName)) +
theme_classic() +
scale_x_date(date_labels = "%m/%d", breaks = "3 days") +
xlab("日期") +
ylab("治愈率 (%)") +
geom_hline(yintercept = 5, color='black', size=.5, alpha=.7, linetype="dotted") +
geom_hline(yintercept = 10, color='black', size=.5, alpha=.7, linetype="dotted") +
geom_hline(yintercept = 15, color='black', size=.5, alpha=.7, linetype="dotted") +
ylim(0,15) +
ggtitle("四省治愈率趋势图(湖北/浙江/河南/广东)") +
scale_color_manual(values=mannul_colors) +
scale_shape_manual(values=mannul_shapes) +
theme(text = element_text(family = "Source Han Sans CN")) +
theme(
plot.title = title,
axis.text=element_text(size=8,face="bold"),
axis.title.x=title_x,
axis.title.y=title_y,
legend.text = element_text(size=8),
legend.title = element_text(size=8),
)
}
# 调用函数绘制图
hubei <- plot_provinces("湖北省", FALSE, TRUE, FALSE)
henan <- plot_provinces("河南省", TRUE, FALSE, FALSE)
zhejiang <- plot_provinces("浙江省", TRUE, TRUE, TRUE)
guangdong <- plot_provinces("广东省", TRUE, FALSE, TRUE)
# 拼接为一张图
multiplot(hubei, henan, zhejiang, guangdong, cols=2) 分析:
1. 作为确诊人数最多的四省,除湖北外,其他省均达到或超过10%的治愈率,相信随着时间的增长,会有更多患者得以康复。
2. 正是由于浙江和河南政府的积极举措,使得这两省的治愈率最为理想,值得其他省份借鉴。
数据处理
# Python
# 筛选武汉数据/改列名
wuhan_data = cnov_data[cnov_data.cityName == "武汉"] >> rename(ticker = X.cityName)
# 筛选非湖北省数据/按时间聚合/改列名
not_hubei_data = province_data[province_data.provinceName != "湖北省"].groupby(
"updateDate").sum().reset_index() >> mutate(ticker = "全国(不含湖北)")
# 筛选湖北省数据/改列名
hubei_data = province_data[province_data.provinceName == "湖北省"] >> rename(ticker = X.provinceName)
# 定义新函数:计算每日新增
def calculation_data(table):
table = table >> mutate(yesterday_confirmed = X.confirmed.shift(1)) >> mutate(
new_confirmed = X.confirmed-X.yesterday_confirmed) >> tail(-1) >> select(X.ticker,X.updateDate,X.new_confirmed)
return table
# 应用新函数计算每日新增
hubei_data = calculation_data(hubei_data)
wuhan_data = calculation_data(wuhan_data)
not_hubei_data = calculation_data(not_hubei_data)
# 合并表
china_data = pd.concat([hubei_data, wuhan_data, not_hubei_data], join="inner").reset_index().drop(columns="index")
china_data.sample(3)## ticker updateDate new_confirmed
## 20 武汉 2020-01-30 356.0
## 15 武汉 2020-01-25 77.0
## 2 湖北省 2020-01-27 365.0
可视化
# R
ggplot(py$china_data, aes(x=as.Date(updateDate, "%Y-%m-%d"), y=new_confirmed, color=ticker)) +
geom_line(size=.8, alpha=.7) +
geom_point(aes(shape=ticker)) +
xlab("日期") +
ylab("人数") +
ggtitle("全国新增确诊趋势图") +
geom_hline(yintercept = 1000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 2000, color='black', size=.8, alpha=.5, linetype="dotted") +
geom_hline(yintercept = 3000, color='black', size=.8, alpha=.5, linetype="dotted") +
theme_classic() +
theme(text = element_text(family = "Source Han Sans CN")) +
scale_x_date(date_labels = "%m/%d", breaks = "2 days") 分析:
1. 可以非常直观地看出,除武汉外,其余省份疫情得到有效的控制,新增确诊人数呈现稳定下降趋势。
2. 武汉以及湖北省疫情最为严峻,目前还未看出好转迹象。