This is a report in which the yelp data acquired for movietheatres and restaurants in Cumming, Georgia is being tidied.
library(tigris)
## Warning: package 'tigris' was built under R version 4.3.3
## To enable caching of data, set `options(tigris_use_cache = TRUE)`
## in your R script or .Rprofile.
library(devtools)
## Warning: package 'devtools' was built under R version 4.3.3
## Loading required package: usethis
## Warning: package 'usethis' was built under R version 4.3.3
library(yelpr)
library(tmap)
## Warning: package 'tmap' was built under R version 4.3.3
## Breaking News: tmap 3.x is retiring. Please test v4, e.g. with
## remotes::install_github('r-tmap/tmap')
library(sf)
## Linking to GEOS 3.11.2, GDAL 3.7.2, PROJ 9.3.0; sf_use_s2() is TRUE
library(tidycensus)
## Warning: package 'tidycensus' was built under R version 4.3.3
library(sf)
library(tmap)
library(jsonlite)
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ purrr::flatten() masks jsonlite::flatten()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(httr)
library(jsonlite)
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.3.3
##
## Attaching package: 'reshape2'
##
## The following object is masked from 'package:tidyr':
##
## smiths
library(here)
## Warning: package 'here' was built under R version 4.3.3
## here() starts at C:/Users/Hina/Desktop
library(yelpr)
library(knitr)
library(leaflet.providers)
## Warning: package 'leaflet.providers' was built under R version 4.3.3
library(dplyr)
tidycensus::census_api_key(Sys.getenv("census_api_key"))
## To install your API key for use in future sessions, run this function with `install = TRUE`.
'install=TRUE'
## [1] "install=TRUE"
tract <- suppressMessages(
get_acs(geography = "tract", # or "block group", "county", "state" etc.
state = "GA",
county = c("Forsyth"),
variables = c(hhincome = 'B19019_001'),
year = 2021,
survey = "acs5", # American Community Survey 5-year estimate
geometry = TRUE, # returns sf objects
output = "wide") # wide vs. long
)
## | | | 0% | | | 1% | |= | 1% | |= | 2% | |== | 2% | |== | 3% | |=== | 4% | |=== | 5% | |==== | 5% | |==== | 6% | |===== | 7% | |====== | 8% | |======= | 9% | |======= | 10% | |======== | 11% | |========= | 12% | |========= | 13% | |========== | 14% | |=========== | 15% | |============ | 17% | |============= | 18% | |============= | 19% | |============== | 20% | |=============== | 21% | |=============== | 22% | |================ | 22% | |================ | 23% | |================= | 24% | |================= | 25% | |================== | 26% | |=================== | 27% | |==================== | 29% | |===================== | 31% | |====================== | 31% | |======================= | 33% | |======================== | 35% | |========================== | 37% | |=========================== | 38% | |=========================== | 39% | |============================ | 40% | |============================ | 41% | |============================= | 41% | |============================= | 42% | |============================== | 42% | |============================== | 43% | |=============================== | 44% | |=============================== | 45% | |================================ | 46% | |================================= | 47% | |================================== | 48% | |================================== | 49% | |=================================== | 50% | |=================================== | 51% | |==================================== | 52% | |===================================== | 53% | |====================================== | 54% | |====================================== | 55% | |======================================= | 55% | |======================================= | 56% | |========================================= | 58% | |========================================= | 59% | |========================================== | 59% | |========================================== | 60% | |=========================================== | 62% | |============================================ | 62% | |============================================= | 64% | |============================================== | 66% | |=============================================== | 67% | |================================================ | 68% | |================================================ | 69% | |================================================= | 70% | |================================================== | 71% | |================================================== | 72% | |=================================================== | 73% | |==================================================== | 74% | |==================================================== | 75% | |===================================================== | 75% | |===================================================== | 76% | |====================================================== | 77% | |======================================================= | 78% | |======================================================= | 79% | |======================================================== | 80% | |========================================================= | 81% | |========================================================= | 82% | |========================================================== | 83% | |=========================================================== | 85% | |============================================================ | 85% | |============================================================= | 87% | |============================================================= | 88% | |============================================================== | 89% | |=============================================================== | 89% | |=============================================================== | 91% | |=================================================================== | 95% | |===================================================================== | 98% | |===================================================================== | 99% | |======================================================================| 100%
cumming <- tigris::places('GA') %>%
filter(NAME == 'Cumming')
## Retrieving data for the year 2022
## | | | 0% | | | 1% | |= | 1% | |= | 2% | |== | 2% | |== | 3% | |=== | 4% | |=== | 5% | |==== | 5% | |==== | 6% | |===== | 7% | |===== | 8% | |====== | 8% | |====== | 9% | |======= | 10% | |======= | 11% | |======== | 11% | |======== | 12% | |========= | 12% | |========= | 13% | |========= | 14% | |========== | 14% | |========== | 15% | |=========== | 16% | |============ | 17% | |============ | 18% | |============== | 19% | |============== | 20% | |============== | 21% | |=============== | 21% | |=============== | 22% | |================ | 22% | |================ | 23% | |================= | 24% | |================= | 25% | |================== | 25% | |================== | 26% | |=================== | 26% | |=================== | 27% | |=================== | 28% | |==================== | 28% | |===================== | 29% | |===================== | 30% | |====================== | 31% | |====================== | 32% | |======================= | 33% | |======================== | 34% | |========================= | 35% | |========================= | 36% | |========================== | 37% | |=========================== | 38% | |=========================== | 39% | |============================ | 40% | |============================= | 41% | |============================= | 42% | |============================== | 42% | |============================== | 43% | |============================== | 44% | |=============================== | 44% | |================================ | 45% | |================================ | 46% | |================================= | 47% | |================================= | 48% | |================================== | 48% | |================================== | 49% | |=================================== | 49% | |=================================== | 50% | |==================================== | 51% | |==================================== | 52% | |===================================== | 52% | |===================================== | 53% | |====================================== | 54% | |====================================== | 55% | |======================================= | 56% | |======================================== | 56% | |======================================== | 57% | |======================================== | 58% | |========================================= | 58% | |========================================= | 59% | |========================================== | 59% | |========================================== | 60% | |=========================================== | 61% | |=========================================== | 62% | |============================================ | 63% | |============================================= | 64% | |============================================= | 65% | |============================================== | 65% | |============================================== | 66% | |=============================================== | 67% | |=============================================== | 68% | |================================================ | 68% | |================================================ | 69% | |================================================= | 70% | |================================================= | 71% | |================================================== | 71% | |================================================== | 72% | |=================================================== | 72% | |=================================================== | 73% | |==================================================== | 74% | |===================================================== | 76% | |====================================================== | 77% | |====================================================== | 78% | |======================================================= | 78% | |======================================================= | 79% | |======================================================== | 79% | |======================================================== | 80% | |======================================================== | 81% | |========================================================= | 81% | |========================================================= | 82% | |========================================================== | 82% | |========================================================== | 83% | |=========================================================== | 84% | |=========================================================== | 85% | |============================================================ | 85% | |============================================================ | 86% | |============================================================= | 86% | |============================================================= | 87% | |============================================================= | 88% | |============================================================== | 88% | |============================================================== | 89% | |=============================================================== | 89% | |=============================================================== | 90% | |================================================================ | 91% | |================================================================ | 92% | |================================================================= | 93% | |================================================================== | 94% | |================================================================== | 95% | |=================================================================== | 95% | |=================================================================== | 96% | |==================================================================== | 97% | |===================================================================== | 98% | |===================================================================== | 99% | |======================================================================| 100%
tract_cumming <- tract[cumming,]
message(sprintf("nrow: %s, ncol: %s", nrow(tract_cumming), ncol(tract_cumming)))
## nrow: 10, ncol: 5
tract_cumming %>% head() %>% knitr::kable()
GEOID | NAME | hhincomeE | hhincomeM | geometry | |
---|---|---|---|---|---|
4 | 13117130409 | Census Tract 1304.09, Forsyth County, Georgia | 69405 | 8031 | MULTIPOLYGON (((-84.13967 3… |
7 | 13117130512 | Census Tract 1305.12, Forsyth County, Georgia | 149750 | 36251 | MULTIPOLYGON (((-84.17291 3… |
9 | 13117130509 | Census Tract 1305.09, Forsyth County, Georgia | 113971 | 37319 | MULTIPOLYGON (((-84.13667 3… |
11 | 13117130415 | Census Tract 1304.15, Forsyth County, Georgia | 125551 | 30625 | MULTIPOLYGON (((-84.19473 3… |
12 | 13117130413 | Census Tract 1304.13, Forsyth County, Georgia | 47383 | 19555 | MULTIPOLYGON (((-84.16471 3… |
19 | 13117130411 | Census Tract 1304.11, Forsyth County, Georgia | 108523 | 12081 | MULTIPOLYGON (((-84.17035 3… |
tract_cumming <- tract_cumming %>%
select(GEOID,
hhincome = hhincomeE) # New name = old name
tmap_mode("view")
## tmap mode set to interactive viewing
tm_shape(tract_cumming) + tm_borders(lwd = 2) +
tm_shape(cumming) + tm_polygons(col = 'red', alpha = 0.4)
get_r <- function(poly, epsg_id){
#---------------------
# Takes: a single POLYGON or LINESTRTING
# Outputs: distance between the centroid of the boundingbox 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_p and c
r <- st_distance(bb_corner, bb_center)
# Multiply 1.1 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.1
return(bb_center)
}
epsg_id <- 4326
r4all_loop <- vector("list", nrow(tract_cumming))
for (i in 1:nrow(tract_cumming)){
r4all_loop[[i]] <- tract_cumming %>%
st_transform(crs = epsg_id) %>%
st_geometry() %>%
.[[i]] %>%
get_r(epsg_id = epsg_id)
}
r4all_loop <- bind_rows(r4all_loop) ### ADDED THIS ####
# Using a functional
r4all_apply <- tract_cumming %>%
st_geometry() %>%
st_transform(crs = epsg_id) %>%
lapply(., function(x) get_r(x, epsg_id = epsg_id))
r4all_apply <- bind_rows(r4all_apply)
# Are these two identical?
identical(r4all_apply, r4all_loop)
## [1] TRUE
ready_4_yelp <- r4all_apply %>%
mutate(x = st_coordinates(.)[,1],
y = st_coordinates(.)[,2])
tmap_mode('view')
## tmap mode set to interactive viewing
ready_4_yelp %>%
# Draw a buffer centered at the centroid of Tract polygons.
# Radius of the buffer is the radius we just calculated using loop
st_buffer(., dist = .$radius) %>%
# Display this buffer in red
tm_shape(.) + tm_polygons(alpha = 0.5, col = 'red') +
# Display the original polygon in blue
tm_shape(tract_cumming) + tm_borders(col= 'blue')
Sys.getenv("yelp_api")
## [1] "t6Lt40U2YpCVz-GEfwwMcFb01sUcKiq__fICygkKxIIKFMiHnd8-HubZ_KTZawxXoLEM3nsGkJ2mxyZSwLJOGLfPl4QoCSubD6gt2MrV9HBQDtNqbUSNSMIurtfYZnYx"
## TEST for businesses - worked for movietheatres
which_tract <- 2
test <- business_search(api_key = Sys.getenv('yelp_api'), #store API
categories = 'movietheatres',
latitude = ready_4_yelp$y[which_tract],
longitude = ready_4_yelp$x[which_tract],
offset = 0, # 1st page, 1st obs
radius = round(ready_4_yelp$radius[which_tract]), # radius requires integer value
limit = 50) # how many business per page
## No encoding supplied: defaulting to UTF-8.
lapply(test, head)
## $businesses
## id alias
## 1 Rs_fBiZoelwe-l69CZB9Ew babas-gyro-and-kabob-cumming
## 2 aNITBwOg4cxl3NmNx7RoOw q-korean-steak-house-cumming
## 3 IPYcTqPg1S_17shPYw1EzQ shuckin-shack-oyster-bar-cumming
## 4 _MO-FoDoqGnx2XK9PWs07A five-boroughs-pizza-tavern-cumming-2
## 5 ciLVqFk4iWc_3QeJQyFurA maries-italian-deli-cumming-3
## 6 q-0H3Q-fGE-ysBoej_UjqQ kumo-sushi-and-ramen-cumming
## name
## 1 Baba's Gyro and Kabob
## 2 Q Korean Steak House
## 3 Shuckin' Shack Oyster Bar
## 4 Five Boroughs Pizza Tavern
## 5 Marie's Italian Deli
## 6 Kumo Sushi & Ramen
## image_url
## 1 https://s3-media2.fl.yelpcdn.com/bphoto/yinZM7J7OHHuo6xPToPlfw/o.jpg
## 2 https://s3-media2.fl.yelpcdn.com/bphoto/dz9I0LXQv5sMmMmCYvSLMQ/o.jpg
## 3 https://s3-media3.fl.yelpcdn.com/bphoto/psc_4rgd0U7qwo3RknBLjA/o.jpg
## 4 https://s3-media3.fl.yelpcdn.com/bphoto/s8kzTOkzftr71EuVdD8EPw/o.jpg
## 5 https://s3-media2.fl.yelpcdn.com/bphoto/qM3ryUiqINx22wjt_T7eSA/o.jpg
## 6 https://s3-media4.fl.yelpcdn.com/bphoto/yvup4woO6kEylOEblArc_g/o.jpg
## is_closed
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## url
## 1 https://www.yelp.com/biz/babas-gyro-and-kabob-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 2 https://www.yelp.com/biz/q-korean-steak-house-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 3 https://www.yelp.com/biz/shuckin-shack-oyster-bar-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 4 https://www.yelp.com/biz/five-boroughs-pizza-tavern-cumming-2?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 5 https://www.yelp.com/biz/maries-italian-deli-cumming-3?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6 https://www.yelp.com/biz/kumo-sushi-and-ramen-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## review_count
## 1 605
## 2 352
## 3 212
## 4 156
## 5 331
## 6 92
## categories rating
## 1 mediterranean, greek, persian, Mediterranean, Greek, Persian/Iranian 4.1
## 2 korean, steak, halal, Korean, Steakhouses, Halal 4.3
## 3 seafood, Seafood 4.0
## 4 gastropubs, pizza, Gastropubs, Pizza 4.1
## 5 delis, pizza, italian, Delis, Pizza, Italian 4.3
## 6 sushi, ramen, Sushi Bars, Ramen 4.4
## coordinates.latitude coordinates.longitude transactions price
## 1 34.15731 -84.15461 pickup, delivery $$
## 2 34.18267 -84.13546 pickup, delivery $$
## 3 34.15221 -84.17223 $$
## 4 34.16804 -84.12360 pickup, delivery $$
## 5 34.18976 -84.13620 delivery $$
## 6 34.18159 -84.13360 <NA>
## location.address1 location.address2 location.address3 location.city
## 1 2310 Ronald Reagan Blvd Ste A Cumming
## 2 872 Buford Rd <NA> Cumming
## 3 415 Peachtree Pkwy Ste 255 Cumming
## 4 1370 Buford Hwy Ste 107 Cumming
## 5 580 Atlanta Rd Ste 34 Cumming
## 6 911 Market Pl Blvd Ste 6 Cumming
## location.zip_code location.country location.state
## 1 30041 US GA
## 2 30041 US GA
## 3 30041 US GA
## 4 30041 US GA
## 5 30040 US GA
## 6 30041 US GA
## location.display_address phone display_phone
## 1 2310 Ronald Reagan Blvd, Ste A, Cumming, GA 30041 +17708888100 (770) 888-8100
## 2 872 Buford Rd, Cumming, GA 30041 +17704068441 (770) 406-8441
## 3 415 Peachtree Pkwy, Ste 255, Cumming, GA 30041 +14702537746 (470) 253-7746
## 4 1370 Buford Hwy, Ste 107, Cumming, GA 30041 +14706954011 (470) 695-4011
## 5 580 Atlanta Rd, Ste 34, Cumming, GA 30040 +17708860084 (770) 886-0084
## 6 911 Market Pl Blvd, Ste 6, Cumming, GA 30041 +16787715828 (678) 771-5828
## distance
## 1 1193.128
## 2 2198.339
## 3 2844.636
## 4 2004.010
## 5 2917.143
## 6 2171.108
## business_hours
## 1 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1200, 1200, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 2 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 2200, 2200, 2200, 2200, 2300, 2300, 2200, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 3 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 2100, 2100, 2100, 2200, 2200, 2100, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 4 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1600, 1600, 1130, 1130, 1130, 1130, 1200, 2030, 2030, 2030, 2030, 2200, 2200, 2030, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 5 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0700, 0700, 0700, 0700, 0700, 0700, 2000, 2000, 2000, 2000, 2100, 2100, 0, 1, 2, 3, 4, 5, REGULAR, TRUE
## 6 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1630, 1100, 1630, 1100, 1630, 1100, 1130, 1130, 1500, 2130, 1500, 2130, 1500, 2130, 2200, 2200, 2130, 0, 0, 2, 2, 3, 3, 4, 5, 6, REGULAR, TRUE
## attributes.business_temp_closed attributes.waitlist_reservation
## 1 NA TRUE
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## attributes.menu_url
## 1 http://www.babasgyros.com/#!lunch-menu/c5hf
## 2 <NA>
## 3 https://www.theshuckinshack.com/wp-content/uploads/2024/04/Shuckin-Shack-Cumming-GA-Food-and-Cocktail-Menu.pdf
## 4 http://www.fiveboroughspizzatavern.com/eat
## 5
## 6 https://irp.cdn-website.com/a75c9c20/files/uploaded/kumo-menu-2023-03-24.pdf
## attributes.open24_hours
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
##
## $total
## [1] 162
##
## $region
## $region$center
## $region$center$longitude
## [1] -84.14519
##
## $region$center$latitude
## [1] 34.1646
paste0("is it a data.frame?: ", is.data.frame(test$businesses), ", ",
" how many rows?: ", nrow(test$businesses), ", ",
" how many columns?: ", ncol(test$businesses))
## [1] "is it a data.frame?: TRUE, how many rows?: 50, how many columns?: 18"
get_yelp <- function(tract, category){
# ----------------------------------
# Gets one row of tract information (1,) and category name (str),
# Outputs a list of business data.frame
Sys.sleep(1)
n <- 1
# First request --------------------------------------------------------------
resp <- business_search(api_key = Sys.getenv("yelp_api"),
categories = category,
latitude = tract$y,
longitude = tract$x,
offset = (n - 1) * 50, # = 0 when n = 1
radius = round(tract$radius),
limit = 50)
# Calculate how many requests are needed in total
required_n <- ceiling(resp$total/50)
out <- vector("list", required_n)
# Store the business information to nth 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 >= 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 = Sys.getenv("yelp_api"),
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
} #<< end of while loop
# Merge all elements in the list into a single data frame
out <- out %>% bind_rows()
return(out)
}
}
print(ready_4_yelp[1, ])
## Simple feature collection with 1 feature and 3 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -84.1217 ymin: 34.22615 xmax: -84.1217 ymax: 34.22615
## Geodetic CRS: WGS 84
## radius geometry x y
## 1 3056.576 [m] POINT (-84.1217 34.22615) -84.1217 34.22615
yelp_first_tract_raw <- get_yelp(ready_4_yelp[1,], "movietheatres")
## No encoding supplied: defaulting to UTF-8.
## No encoding supplied: defaulting to UTF-8.
yelp_first_tract <- get_yelp(ready_4_yelp[1,], "movietheatres") %>%
as_tibble()
## No encoding supplied: defaulting to UTF-8.
## No encoding supplied: defaulting to UTF-8.
yelp_all_movietheatres_list <- vector("list", nrow(ready_4_yelp))
# Looping through all Census Tracts
for (row in 1:nrow(ready_4_yelp)){
yelp_all_movietheatres_list[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "movietheatres"))
print(paste0("Current row: ", row))
}
## [1] "Current row: 1"
## [1] "Current row: 2"
## [1] "Current row: 3"
## [1] "Current row: 4"
## [1] "Current row: 5"
## [1] "Current row: 6"
## [1] "Current row: 7"
## [1] "Current row: 8"
## [1] "Current row: 9"
## [1] "Current row: 10"
# Collapsing the list into a data.frame
yelp_all_movietheatres <- yelp_all_movietheatres_list %>% bind_rows() %>% as_tibble()
# print
yelp_all_movietheatres %>% print(width=1000)
## # A tibble: 1,202 × 18
## id alias
## <chr> <chr>
## 1 -QzATE8gbPVyjI9CTYSUOg tams-backstage-cumming
## 2 MdsnJ4UjFpgC0aJNqoaQ_w gasthaus-tirol-cumming-2
## 3 WruWv2Q96AcbxrrG_ucIsg balsas-mexican-restaurant-cumming
## 4 kFL2Ysx-RmhQ-_ALHAv-PA village-burger-cumming-cumming
## 5 ifHY8ZAwAho9uHAiqHyywA annunziatas-pizza-and-pasta-cumming
## 6 ITC3cioi7LP52zj8CAOHLA homestead-cumming
## 7 6CLbYKwLMOg1hO7l3Ga4sg sliceability-cumming
## 8 3rfhvsxSEF_MkWdzxhUShw sawnee-mountain-biscuit-cumming
## 9 yASAsKLBr6lOtXlrfExU_Q mexican-grill-cumming
## 10 SeG1Jtl0spcieaUZX0KBNg smokeyq-cumming
## name
## <chr>
## 1 Tam's Backstage
## 2 Gasthaus Tirol
## 3 Balsas Mexican Restaurant
## 4 Village Burger - Cumming
## 5 Annunziata's Pizza & Pasta
## 6 Homestead
## 7 SliceAbility
## 8 Sawnee Mountain Biscuit
## 9 Mexican Grill
## 10 SmokeyQ
## image_url
## <chr>
## 1 https://s3-media2.fl.yelpcdn.com/bphoto/SRhLlUuNWhgz-kigadFD-w/o.jpg
## 2 https://s3-media1.fl.yelpcdn.com/bphoto/LSp42VOe43JPzjAHwfJzjA/o.jpg
## 3 https://s3-media2.fl.yelpcdn.com/bphoto/2LfESnbOdr8voTqasjhKJQ/o.jpg
## 4 https://s3-media1.fl.yelpcdn.com/bphoto/XCuVdf2GKTzSVwaAMolQqw/o.jpg
## 5 https://s3-media4.fl.yelpcdn.com/bphoto/96iITIDdyTu883G80tIIgw/o.jpg
## 6 https://s3-media3.fl.yelpcdn.com/bphoto/gWwCpMXKbV1NzQ3GCwRrZQ/o.jpg
## 7 https://s3-media3.fl.yelpcdn.com/bphoto/MM8LN_pUOEpSzwRRgOKHXQ/o.jpg
## 8 https://s3-media2.fl.yelpcdn.com/bphoto/aFkvv-P6C4qvGkQu4C15Iw/o.jpg
## 9 https://s3-media4.fl.yelpcdn.com/bphoto/M-WrYJCIfntaXyFG99vZ4Q/o.jpg
## 10 https://s3-media4.fl.yelpcdn.com/bphoto/IVONTBz_vuFSMn5Tiyf6zg/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/tams-backstage-cumming?adjust_creative=1K83ZF1zfv8V…
## 2 https://www.yelp.com/biz/gasthaus-tirol-cumming-2?adjust_creative=1K83ZF1zfv…
## 3 https://www.yelp.com/biz/balsas-mexican-restaurant-cumming?adjust_creative=1…
## 4 https://www.yelp.com/biz/village-burger-cumming-cumming?adjust_creative=1K83…
## 5 https://www.yelp.com/biz/annunziatas-pizza-and-pasta-cumming?adjust_creative…
## 6 https://www.yelp.com/biz/homestead-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_…
## 7 https://www.yelp.com/biz/sliceability-cumming?adjust_creative=1K83ZF1zfv8Vvq…
## 8 https://www.yelp.com/biz/sawnee-mountain-biscuit-cumming?adjust_creative=1K8…
## 9 https://www.yelp.com/biz/mexican-grill-cumming?adjust_creative=1K83ZF1zfv8Vv…
## 10 https://www.yelp.com/biz/smokeyq-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1o…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 264 <df [2 × 2]> 4.2 34.2 -84.1 <chr [1]>
## 2 224 <df [3 × 2]> 3.9 34.2 -84.1 <chr [1]>
## 3 125 <df [1 × 2]> 4.2 34.2 -84.1 <chr [2]>
## 4 210 <df [3 × 2]> 4.1 34.2 -84.1 <chr [2]>
## 5 129 <df [3 × 2]> 4.2 34.2 -84.1 <chr [1]>
## 6 72 <df [3 × 2]> 3.8 34.2 -84.1 <chr [0]>
## 7 41 <df [3 × 2]> 4.8 34.2 -84.1 <chr [2]>
## 8 55 <df [2 × 2]> 4.5 34.2 -84.1 <chr [1]>
## 9 10 <df [1 × 2]> 4.8 34.2 -84.1 <chr [1]>
## 10 40 <df [1 × 2]> 4.4 34.2 -84.1 <chr [1]>
## price location$address1 $address2 $address3 $city $zip_code
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 $$ 215 Ingram Ave "" "" Cumming 30040
## 2 $$ 310 Atlanta Rd "" "" Cumming 30040
## 3 $$ 1495 Dahlonega Hwy <NA> "" Cumming 30040
## 4 $$ 101 W Courthouse Square <NA> "" Cumming 30040
## 5 <NA> 111 W Courthouse Sq "" <NA> Cumming 30040
## 6 <NA> 420 Vision Dr "Ste A101" <NA> Cumming 30040
## 7 $ 420 Vision Dr "Ste A102" <NA> Cumming 30028
## 8 $ 104 13th St "" "" Cumming 30040
## 9 $ 601 Dahlonega St "" <NA> Cumming 30040
## 10 $ 1850 Bald Ridge Marina Rd "" <NA> Cumming 30041
## $country $state $display_address phone display_phone distance
## <chr> <chr> <list> <chr> <chr> <dbl>
## 1 US GA <chr [2]> +16784558310 (678) 455-8310 2424.
## 2 US GA <chr [2]> +17708447244 (770) 844-7244 2993.
## 3 US GA <chr [2]> +16784568368 (678) 456-8368 1490.
## 4 US GA <chr [2]> +14702394502 (470) 239-4502 2753.
## 5 US GA <chr [2]> +17708873730 (770) 887-3730 2786.
## 6 US GA <chr [3]> +14708352316 (470) 835-2316 2462.
## 7 US GA <chr [3]> +14708352324 (470) 835-2324 2378.
## 8 US GA <chr [2]> +17708874615 (770) 887-4615 1648.
## 9 US GA <chr [2]> +16783418107 (678) 341-8107 1002.
## 10 US GA <chr [2]> +14705153683 (470) 515-3683 2686.
## business_hours attributes$business_temp_closed
## <list> <int>
## 1 <df [1 × 3]> NA
## 2 <df [1 × 3]> NA
## 3 <df [1 × 3]> NA
## 4 <df [1 × 3]> NA
## 5 <df [1 × 3]> NA
## 6 <df [1 × 3]> NA
## 7 <df [1 × 3]> NA
## 8 <df [1 × 3]> NA
## 9 <df [1 × 3]> NA
## 10 <df [1 × 3]> NA
## $menu_url
## <chr>
## 1 http://tamsbackstage.com/index-3.html
## 2 http://www.gasthaus-cumming.com/menu.html
## 3 https://img1.wsimg.com/blobby/go/9903f269-7bc9-4fb7-9de5-de01b0c77e1e/downlo…
## 4 https://www.villageburger.com/Menu
## 5 https://www.annunziataspizza.com/menu
## 6 https://homesteadga.com/wp-content/uploads/Homestead_Menu.pdf
## 7 <NA>
## 8 https://www.sawneemtnbiscuitco.com/menu
## 9 <NA>
## 10 https://www.smokeyqbbq.com/menu
## $open24_hours $waitlist_reservation
## <lgl> <lgl>
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## 7 NA FALSE
## 8 NA NA
## 9 NA NA
## 10 NA NA
## # ℹ 1,192 more rows
yelp_all_restaurants_list <- vector("list", nrow(ready_4_yelp)) # Make a vector to store the data
for (row in 1:nrow(ready_4_yelp)){ # Looping through all Census Tracts (for-loop)
yelp_all_movietheatres_list[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "restaurants"))
print(paste0("Current row: ", row))
}
## [1] "Current row: 1"
## [1] "Current row: 2"
## [1] "Current row: 3"
## [1] "Current row: 4"
## [1] "Current row: 5"
## [1] "Current row: 6"
## [1] "Current row: 7"
## [1] "Current row: 8"
## [1] "Current row: 9"
## [1] "Current row: 10"
yelp_all_restaurants <- yelp_all_restaurants_list %>% bind_rows() %>% as_tibble() # Merge all elements in the list into a single data frame
yelp_all_restaurants %>% print(width=1000) # print
## # A tibble: 0 × 0
message(sprintf("nrow: %s, ncol: %s", nrow(yelp_all_restaurants), ncol(yelp_all_restaurants)))
## nrow: 0, ncol: 0
yelp_two_biz_all <- bind_rows(yelp_all_movietheatres, yelp_all_restaurants)
message(sprintf("nrow: %s, ncol: %s", nrow(yelp_two_biz_all), ncol(yelp_two_biz_all)))
## nrow: 1202, ncol: 18
library(tidyverse)
library(sf)
library(here)
library(tmap)
library(purrr)
# Duplicates in column "name" removed for the plots of both movietheatres and restaurants
dupl_yelp <-yelp_two_biz_all
dupl_yelp[!duplicated(dupl_yelp$name),]
## # A tibble: 287 × 18
## id alias name image_url is_closed url review_count categories rating
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl>
## 1 -QzATE8… tams… Tam'… https://… FALSE http… 264 <df> 4.2
## 2 MdsnJ4U… gast… Gast… https://… FALSE http… 224 <df> 3.9
## 3 WruWv2Q… bals… Bals… https://… FALSE http… 125 <df> 4.2
## 4 kFL2Ysx… vill… Vill… https://… FALSE http… 210 <df> 4.1
## 5 ifHY8ZA… annu… Annu… https://… FALSE http… 129 <df> 4.2
## 6 ITC3cio… home… Home… https://… FALSE http… 72 <df> 3.8
## 7 6CLbYKw… slic… Slic… https://… FALSE http… 41 <df> 4.8
## 8 3rfhvsx… sawn… Sawn… https://… FALSE http… 55 <df> 4.5
## 9 yASAsKL… mexi… Mexi… https://… FALSE http… 10 <df> 4.8
## 10 SeG1Jtl… smok… Smok… https://… FALSE http… 40 <df> 4.4
## # ℹ 277 more rows
## # ℹ 9 more variables: coordinates <df[,2]>, transactions <list>, price <chr>,
## # location <df[,8]>, phone <chr>, display_phone <chr>, distance <dbl>,
## # business_hours <list>, attributes <df[,4]>
print(dupl_yelp)
## # A tibble: 1,202 × 18
## id alias name image_url is_closed url review_count categories rating
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl>
## 1 -QzATE8… tams… Tam'… https://… FALSE http… 264 <df> 4.2
## 2 MdsnJ4U… gast… Gast… https://… FALSE http… 224 <df> 3.9
## 3 WruWv2Q… bals… Bals… https://… FALSE http… 125 <df> 4.2
## 4 kFL2Ysx… vill… Vill… https://… FALSE http… 210 <df> 4.1
## 5 ifHY8ZA… annu… Annu… https://… FALSE http… 129 <df> 4.2
## 6 ITC3cio… home… Home… https://… FALSE http… 72 <df> 3.8
## 7 6CLbYKw… slic… Slic… https://… FALSE http… 41 <df> 4.8
## 8 3rfhvsx… sawn… Sawn… https://… FALSE http… 55 <df> 4.5
## 9 yASAsKL… mexi… Mexi… https://… FALSE http… 10 <df> 4.8
## 10 SeG1Jtl… smok… Smok… https://… FALSE http… 40 <df> 4.4
## # ℹ 1,192 more rows
## # ℹ 9 more variables: coordinates <df[,2]>, transactions <list>, price <chr>,
## # location <df[,8]>, phone <chr>, display_phone <chr>, distance <dbl>,
## # business_hours <list>, attributes <df[,4]>
sapply(dupl_yelp, class) %>% print()
## id alias name image_url is_closed
## "character" "character" "character" "character" "logical"
## url review_count categories rating coordinates
## "character" "integer" "list" "numeric" "data.frame"
## transactions price location phone display_phone
## "list" "character" "data.frame" "character" "character"
## distance business_hours attributes
## "numeric" "list" "data.frame"
dupl_yelp$coordinates %>% head()
## latitude longitude
## 1 34.20818 -84.13662
## 2 34.20125 -84.13404
## 3 34.23950 -84.12144
## 4 34.20695 -84.14059
## 5 34.20659 -84.14063
## 6 34.21717 -84.14611
yelp_flat <- dupl_yelp %>%
jsonlite::flatten()
# Print the flattened yelp data
print(dupl_yelp)
## # A tibble: 1,202 × 18
## id alias name image_url is_closed url review_count categories rating
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl>
## 1 -QzATE8… tams… Tam'… https://… FALSE http… 264 <df> 4.2
## 2 MdsnJ4U… gast… Gast… https://… FALSE http… 224 <df> 3.9
## 3 WruWv2Q… bals… Bals… https://… FALSE http… 125 <df> 4.2
## 4 kFL2Ysx… vill… Vill… https://… FALSE http… 210 <df> 4.1
## 5 ifHY8ZA… annu… Annu… https://… FALSE http… 129 <df> 4.2
## 6 ITC3cio… home… Home… https://… FALSE http… 72 <df> 3.8
## 7 6CLbYKw… slic… Slic… https://… FALSE http… 41 <df> 4.8
## 8 3rfhvsx… sawn… Sawn… https://… FALSE http… 55 <df> 4.5
## 9 yASAsKL… mexi… Mexi… https://… FALSE http… 10 <df> 4.8
## 10 SeG1Jtl… smok… Smok… https://… FALSE http… 40 <df> 4.4
## # ℹ 1,192 more rows
## # ℹ 9 more variables: coordinates <df[,2]>, transactions <list>, price <chr>,
## # location <df[,8]>, phone <chr>, display_phone <chr>, distance <dbl>,
## # business_hours <list>, attributes <df[,4]>
sapply(yelp_flat, class) %>% print()
## id alias
## "character" "character"
## name image_url
## "character" "character"
## is_closed url
## "logical" "character"
## review_count categories
## "integer" "list"
## rating transactions
## "numeric" "list"
## price phone
## "character" "character"
## display_phone distance
## "character" "numeric"
## business_hours coordinates.latitude
## "list" "numeric"
## coordinates.longitude location.address1
## "numeric" "character"
## location.address2 location.address3
## "character" "character"
## location.city location.zip_code
## "character" "character"
## location.country location.state
## "character" "character"
## location.display_address attributes.business_temp_closed
## "list" "integer"
## attributes.menu_url attributes.open24_hours
## "character" "logical"
## attributes.waitlist_reservation
## "logical"
yelp_flat$coordinates.latitude %>% head()
## [1] 34.20818 34.20125 34.23950 34.20695 34.20659 34.21717
yelp_concat <- yelp_flat %>%
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=", ")))
sapply(yelp_concat, class) %>% print()
## id alias
## "character" "character"
## name image_url
## "character" "character"
## is_closed url
## "logical" "character"
## review_count categories
## "integer" "list"
## rating transactions
## "numeric" "character"
## price phone
## "character" "character"
## display_phone distance
## "character" "numeric"
## business_hours coordinates.latitude
## "list" "numeric"
## coordinates.longitude location.address1
## "numeric" "character"
## location.address2 location.address3
## "character" "character"
## location.city location.zip_code
## "character" "character"
## location.country location.state
## "character" "character"
## location.display_address attributes.business_temp_closed
## "character" "integer"
## attributes.menu_url attributes.open24_hours
## "character" "logical"
## attributes.waitlist_reservation
## "logical"
concate_list <- function(x){
# x is a data frame with columns "alias" and "title" from Yelp$categories
# returns a character vector containing category concatenated titles
titles <- x[["title"]] %>% str_c(collapse = ", ")
return(titles)
}
yelp_flat2 <- yelp_concat %>%
mutate(categories = categories %>% map_chr(concate_list))
yelp_flat2 %>% head()
## id alias
## 1 -QzATE8gbPVyjI9CTYSUOg tams-backstage-cumming
## 2 MdsnJ4UjFpgC0aJNqoaQ_w gasthaus-tirol-cumming-2
## 3 WruWv2Q96AcbxrrG_ucIsg balsas-mexican-restaurant-cumming
## 4 kFL2Ysx-RmhQ-_ALHAv-PA village-burger-cumming-cumming
## 5 ifHY8ZAwAho9uHAiqHyywA annunziatas-pizza-and-pasta-cumming
## 6 ITC3cioi7LP52zj8CAOHLA homestead-cumming
## name
## 1 Tam's Backstage
## 2 Gasthaus Tirol
## 3 Balsas Mexican Restaurant
## 4 Village Burger - Cumming
## 5 Annunziata's Pizza & Pasta
## 6 Homestead
## image_url
## 1 https://s3-media2.fl.yelpcdn.com/bphoto/SRhLlUuNWhgz-kigadFD-w/o.jpg
## 2 https://s3-media1.fl.yelpcdn.com/bphoto/LSp42VOe43JPzjAHwfJzjA/o.jpg
## 3 https://s3-media2.fl.yelpcdn.com/bphoto/2LfESnbOdr8voTqasjhKJQ/o.jpg
## 4 https://s3-media1.fl.yelpcdn.com/bphoto/XCuVdf2GKTzSVwaAMolQqw/o.jpg
## 5 https://s3-media4.fl.yelpcdn.com/bphoto/96iITIDdyTu883G80tIIgw/o.jpg
## 6 https://s3-media3.fl.yelpcdn.com/bphoto/gWwCpMXKbV1NzQ3GCwRrZQ/o.jpg
## is_closed
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## url
## 1 https://www.yelp.com/biz/tams-backstage-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 2 https://www.yelp.com/biz/gasthaus-tirol-cumming-2?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 3 https://www.yelp.com/biz/balsas-mexican-restaurant-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 4 https://www.yelp.com/biz/village-burger-cumming-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 5 https://www.yelp.com/biz/annunziatas-pizza-and-pasta-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6 https://www.yelp.com/biz/homestead-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## review_count categories rating transactions price
## 1 264 New American, Wine Bars 4.2 delivery $$
## 2 224 German, Salad, Beer Gardens 3.9 delivery $$
## 3 125 Mexican 4.2 delivery, pickup $$
## 4 210 Burgers, Hot Dogs, Salad 4.1 delivery, pickup $$
## 5 129 Pizza, Italian, Sandwiches 4.2 delivery <NA>
## 6 72 Salad, American, Cocktail Bars 3.8 <NA>
## phone display_phone distance
## 1 +16784558310 (678) 455-8310 2423.907
## 2 +17708447244 (770) 844-7244 2992.678
## 3 +16784568368 (678) 456-8368 1490.178
## 4 +14702394502 (470) 239-4502 2753.438
## 5 +17708873730 (770) 887-3730 2785.597
## 6 +14708352316 (470) 835-2316 2462.418
## business_hours
## 1 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1600, 2100, 2100, 2100, 2100, 2130, 2130, 0, 1, 2, 3, 4, 5, REGULAR, TRUE
## 2 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1400, 2100, 1400, 2100, 1400, 2100, 1400, 2200, 1400, 2200, 1400, 2100, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, REGULAR, TRUE
## 3 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0700, 0700, 0700, 0700, 0700, 0700, 0700, 2200, 2200, 2200, 2200, 2200, 2200, 2100, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 4 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 2000, 2000, 2000, 2000, 2100, 2100, 2000, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 5 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1200, 1600, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 6 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 2200, 2200, 2200, 2200, 2300, 2300, 2200, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## coordinates.latitude coordinates.longitude location.address1
## 1 34.20818 -84.13662 215 Ingram Ave
## 2 34.20125 -84.13404 310 Atlanta Rd
## 3 34.23950 -84.12144 1495 Dahlonega Hwy
## 4 34.20695 -84.14059 101 W Courthouse Square
## 5 34.20659 -84.14063 111 W Courthouse Sq
## 6 34.21717 -84.14611 420 Vision Dr
## location.address2 location.address3 location.city location.zip_code
## 1 Cumming 30040
## 2 Cumming 30040
## 3 <NA> Cumming 30040
## 4 <NA> Cumming 30040
## 5 <NA> Cumming 30040
## 6 Ste A101 <NA> Cumming 30040
## location.country location.state location.display_address
## 1 US GA 215 Ingram Ave, Cumming, GA 30040
## 2 US GA 310 Atlanta Rd, Cumming, GA 30040
## 3 US GA 1495 Dahlonega Hwy, Cumming, GA 30040
## 4 US GA 101 W Courthouse Square, Cumming, GA 30040
## 5 US GA 111 W Courthouse Sq, Cumming, GA 30040
## 6 US GA 420 Vision Dr, Ste A101, Cumming, GA 30040
## attributes.business_temp_closed
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
## attributes.menu_url
## 1 http://tamsbackstage.com/index-3.html
## 2 http://www.gasthaus-cumming.com/menu.html
## 3 https://img1.wsimg.com/blobby/go/9903f269-7bc9-4fb7-9de5-de01b0c77e1e/downloads/rio%20menu%202019%20letter.pdf?ver=1563053267407
## 4 https://www.villageburger.com/Menu
## 5 https://www.annunziataspizza.com/menu
## 6 https://homesteadga.com/wp-content/uploads/Homestead_Menu.pdf
## attributes.open24_hours attributes.waitlist_reservation
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
yelp_unique <- dupl_yelp %>%
distinct(id, .keep_all=T)
glue::glue("Before dropping duplicated rows, there were {nrow(dupl_yelp)} rows. After dropping them, there are {nrow(yelp_unique)} rows") %>%
print()
## Before dropping duplicated rows, there were 1202 rows. After dropping them, there are 338 rows
yelp_flat <- yelp_unique %>%
# 1. Flattening columns with data frame
jsonlite::flatten() %>%
# 2. Handling list-columns
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))
yelp_flat %>%
map_dbl(., function(x) sum(is.na(x)))
## id alias
## 0 0
## name image_url
## 0 0
## is_closed url
## 0 0
## review_count categories
## 0 0
## rating transactions
## 0 0
## price phone
## 157 0
## display_phone distance
## 0 0
## business_hours coordinates.latitude
## 0 0
## coordinates.longitude location.address1
## 0 12
## location.address2 location.address3
## 87 128
## location.city location.zip_code
## 0 0
## location.country location.state
## 0 0
## location.display_address attributes.business_temp_closed
## 0 336
## attributes.menu_url attributes.open24_hours
## 156 338
## attributes.waitlist_reservation
## 324
identical(is.na(yelp_flat$coordinates.latitude),
is.na(yelp_flat$coordinates.longitude))
## [1] TRUE
#There seems to be many missing values in 'price' and 'location' columns, as well as business attributes like temp_closed, open24_hours, menu_url and waitlist_reservation. I will drop the 'NA's in the price and location columns since that is important information.
yelp_dropna <- yelp_flat %>%
filter(!is.na(coordinates.longitude) & !is.na(price))
print(paste0("Before: ", nrow(yelp_flat)))
## [1] "Before: 338"
print(paste0("After: ", nrow(yelp_dropna)))
## [1] "After: 181"
#Many points appeared outside the City of Cumming boundary. These are clearly errors; will delete them.
# city boundary
cumming <- tigris::places("GA", progress_bar = FALSE) %>%
filter(NAME == 'Cumming') %>%
st_transform(4326)
## Retrieving data for the year 2022
# Converting yelp_dropna into a sf object
yelp_sf <- yelp_dropna %>%
st_as_sf(coords=c("coordinates.longitude", "coordinates.latitude"),
crs = 4326)
# sf subsets
yelp_in <- yelp_sf[cumming, ]
print(paste0("Before: ", nrow(yelp_sf)))
## [1] "Before: 181"
print(paste0("After: ", nrow(yelp_in)))
## [1] "After: 58"
glue::glue("nrow before: {nrow(dupl_yelp)} -> nrow after: {nrow(yelp_in)} \n
ncol before: {ncol(dupl_yelp)} -> ncol after: {ncol(yelp_in)} \n") %>%
print()
## nrow before: 1202 -> nrow after: 58
##
## ncol before: 18 -> ncol after: 28
#Adding census data to provide social context to the yelp data for additional insights.
# Get Census data at the Block Group level
library(tidycensus)
tidycensus::census_api_key(Sys.getenv("census_api_key"))
## To install your API key for use in future sessions, run this function with `install = TRUE`.
'install=TRUE'
## [1] "install=TRUE"
bg <- get_acs(geography = "block group",
state = "GA",
county = c("Forsyth"),
variables = c(hhincome = 'B19013_001'),
year = 2022,
survey = "acs5", # American Community Survey 5-year estimate
geometry = TRUE, # We want sf object
output = "wide",
progress = FALSE) %>%
rename(hhincome = hhincomeE) %>%
st_transform(4326)
## Getting data from the 2018-2022 5-year ACS
## Downloading feature geometry from the Census website. To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
bg_cumming <- bg[cumming,]
# Spatial join
census_yelp <- st_join(bg_cumming, yelp_in, join = st_intersects)
yelp_census <- st_join(yelp_in, bg_cumming, join = st_intersects)
# number of rows
cat('census_yelp: ', nrow(census_yelp))
## census_yelp: 68
cat('yelp_census: ', nrow(yelp_census))
## yelp_census: 58
# View
census_yelp %>% head()
## Simple feature collection with 6 features and 31 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -84.15466 ymin: 34.20609 xmax: -84.1368 ymax: 34.22688
## Geodetic CRS: WGS 84
## GEOID NAME
## 6 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## 6.1 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## 6.2 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## 6.3 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## 6.4 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## 6.5 131171304131 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia
## hhincome hhincomeM id alias
## 6 80924 55522 kFL2Ysx-RmhQ-_ALHAv-PA village-burger-cumming-cumming
## 6.1 80924 55522 6CLbYKwLMOg1hO7l3Ga4sg sliceability-cumming
## 6.2 80924 55522 3rfhvsxSEF_MkWdzxhUShw sawnee-mountain-biscuit-cumming
## 6.3 80924 55522 MvhsmiIj59JVjto4S8NHvQ happy-family-cumming
## 6.4 80924 55522 a4ktb-erFBzvUrWtVX_5qw subway-cumming-28
## 6.5 80924 55522 j6HCUt0eV1wEZUZ61l_3Ug hardees-cumming-2
## name
## 6 Village Burger - Cumming
## 6.1 SliceAbility
## 6.2 Sawnee Mountain Biscuit
## 6.3 Happy Family
## 6.4 Subway
## 6.5 Hardee's
## image_url
## 6 https://s3-media1.fl.yelpcdn.com/bphoto/XCuVdf2GKTzSVwaAMolQqw/o.jpg
## 6.1 https://s3-media3.fl.yelpcdn.com/bphoto/MM8LN_pUOEpSzwRRgOKHXQ/o.jpg
## 6.2 https://s3-media2.fl.yelpcdn.com/bphoto/aFkvv-P6C4qvGkQu4C15Iw/o.jpg
## 6.3 https://s3-media1.fl.yelpcdn.com/bphoto/Ae3YRkYeZ1bd2mQ-Zb3XPg/o.jpg
## 6.4 https://s3-media2.fl.yelpcdn.com/bphoto/gLfPUkwKQh-RildnZlo2iQ/o.jpg
## 6.5 https://s3-media3.fl.yelpcdn.com/bphoto/gT0Q-RknEVOGWdGrawlJug/o.jpg
## is_closed
## 6 FALSE
## 6.1 FALSE
## 6.2 FALSE
## 6.3 FALSE
## 6.4 FALSE
## 6.5 FALSE
## url
## 6 https://www.yelp.com/biz/village-burger-cumming-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6.1 https://www.yelp.com/biz/sliceability-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6.2 https://www.yelp.com/biz/sawnee-mountain-biscuit-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6.3 https://www.yelp.com/biz/happy-family-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6.4 https://www.yelp.com/biz/subway-cumming-28?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6.5 https://www.yelp.com/biz/hardees-cumming-2?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## review_count categories rating transactions price
## 6 210 Burgers, Hot Dogs, Salad 4.1 delivery, pickup $$
## 6.1 41 Pizza, Desserts, Salad 4.8 delivery, pickup $
## 6.2 55 Breakfast & Brunch, Sandwiches 4.5 delivery $
## 6.3 129 Chinese, Japanese, Sushi Bars 3.7 delivery $$
## 6.4 5 Sandwiches, Fast Food 3.8 delivery, pickup $
## 6.5 31 Burgers, Fast Food 2.5 delivery, pickup $
## phone display_phone distance
## 6 +14702394502 (470) 239-4502 2753.438
## 6.1 +14708352324 (470) 835-2324 2377.851
## 6.2 +17708874615 (770) 887-4615 1648.054
## 6.3 +14706957233 (470) 695-7233 2762.146
## 6.4 +17708880758 (770) 888-0758 3004.537
## 6.5 +17708444440 (770) 844-4440 2839.351
## business_hours
## 6 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 2000, 2000, 2000, 2000, 2100, 2100, 2000, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 6.1 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1200, 2000, 2000, 2000, 2200, 2000, 2200, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 6.2 FALSE, FALSE, FALSE, FALSE, FALSE, 0600, 0600, 0600, 0600, 0600, 1200, 1200, 1200, 1200, 1200, 1, 2, 3, 4, 5, REGULAR, FALSE
## 6.3 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1130, 1130, 2130, 2130, 2130, 2230, 2230, 2130, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 6.4 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0900, 0900, 0900, 0900, 0900, 1000, 1000, 2000, 2000, 2000, 2000, 2000, 2000, 1900, 0, 1, 2, 3, 4, 5, 6, REGULAR, FALSE
## 6.5 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0500, 0500, 0500, 0500, 0500, 0500, 0600, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 0, 1, 2, 3, 4, 5, 6, REGULAR, FALSE
## location.address1 location.address2 location.address3 location.city
## 6 101 W Courthouse Square <NA> Cumming
## 6.1 420 Vision Dr Ste A102 <NA> Cumming
## 6.2 104 13th St Cumming
## 6.3 103 W Courthouse Sq Cumming
## 6.4 533 Canton Hwy Ste 100 Cumming
## 6.5 125 W Maple St Cumming
## location.zip_code location.country location.state
## 6 30040 US GA
## 6.1 30028 US GA
## 6.2 30040 US GA
## 6.3 30040 US GA
## 6.4 30040 US GA
## 6.5 30040 US GA
## location.display_address attributes.business_temp_closed
## 6 101 W Courthouse Square, Cumming, GA 30040 NA
## 6.1 420 Vision Dr, Ste A102, Cumming, GA 30028 NA
## 6.2 104 13th St, Cumming, GA 30040 NA
## 6.3 103 W Courthouse Sq, Cumming, GA 30040 NA
## 6.4 533 Canton Hwy, Ste 100, Cumming, GA 30040 NA
## 6.5 125 W Maple St, Cumming, GA 30040 NA
## attributes.menu_url attributes.open24_hours
## 6 https://www.villageburger.com/Menu NA
## 6.1 <NA> NA
## 6.2 https://www.sawneemtnbiscuitco.com/menu NA
## 6.3 <NA> NA
## 6.4 <NA> NA
## 6.5 https://hardees.com/menu NA
## attributes.waitlist_reservation geometry
## 6 NA MULTIPOLYGON (((-84.15451 3...
## 6.1 FALSE MULTIPOLYGON (((-84.15451 3...
## 6.2 NA MULTIPOLYGON (((-84.15451 3...
## 6.3 NA MULTIPOLYGON (((-84.15451 3...
## 6.4 NA MULTIPOLYGON (((-84.15451 3...
## 6.5 NA MULTIPOLYGON (((-84.15451 3...
yelp_census %>% head()
## Simple feature collection with 6 features and 31 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -84.14626 ymin: 34.20125 xmax: -84.13125 ymax: 34.22181
## Geodetic CRS: WGS 84
## id alias
## 1 -QzATE8gbPVyjI9CTYSUOg tams-backstage-cumming
## 2 MdsnJ4UjFpgC0aJNqoaQ_w gasthaus-tirol-cumming-2
## 4 kFL2Ysx-RmhQ-_ALHAv-PA village-burger-cumming-cumming
## 5 6CLbYKwLMOg1hO7l3Ga4sg sliceability-cumming
## 6 3rfhvsxSEF_MkWdzxhUShw sawnee-mountain-biscuit-cumming
## 7 yASAsKLBr6lOtXlrfExU_Q mexican-grill-cumming
## name
## 1 Tam's Backstage
## 2 Gasthaus Tirol
## 4 Village Burger - Cumming
## 5 SliceAbility
## 6 Sawnee Mountain Biscuit
## 7 Mexican Grill
## image_url
## 1 https://s3-media2.fl.yelpcdn.com/bphoto/SRhLlUuNWhgz-kigadFD-w/o.jpg
## 2 https://s3-media1.fl.yelpcdn.com/bphoto/LSp42VOe43JPzjAHwfJzjA/o.jpg
## 4 https://s3-media1.fl.yelpcdn.com/bphoto/XCuVdf2GKTzSVwaAMolQqw/o.jpg
## 5 https://s3-media3.fl.yelpcdn.com/bphoto/MM8LN_pUOEpSzwRRgOKHXQ/o.jpg
## 6 https://s3-media2.fl.yelpcdn.com/bphoto/aFkvv-P6C4qvGkQu4C15Iw/o.jpg
## 7 https://s3-media4.fl.yelpcdn.com/bphoto/M-WrYJCIfntaXyFG99vZ4Q/o.jpg
## is_closed
## 1 FALSE
## 2 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## 7 FALSE
## url
## 1 https://www.yelp.com/biz/tams-backstage-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 2 https://www.yelp.com/biz/gasthaus-tirol-cumming-2?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 4 https://www.yelp.com/biz/village-burger-cumming-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 5 https://www.yelp.com/biz/sliceability-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 6 https://www.yelp.com/biz/sawnee-mountain-biscuit-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## 7 https://www.yelp.com/biz/mexican-grill-cumming?adjust_creative=1K83ZF1zfv8Vvq4F_1oE-A&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=1K83ZF1zfv8Vvq4F_1oE-A
## review_count categories rating transactions price
## 1 264 New American, Wine Bars 4.2 delivery $$
## 2 224 German, Salad, Beer Gardens 3.9 delivery $$
## 4 210 Burgers, Hot Dogs, Salad 4.1 delivery, pickup $$
## 5 41 Pizza, Desserts, Salad 4.8 delivery, pickup $
## 6 55 Breakfast & Brunch, Sandwiches 4.5 delivery $
## 7 10 Mexican 4.8 delivery $
## phone display_phone distance
## 1 +16784558310 (678) 455-8310 2423.907
## 2 +17708447244 (770) 844-7244 2992.678
## 4 +14702394502 (470) 239-4502 2753.438
## 5 +14708352324 (470) 835-2324 2377.851
## 6 +17708874615 (770) 887-4615 1648.054
## 7 +16783418107 (678) 341-8107 1002.345
## business_hours
## 1 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1600, 2100, 2100, 2100, 2100, 2130, 2130, 0, 1, 2, 3, 4, 5, REGULAR, TRUE
## 2 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1100, 1700, 1400, 2100, 1400, 2100, 1400, 2100, 1400, 2200, 1400, 2200, 1400, 2100, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, REGULAR, TRUE
## 4 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 2000, 2000, 2000, 2000, 2100, 2100, 2000, 0, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 5 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1200, 2000, 2000, 2000, 2200, 2000, 2200, 1, 2, 3, 4, 5, 6, REGULAR, TRUE
## 6 FALSE, FALSE, FALSE, FALSE, FALSE, 0600, 0600, 0600, 0600, 0600, 1200, 1200, 1200, 1200, 1200, 1, 2, 3, 4, 5, REGULAR, FALSE
## 7 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0730, 0730, 0730, 0730, 0730, 0830, 1630, 1630, 1630, 1630, 1630, 1530, 0, 1, 2, 3, 4, 5, REGULAR, FALSE
## location.address1 location.address2 location.address3 location.city
## 1 215 Ingram Ave Cumming
## 2 310 Atlanta Rd Cumming
## 4 101 W Courthouse Square <NA> Cumming
## 5 420 Vision Dr Ste A102 <NA> Cumming
## 6 104 13th St Cumming
## 7 601 Dahlonega St <NA> Cumming
## location.zip_code location.country location.state
## 1 30040 US GA
## 2 30040 US GA
## 4 30040 US GA
## 5 30028 US GA
## 6 30040 US GA
## 7 30040 US GA
## location.display_address attributes.business_temp_closed
## 1 215 Ingram Ave, Cumming, GA 30040 NA
## 2 310 Atlanta Rd, Cumming, GA 30040 NA
## 4 101 W Courthouse Square, Cumming, GA 30040 NA
## 5 420 Vision Dr, Ste A102, Cumming, GA 30028 NA
## 6 104 13th St, Cumming, GA 30040 NA
## 7 601 Dahlonega St, Cumming, GA 30040 NA
## attributes.menu_url attributes.open24_hours
## 1 http://tamsbackstage.com/index-3.html NA
## 2 http://www.gasthaus-cumming.com/menu.html NA
## 4 https://www.villageburger.com/Menu NA
## 5 <NA> NA
## 6 https://www.sawneemtnbiscuitco.com/menu NA
## 7 <NA> NA
## attributes.waitlist_reservation GEOID
## 1 NA 131171304091
## 2 NA 131171304102
## 4 NA 131171304131
## 5 FALSE 131171304131
## 6 NA 131171304131
## 7 NA 131171304091
## NAME hhincome
## 1 Block Group 1; Census Tract 1304.09; Forsyth County; Georgia 88056
## 2 Block Group 2; Census Tract 1304.10; Forsyth County; Georgia 47781
## 4 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia 80924
## 5 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia 80924
## 6 Block Group 1; Census Tract 1304.13; Forsyth County; Georgia 80924
## 7 Block Group 1; Census Tract 1304.09; Forsyth County; Georgia 88056
## hhincomeM geometry
## 1 80905 POINT (-84.13662 34.20818)
## 2 5383 POINT (-84.13404 34.20125)
## 4 55522 POINT (-84.14059 34.20695)
## 5 55522 POINT (-84.14626 34.21945)
## 6 55522 POINT (-84.13802 34.22015)
## 7 80905 POINT (-84.13125 34.22181)
#The findings have changed after tidying the data. The restaurants with missing location information have been removed; there were not any name duplictes. After flattening the tables, columsn increased from 18 to 28. Howvwer rows were reduced from 2094 to 58. This is for both movie theatres and restaurants. Expensive POI's are clustered together but the cheaper ones are more spread out, especially towards the north of the city.
#Restaurants with the highest rating seem to be central; this location has both cheap and expensive restaurants.
#There seems to be a relationship between the proximity of the expensive restaurant and neighbourhoods with higher household income. They are closer together. There does not seem to be a relationship between rating score and review count, though those restuarants with both a high rating and review count will be the most popular.
Visualize
## tmap mode set to interactive viewing
Note that the echo = FALSE
parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.