查看原文
其他

R | 对亚马逊新总部可能位置进行可视化

Sharp Sight R语言中文社区 2019-04-22

点击蓝字关注这个神奇的公众号~

作者:Sharp Sight   

翻译:王亨

来源公众号:跟着菜鸟一起学R语言


听说上次分前不久,亚马逊宣布在寻找一个城市建立第二个总部。

他们对这个城市的标准是超过100万人,同时这个城市也要大批高学历人才。
在一个新闻网站上面发现,我发现了一些可能的城市名单,他们都有超过100万的人口,而且每个城市都是人才济济。
https://www.cbsnews.com/news/amazon-hq2-cities-location-choices-new-second-headquarters/

新闻网页上已经对其进行了可视化,但是在这里,我要用R进行可视化。这是一个对爬虫/数据处理/可视化很好的锻炼机会。运行下面这些代码需要科学上网了

有了这个想法,我们首先要爬取数据,然后数据处理(使用dplyr和一些其他工具),然后使用ggplot2绘制地图。

我需要说明的是我们这个分析不是完美的,因为不知道全部的城市名单,也不知道最终的选择标准,即使我们知道了,一个完整的分析远远超过了像博客这样的简单程度.

按照刚才说的,我们首先要做的就是进行数据预处理。

首先,我们先加载一些我们需要的包。

#==============# LOAD PACKAGES#==============

library(rvest)

library(tidyverse)

library(stringr)

library(ggmap)

我们要用rvest包里面的几个函数来爬取数据,然后转换为一个数据框。

html.amz_cities <- read_html("https://www.cbsnews.com/news/amazons-hq2-cities-second-headquarters-these-cities-are-contenders/")

df.amz_cities <- html.amz_cities %>%  html_nodes("table") %>%  .[[1]] %>%   html_table()

# inspect

df.amz_cities %>% head()

我们现在来改变一下列名,党我们爬取到的数据时,它从网页上面没有读取到,所以我们就要自己动手添加。

#====================

# CHANGE COLUMN NAMES

#====================

# inspect initial column names


colnames(df.amz_cities)# assign new column names

colnames(df.amz_cities) <- c("metro_area", 'state', 'population_tot', 'bachelors_degree_pct')
# inspect

df.amz_cities %>% head()

和我们预期的一样,爬取的数据列名(原网页显示的列名)在我们新建数据框的第一行,这个是不合适的,所以我们就删去第一行。

#==============================================

# REMOVE FIRST ROW

# - when we scraped the data, the column names

#   on the table were read in as the first row

#   of data.# - Therefore, we need to remove the first row

#==============================================

df.amz_cities <- df.amz_cities %>% filter(row_number() != 1)

现在我们需要修改两个变量bachelors_degree_pct 和population_tot,它们现在是字符类型,但我们需要将它转换为数字类型。因此我们需要强制类型转换。

#=======# MODIFY VARIABLES

# - both bachelors_degree_pct and population_tot were scraped as character variables

#    but we need them in numeric format

# - we will use techniques to parse/coerce these variable from char to numeric#
df.amz_cities <- mutate(df.amz_cities, population_tot = parse_number(population_tot))
# check

typeof(df.amz_cities$population_tot)
# inspect

df.amz_cities %>% head()
#--------# COERCE: bachelors_degree_pct#---------------

df.amz_cities <- mutate(df.amz_cities, bachelors_degree_pct = as.numeric(bachelors_degree_pct))

现在我们需要创建一个变量,包含城市名。数据中有一个变量叫metro_area,比如New York-Newark-Jersey City.中的。metro_area这个变量或许有用,但是我们从数据中地理编码时也许会出错,因为它表示的范围太广。因此我们需要一个准确的城市名来对其进行地理编码。

出于这种目的,我们新建一个city变量通过metro 名来存储一个具体的城市名。我们要用到stringr::str_extract()函数,以及结合正则表达式就可以提取城市名。

#=====# CREATE VARIABLE: city

# - here, we're using the stringr function str_extract() to

#   extract the primary city name from the metro_area variable

# - to do this, we're using a regex to pull out the city name

#   prior to the first '-' character#

df.amz_cities <- df.amz_cities %>% mutate(city = str_extract(metro_area, "^[^-]*"))

现在我们已经有具体的城市名,现在要用函数来对每个城市进行地理编码获取每个城市的经纬度。然后我们再用cbind()函数将地理编码数据在加入到数据框里面。

# GEOCODE# - here, we're getting the lat/long data#

data.geo <- geocode(df.amz_cities$city)#inspectdata.geo %>% head()data.geo
#=# RECOMBINE: merge geo data to data frame#

