各个省肺炎感染类型及人数可视化R语言基于地理位置进行分面

20 篇文章 5 订阅
2 篇文章 1 订阅

(各个省肺炎感染类型及人数可视化)R语言基于地理位置进行分面

不知道大家有没有看过这样的图:乍一看还以为是元素周期表(哈哈哈,化学都还给老师了)。实际上他这个是根据美国各个州的地理位置进行分面(在R语言里面一般使用facet_grid()或者facet_wrap()来做,其实还有很多,我一般只用这两个)

接下来就是来分析一下,如何画这个图,当然单纯靠ggplot2包肯定可以,但是重复造轮子太麻烦了,今天也就是介绍一个R包——geofacet

这个包就是可以快速的基于地理信息画出上面的案例(实际上上面的图也就是这个包的一个demo)。我只会一点点R语言,我就从我的理解角度进行画图。

我觉得,像R语言这个编程,在不考虑统计、数学这些知识下,只要掌握数据结构和函数的一些主要要求,基本上都可以满足需求。

library(geofacet)
library(ggplot2)

ggplot(state_ranks, aes(variable, rank, fill = variable))  
  geom_col()  
  coord_flip()   
  theme_bw()  
  facet_geo(~state)

画出上面这个图,只需要这么多代码,一行一行分解

第一行到第三行肯定不要解释了,从安装包到加载包,这个是基础的。

从第五行到第九行,一共5行代码,第五行的ggplot(state_ranks, aes(variable, rank, fill = variable)) 这句话是说加载state_ranks这个数据,然后选择x轴为state_ranksvariable变量,y轴为rank变量,填充颜色是variable

geom_col()函数是画条形图,coord_flip()是将坐标轴旋转一下,theme_bw()函数是设置一下这个绘画的主题,然后告诉facet_geo()函数(geofacet包提供的),让这个图根据state_ranks里面的state这个变量进行分面,然后就得出这个图了,实际上确实很简单(只要是你数据格式正确!!!)。如果你以为只要数据框有这几个变量,就可以画出图来,简直是大错特错。我们真正应该值得注意的是state_ranks这个数据框,好好看一看这个数据框是什么样的。

# > state_ranks
#     state                 name   variable rank
# 1      AK               Alaska  education   28
# 2      AK               Alaska employment   50
# 3      AK               Alaska     health   25
# 4      AK               Alaska     wealth    5
# 5      AK               Alaska      sleep   27
# 6      AK               Alaska    insured   50
# 7      AL              Alabama  education   45
# > str(state_ranks)
# 'data.frame':  306 obs. of  4 variables:
#   $ state   : chr  "AK" "AK" "AK" "AK" ...
# $ name    : chr  "Alaska" "Alaska" "Alaska" "Alaska" ...
# $ variable: chr  "education" "employment" "health" "wealth" ...
# $ rank    : num  28 50 25 5 27 50 45 49 48 47 ...

仔细看看这个数据表就知道了,这个数据表的state都是各个州的缩写,name都是各个州的全称, variable是变量属性(只有六种),rank对应的是数值。facet_geo(~state)什么意思??“state_ranks这个数据框对facet_geo()函数说,你就按照我的state进行分面就可以啦,然后facet_geo()就根据state_rankstate这列进行匹配,按照预先设定好的位置进行分面。”

那么他是按照什么来进行分面的?预先设置的位置数据怎么储存的??实际上看一下facet_geo函数就知道啦,看到下面有个grid = "us_state_grid1"。说明就是按照us_state_grid1来分面的(我是在看完官方写的demo,我才知道的,刚开始我也是蒙蔽)

那么us_state_grid1是什么样子的?

# > us_state_grid1
# row col code                 name
# 1    6   7   AL              Alabama
# 2    7   2   AK               Alaska
# 3    5   2   AZ              Arizona
# 4    5   5   AR             Arkansas
# 5    4   1   CA           California
# 6    4   3   CO             Colorado

实不相瞒,他就是长得这样的,当state_ranksfacet_geo函数说:“你就按照我的state进行分类”。然后facet_geo函数就将state_ranksstate变量和us_state_grid1name进行匹配,发现都一样,然后就按照us_state_grid1的各个州对应的rowcol(也就是行列位置)进行分面,把不同的州的位置根据rowcol数值,一一放到对应的位置上。最终成功展出这样的美国地图。

第二个案例

# > head(state_unemp)
# year rate state
# 1 2000  4.6    AL
# 2 2001  6.0    AL
# 3 2002  5.8    AL
# 4 2003  6.0    AL
# 5 2004  5.2    AL
# 6 2005  4.2    AL
# > head(us_state_grid2)
# row col code       name
# 1   6   7   AL    Alabama
# 2   1   1   AK     Alaska
# 3   6   2   AZ    Arizona
# 4   6   5   AR   Arkansas
# 5   6   1   CA California
# 6   5   3   CO   Colorado
ggplot(state_unemp, aes(year, rate))  
  geom_line()  
  facet_geo(~ state, grid = "us_state_grid2", label = "code")  
  scale_x_continuous(labels = function(x) paste0("'", substr(x, 3, 4)))  
  labs(title = "Seasonally Adjusted US Unemployment Rate 2000-2016",
       caption = "Data Source: bls.gov",
       x = "Year",
       y = "Unemployment Rate (%)")  
  theme(strip.text.x = element_text(size = 6))

