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

浏览: 1650

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

他们对这个城市的标准是超过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 = b

image.png

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

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

# 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\nPercent"
      ,size = "Total Population\n(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")
       )

image.png

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

附注:本文由王亨翻译,限于个人水平有限以及第一次翻译,如有不足还请多多指教。

image.png

推荐 0
本文由 王亨 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册