Art museums with the largest review counts are located three to four blocks away from the main city streets (e.g., East 79th Street, West Houston Street). Middle review count art museums are located directly near the main city streets, while those with the smallest review counts are located very far from the central blocks. This pattern could provide a clue for location allocation analysis.
Used bookstores are distributed away from the margins of central Manhattan.
library(tidycensus)
library(sf)
## Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE
library(tmap)
## The legacy packages maptools, rgdal, and rgeos, underpinning the sp package,
## which was just loaded, will retire in October 2023.
## Please refer to R-spatial evolution reports for details, especially
## https://r-spatial.org/r/2023/05/15/evolution4.html.
## It may be desirable to make the sf package available;
## package maintainers should consider adding sf to Suggests:.
## The sp package is now running under evolution status 2
## (status 2 uses the sf package in place of rgdal)
library(jsonlite)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── 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)
##
## Attaching package: 'reshape2'
##
## The following object is masked from 'package:tidyr':
##
## smiths
library(here)
## here() starts at /home/rstudio
library(yelpr)
library(knitr)
library(tigris)
## To enable caching of data, set `options(tigris_use_cache = TRUE)`
## in your R script or .Rprofile.
# get help from documentation
?tidycensus::get_acs
# get api key
tidycensus::census_api_key(Sys.getenv("census_api"))
## To install your API key for use in future sessions, run this function with `install = TRUE`.
tract <- suppressMessages(
get_acs(geography = "tract", # or "block group", "county", "state" etc.
state = "NY",
county = "New York",
variables = c(hhincome = 'B19019_001',
race.tot = "B02001_001",
race.white = "B02001_002",
race.black = 'B02001_003'
),
year = 2021,
survey = "acs5", # American Community Survey 5-year estimate
geometry = TRUE, # returns sf objects
output = "wide") # wide vs. long
)
## Warning: • You have not set a Census API key. Users without a key are limited to 500
## queries per day and may experience performance limitations.
## ℹ For best results, get a Census API key at
## http://api.census.gov/data/key_signup.html and then supply the key to the
## `census_api_key()` function to use it throughout your tidycensus session.
## This warning is displayed once per session.
##
|
| | 0%
|
|= | 1%
|
|= | 2%
|
|== | 3%
|
|=== | 4%
|
|=== | 5%
|
|==== | 6%
|
|===== | 7%
|
|====== | 8%
|
|====== | 9%
|
|======= | 10%
|
|======= | 11%
|
|======== | 12%
|
|========= | 12%
|
|========= | 13%
|
|========== | 14%
|
|========== | 15%
|
|=========== | 16%
|
|============ | 17%
|
|============= | 18%
|
|============= | 19%
|
|============== | 20%
|
|============== | 21%
|
|=============== | 21%
|
|================ | 22%
|
|================= | 24%
|
|================= | 25%
|
|================== | 26%
|
|=================== | 26%
|
|=================== | 27%
|
|==================== | 28%
|
|==================== | 29%
|
|===================== | 30%
|
|===================== | 31%
|
|====================== | 31%
|
|======================= | 32%
|
|======================= | 33%
|
|========================= | 36%
|
|========================== | 37%
|
|=========================== | 38%
|
|=========================== | 39%
|
|============================ | 40%
|
|============================= | 41%
|
|============================== | 42%
|
|============================== | 43%
|
|=============================== | 44%
|
|================================ | 46%
|
|================================== | 48%
|
|=================================== | 50%
|
|==================================== | 51%
|
|===================================== | 52%
|
|===================================== | 53%
|
|====================================== | 54%
|
|======================================= | 55%
|
|======================================= | 56%
|
|======================================== | 57%
|
|========================================= | 58%
|
|========================================= | 59%
|
|========================================== | 60%
|
|=========================================== | 61%
|
|=========================================== | 62%
|
|============================================ | 63%
|
|============================================= | 64%
|
|============================================= | 65%
|
|============================================== | 66%
|
|=============================================== | 67%
|
|================================================ | 68%
|
|================================================= | 70%
|
|================================================== | 71%
|
|================================================== | 72%
|
|=================================================== | 73%
|
|==================================================== | 74%
|
|==================================================== | 75%
|
|===================================================== | 75%
|
|===================================================== | 76%
|
|====================================================== | 77%
|
|====================================================== | 78%
|
|======================================================= | 79%
|
|======================================================== | 79%
|
|======================================================== | 80%
|
|========================================================= | 81%
|
|========================================================= | 82%
|
|========================================================== | 83%
|
|=========================================================== | 84%
|
|============================================================ | 85%
|
|============================================================ | 86%
|
|============================================================= | 87%
|
|============================================================= | 88%
|
|============================================================== | 89%
|
|=============================================================== | 89%
|
|=============================================================== | 90%
|
|================================================================ | 91%
|
|================================================================ | 92%
|
|================================================================= | 93%
|
|================================================================== | 94%
|
|=================================================================== | 95%
|
|=================================================================== | 96%
|
|==================================================================== | 97%
|
|==================================================================== | 98%
|
|======================================================================| 99%
|
|======================================================================| 100%
tract
## Simple feature collection with 310 features and 10 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -74.04741 ymin: 40.68394 xmax: -73.907 ymax: 40.88221
## Geodetic CRS: NAD83
## First 10 features:
## GEOID NAME hhincomeE
## 1 36061006900 Census Tract 69, New York County, New York 237500
## 2 36061026700 Census Tract 267, New York County, New York 59559
## 3 36061015501 Census Tract 155.01, New York County, New York 191490
## 4 36061018300 Census Tract 183, New York County, New York 129909
## 5 36061026900 Census Tract 269, New York County, New York 60619
## 6 36061031703 Census Tract 317.03, New York County, New York 250001
## 7 36061013203 Census Tract 132.03, New York County, New York 110642
## 8 36061009100 Census Tract 91, New York County, New York 148859
## 9 36061015802 Census Tract 158.02, New York County, New York 77889
## 10 36061001300 Census Tract 13, New York County, New York 193065
## hhincomeM race.totE race.totM race.whiteE race.whiteM race.blackE
## 1 65948 2450 372 2096 352 19
## 2 11892 2119 258 1296 218 54
## 3 66452 5197 1230 4168 1235 145
## 4 46158 8578 1408 6462 1155 291
## 5 8905 9464 1462 1886 726 614
## 6 NA 6419 786 4774 800 124
## 7 56334 4452 1098 3848 1234 0
## 8 50521 6656 813 4848 745 557
## 9 29354 4284 631 2719 542 424
## 10 22753 4844 728 3087 500 348
## race.blackM geometry
## 1 22 MULTIPOLYGON (((-74.02064 4...
## 2 43 MULTIPOLYGON (((-73.93001 4...
## 3 198 MULTIPOLYGON (((-73.98682 4...
## 4 168 MULTIPOLYGON (((-73.98258 4...
## 5 413 MULTIPOLYGON (((-73.93286 4...
## 6 159 MULTIPOLYGON (((-74.02398 4...
## 7 13 MULTIPOLYGON (((-73.95365 4...
## 8 311 MULTIPOLYGON (((-73.99849 4...
## 9 337 MULTIPOLYGON (((-73.95206 4...
## 10 235 MULTIPOLYGON (((-74.01551 4...
tmap_mode("view")
## tmap mode set to interactive viewing
?place
## No documentation for 'place' in specified packages and libraries:
## you could try '??place'
manhattan <- places('NY') %>%
filter(NAME == 'New York')
## Retrieving data for the year 2021
##
|
| | 0%
|
| | 1%
|
|= | 1%
|
|= | 2%
|
|== | 2%
|
|== | 3%
|
|=== | 4%
|
|=== | 5%
|
|==== | 5%
|
|==== | 6%
|
|===== | 7%
|
|====== | 8%
|
|======= | 9%
|
|======= | 10%
|
|======== | 11%
|
|======== | 12%
|
|========= | 12%
|
|========= | 13%
|
|========== | 14%
|
|========== | 15%
|
|=========== | 15%
|
|=========== | 16%
|
|============ | 17%
|
|============= | 19%
|
|============== | 19%
|
|============== | 20%
|
|=============== | 21%
|
|=============== | 22%
|
|================ | 23%
|
|================= | 24%
|
|================= | 25%
|
|================== | 25%
|
|================== | 26%
|
|=================== | 27%
|
|=================== | 28%
|
|==================== | 28%
|
|==================== | 29%
|
|===================== | 30%
|
|===================== | 31%
|
|====================== | 32%
|
|======================= | 33%
|
|======================= | 34%
|
|======================== | 34%
|
|======================== | 35%
|
|========================= | 35%
|
|========================= | 36%
|
|========================== | 36%
|
|========================== | 37%
|
|=========================== | 38%
|
|=========================== | 39%
|
|============================ | 39%
|
|============================ | 40%
|
|============================= | 41%
|
|============================= | 42%
|
|============================== | 42%
|
|============================== | 43%
|
|=============================== | 44%
|
|=============================== | 45%
|
|================================ | 45%
|
|================================ | 46%
|
|================================= | 47%
|
|================================== | 48%
|
|================================== | 49%
|
|=================================== | 50%
|
|=================================== | 51%
|
|==================================== | 51%
|
|==================================== | 52%
|
|===================================== | 53%
|
|====================================== | 54%
|
|======================================= | 55%
|
|======================================= | 56%
|
|======================================== | 57%
|
|========================================= | 58%
|
|========================================= | 59%
|
|========================================== | 59%
|
|========================================== | 60%
|
|=========================================== | 61%
|
|============================================ | 62%
|
|============================================ | 63%
|
|============================================= | 64%
|
|============================================== | 66%
|
|=============================================== | 67%
|
|=============================================== | 68%
|
|================================================ | 68%
|
|================================================ | 69%
|
|================================================= | 70%
|
|================================================= | 71%
|
|================================================== | 71%
|
|================================================== | 72%
|
|=================================================== | 72%
|
|=================================================== | 73%
|
|==================================================== | 74%
|
|===================================================== | 76%
|
|====================================================== | 77%
|
|====================================================== | 78%
|
|======================================================= | 78%
|
|======================================================= | 79%
|
|======================================================== | 79%
|
|======================================================== | 80%
|
|========================================================= | 81%
|
|========================================================= | 82%
|
|========================================================== | 82%
|
|========================================================== | 83%
|
|=========================================================== | 84%
|
|============================================================ | 86%
|
|============================================================= | 87%
|
|============================================================= | 88%
|
|============================================================== | 88%
|
|============================================================== | 89%
|
|=============================================================== | 90%
|
|=============================================================== | 91%
|
|================================================================ | 91%
|
|================================================================ | 92%
|
|================================================================= | 92%
|
|================================================================= | 93%
|
|================================================================== | 94%
|
|================================================================== | 95%
|
|=================================================================== | 96%
|
|==================================================================== | 97%
|
|==================================================================== | 98%
|
|===================================================================== | 98%
|
|===================================================================== | 99%
|
|======================================================================| 99%
|
|======================================================================| 100%
tm_shape(tract) + tm_borders() + tm_shape(manhattan) + tm_borders(col = 'red')
# Function: Get tract-wise radius
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.2
return(bb_center)
}
## Using a loop -----------------------------------------------------------------
# Creating an empty vector of NA.
# Results will fill this vector
epsg_id <- 4326
r4all_loop <- vector("list", nrow(tract))
# Starting a for-loop
for (i in 1:nrow(tract)){
r4all_loop[[i]] <- tract %>%
st_transform(crs = epsg_id) %>%
st_geometry() %>%
.[[i]] %>%
get_r(epsg_id = epsg_id)
}
r4all_loop <- bind_rows(r4all_loop)
# Using a functional -----------------------------------------------------------
# We use a functional (sapply) to apply this custom function to each Census Tract.
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)
# Are these two identical?
identical(r4all_apply, r4all_loop)
## [1] TRUE
# Appending X Y coordinates as seprate columns
ready_4_yelp <- r4all_apply %>%
mutate(x = st_coordinates(.)[,1],
y = st_coordinates(.)[,2])
tmap_mode('view')
## tmap mode set to interactive viewing
# Select the first 10 rows
ready_4_yelp[1:10,] %>%
# 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[1:10,]) + tm_borders(col= 'blue')
# Function for formatting the url for API request
url_format <- function(latitude = NULL, longitude = NULL,
radius = NULL, categories = NULL, offset = NULL, limit = NULL){
# Parameters
base_url <- "https://api.yelp.com/v3/businesses/search?"
latitude <- paste0("latitude=", latitude)
longitude <- paste0("longitude=", longitude)
radius <- paste0("radius=", radius)
categories <- paste0("categories=", categories)
offset <- paste0("offset=", offset)
limit <- paste0("limit=", limit)
# Out
full_url <- paste0(c(base_url, latitude, longitude, radius, categories, offset, limit), collapse = "&")
return(full_url)
}
# FUNCTION
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_key"),
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 is where the results will be appended to.
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
# pagination
# because we don't know how many times to loop
while(n <= required_n){
resp <- business_search(api_key = Sys.getenv("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
} #<< end of while loop
# Merge all elements in the list into a single data frame
out <- out %>% bind_rows()
return(out)
}
}
# Prepare a collector
yelp_all_list_usedbooks <- vector("list", nrow(ready_4_yelp))
# Looping through all Census Tracts
for (row in 1:nrow(ready_4_yelp)){
if (row > 80){
break
}
yelp_all_list_usedbooks[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "usedbooks"))
if (row %% 10 == 0){
print(paste0("Current row: ", row))
}
}
## [1] "Current row: 10"
## [1] "Current row: 20"
## [1] "Current row: 30"
## [1] "Current row: 40"
## [1] "Current row: 50"
## [1] "Current row: 60"
## [1] "Current row: 70"
## [1] "Current row: 80"
# Collapsing the list into a data.frame
yelp_all_usedbooks <- yelp_all_list_usedbooks %>% bind_rows() %>% as_tibble()
# print
yelp_all_usedbooks %>% print(width=1000)
## # A tibble: 12 × 16
## id alias
## <chr> <chr>
## 1 Q9tN_O7jTNb1Kj30KqB_ig the-book-cellar-new-york-2
## 2 eIm1HIWDk77Rd2t1_-yABg aeon-bookstore-new-york-2
## 3 eIm1HIWDk77Rd2t1_-yABg aeon-bookstore-new-york-2
## 4 IYKGq4bU9byRjny-fwVq2g sweet-pickle-books-new-york
## 5 2k44b8JBXAWCDKmWN0xWjg the-strand-new-york-4
## 6 LzQ7DXioKhiTGH1P-8521Q westsider-rare-and-used-books-new-york
## 7 QghL38LTrtS4buJuvl33qw chegg-new-york-2
## 8 Q9tN_O7jTNb1Kj30KqB_ig the-book-cellar-new-york-2
## 9 eIm1HIWDk77Rd2t1_-yABg aeon-bookstore-new-york-2
## 10 QghL38LTrtS4buJuvl33qw chegg-new-york-2
## 11 Mby2Il30GGvcz7AOorl4XQ strand-bookstore-new-york
## 12 UAGB45qyOZfCvSQHkkhMKA alabaster-bookshop-new-york
## name
## <chr>
## 1 The Book Cellar
## 2 Aeon Bookstore
## 3 Aeon Bookstore
## 4 Sweet Pickle Books
## 5 The Strand
## 6 Westsider Rare and Used Books
## 7 Chegg
## 8 The Book Cellar
## 9 Aeon Bookstore
## 10 Chegg
## 11 Strand Bookstore
## 12 Alabaster Bookshop
## image_url
## <chr>
## 1 https://s3-media4.fl.yelpcdn.com/bphoto/pfNIwM6y-JaWsNKg0KUwjA/o.jpg
## 2 https://s3-media2.fl.yelpcdn.com/bphoto/GTiXI_H2h91Hh1n6zI6dYA/o.jpg
## 3 https://s3-media2.fl.yelpcdn.com/bphoto/GTiXI_H2h91Hh1n6zI6dYA/o.jpg
## 4 https://s3-media4.fl.yelpcdn.com/bphoto/snZSg3RkdHpcyRUNdexl7w/o.jpg
## 5 https://s3-media2.fl.yelpcdn.com/bphoto/lnIjDRj6j7iMJIQBaJeQuQ/o.jpg
## 6 https://s3-media4.fl.yelpcdn.com/bphoto/LGrYHwsH_gYXREshdJibcw/o.jpg
## 7 https://s3-media2.fl.yelpcdn.com/bphoto/DFh38sPvp5xLQU34EU44gQ/o.jpg
## 8 https://s3-media4.fl.yelpcdn.com/bphoto/pfNIwM6y-JaWsNKg0KUwjA/o.jpg
## 9 https://s3-media2.fl.yelpcdn.com/bphoto/GTiXI_H2h91Hh1n6zI6dYA/o.jpg
## 10 https://s3-media2.fl.yelpcdn.com/bphoto/DFh38sPvp5xLQU34EU44gQ/o.jpg
## 11 https://s3-media3.fl.yelpcdn.com/bphoto/fi-Iezn0TMnMWGQn61TXaA/o.jpg
## 12 https://s3-media3.fl.yelpcdn.com/bphoto/-Lkj72mxIV9mipOuaD2bjg/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
## 11 FALSE
## 12 FALSE
## url
## <chr>
## 1 https://www.yelp.com/biz/the-book-cellar-new-york-2?adjust_creative=aOMz3ElZ…
## 2 https://www.yelp.com/biz/aeon-bookstore-new-york-2?adjust_creative=aOMz3ElZ4…
## 3 https://www.yelp.com/biz/aeon-bookstore-new-york-2?adjust_creative=aOMz3ElZ4…
## 4 https://www.yelp.com/biz/sweet-pickle-books-new-york?adjust_creative=aOMz3El…
## 5 https://www.yelp.com/biz/the-strand-new-york-4?adjust_creative=aOMz3ElZ4MnHC…
## 6 https://www.yelp.com/biz/westsider-rare-and-used-books-new-york?adjust_creat…
## 7 https://www.yelp.com/biz/chegg-new-york-2?adjust_creative=aOMz3ElZ4MnHCySKsR…
## 8 https://www.yelp.com/biz/the-book-cellar-new-york-2?adjust_creative=aOMz3ElZ…
## 9 https://www.yelp.com/biz/aeon-bookstore-new-york-2?adjust_creative=aOMz3ElZ4…
## 10 https://www.yelp.com/biz/chegg-new-york-2?adjust_creative=aOMz3ElZ4MnHCySKsR…
## 11 https://www.yelp.com/biz/strand-bookstore-new-york?adjust_creative=aOMz3ElZ4…
## 12 https://www.yelp.com/biz/alabaster-bookshop-new-york?adjust_creative=aOMz3El…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 41 <df [1 × 2]> 5 40.8 -74.0 <list [0]>
## 2 8 <df [1 × 2]> 5 40.7 -74.0 <list [0]>
## 3 8 <df [1 × 2]> 5 40.7 -74.0 <list [0]>
## 4 16 <df [2 × 2]> 3 40.7 -74.0 <list [0]>
## 5 21 <df [2 × 2]> 4 40.8 -74.0 <list [0]>
## 6 135 <df [3 × 2]> 4 40.8 -74.0 <list [0]>
## 7 1 <df [1 × 2]> 3 40.8 -74.0 <list [0]>
## 8 41 <df [1 × 2]> 5 40.8 -74.0 <list [0]>
## 9 8 <df [1 × 2]> 5 40.7 -74.0 <list [0]>
## 10 1 <df [1 × 2]> 3 40.8 -74.0 <list [0]>
## 11 1679 <df [2 × 2]> 4.5 40.7 -74.0 <list [0]>
## 12 43 <df [2 × 2]> 4 40.7 -74.0 <list [0]>
## price location$address1 $address2 $address3 $city $zip_code $country
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 $ 1465 York Ave <NA> "" New York 10075 US
## 2 <NA> 151 E Broadway "" <NA> New York 10002 US
## 3 <NA> 151 E Broadway "" <NA> New York 10002 US
## 4 <NA> 47 Orchard St "" <NA> New York 10002 US
## 5 <NA> 450 Columbus Ave <NA> "" New York 10024 US
## 6 $ 2246 Broadway "" "" New York 10024 US
## 7 <NA> 10 E 39th St "" <NA> New York 10016 US
## 8 $ 1465 York Ave <NA> "" New York 10075 US
## 9 <NA> 151 E Broadway "" <NA> New York 10002 US
## 10 <NA> 10 E 39th St "" <NA> New York 10016 US
## 11 $$ 828 Broadway "" "" New York 10003 US
## 12 $$ 122 4th Ave "" "" New York 10003 US
## $state $display_address phone display_phone distance
## <chr> <list> <chr> <chr> <dbl>
## 1 NY <chr [2]> "+12129309256" "(212) 930-9256" 86.9
## 2 NY <chr [2]> "+19176757253" "(917) 675-7253" 840.
## 3 NY <chr [2]> "+19176757253" "(917) 675-7253" 1125.
## 4 NY <chr [2]> "" "" 1298.
## 5 NY <chr [2]> "" "" 473.
## 6 NY <chr [2]> "+12123620706" "(212) 362-0706" 661.
## 7 NY <chr [2]> "" "" 79.7
## 8 NY <chr [2]> "+12129309256" "(212) 930-9256" 248.
## 9 NY <chr [2]> "+19176757253" "(917) 675-7253" 474.
## 10 NY <chr [2]> "" "" 232.
## 11 NY <chr [2]> "+12124731452" "(212) 473-1452" 386.
## 12 NY <chr [2]> "+12129823550" "(212) 982-3550" 323.
# Extract coordinates
yelp_sf_usedbooks <- yelp_all_usedbooks %>%
mutate(x = .$coordinates$longitude,
y = .$coordinates$latitude) %>%
filter(!is.na(x) & !is.na(y)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326)
# Map
tm_shape(yelp_sf_usedbooks) +
tm_dots(col = "review_count", style="quantile")
# Prepare a collector
yelp_all_list_artmuseums <- vector("list", nrow(ready_4_yelp))
# Looping through all Census Tracts
for (row in 1:nrow(ready_4_yelp)){
if (row > 80){
break
}
yelp_all_list_artmuseums[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "artmuseums"))
if (row %% 10 == 0){
print(paste0("Current row: ", row))
}
}
## [1] "Current row: 10"
## [1] "Current row: 20"
## [1] "Current row: 30"
## [1] "Current row: 40"
## [1] "Current row: 50"
## [1] "Current row: 60"
## [1] "Current row: 70"
## [1] "Current row: 80"
# Collapsing the list into a data.frame
yelp_all_artmuseums <- yelp_all_list_artmuseums %>% bind_rows() %>% as_tibble()
# print
yelp_all_artmuseums %>% print(width=1000)
## # A tibble: 35 × 16
## id alias
## <chr> <chr>
## 1 FCt4zU9tPAewEnEniRRLbg color-factory-new-york
## 2 lvBT0xJnQdfixkbJTZdcLw van-gogh-the-immersive-experience-new-york
## 3 bFg9sE5jaQuscKh67p1akA poster-house-new-york
## 4 zq8BL3Io6tm8lON2M1jXqw hall-des-lumières-new-york
## 5 lvBT0xJnQdfixkbJTZdcLw van-gogh-the-immersive-experience-new-york
## 6 07BcIHCOFK9dP0PW-xBbLQ studio-museum-harlem-new-york-3
## 7 E672oSwgE6Vm4izZlpA6lQ the-frick-collection-new-york
## 8 Ch4aTjvR7rwkt-J3KkDRKg louis-vuitton-exhibition-nyc-new-york
## 9 9SfNHqx0Cpq2DGKgYrJ2wA banksy-building-castles-in-the-sky-new-york
## 10 zq8BL3Io6tm8lON2M1jXqw hall-des-lumières-new-york
## name
## <chr>
## 1 Color Factory
## 2 Van Gogh The Immersive Experience
## 3 Poster House
## 4 Hall des Lumières
## 5 Van Gogh The Immersive Experience
## 6 Studio Museum Harlem
## 7 The Frick Collection
## 8 Louis Vuitton Exhibition NYC
## 9 Banksy Building Castles in the Sky
## 10 Hall des Lumières
## image_url
## <chr>
## 1 https://s3-media4.fl.yelpcdn.com/bphoto/9EzdDgTBV2_TlenzxczIVA/o.jpg
## 2 https://s3-media1.fl.yelpcdn.com/bphoto/HAMoPn6BkLAZHTisFgBxUQ/o.jpg
## 3 https://s3-media3.fl.yelpcdn.com/bphoto/t3WcrmZdGQI1wMt4khpTDw/o.jpg
## 4 https://s3-media3.fl.yelpcdn.com/bphoto/Wk32HtzJLsrVa6zjhOEhng/o.jpg
## 5 https://s3-media1.fl.yelpcdn.com/bphoto/HAMoPn6BkLAZHTisFgBxUQ/o.jpg
## 6 https://s3-media3.fl.yelpcdn.com/bphoto/eNeOmHgR250Edv2aFxHTbg/o.jpg
## 7 https://s3-media3.fl.yelpcdn.com/bphoto/-i_OY0EvjnBmFB9fDBlb5A/o.jpg
## 8 https://s3-media1.fl.yelpcdn.com/bphoto/CzFgtDiK5m10lJV_fhhw4g/o.jpg
## 9 https://s3-media1.fl.yelpcdn.com/bphoto/PodfVKLYs5gDnW78wMyU-A/o.jpg
## 10 https://s3-media3.fl.yelpcdn.com/bphoto/Wk32HtzJLsrVa6zjhOEhng/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/color-factory-new-york?adjust_creative=aOMz3ElZ4MnH…
## 2 https://www.yelp.com/biz/van-gogh-the-immersive-experience-new-york?adjust_c…
## 3 https://www.yelp.com/biz/poster-house-new-york?adjust_creative=aOMz3ElZ4MnHC…
## 4 https://www.yelp.com/biz/hall-des-lumi%C3%A8res-new-york?adjust_creative=aOM…
## 5 https://www.yelp.com/biz/van-gogh-the-immersive-experience-new-york?adjust_c…
## 6 https://www.yelp.com/biz/studio-museum-harlem-new-york-3?adjust_creative=aOM…
## 7 https://www.yelp.com/biz/the-frick-collection-new-york?adjust_creative=aOMz3…
## 8 https://www.yelp.com/biz/louis-vuitton-exhibition-nyc-new-york?adjust_creati…
## 9 https://www.yelp.com/biz/banksy-building-castles-in-the-sky-new-york?adjust_…
## 10 https://www.yelp.com/biz/hall-des-lumi%C3%A8res-new-york?adjust_creative=aOM…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 560 <df [1 × 2]> 4 40.7 -74.0 <list [0]>
## 2 55 <df [1 × 2]> 3.5 40.7 -74.0 <list [0]>
## 3 36 <df [2 × 2]> 4.5 40.7 -74.0 <list [0]>
## 4 36 <df [1 × 2]> 4 40.7 -74.0 <list [0]>
## 5 55 <df [1 × 2]> 3.5 40.7 -74.0 <list [0]>
## 6 46 <df [1 × 2]> 4 40.8 -73.9 <list [0]>
## 7 516 <df [1 × 2]> 4.5 40.8 -74.0 <list [0]>
## 8 10 <df [1 × 2]> 4.5 40.8 -74.0 <list [0]>
## 9 1 <df [1 × 2]> 5 40.7 -74.0 <list [0]>
## 10 36 <df [1 × 2]> 4 40.7 -74.0 <list [0]>
## location$address1 $address2 $address3 $city $zip_code $country $state
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 251 Spring St "" <NA> New York 10013 US NY
## 2 300 Vesey St "" <NA> New York 10282 US NY
## 3 119 W 23rd St "" <NA> New York 10011 US NY
## 4 49 Chambers St <NA> "" New York 10007 US NY
## 5 300 Vesey St "" <NA> New York 10282 US NY
## 6 144 W 125th St "" "" New York 10027 US NY
## 7 945 Madison Ave "" "" New York 10021 US NY
## 8 660 Madison Ave "" <NA> New York 10065 US NY
## 9 250 Bowery "" <NA> New York 10012 US NY
## 10 49 Chambers St <NA> "" New York 10007 US NY
## $display_address phone display_phone distance price
## <list> <chr> <chr> <dbl> <chr>
## 1 <chr [2]> "" "" 883. <NA>
## 2 <chr [2]> "" "" 176. <NA>
## 3 <chr [2]> "+19177222439" "(917) 722-2439" 205. <NA>
## 4 <chr [2]> "+13322428810" "(332) 242-8810" 851. <NA>
## 5 <chr [2]> "" "" 718. <NA>
## 6 <chr [2]> "+12128644500" "(212) 864-4500" 329. <NA>
## 7 <chr [2]> "+12122880700" "(212) 288-0700" 316. <NA>
## 8 <chr [2]> "" "" 260. <NA>
## 9 <chr [2]> "" "" 356. <NA>
## 10 <chr [2]> "+13322428810" "(332) 242-8810" 739. <NA>
## # ℹ 25 more rows
# Extract coordinates
yelp_sf_artmuseums <- yelp_all_artmuseums %>%
mutate(x = .$coordinates$longitude,
y = .$coordinates$latitude) %>%
filter(!is.na(x) & !is.na(y)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326)
# Map
tm_shape(yelp_sf_artmuseums) +
tm_dots(col = "review_count", style="quantile")