上面的代码中从第一行到第九行,都是观察两个数据框,state_unemp是我们要可视化的数据,us_state_grid2是网格。根据这个网格标记的位置来找各个州的位置。第17、18行是说根据state_unempyear为横坐标,rate为纵坐标,画出折线图。第19行是分面,以state_unempstate变量为依据,按照网格us_state_grid2来画位置,各个位置的面的名称依据us_state_grid2code变量,然后第20行到25行都是对坐标轴的标签进行修改。

最后图如下:

实际上确实很简单。

用疫情和中国各个省的一个分面地图

但是目前数据还不好找,先待定,到时候,我会介绍如何自己做一个中国地图的版本。虽然现在也已经有了。

昨晚(放弃看春晚,连夜写代码,终于画出来啦)

为了符合当今时事,我们使用新浪新闻提供的数据:https://news.sina.cn/zt_d/yiqing0121

将上面的数据手动输入Rstudio里面, 代码如下:

library(geofacet)
library(ggplot2)
pro <- c("湖北", "北京", "广东", "上海", "浙江", 
         "云南", "四川", "山东", "广西", "贵州", 
         "安徽", "海南", "宁夏", "吉林", "江西", 
         "天津", "河南", "重庆", "山西", "黑龙江", 
         "湖南", "辽宁", "澳门", "台湾", "福建", 
         "香港", "河北", "内蒙古", "江苏", "陕西", 
         "新疆", "甘肃", "青海")
pro_eng <- sort(tolower(china_prov_grid2$name))[c(14,2,6,26,34,
                                                  33,28,25,7,8,
                                                  1,9,22,19,18,
                                                  30,12,3,27,11,
                                                  15,20,21,29,4,
                                                  13,10,16,17,24,
                                                  32,5,23)]
`确诊` <- c(549, 36, 53, 20, 43,
          1, 15, 15, 13, 4, 
          15, 5, 3, 3, 7, 
          8, 9, 27, 1, 4, 
          24, 4, 2, 2, 10, 
          2, 2,1,9,5,
          2, 2, 0)
`疑似` <- c(0, 0, 0, 22, 
          0, 0, 4, 
          0, 0, 0, 4, 32, 1,
          0, 0, 0, 42, 13, 0,0,0,0,0,0,2, 36,
          0, 2, 0, 0, 0, 0,1)
my_data <- data.frame(province = pro, province_eng = pro_eng,
                      `确诊` = `确诊`, `疑似` = `疑似`)
> head(my_data)
# province province_eng 确诊 疑似
# 1     湖北        hubei  549    0
# 2     北京      beijing   36    0
# 3     广东    guangdong   53    0
# 4     上海     shanghai   20   22
# 5     浙江     zhejiang   43    0
# 6     云南       yunnan    1    0

上面第11行代码是将各个省的中文名字和拼音联系到一起。为了省事,我都用了小写,最后,要展现得数据是32行开始的。

这个时候my_data是宽数据,要将宽数据转换为长数据。因为是ggplot2做图本来就要求的, 代码如下:

library(tidyverse)
my_data_long <- reshape2::melt(my_data, id.vars = c("province", "province_eng"))
head(my_data_long)
# province province_eng variable value
# 1     湖北        hubei     确诊   549
# 2     北京      beijing     确诊    36
# 3     广东    guangdong     确诊    53
# 4     上海     shanghai     确诊    20
# 5     浙江     zhejiang     确诊    43
# 6     云南       yunnan     确诊     1

实际上facet_geo包提供的中国地图是34个省,但是新浪新闻提供的数据是33个省,通过代码简单看一下就知道:西藏没有被包含。那么舍去掉,自己定义一个grid。

setdiff(tolower(china_prov_grid2$name), my_data$province_eng)
# [1] "tibet"

接下来就是定义自己的grid,然后画出来, code如下:

my_grid <- china_prov_grid2 %>% 
  mutate(name = tolower(name)) %>% 
  filter(name != "tibet")

my_data <- my_data %>% 
  mutate_if(is.factor, as.character)
head(my_data)
# province province_eng 确诊 疑似
# 1     湖北        hubei  549    0
# 2     北京      beijing   36    0
# 3     广东    guangdong   53    0
# 4     上海     shanghai   20   22
# 5     浙江     zhejiang   43    0
# 6     云南       yunnan    1    0
head(my_grid)
# code row col     name
# 1   XJ   4   1 xinjiang
# 2   GS   4   2    gansu
# 3   QH   5   2  qinghai
# 4   SC   6   2  sichuan
# 5   YN   7   2   yunnan
# 6   NX   5   3  ningxia

看到上面的my_gridmy_data, 就可以得出,这两个表通过nameprovince_eng变量进行匹配。

然后图如下:


ggplot(my_data_long, aes(x = variable, y = value, fill = variable))   
  geom_col()   geom_text(aes(x = variable, y = value, label = value), hjust = 0.9) 
  facet_geo(~ province_eng, grid = my_grid)   
  theme_bw()   coord_flip()   
  labs(title = "武汉疫情分布",
       subtitle = "截止2020年1月24日23时",
       caption = "Data Source: https://news.sina.cn/zt_d/yiqing0121",
       x = "症状",
       y = "数量")   
  theme(plot.title = element_text(hjust = 0.5, size = 16))


上面各个表每一个块是代表各个省(我怎么设置都没办法将标签从拼音改为中文)不同的颜色代表确诊人数和疑似人数。

最后声明一下:

数据来源为新浪新闻,时事数据更新:网站为:https://news.sina.cn/zt_d/yiqing0121。可能我在手动输入的过程中,会有误差,主要是提供分析方法,请不要相信我的统计图反映的数据!!!

最后可以去安装这个包试一试:
https://hafen.github.io/geofacet/

https://hafen.github.io/geofacet/rd.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuanzhoulvpi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值