## Load packages
library(tidycensus)
library(sf)
## Linking to GEOS 3.9.1, GDAL 3.4.3, PROJ 7.2.1; sf_use_s2() is TRUE
library(tmap)
library(jsonlite)
library(tidyverse)
## ── Attaching packages
## ───────────────────────────────────────
## tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6 ✔ purrr 0.3.4
## ✔ tibble 3.1.8 ✔ dplyr 1.0.10
## ✔ tidyr 1.2.1 ✔ stringr 1.4.1
## ✔ readr 2.1.2 ✔ forcats 0.5.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ purrr::flatten() masks jsonlite::flatten()
## ✖ dplyr::lag() masks stats::lag()
library(httr)
library(jsonlite)
library(reshape2)
##
## Attaching package: 'reshape2'
##
## The following object is masked from 'package:tidyr':
##
## smiths
library(here)
## here() starts at C:/Users/iskim/Dropbox (GaTech)/2022-2023/2022 Fall/CP 8883 Intro to Urban Analytics/UA_module1
# devtools::install_github("OmaymaS/yelpr")
library(yelpr)
library(knitr)
## Session info
sessionInfo()
## R version 4.2.1 (2022-06-23 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 22000)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=English_United States.utf8
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] knitr_1.40 yelpr_0.1.0 here_1.0.1 reshape2_1.4.4
## [5] httr_1.4.4 forcats_0.5.2 stringr_1.4.1 dplyr_1.0.10
## [9] purrr_0.3.4 readr_2.1.2 tidyr_1.2.1 tibble_3.1.8
## [13] ggplot2_3.3.6 tidyverse_1.3.2 jsonlite_1.8.0 tmap_3.3-3
## [17] sf_1.0-8 tidycensus_1.2.3
##
## loaded via a namespace (and not attached):
## [1] fs_1.5.2 lubridate_1.8.0 RColorBrewer_1.1-3
## [4] rprojroot_2.0.3 tools_4.2.1 backports_1.4.1
## [7] bslib_0.4.0 utf8_1.2.2 rgdal_1.5-32
## [10] R6_2.5.1 KernSmooth_2.23-20 DBI_1.1.3
## [13] colorspace_2.0-3 raster_3.5-29 withr_2.5.0
## [16] sp_1.5-0 tidyselect_1.1.2 leaflet_2.1.1
## [19] compiler_4.2.1 leafem_0.2.0 cli_3.4.0
## [22] rvest_1.0.3 xml2_1.3.3 sass_0.4.2
## [25] scales_1.2.1 classInt_0.4-7 proxy_0.4-27
## [28] rappdirs_0.3.3 digest_0.6.29 foreign_0.8-82
## [31] rmarkdown_2.16 base64enc_0.1-3 dichromat_2.0-0.1
## [34] pkgconfig_2.0.3 htmltools_0.5.3 dbplyr_2.2.1
## [37] fastmap_1.1.0 readxl_1.4.1 htmlwidgets_1.5.4
## [40] rlang_1.0.5 rstudioapi_0.14 jquerylib_0.1.4
## [43] generics_0.1.3 crosstalk_1.2.0 googlesheets4_1.0.1
## [46] magrittr_2.0.3 Rcpp_1.0.9 munsell_0.5.0
## [49] fansi_1.0.3 abind_1.4-5 lifecycle_1.0.2
## [52] terra_1.6-17 stringi_1.7.8 leafsync_0.1.0
## [55] yaml_2.3.5 plyr_1.8.7 tmaptools_3.1-1
## [58] grid_4.2.1 maptools_1.1-4 parallel_4.2.1
## [61] crayon_1.5.1 lattice_0.20-45 haven_2.5.1
## [64] stars_0.5-6 hms_1.1.2 pillar_1.8.1
## [67] uuid_1.1-0 codetools_0.2-18 reprex_2.0.2
## [70] XML_3.99-0.10 glue_1.6.2 evaluate_0.16
## [73] modelr_0.1.9 png_0.1-7 vctrs_0.4.1
## [76] tzdb_0.3.0 cellranger_1.1.0 gtable_0.3.1
## [79] assertthat_0.2.1 cachem_1.0.6 xfun_0.32
## [82] lwgeom_0.2-8 broom_1.0.1 e1071_1.7-11
## [85] class_7.3-20 googledrive_2.0.0 viridisLite_0.4.1
## [88] gargle_1.2.1 tigris_1.6.1 units_0.8-0
## [91] ellipsis_0.3.2
## Load my Census API key
load(here('data', 'census_api_key.RData')) # Load the API key save in my local machine
census_api_key(census.api.key) %>% suppressMessages() # Activate the key in this R session
rm(census.api.key) # Remove from the environment
## Download tract polygons in Fulton and Dekalb (Year = 2019)
tract <- get_acs(geography = "tract",
state = "GA",
county = c("Fulton", "Dekalb"),
variables = c(workers = "B08006_001", # SEX OF WORKERS BY MEANS OF TRANSPORTATION TO WORK: Total (Male and Female)
workers.bicycle.commute = "B08006_014" # SEX OF WORKERS BY MEANS OF TRANSPORTATION TO WORK: Bicycle among Total (Male and Female)
),
year = 2019,
survey = "acs5",
geometry = T,
output = "wide"
) %>%
suppressMessages()
##
|
| | 0%
|
|= | 1%
|
|= | 2%
|
|== | 3%
|
|=== | 4%
|
|==== | 5%
|
|==== | 6%
|
|===== | 7%
|
|====== | 8%
|
|====== | 9%
|
|======= | 10%
|
|======= | 11%
|
|======== | 12%
|
|========= | 12%
|
|========= | 13%
|
|========== | 14%
|
|=========== | 15%
|
|============ | 16%
|
|============ | 17%
|
|============ | 18%
|
|============= | 19%
|
|============== | 20%
|
|=============== | 21%
|
|================ | 22%
|
|================= | 24%
|
|================= | 25%
|
|================== | 26%
|
|=================== | 27%
|
|==================== | 29%
|
|===================== | 29%
|
|====================== | 31%
|
|======================= | 32%
|
|======================= | 33%
|
|======================== | 34%
|
|========================= | 36%
|
|========================== | 37%
|
|========================== | 38%
|
|=========================== | 38%
|
|============================ | 39%
|
|============================= | 41%
|
|============================= | 42%
|
|============================== | 43%
|
|=============================== | 44%
|
|================================ | 45%
|
|================================= | 47%
|
|================================== | 49%
|
|=================================== | 50%
|
|===================================== | 52%
|
|====================================== | 54%
|
|======================================= | 56%
|
|======================================== | 57%
|
|========================================== | 60%
|
|=========================================== | 61%
|
|============================================ | 63%
|
|============================================= | 64%
|
|============================================== | 65%
|
|=============================================== | 67%
|
|================================================ | 68%
|
|================================================= | 70%
|
|================================================== | 71%
|
|================================================== | 72%
|
|==================================================== | 74%
|
|==================================================== | 75%
|
|===================================================== | 75%
|
|====================================================== | 77%
|
|======================================================= | 79%
|
|======================================================== | 80%
|
|========================================================= | 81%
|
|========================================================== | 82%
|
|========================================================== | 83%
|
|=========================================================== | 85%
|
|============================================================ | 86%
|
|============================================================= | 87%
|
|============================================================== | 88%
|
|=============================================================== | 90%
|
|================================================================ | 92%
|
|================================================================= | 93%
|
|=================================================================== | 95%
|
|==================================================================== | 97%
|
|===================================================================== | 99%
|
|======================================================================| 100%
## View the data
message(sprintf("Number of rows: %s, Number of columns: %s", nrow(tract), ncol(tract)))
## Number of rows: 349, Number of columns: 7
## Retain only those with estimates and rename them
tract <- tract %>%
select(GEOID, NAME,
workers = workersE,
workers.bicycle.commute = workers.bicycle.commuteE)
## Print the data
tract
## Simple feature collection with 349 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -84.85071 ymin: 33.50251 xmax: -84.02371 ymax: 34.18629
## Geodetic CRS: NAD83
## First 10 features:
## GEOID NAME workers
## 1 13121001100 Census Tract 11, Fulton County, Georgia 3972
## 2 13121009603 Census Tract 96.03, Fulton County, Georgia 3293
## 3 13121005800 Census Tract 58, Fulton County, Georgia 736
## 4 13121010117 Census Tract 101.17, Fulton County, Georgia 2941
## 5 13121009502 Census Tract 95.02, Fulton County, Georgia 2087
## 6 13089021213 Census Tract 212.13, DeKalb County, Georgia 1365
## 7 13121011202 Census Tract 112.02, Fulton County, Georgia 1788
## 8 13089023506 Census Tract 235.06, DeKalb County, Georgia 2687
## 9 13121004900 Census Tract 49, Fulton County, Georgia 1665
## 10 13121004800 Census Tract 48, Fulton County, Georgia 402
## workers.bicycle.commute geometry
## 1 71 MULTIPOLYGON (((-84.38782 3...
## 2 0 MULTIPOLYGON (((-84.38738 3...
## 3 12 MULTIPOLYGON (((-84.41692 3...
## 4 24 MULTIPOLYGON (((-84.36575 3...
## 5 0 MULTIPOLYGON (((-84.39472 3...
## 6 0 MULTIPOLYGON (((-84.34783 3...
## 7 0 MULTIPOLYGON (((-84.46052 3...
## 8 0 MULTIPOLYGON (((-84.25237 3...
## 9 28 MULTIPOLYGON (((-84.38779 3...
## 10 4 MULTIPOLYGON (((-84.38771 3...
## Define a function that outputs the center of the bounding box of a polygon and the radius of a circle encompassing the bounding box tightly
# Function: Get tract-wise radius
get_r <- function(poly, epsg_id) {
#---------------------------------------------------------------------------------------------#
# Takes: a single POLYGON or LINESTRING #
# Outputs: distance between the centroid of the bounding box and a corner of the bounding box #
#---------------------------------------------------------------------------------------------#
# Get bounding box of a given polygon
bb <- st_bbox(poly)
# Get lat & long coordinates of any one corner of the bounding box
bb_corner <- st_point(c(bb[1], bb[2])) %>% st_sfc(crs = epsg_id)
# Get centroid of the bb
bb_center_x <- (bb[3]+bb[1])/2
bb_center_y <- (bb[4]+bb[2])/2
bb_center <- st_point(c(bb_center_x, bb_center_y)) %>%
st_sfc(crs = epsg_id) %>%
st_sf()
# Get the distance between bb_corner and bb_center
r <- st_distance(bb_corner, bb_center)
# Multiply 1.2 to make the circle a bit larger than the Census Tract.
# See the Yelp explanation of their radius parameter to see why we do this.
bb_center$radius <- r*1.2
return(bb_center)
}
## Use a functional (lapply) to apply this custom function to each Census Tract.
epsg_id <- 4326 # WGS 84 (World Geodetic System 1984) used in GPS
r4all_apply <- tract %>%
st_geometry() %>%
st_transform(crs = epsg_id) %>%
lapply(., function(x) get_r(x, epsg_id = epsg_id))
r4all_apply <- bind_rows(r4all_apply)
## Appending XY coordinates as separate columns
ready_4_yelp <- r4all_apply %>%
mutate(x = st_coordinates(.)[, 1],
y = st_coordinates(.)[, 2])
## Visualize the results
# Activate the interactive mode
tmap_mode('view') %>% suppressMessages()
# Display data (the first 10 rows)
ready_4_yelp[1:10, ] %>%
st_buffer(., dist = .$radius) %>%
tm_shape(.) + tm_polygons(alpha = 0.5, col = 'red') +
tm_shape(tract[1:10, ]) + tm_borders(col = 'blue')
## Load my Yelp API key
load(here('data', 'yelp_api_key.RData')) # Load the API key save in my local machine
## Define a function that downloads all businesses of a selected category in a Census tract
get_yelp <- function(tract, category){
# ---------------------------------------------------------------- #
# Gets one row of tract information (1,) and category name (str), #
# Outputs a list of business data.frame #
# ---------------------------------------------------------------- #
n <- 1
# First request ------------------------------------------------
resp <- business_search(api_key = yelp.api.key,
categories = category,
latitude = tract$y,
longitude = tract$x,
offset = (n - 1) * 50,
radius = round(tract$radius),
limit = 50)
# Calculate how many requests are needed in total
required_n <- ceiling(resp$total/50)
# "out" is where the results will be appended to
out <- vector("list", required_n)
# Store the business information to n-th slot in "out"
out[[n]] <- resp$businesses
# Change the name of the elements to the total required_n
# This is to know if there are more than 1000 businesses, we know how many
names(out)[n] <- required_n
# Throw error if more than 1000
if (resp$total >= 1000)
{
# Glue formats string by inserting {n} with what's currently stored in object n
print(glue::glue("{n}th row has more than 1000 businesses."))
# Stop before going into the loop because we need to break down Census Tract to something smaller
return(out)
}
else
{
# Add 1 to n
n <- n + 1
# Now we know required_n -----------------------------------------------------
# Starting a loop
while(n <= required_n){
resp <- business_search(api_key = yelp.api.key,
categories = category,
latitude = tract$y,
longitude = tract$x,
offset = (n - 1) * 50,
radius = round(tract$radius),
limit = 50)
out[[n]] <- resp$businesses
n <- n + 1
}
# Merge all elements in the list into a single data frame
out <- out %>% bind_rows()
return(out)
}
}
## Prepare a collector
yelp_all_list <- vector("list", nrow(ready_4_yelp))
## Looping through all Census Tracts
for (row in 1:nrow(ready_4_yelp)){
yelp_all_list[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "bikerentals"))
if (row %% 1 == 0){
Sys.sleep(1)
print(paste0("Current row: ", row))
}
}
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 1"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 2"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 3"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 4"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 5"
## [1] "Current row: 6"
## [1] "Current row: 7"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 8"
## [1] "Current row: 9"
## [1] "Current row: 10"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 11"
## [1] "Current row: 12"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 13"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 14"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 15"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 16"
## [1] "Current row: 17"
## [1] "Current row: 18"
## [1] "Current row: 19"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 20"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 21"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 22"
## [1] "Current row: 23"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 24"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 25"
## [1] "Current row: 26"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 27"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 28"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 29"
## [1] "Current row: 30"
## [1] "Current row: 31"
## [1] "Current row: 32"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 33"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 34"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 35"
## [1] "Current row: 36"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 37"
## [1] "Current row: 38"
## [1] "Current row: 39"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 40"
## [1] "Current row: 41"
## [1] "Current row: 42"
## [1] "Current row: 43"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 44"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 45"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 46"
## [1] "Current row: 47"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 48"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 49"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 50"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 51"
## [1] "Current row: 52"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 53"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 54"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 55"
## [1] "Current row: 56"
## [1] "Current row: 57"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 58"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 59"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 60"
## [1] "Current row: 61"
## [1] "Current row: 62"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 63"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 64"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 65"
## [1] "Current row: 66"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 67"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 68"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 69"
## [1] "Current row: 70"
## [1] "Current row: 71"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 72"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 73"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 74"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 75"
## [1] "Current row: 76"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 77"
## [1] "Current row: 78"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 79"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 80"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 81"
## [1] "Current row: 82"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 83"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 84"
## [1] "Current row: 85"
## [1] "Current row: 86"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 87"
## [1] "Current row: 88"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 89"
## [1] "Current row: 90"
## [1] "Current row: 91"
## [1] "Current row: 92"
## [1] "Current row: 93"
## [1] "Current row: 94"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 95"
## [1] "Current row: 96"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 97"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 98"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 99"
## [1] "Current row: 100"
## [1] "Current row: 101"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 102"
## [1] "Current row: 103"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 104"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 105"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 106"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 107"
## [1] "Current row: 108"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 109"
## [1] "Current row: 110"
## [1] "Current row: 111"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 112"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 113"
## [1] "Current row: 114"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 115"
## [1] "Current row: 116"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 117"
## [1] "Current row: 118"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 119"
## [1] "Current row: 120"
## [1] "Current row: 121"
## [1] "Current row: 122"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 123"
## [1] "Current row: 124"
## [1] "Current row: 125"
## [1] "Current row: 126"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 127"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 128"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 129"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 130"
## [1] "Current row: 131"
## [1] "Current row: 132"
## [1] "Current row: 133"
## [1] "Current row: 134"
## [1] "Current row: 135"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 136"
## [1] "Current row: 137"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 138"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 139"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 140"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 141"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 142"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 143"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 144"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 145"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 146"
## [1] "Current row: 147"
## [1] "Current row: 148"
## [1] "Current row: 149"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 150"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 151"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 152"
## [1] "Current row: 153"
## [1] "Current row: 154"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 155"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 156"
## [1] "Current row: 157"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 158"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 159"
## [1] "Current row: 160"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 161"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 162"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 163"
## [1] "Current row: 164"
## [1] "Current row: 165"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 166"
## [1] "Current row: 167"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 168"
## [1] "Current row: 169"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 170"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 171"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 172"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 173"
## [1] "Current row: 174"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 175"
## [1] "Current row: 176"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 177"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 178"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 179"
## [1] "Current row: 180"
## [1] "Current row: 181"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 182"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 183"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 184"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 185"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 186"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 187"
## [1] "Current row: 188"
## [1] "Current row: 189"
## [1] "Current row: 190"
## [1] "Current row: 191"
## [1] "Current row: 192"
## [1] "Current row: 193"
## [1] "Current row: 194"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 195"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 196"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 197"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 198"
## [1] "Current row: 199"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 200"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 201"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 202"
## [1] "Current row: 203"
## [1] "Current row: 204"
## [1] "Current row: 205"
## [1] "Current row: 206"
## [1] "Current row: 207"
## [1] "Current row: 208"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 209"
## [1] "Current row: 210"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 211"
## [1] "Current row: 212"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 213"
## [1] "Current row: 214"
## [1] "Current row: 215"
## [1] "Current row: 216"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 217"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 218"
## [1] "Current row: 219"
## [1] "Current row: 220"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 221"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 222"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 223"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 224"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 225"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 226"
## [1] "Current row: 227"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 228"
## [1] "Current row: 229"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 230"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 231"
## [1] "Current row: 232"
## [1] "Current row: 233"
## [1] "Current row: 234"
## [1] "Current row: 235"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 236"
## [1] "Current row: 237"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 238"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 239"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 240"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 241"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 242"
## [1] "Current row: 243"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 244"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 245"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 246"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 247"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 248"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 249"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 250"
## [1] "Current row: 251"
## [1] "Current row: 252"
## [1] "Current row: 253"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 254"
## [1] "Current row: 255"
## [1] "Current row: 256"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 257"
## [1] "Current row: 258"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 259"
## [1] "Current row: 260"
## [1] "Current row: 261"
## [1] "Current row: 262"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 263"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 264"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 265"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 266"
## [1] "Current row: 267"
## [1] "Current row: 268"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 269"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 270"
## [1] "Current row: 271"
## [1] "Current row: 272"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 273"
## [1] "Current row: 274"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 275"
## [1] "Current row: 276"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 277"
## [1] "Current row: 278"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 279"
## [1] "Current row: 280"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 281"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 282"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 283"
## [1] "Current row: 284"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 285"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 286"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 287"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 288"
## [1] "Current row: 289"
## [1] "Current row: 290"
## [1] "Current row: 291"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 292"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 293"
## [1] "Current row: 294"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 295"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 296"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 297"
## [1] "Current row: 298"
## [1] "Current row: 299"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 300"
## [1] "Current row: 301"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 302"
## [1] "Current row: 303"
## [1] "Current row: 304"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 305"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 306"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 307"
## [1] "Current row: 308"
## [1] "Current row: 309"
## [1] "Current row: 310"
## [1] "Current row: 311"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 312"
## [1] "Current row: 313"
## [1] "Current row: 314"
## [1] "Current row: 315"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 316"
## [1] "Current row: 317"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 318"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 319"
## [1] "Current row: 320"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 321"
## [1] "Current row: 322"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 323"
## [1] "Current row: 324"
## [1] "Current row: 325"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 326"
## [1] "Current row: 327"
## [1] "Current row: 328"
## [1] "Current row: 329"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 330"
## [1] "Current row: 331"
## [1] "Current row: 332"
## [1] "Current row: 333"
## [1] "Current row: 334"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 335"
## [1] "Current row: 336"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 337"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 338"
## [1] "Current row: 339"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 340"
## [1] "Current row: 341"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 342"
## [1] "Current row: 343"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 344"
## [1] "Current row: 345"
## [1] "Current row: 346"
## [1] "Current row: 347"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 348"
## Warning: Outer names are only allowed for unnamed scalar atomic inputs
## [1] "Current row: 349"
## Collapsing the list into a data.frame
yelp_all <- yelp_all_list %>% bind_rows() %>% as_tibble()
## Print
yelp_all %>% print(width=1000)
## # A tibble: 208 × 16
## id alias
## <chr> <chr>
## 1 FK7-M9BGyCgpEmVifcPfoA aztec-cycles-stone-mountain
## 2 FK7-M9BGyCgpEmVifcPfoA aztec-cycles-stone-mountain
## 3 JkkHRgYj0mvdgbMXFm436w civil-bikes-atlanta
## 4 FK7-M9BGyCgpEmVifcPfoA aztec-cycles-stone-mountain
## 5 UmftRC3h0h_owHEm5ZLp7Q jump-atlanta-2
## 6 FK7-M9BGyCgpEmVifcPfoA aztec-cycles-stone-mountain
## 7 JkkHRgYj0mvdgbMXFm436w civil-bikes-atlanta
## 8 kJJiJqGbiO_QXmdhol3hIQ british-and-american-bikes-atlanta
## 9 FK7-M9BGyCgpEmVifcPfoA aztec-cycles-stone-mountain
## 10 ot4UyUsRAlTFudTlCVRMrQ pedego-electric-bikes-alpharetta-alpharetta
## name
## <chr>
## 1 Aztec Cycles
## 2 Aztec Cycles
## 3 Civil Bikes
## 4 Aztec Cycles
## 5 JUMP
## 6 Aztec Cycles
## 7 Civil Bikes
## 8 British and American Bikes
## 9 Aztec Cycles
## 10 Pedego Electric Bikes Alpharetta
## image_url
## <chr>
## 1 https://s3-media3.fl.yelpcdn.com/bphoto/re-aoEuun-QS1SE7dQCySQ/o.jpg
## 2 https://s3-media3.fl.yelpcdn.com/bphoto/re-aoEuun-QS1SE7dQCySQ/o.jpg
## 3 https://s3-media4.fl.yelpcdn.com/bphoto/JqTLT-chrqtbyuoB-52gdw/o.jpg
## 4 https://s3-media3.fl.yelpcdn.com/bphoto/re-aoEuun-QS1SE7dQCySQ/o.jpg
## 5 https://s3-media2.fl.yelpcdn.com/bphoto/D87H00XdLWZJS-LvQkTalA/o.jpg
## 6 https://s3-media3.fl.yelpcdn.com/bphoto/re-aoEuun-QS1SE7dQCySQ/o.jpg
## 7 https://s3-media4.fl.yelpcdn.com/bphoto/JqTLT-chrqtbyuoB-52gdw/o.jpg
## 8 https://s3-media2.fl.yelpcdn.com/bphoto/9I0G3Ge2yKFg6184t1XYEQ/o.jpg
## 9 https://s3-media3.fl.yelpcdn.com/bphoto/re-aoEuun-QS1SE7dQCySQ/o.jpg
## 10 https://s3-media2.fl.yelpcdn.com/bphoto/gPNidtknlSWKu3Bh4iOJ3Q/o.jpg
## is_closed
## <lgl>
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## 7 FALSE
## 8 FALSE
## 9 FALSE
## 10 FALSE
## url
## <chr>
## 1 https://www.yelp.com/biz/aztec-cycles-stone-mountain?adjust_creative=wA5TIrp…
## 2 https://www.yelp.com/biz/aztec-cycles-stone-mountain?adjust_creative=wA5TIrp…
## 3 https://www.yelp.com/biz/civil-bikes-atlanta?adjust_creative=wA5TIrpKGJmySk7…
## 4 https://www.yelp.com/biz/aztec-cycles-stone-mountain?adjust_creative=wA5TIrp…
## 5 https://www.yelp.com/biz/jump-atlanta-2?adjust_creative=wA5TIrpKGJmySk7ny-tL…
## 6 https://www.yelp.com/biz/aztec-cycles-stone-mountain?adjust_creative=wA5TIrp…
## 7 https://www.yelp.com/biz/civil-bikes-atlanta?adjust_creative=wA5TIrpKGJmySk7…
## 8 https://www.yelp.com/biz/british-and-american-bikes-atlanta?adjust_creative=…
## 9 https://www.yelp.com/biz/aztec-cycles-stone-mountain?adjust_creative=wA5TIrp…
## 10 https://www.yelp.com/biz/pedego-electric-bikes-alpharetta-alpharetta?adjust_…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 54 <df [3 × 2]> 5 33.8 -84.2 <list [0]>
## 2 54 <df [3 × 2]> 5 33.8 -84.2 <list [0]>
## 3 9 <df [2 × 2]> 4.5 33.7 -84.4 <list [0]>
## 4 54 <df [3 × 2]> 5 33.8 -84.2 <list [0]>
## 5 1 <df [2 × 2]> 1 33.7 -84.4 <list [0]>
## 6 54 <df [3 × 2]> 5 33.8 -84.2 <list [0]>
## 7 9 <df [2 × 2]> 4.5 33.7 -84.4 <list [0]>
## 8 2 <df [2 × 2]> 5 33.9 -84.3 <list [0]>
## 9 54 <df [3 × 2]> 5 33.8 -84.2 <list [0]>
## 10 7 <df [3 × 2]> 5 34.0 -84.3 <list [0]>
## price location$address1 $address2 $address3 $city
## <chr> <chr> <chr> <chr> <chr>
## 1 $$ "901 Main St" "" "" Stone Mountain
## 2 $$ "901 Main St" "" "" Stone Mountain
## 3 <NA> "" <NA> "" Atlanta
## 4 $$ "901 Main St" "" "" Stone Mountain
## 5 <NA> "" "" <NA> Atlanta
## 6 $$ "901 Main St" "" "" Stone Mountain
## 7 <NA> "" <NA> "" Atlanta
## 8 <NA> "4264 F Winters Chapel Rd" "" "" Atlanta
## 9 $$ "901 Main St" "" "" Stone Mountain
## 10 <NA> "6480 N Point Pkwy" "Ste 1100b" <NA> Alpharetta
## $zip_code $country $state $display_address phone display_phone
## <chr> <chr> <chr> <list> <chr> <chr>
## 1 30083 US GA <chr [2]> +16786369043 (678) 636-9043
## 2 30083 US GA <chr [2]> +16786369043 (678) 636-9043
## 3 30312 US GA <chr [1]> +14043238754 (404) 323-8754
## 4 30083 US GA <chr [2]> +16786369043 (678) 636-9043
## 5 30301 US GA <chr [1]> +18333006106 (833) 300-6106
## 6 30083 US GA <chr [2]> +16786369043 (678) 636-9043
## 7 30312 US GA <chr [1]> +14043238754 (404) 323-8754
## 8 30360 US GA <chr [2]> +17704518868 (770) 451-8868
## 9 30083 US GA <chr [2]> +16786369043 (678) 636-9043
## 10 30022 US GA <chr [3]> +14042810264 (404) 281-0264
## distance
## <dbl>
## 1 22818.
## 2 29547.
## 3 366.
## 4 20724.
## 5 1238.
## 6 20887.
## 7 527.
## 8 1715.
## 9 1921.
## 10 2501.
## # … with 198 more rows
## Save the yelp data
write_rds(yelp_all, file = here('data', 'yelp_all_mini_assignment3.rds'))
## Check duplicated values in the "id" column and delete duplicated rows
yelp_all <- yelp_all %>%
distinct(id, .keep_all = T) # from 208 rows to 16 rows
## Print
yelp_all
## # A tibble: 16 × 16
## id alias name image…¹ is_cl…² url revie…³ categ…⁴ rating coord…⁵
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl> <dbl>
## 1 FK7-M9BGyCg… azte… Azte… https:… FALSE http… 54 <df> 5 33.8
## 2 JkkHRgYj0mv… civi… Civi… https:… FALSE http… 9 <df> 4.5 33.7
## 3 UmftRC3h0h_… jump… JUMP https:… FALSE http… 1 <df> 1 33.7
## 4 kJJiJqGbiO_… brit… Brit… https:… FALSE http… 2 <df> 5 33.9
## 5 ot4UyUsRAlT… pede… Pede… https:… FALSE http… 7 <df> 5 34.0
## 6 LsNS77QoD4w… dads… Dad'… https:… FALSE http… 64 <df> 4.5 33.8
## 7 b3nacMG8PR7… atla… Atla… https:… FALSE http… 124 <df> 4.5 33.8
## 8 8PfRbXo6qhK… atla… Atla… https:… FALSE http… 40 <df> 4.5 33.8
## 9 rbf8bVY0cuq… pede… Pede… https:… FALSE http… 9 <df> 4.5 33.7
## 10 BozJwfoXvoD… podi… Podi… https:… FALSE http… 19 <df> 4.5 33.8
## 11 OJVvH1CUZac… rosw… Rosw… https:… FALSE http… 70 <df> 4 34.0
## 12 vfp82FZBVz1… rela… Rela… https:… FALSE http… 12 <df> 2 33.6
## 13 0H4julqllnl… ston… Ston… https:… FALSE http… 7 <df> 3.5 33.8
## 14 cRTM5f8ATvV… the-… The … https:… FALSE http… 1 <df> 1 34.1
## 15 xF82sx0_jxT… atla… Atla… https:… FALSE http… 13 <df> 4 33.4
## 16 gcl6O-ZWTTr… clou… Clou… https:… FALSE http… 1 <df> 1 33.8
## # … with 7 more variables: coordinates$longitude <dbl>, transactions <list>,
## # price <chr>, location <df[,8]>, phone <chr>, display_phone <chr>,
## # distance <dbl>, and abbreviated variable names ¹image_url, ²is_closed,
## # ³review_count, ⁴categories, ⁵coordinates$latitude
## Define a custom function that takes a data frame in "categories" column in Yelp data and returns a character vector
concate_list <- function(x) {
# "x" is a data frame with columns "alias" and "title" from Yelp$categories
# The function returns a character vector
titles <- x$title %>% str_c(collapse = ", ")
return(titles)
}
## Flatten columns
yelp_all <- yelp_all %>%
# Flatten data-frame-columns ("coordinates" and "location")
jsonlite::flatten() %>%
relocate(coordinates.latitude, coordinates.longitude, .after = rating) %>%
relocate(location.address1, location.address2, location.address3, location.city,
location.zip_code, location.country, location.state, location.display_address, .after = price) %>%
as_tibble() %>%
# Flatten list-columns ("transactions" (empty), "location.display_address", and "categories")
mutate(transactions = transactions %>% map_chr(function(x) str_c(x, collapse = ", ")),
location.display_address = location.display_address %>% map_chr(function(x) str_c(x, collapse = ", ")),
categories = categories %>% map_chr(concate_list)
)
## Print
yelp_all
## # A tibble: 16 × 24
## id alias name image…¹ is_cl…² url revie…³ categ…⁴ rating coord…⁵
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <chr> <dbl> <dbl>
## 1 FK7-M9BGyCg… azte… Azte… https:… FALSE http… 54 Bikes,… 5 33.8
## 2 JkkHRgYj0mv… civi… Civi… https:… FALSE http… 9 Bike R… 4.5 33.7
## 3 UmftRC3h0h_… jump… JUMP https:… FALSE http… 1 Scoote… 1 33.7
## 4 kJJiJqGbiO_… brit… Brit… https:… FALSE http… 2 Motorc… 5 33.9
## 5 ot4UyUsRAlT… pede… Pede… https:… FALSE http… 7 Bike R… 5 34.0
## 6 LsNS77QoD4w… dads… Dad'… https:… FALSE http… 64 Smog C… 4.5 33.8
## 7 b3nacMG8PR7… atla… Atla… https:… FALSE http… 124 Bike R… 4.5 33.8
## 8 8PfRbXo6qhK… atla… Atla… https:… FALSE http… 40 Bike R… 4.5 33.8
## 9 rbf8bVY0cuq… pede… Pede… https:… FALSE http… 9 Bikes,… 4.5 33.7
## 10 BozJwfoXvoD… podi… Podi… https:… FALSE http… 19 Bikes,… 4.5 33.8
## 11 OJVvH1CUZac… rosw… Rosw… https:… FALSE http… 70 Bikes,… 4 34.0
## 12 vfp82FZBVz1… rela… Rela… https:… FALSE http… 12 Party … 2 33.6
## 13 0H4julqllnl… ston… Ston… https:… FALSE http… 7 Bikes,… 3.5 33.8
## 14 cRTM5f8ATvV… the-… The … https:… FALSE http… 1 Bike R… 1 34.1
## 15 xF82sx0_jxT… atla… Atla… https:… FALSE http… 13 Bike R… 4 33.4
## 16 gcl6O-ZWTTr… clou… Clou… https:… FALSE http… 1 Scoote… 1 33.8
## # … with 14 more variables: coordinates.longitude <dbl>, transactions <chr>,
## # price <chr>, location.address1 <chr>, location.address2 <chr>,
## # location.address3 <chr>, location.city <chr>, location.zip_code <chr>,
## # location.country <chr>, location.state <chr>,
## # location.display_address <chr>, phone <chr>, display_phone <chr>,
## # distance <dbl>, and abbreviated variable names ¹image_url, ²is_closed,
## # ³review_count, ⁴categories, ⁵coordinates.latitude
## Check missing values in "coordinates.latitude" and "coordinates.longitude" variables
yelp_all %>% select(coordinates.latitude, coordinates.longitude) %>% summary()
## coordinates.latitude coordinates.longitude
## Min. :33.44 Min. :-84.59
## 1st Qu.:33.75 1st Qu.:-84.38
## Median :33.79 Median :-84.35
## Mean :33.81 Mean :-84.34
## 3rd Qu.:33.85 3rd Qu.:-84.29
## Max. :34.06 Max. :-84.10
## No missing values in "coordinates.latitude" and "coordinates.longitude" -> Keep all rows
## Create an sf object (crs = 4326)
yelp_sf <- yelp_all %>%
mutate(x = .$coordinates.longitude,
y = .$coordinates.latitude) %>%
filter(!is.na(x) & !is.na(y)) %>% # No row is removed
st_as_sf(coords = c("x", "y"), crs = 4326)
## Change the CRS of "tract" so that the CRS is the same as that of "yelp_sf"
tract <- st_transform(tract, crs = 4326)
## Check current data
tmap_mode('view') %>% suppressMessages()
tm_shape(yelp_sf) + tm_dots() +
tm_shape(tract %>% st_union()) + tm_borders()
## Keep only cases fall inside Fulton and Dekalb County
yelp_sf <- yelp_sf[tract %>% st_union(), , op = st_intersects] # from 16 rows to 14 rows
## Check the output
tmap_mode('view') %>% suppressMessages()
tm_shape(yelp_sf) + tm_dots() +
tm_shape(tract) + tm_borders()
## Get the number of bike rentals by tract
bike_rentals_by_tract <- st_join(tract, yelp_sf %>% mutate(count = 1)) %>%
group_by(GEOID) %>%
summarize(count = sum(count, na.rm = T))
# Attach the result to the census data
tract_with_bike_rentals_count <- tract %>%
left_join(bike_rentals_by_tract %>% st_drop_geometry(), by = "GEOID")
# Mapping
tm_shape(tract_with_bike_rentals_count %>% mutate(count = as.integer(count))) + tm_polygons(col="count") +
tm_shape(yelp_sf) + tm_dots()
## Create a variable for the proportion of workers commuting via bicycle by tract
tract_with_bike_rentals_count <- tract_with_bike_rentals_count %>%
mutate(proportion.workers.bicycle.commute = workers.bicycle.commute/workers)
## Remove 4 census tracts with no workers (among 349 census tracts)
## They do not have bike rental shops
tract_with_bike_rentals_count <- tract_with_bike_rentals_count %>%
filter(workers != 0)
## Existence of bike rental shops and the proportion of workers commuting via bike
# Create a binary variable
tract_with_bike_rentals_count$Bike.rental <- ifelse(tract_with_bike_rentals_count$count > 0, "Yes", "No")
# Visualize using a box plot
boxplot(proportion.workers.bicycle.commute ~ Bike.rental, data = tract_with_bike_rentals_count,
main = "Boxplot of Bike Rental Shop and Proportion of Bike Commuters",
xlab = "Whether Bike Rental Shops are Present",
ylab = "Proportion of Bike Commuters")
## Mapping bike rental shops and the "number" of bike commuters
tm_shape(tract_with_bike_rentals_count) +
tm_polygons(col = "workers.bicycle.commute")
tm_shape(yelp_sf) + tm_dots()
## Mapping bike rental shops and the "proportion" of bike commuters
tm_shape(tract_with_bike_rentals_count %>% rename()) + tm_polygons(col = "proportion.workers.bicycle.commute") +
tm_shape(yelp_sf) + tm_dots()