df.amz_cities <- cbind(df.amz_cities, data.geo)df.amz_cities

现在我们要用dplyr::rename()函数将数据框列名为lon重命名为long。

#==# RENAME VARIABLE: lon -> long

# - we'll rename lon to lon, just because 'long' is consistent

#   with the name for longitude in other data sources

#   that we will use#

df.amz_cities <- rename(df.amz_cities, long = lon)   # get column names names
df.amz_cities %>% names()

为了让数据读起来很简单,我们需要对数据进行重新排序,city, state, and metro,然后是地理坐标信息,最后再是人口,和有高学历人才所占比例。

# REORDER COLUMN NAMES# - here, we're just doing it manually ...#


df.amz_cities <- select(df.amz_cities, city, state, metro_area, long, lat, population_tot, bachelors_degree_pct)
# inspect
df.amz_cities %>% head()

我们要在一张美国地图上面进行可视化,这里需要用到map_data()函数。

#===============# GET USA MAP

# - this is the map of the USA states, upon which

#   we will plot our city data points#==


map.states <- map_data("state")

#====================================# PLOT

# - here, we're actually creating the 

#   data visualizations with ggplot()
# FIRST ITERATION

# - this is just a 'first pass' to check that

#   everything looks good before we take the time

#   to format it

#------------------------------------------------


ggplot() +

  geom_polygon(data = map.states, aes(x = long, y = lat, group = group)) +

     geom_point(data = df.amz_cities, aes(x = long, y = lat, size = population_tot, color = bachelors_degree_pct))

从颜色深度等级上看一切看起来都正常。那些点也在正确的位置,大致看来都很正常。

现在,我们有一个初始版本,现在要通过添加标题、主题元素的格式等来调整一下图片。

# FINALIZED VERSION (FORMATTED)

# - this is the 'finalized' version with all of the

#   detailed formatting#

ggplot() +

  geom_polygon(data = map.states, aes(x = long, y = lat, group = group)) +          geom_point(data = df.amz_cities, aes(x = long, y = lat, size = population_tot, color = bachelors_degree_pct*.01), alpha = .5) +  geom_point(data = df.amz_cities, aes(x = long, y = lat, size = population_tot, color = bachelors_degree_pct*.01), shape = 1) +

  coord_map(projection = "albers", lat0 = 30, lat1 = 40, xlim = c(-121,-73), ylim = c(25,51)) +

  scale_color_gradient2(low = "red", mid = "yellow", high = "green", midpoint = .41, labels = scales::percent_format()) +

  scale_size_continuous(range = c(.9, 11),  breaks = c(2000000, 10000000, 20000000),labels = scales::comma_format()) +

  guides(color = guide_legend(reverse = T, override.aes = list(alpha = 1, size = 4) )) +

  labs(color = "Bachelor's Degree Percent"

       ,size = "Total Population (metro area)"

       ,title = "Possible cities for new Amazon Headquarters"

       ,subtitle = "Based on population & percent of people with college degrees") +

  theme(text = element_text(colour = "#444444", family = "Gill Sans")

        ,panel.background = element_blank()

        ,axis.title = element_blank()

        ,axis.ticks = element_blank()

        ,axis.text = element_blank()

        ,plot.title = element_text(size = 28)

        ,plot.subtitle = element_text(size = 12)

        ,legend.key = element_rect(fill = "white")

        )

总结:这是一个不全面的分析。因为没有详细的选择标准,很难得出任何确切的结论。但是,这是为了给你一些提示,那就是可以使用R及其工具。 如果你这方面的兴趣,你可以通过收集更多的数据和制作更多的图表来扩展这个分析使之更加完善。

附注:本文由王亨翻译,限于个人水平有限以及第一次翻译,如有不足还请多多指教。点击阅读原文即可查看英文原文,转载请后台留言。






 大家都在看 

2017年R语言发展报告(国内)

R语言中文社区历史文章整理(作者篇)

R语言中文社区历史文章整理(类型篇)


公众号后台回复关键字即可学习

回复 R                  R语言快速入门及数据挖掘 
回复 Kaggle案例  Kaggle十大案例精讲(连载中)
回复 文本挖掘      手把手教你做文本挖掘
回复 可视化          R语言可视化在商务场景中的应用 
回复 大数据         大数据系列免费视频教程 
回复 量化投资      张丹教你如何用R语言量化投资 
回复 用户画像      京东大数据,揭秘用户画像
回复 数据挖掘     常用数据挖掘算法原理解释与应用
回复 机器学习     人工智能系列之机器学习与实践
回复 爬虫            R语言爬虫实战案例分享

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存