Census 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`.
Getting Census Tract Boundary of Ithaca
#### Tract polygons for the Yelp query
tract <- suppressMessages(
get_acs(geography = "tract",
state = "NY",
county = c("Tompkins"),
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
)
ithac <- tigris::places('NY') %>%
filter(NAME == 'Ithaca')
## Retrieving data for the year 2022
tract_ithac <- tract[ithac,]
# Retaining only those I want.
# Notice that select function can also change names when it selects columns.
tract_ithac <- tract_ithac %>%
select(GEOID,
hhincome = hhincomeE) # New name = old name
tmap_mode("view")
## tmap mode set to interactive viewing
tm_shape(tract_ithac) + tm_borders(lwd = 2) +
tm_shape(ithac) + tm_polygons(col = 'red', alpha = 0.4)
# 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.1
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_ithac))
# Starting a for-loop
for (i in 1:nrow(tract_ithac)){
r4all_loop[[i]] <- tract_ithac %>%
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_ithac %>%
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
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_ithac) + tm_borders(col= 'blue')
yelpr package (Category: Restaurants, Flowers & Gifts)
which_tract <- 2
test <- business_search(api_key = Sys.getenv('yelp_api'), # like we did for census, store your api key
categories = 'restaurants,flowers', # return only restaurant businesses
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 h0nPGPVrqZHCrrauTrywrA mix-kitchen-and-bar-ithaca-11
## 2 4GTwlHQ5qN9NGIpiySpBsA silo-food-truck-no-title
## 3 MBISWEvAzDb710ZCyvNu2A sunset-grill-ithaca
## 4 eTfO8fF3WWcyhN4SHG2TJw sandellas-flat-bread-cafe-ithaca
## 5 3QCY93kLbH29Cctus8IyKQ rogans-corner-ithaca
## 6 2Aee_Fb6aPb1sYyXqvjsEA tower-club-ithaca-2
## name
## 1 MIX Kitchen & Bar
## 2 Silo Food Truck
## 3 Sunset Grill
## 4 Sandella's Flat Bread Cafe
## 5 Rogan's Corner
## 6 Tower Club
## image_url
## 1 https://s3-media4.fl.yelpcdn.com/bphoto/vPdGPwsAJf4X_B2NsZMdkg/o.jpg
## 2 https://s3-media2.fl.yelpcdn.com/bphoto/_O_grfubATER8HrkhwPzJA/o.jpg
## 3 https://s3-media1.fl.yelpcdn.com/bphoto/mAa-6PRyk3VPcQEm77E9HQ/o.jpg
## 4
## 5 https://s3-media1.fl.yelpcdn.com/bphoto/HsJPLkZYReQgTSbQB95Mnw/o.jpg
## 6
## is_closed
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 FALSE
## 5 FALSE
## 6 FALSE
## url
## 1 https://www.yelp.com/biz/mix-kitchen-and-bar-ithaca-11?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## 2 https://www.yelp.com/biz/silo-food-truck-no-title?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## 3 https://www.yelp.com/biz/sunset-grill-ithaca?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## 4 https://www.yelp.com/biz/sandellas-flat-bread-cafe-ithaca?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## 5 https://www.yelp.com/biz/rogans-corner-ithaca?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## 6 https://www.yelp.com/biz/tower-club-ithaca-2?adjust_creative=NJjwKPgIcFpchzBhkT2XWg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=NJjwKPgIcFpchzBhkT2XWg
## review_count
## 1 452
## 2 32
## 3 126
## 4 0
## 5 41
## 6 0
## categories
## 1 tapasmallplates, cocktailbars, steak, Tapas/Small Plates, Cocktail Bars, Steakhouses
## 2 foodtrucks, comfortfood, breweries, Food Trucks, Comfort Food, Breweries
## 3 tradamerican, breakfast_brunch, sandwiches, American, Breakfast & Brunch, Sandwiches
## 4 bakeries, mexican, sandwiches, Bakeries, Mexican, Sandwiches
## 5 pizza, sandwiches, Pizza, Sandwiches
## 6 newamerican, New American
## rating coordinates.latitude coordinates.longitude transactions price
## 1 4.3 42.43031 -76.50317 delivery $$
## 2 4.4 42.43855 -76.50757 <NA>
## 3 3.5 42.42888 -76.49730 delivery $$
## 4 0.0 42.42278 -76.49420 <NA>
## 5 2.6 42.42875 -76.49751 delivery, pickup $
## 6 0.0 42.42106 -76.50111 <NA>
## location.address1 location.address2 location.address3 location.city
## 1 205 Elmira Rd <NA> <NA> Ithaca
## 2 620 W Green St <NA> Ithaca
## 3 823 Danby Rd <NA> <NA> Ithaca
## 4 1101 Terrace Dining Hall Ithaca
## 5 825 Danby Rd Ithaca
## 6 953 Danby Rd Ithaca
## location.zip_code location.country location.state
## 1 14850 US NY
## 2 14850 US NY
## 3 14850 US NY
## 4 14850 US NY
## 5 14850 US NY
## 6 14850 US NY
## location.display_address phone display_phone
## 1 205 Elmira Rd, Ithaca, NY 14850 +16073194248 (607) 319-4248
## 2 620 W Green St, Ithaca, NY 14850
## 3 823 Danby Rd, Ithaca, NY 14850 +16072721986 (607) 272-1986
## 4 1101 Terrace Dining Hall, Ithaca, NY 14850 +16072741176 (607) 274-1176
## 5 825 Danby Rd, Ithaca, NY 14850 +16072777191 (607) 277-7191
## 6 953 Danby Rd, Ithaca, NY 14850 +16072743393 (607) 274-3393
## distance
## 1 1162.6626
## 2 2110.2622
## 3 728.8960
## 4 136.5052
## 5 725.5237
## 6 604.7391
## business_hours
## 1 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 0900, 1630, 0900, 1630, 2130, 2130, 2130, 1500, 2130, 1500, 2130, 2, 3, 4, 5, 5, 6, 6, REGULAR, FALSE
## 2 FALSE, FALSE, FALSE, FALSE, FALSE, 1600, 1600, 1600, 1200, 1400, 2100, 2100, 2200, 2200, 2000, 2, 3, 4, 5, 6, REGULAR, FALSE
## 3 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0700, 0700, 0700, 0700, 0700, 0700, 0700, 1500, 1500, 2100, 2100, 2100, 2100, 1500, 0, 1, 2, 3, 4, 5, 6, REGULAR, FALSE
## 4 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0730, 0730, 0730, 0730, 0730, 1200, 1200, 2200, 2200, 2200, 2200, 1700, 1900, 1900, 0, 1, 2, 3, 4, 5, 6, REGULAR, FALSE
## 5 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 2215, 2215, 2215, 2215, 2215, 2215, 2215, 0, 1, 2, 3, 4, 5, 6, REGULAR, FALSE
## 6 NULL
## attributes.business_temp_closed
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
## attributes.menu_url
## 1 https://www.mixithaca.com/menus
## 2 https://silo-food-truck.square.site/
## 3
## 4 <NA>
## 5 http://www.roganscornerrest.com/page2.cfm?idd=1&more=1
## 6 <NA>
## attributes.open24_hours attributes.waitlist_reservation
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
##
## $total
## [1] 11
##
## $region
## $region$center
## $region$center$longitude
## [1] -76.49268
##
## $region$center$latitude
## [1] 42.42328
# See what's inside
names(test)
## [1] "businesses" "total" "region"
# Business
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?: 11, how many columns?: 18"
Defining function for accessing Yelp API for one Census Tract
# 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"),
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
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)
}
}
# Apply the function for the first Census Tract
yelp_first_tract1 <- get_yelp(ready_4_yelp[1,], 'restaurants') %>%
as_tibble()
## No encoding supplied: defaulting to UTF-8.
## No encoding supplied: defaulting to UTF-8.
yelp_first_tract2 <- get_yelp(ready_4_yelp[1,], 'flowers') %>%
as_tibble()
## No encoding supplied: defaulting to UTF-8.
# Print
yelp_first_tract1 %>% print
## # A tibble: 67 × 18
## id alias name image_url is_closed url review_count categories rating
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl>
## 1 3XDW8Ot… gola… Gola… https://… FALSE http… 169 <df> 4
## 2 4o6C5dF… itha… Itha… https://… FALSE http… 586 <df> 3.9
## 3 JlCzPAt… de-t… De T… https://… FALSE http… 125 <df> 3.4
## 4 T-n8QFM… reds… Red'… https://… FALSE http… 271 <df> 3.9
## 5 v1zbzBE… le-c… Le C… https://… FALSE http… 120 <df> 4.6
## 6 uOxHLne… merc… Merc… https://… FALSE http… 179 <df> 4.1
## 7 BdMKj3r… thom… Thom… https://… FALSE http… 184 <df> 4.4
## 8 dycxEZt… creo… Creo… https://… FALSE http… 43 <df> 4.3
## 9 ud9RNk5… wing… Wing… https://… FALSE http… 91 <df> 3.9
## 10 ntH3yiP… sime… Sime… https://… FALSE http… 294 <df> 3.8
## # ℹ 57 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]>
yelp_first_tract2 %>% print
## # A tibble: 2 × 18
## id alias name image_url is_closed url review_count categories rating
## <chr> <chr> <chr> <chr> <lgl> <chr> <int> <list> <dbl>
## 1 jDsvWSwt… bool… Bool… https://… FALSE http… 23 <df> 4.1
## 2 UHDpAts-… melo… Melo… https://… FALSE http… 0 <df> 0
## # ℹ 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[,3]>
Repeating for all other Census Tracts
# Prepare a collector
yelp_all_list <- vector("list", nrow(ready_4_yelp))
yelp_all_list1 <- vector("list", nrow(ready_4_yelp))
yelp_all_list2 <- 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,], "restaurants,flowers"))
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"
## [1] "Current row: 11"
## [1] "Current row: 12"
## [1] "Current row: 13"
## [1] "Current row: 14"
## [1] "Current row: 15"
for (row in 1:nrow(ready_4_yelp)){
yelp_all_list1[[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"
## [1] "Current row: 11"
## [1] "Current row: 12"
## [1] "Current row: 13"
## [1] "Current row: 14"
## [1] "Current row: 15"
for (row in 1:nrow(ready_4_yelp)){
yelp_all_list2[[row]] <- suppressMessages(get_yelp(ready_4_yelp[row,], "flowers"))
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"
## [1] "Current row: 11"
## [1] "Current row: 12"
## [1] "Current row: 13"
## [1] "Current row: 14"
## [1] "Current row: 15"
# Collapsing the list into a data.frame
yelp_all <- yelp_all_list %>% bind_rows() %>% as_tibble()
yelp_all1 <- yelp_all_list1 %>% bind_rows() %>% as_tibble()
yelp_all2 <- yelp_all_list2 %>% bind_rows() %>% as_tibble()
# print
yelp_all %>% print(width=1000)
## # A tibble: 1,534 × 18
## id alias
## <chr> <chr>
## 1 3XDW8Ot7jSVH_rsm5WBwQA gola-osteria-ithaca
## 2 4o6C5dFjyjBvF1g9st78NA ithaca-ale-house-ithaca
## 3 JlCzPAtL7rA5GdCmyUEPow de-tasty-hot-pot-ithaca-2
## 4 T-n8QFMx2zceV5M_ZKtgIA reds-place-ithaca
## 5 v1zbzBEnZ7odA9oeu25e4A le-cafe-cent-dix-ithaca-2
## 6 uOxHLnePU2wyTqPJ_p7ryw mercato-bar-and-kitchen-ithaca
## 7 BdMKj3rHVnHxZvxe_NCDHA thompson-and-bleecker-ithaca-2
## 8 dycxEZtWSaAv4xDAlidZPw creola-southern-steakhouse-ithaca
## 9 ud9RNk52okJkisfMOAHtyw wings-over-ithaca-ithaca-3
## 10 ntH3yiPIjLyMxYDCfY-UUQ simeons-on-the-commons-ithaca
## name
## <chr>
## 1 Gola Osteria
## 2 Ithaca Ale House
## 3 De Tasty Hot Pot
## 4 Red's Place
## 5 Le Cafe Cent-Dix
## 6 Mercato Bar & Kitchen
## 7 Thompson and Bleecker
## 8 Creola Southern Steakhouse
## 9 Wings Over Ithaca
## 10 Simeon's On The Commons
## image_url
## <chr>
## 1 https://s3-media3.fl.yelpcdn.com/bphoto/HC9v38sBsVMz62uFKy8Y0A/o.jpg
## 2 https://s3-media2.fl.yelpcdn.com/bphoto/1AeybJBqPvyniCGL9sGMmg/o.jpg
## 3 https://s3-media4.fl.yelpcdn.com/bphoto/nbBvObp5AunbyrsP3GqtLA/o.jpg
## 4 https://s3-media2.fl.yelpcdn.com/bphoto/AGjFqTEa3EJzWwCLVkJaTw/o.jpg
## 5 https://s3-media3.fl.yelpcdn.com/bphoto/1OUhGwPRzZLlkwOTaTcjlQ/o.jpg
## 6 https://s3-media4.fl.yelpcdn.com/bphoto/YpkL8iviu0KXMOuKN_FY9Q/o.jpg
## 7 https://s3-media4.fl.yelpcdn.com/bphoto/Ccl2pjXgvKRRxZShz-O8ww/o.jpg
## 8 https://s3-media1.fl.yelpcdn.com/bphoto/iuBG6OD7__XRYmDHVAOADg/o.jpg
## 9 https://s3-media1.fl.yelpcdn.com/bphoto/S2oyB-RhWXDQfT6Hjb7Nxg/o.jpg
## 10 https://s3-media3.fl.yelpcdn.com/bphoto/rzrle6pCS_-gKKjZYFuN9A/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/gola-osteria-ithaca?adjust_creative=NJjwKPgIcFpchzB…
## 2 https://www.yelp.com/biz/ithaca-ale-house-ithaca?adjust_creative=NJjwKPgIcFp…
## 3 https://www.yelp.com/biz/de-tasty-hot-pot-ithaca-2?adjust_creative=NJjwKPgIc…
## 4 https://www.yelp.com/biz/reds-place-ithaca?adjust_creative=NJjwKPgIcFpchzBhk…
## 5 https://www.yelp.com/biz/le-cafe-cent-dix-ithaca-2?adjust_creative=NJjwKPgIc…
## 6 https://www.yelp.com/biz/mercato-bar-and-kitchen-ithaca?adjust_creative=NJjw…
## 7 https://www.yelp.com/biz/thompson-and-bleecker-ithaca-2?adjust_creative=NJjw…
## 8 https://www.yelp.com/biz/creola-southern-steakhouse-ithaca?adjust_creative=N…
## 9 https://www.yelp.com/biz/wings-over-ithaca-ithaca-3?adjust_creative=NJjwKPgI…
## 10 https://www.yelp.com/biz/simeons-on-the-commons-ithaca?adjust_creative=NJjwK…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 169 <df [2 × 2]> 4 42.4 -76.5 <chr [1]>
## 2 586 <df [3 × 2]> 3.9 42.4 -76.5 <chr [1]>
## 3 125 <df [3 × 2]> 3.4 42.4 -76.5 <chr [2]>
## 4 271 <df [2 × 2]> 3.9 42.4 -76.5 <chr [1]>
## 5 120 <df [3 × 2]> 4.6 42.4 -76.5 <chr [1]>
## 6 179 <df [2 × 2]> 4.1 42.4 -76.5 <chr [1]>
## 7 184 <df [3 × 2]> 4.4 42.4 -76.5 <chr [1]>
## 8 43 <df [2 × 2]> 4.3 42.4 -76.5 <chr [1]>
## 9 91 <df [3 × 2]> 3.9 42.4 -76.5 <chr [2]>
## 10 294 <df [3 × 2]> 3.8 42.4 -76.5 <chr [1]>
## price location$address1 $address2 $address3 $city $zip_code $country
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 $$$ 115 South Quarry St "" "" Ithaca 14850 US
## 2 $$ 301 East State St "Ste 1" "" Ithaca 14850 US
## 3 $$ 422 Eddy St "" "" Ithaca 14850 US
## 4 $$ 107 N Aurora St "" "" Ithaca 14850 US
## 5 $$$ 110 N Aurora St <NA> "" Ithaca 14850 US
## 6 $$$ 108 N Aurora St "" "" Ithaca 14850 US
## 7 $$ 211 E Seneca St <NA> "" Ithaca 14850 US
## 8 <NA> 112 N Aurora St "" <NA> Ithaca 14850 US
## 9 $$ 121 Dryden Rd <NA> "" Ithaca 14850 US
## 10 $$ 224 E State St "" "" Ithaca 14850 US
## $state $display_address phone display_phone distance business_hours
## <chr> <list> <chr> <chr> <dbl> <list>
## 1 NY <chr [2]> +16072730333 (607) 273-0333 393. <df [1 × 3]>
## 2 NY <chr [3]> +16072567977 (607) 256-7977 525. <df [1 × 3]>
## 3 NY <chr [2]> +16078212312 (607) 821-2312 231. <df [1 × 3]>
## 4 NY <chr [2]> +16073194486 (607) 319-4486 545. <df [1 × 3]>
## 5 NY <chr [2]> +16073190750 (607) 319-0750 567. <df [1 × 3]>
## 6 NY <chr [2]> +16073195171 (607) 319-5171 577. <df [1 × 3]>
## 7 NY <chr [2]> +16073190851 (607) 319-0851 594. <df [1 × 3]>
## 8 NY <chr [2]> +16072721438 (607) 272-1438 575. <df [1 × 3]>
## 9 NY <chr [2]> +16073194664 (607) 319-4664 237. <df [1 × 3]>
## 10 NY <chr [2]> +16072722212 (607) 272-2212 573. <df [1 × 3]>
## attributes$business_temp_closed $menu_url
## <lgl> <chr>
## 1 NA "https://golaosteria.com/menubkp"
## 2 NA "http://www.ithacaalehouse.com/menu"
## 3 NA "http://www.tastyhotpot.com/menu"
## 4 NA "http://www.redsplaceithaca.com/menu/"
## 5 NA "https://www.lecafecentdix.com/menu"
## 6 NA ""
## 7 NA <NA>
## 8 NA <NA>
## 9 NA "https://www.wingsover.com/menu"
## 10 NA ""
## $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 NA
## 8 NA TRUE
## 9 NA NA
## 10 NA NA
## # ℹ 1,524 more rows
yelp_all1 %>% print(width=1000)
## # A tibble: 1,449 × 18
## id alias
## <chr> <chr>
## 1 3XDW8Ot7jSVH_rsm5WBwQA gola-osteria-ithaca
## 2 4o6C5dFjyjBvF1g9st78NA ithaca-ale-house-ithaca
## 3 JlCzPAtL7rA5GdCmyUEPow de-tasty-hot-pot-ithaca-2
## 4 T-n8QFMx2zceV5M_ZKtgIA reds-place-ithaca
## 5 v1zbzBEnZ7odA9oeu25e4A le-cafe-cent-dix-ithaca-2
## 6 uOxHLnePU2wyTqPJ_p7ryw mercato-bar-and-kitchen-ithaca
## 7 BdMKj3rHVnHxZvxe_NCDHA thompson-and-bleecker-ithaca-2
## 8 dycxEZtWSaAv4xDAlidZPw creola-southern-steakhouse-ithaca
## 9 ud9RNk52okJkisfMOAHtyw wings-over-ithaca-ithaca-3
## 10 ntH3yiPIjLyMxYDCfY-UUQ simeons-on-the-commons-ithaca
## name
## <chr>
## 1 Gola Osteria
## 2 Ithaca Ale House
## 3 De Tasty Hot Pot
## 4 Red's Place
## 5 Le Cafe Cent-Dix
## 6 Mercato Bar & Kitchen
## 7 Thompson and Bleecker
## 8 Creola Southern Steakhouse
## 9 Wings Over Ithaca
## 10 Simeon's On The Commons
## image_url
## <chr>
## 1 https://s3-media3.fl.yelpcdn.com/bphoto/HC9v38sBsVMz62uFKy8Y0A/o.jpg
## 2 https://s3-media2.fl.yelpcdn.com/bphoto/1AeybJBqPvyniCGL9sGMmg/o.jpg
## 3 https://s3-media4.fl.yelpcdn.com/bphoto/nbBvObp5AunbyrsP3GqtLA/o.jpg
## 4 https://s3-media2.fl.yelpcdn.com/bphoto/AGjFqTEa3EJzWwCLVkJaTw/o.jpg
## 5 https://s3-media3.fl.yelpcdn.com/bphoto/1OUhGwPRzZLlkwOTaTcjlQ/o.jpg
## 6 https://s3-media4.fl.yelpcdn.com/bphoto/YpkL8iviu0KXMOuKN_FY9Q/o.jpg
## 7 https://s3-media4.fl.yelpcdn.com/bphoto/Ccl2pjXgvKRRxZShz-O8ww/o.jpg
## 8 https://s3-media1.fl.yelpcdn.com/bphoto/iuBG6OD7__XRYmDHVAOADg/o.jpg
## 9 https://s3-media1.fl.yelpcdn.com/bphoto/S2oyB-RhWXDQfT6Hjb7Nxg/o.jpg
## 10 https://s3-media3.fl.yelpcdn.com/bphoto/rzrle6pCS_-gKKjZYFuN9A/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/gola-osteria-ithaca?adjust_creative=NJjwKPgIcFpchzB…
## 2 https://www.yelp.com/biz/ithaca-ale-house-ithaca?adjust_creative=NJjwKPgIcFp…
## 3 https://www.yelp.com/biz/de-tasty-hot-pot-ithaca-2?adjust_creative=NJjwKPgIc…
## 4 https://www.yelp.com/biz/reds-place-ithaca?adjust_creative=NJjwKPgIcFpchzBhk…
## 5 https://www.yelp.com/biz/le-cafe-cent-dix-ithaca-2?adjust_creative=NJjwKPgIc…
## 6 https://www.yelp.com/biz/mercato-bar-and-kitchen-ithaca?adjust_creative=NJjw…
## 7 https://www.yelp.com/biz/thompson-and-bleecker-ithaca-2?adjust_creative=NJjw…
## 8 https://www.yelp.com/biz/creola-southern-steakhouse-ithaca?adjust_creative=N…
## 9 https://www.yelp.com/biz/wings-over-ithaca-ithaca-3?adjust_creative=NJjwKPgI…
## 10 https://www.yelp.com/biz/simeons-on-the-commons-ithaca?adjust_creative=NJjwK…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 169 <df [2 × 2]> 4 42.4 -76.5 <chr [1]>
## 2 586 <df [3 × 2]> 3.9 42.4 -76.5 <chr [1]>
## 3 125 <df [3 × 2]> 3.4 42.4 -76.5 <chr [2]>
## 4 271 <df [2 × 2]> 3.9 42.4 -76.5 <chr [1]>
## 5 120 <df [3 × 2]> 4.6 42.4 -76.5 <chr [1]>
## 6 179 <df [2 × 2]> 4.1 42.4 -76.5 <chr [1]>
## 7 184 <df [3 × 2]> 4.4 42.4 -76.5 <chr [1]>
## 8 43 <df [2 × 2]> 4.3 42.4 -76.5 <chr [1]>
## 9 91 <df [3 × 2]> 3.9 42.4 -76.5 <chr [2]>
## 10 294 <df [3 × 2]> 3.8 42.4 -76.5 <chr [1]>
## price location$address1 $address2 $address3 $city $zip_code $country
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 $$$ 115 South Quarry St "" "" Ithaca 14850 US
## 2 $$ 301 East State St "Ste 1" "" Ithaca 14850 US
## 3 $$ 422 Eddy St "" "" Ithaca 14850 US
## 4 $$ 107 N Aurora St "" "" Ithaca 14850 US
## 5 $$$ 110 N Aurora St <NA> "" Ithaca 14850 US
## 6 $$$ 108 N Aurora St "" "" Ithaca 14850 US
## 7 $$ 211 E Seneca St <NA> "" Ithaca 14850 US
## 8 <NA> 112 N Aurora St "" <NA> Ithaca 14850 US
## 9 $$ 121 Dryden Rd <NA> "" Ithaca 14850 US
## 10 $$ 224 E State St "" "" Ithaca 14850 US
## $state $display_address phone display_phone distance business_hours
## <chr> <list> <chr> <chr> <dbl> <list>
## 1 NY <chr [2]> +16072730333 (607) 273-0333 393. <df [1 × 3]>
## 2 NY <chr [3]> +16072567977 (607) 256-7977 525. <df [1 × 3]>
## 3 NY <chr [2]> +16078212312 (607) 821-2312 231. <df [1 × 3]>
## 4 NY <chr [2]> +16073194486 (607) 319-4486 545. <df [1 × 3]>
## 5 NY <chr [2]> +16073190750 (607) 319-0750 567. <df [1 × 3]>
## 6 NY <chr [2]> +16073195171 (607) 319-5171 577. <df [1 × 3]>
## 7 NY <chr [2]> +16073190851 (607) 319-0851 594. <df [1 × 3]>
## 8 NY <chr [2]> +16072721438 (607) 272-1438 575. <df [1 × 3]>
## 9 NY <chr [2]> +16073194664 (607) 319-4664 237. <df [1 × 3]>
## 10 NY <chr [2]> +16072722212 (607) 272-2212 573. <df [1 × 3]>
## attributes$business_temp_closed $menu_url
## <lgl> <chr>
## 1 NA "https://golaosteria.com/menubkp"
## 2 NA "http://www.ithacaalehouse.com/menu"
## 3 NA "http://www.tastyhotpot.com/menu"
## 4 NA "http://www.redsplaceithaca.com/menu/"
## 5 NA "https://www.lecafecentdix.com/menu"
## 6 NA ""
## 7 NA <NA>
## 8 NA <NA>
## 9 NA "https://www.wingsover.com/menu"
## 10 NA ""
## $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 NA
## 8 NA TRUE
## 9 NA NA
## 10 NA NA
## # ℹ 1,439 more rows
yelp_all2 %>% print(width=1000)
## # A tibble: 103 × 18
## id alias name
## <chr> <chr> <chr>
## 1 jDsvWSwti8oL2qAIWp7noA bools-flower-shop-ithaca Bool's Flower Shop
## 2 UHDpAts-5yibQ1nedxGucA melodia-flowers-ithaca Melodia Flowers
## 3 lUNuOGkS43qKGe_PRtrEJQ willow-floral-studios-no-title Willow Floral Studios
## 4 MFpBoQIK8MkBX9wxyFlUpg best-in-bloom-syracuse-2 Best in Bloom
## 5 UHDpAts-5yibQ1nedxGucA melodia-flowers-ithaca Melodia Flowers
## 6 vXwTHb4ejO5Jm-FEhPjtnw sunny-days-ithaca-2 Sunny Days
## 7 hVTDbmucYcA3hMYvoPWYDA mockingbird-paperie-ithaca Mockingbird Paperie
## 8 jDsvWSwti8oL2qAIWp7noA bools-flower-shop-ithaca Bool's Flower Shop
## 9 RGvfeizEiZgHC4GkFm8I6Q 3-d-light-loose-threads-ithaca 3-D Light-Loose Threads
## 10 b8QWnAKo4EnZpYckAZwS_g ithacamade-ithaca Ithacamade
## image_url
## <chr>
## 1 https://s3-media2.fl.yelpcdn.com/bphoto/Kd4czZCdJsBc1vuyE8MxEg/o.jpg
## 2 https://s3-media1.fl.yelpcdn.com/bphoto/QeByo90bX5ZOPA4Dzs8www/o.jpg
## 3 https://s3-media1.fl.yelpcdn.com/bphoto/nZMB9h0Myb6IF9vpYtVhUA/o.jpg
## 4 https://s3-media2.fl.yelpcdn.com/bphoto/8-WgnUN6BRnSu9ddE8UK3Q/o.jpg
## 5 https://s3-media1.fl.yelpcdn.com/bphoto/QeByo90bX5ZOPA4Dzs8www/o.jpg
## 6 https://s3-media2.fl.yelpcdn.com/bphoto/LsJVRiU5jieaiRVVsZm-Lg/o.jpg
## 7 https://s3-media3.fl.yelpcdn.com/bphoto/L2aznWmRtwrDGJuEIRd9Zw/o.jpg
## 8 https://s3-media2.fl.yelpcdn.com/bphoto/Kd4czZCdJsBc1vuyE8MxEg/o.jpg
## 9 https://s3-media1.fl.yelpcdn.com/bphoto/YfEdV-xQZ8eSaHoqBYQnpw/o.jpg
## 10 https://s3-media2.fl.yelpcdn.com/bphoto/orEte5AdbffixTIXzIZoTg/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/bools-flower-shop-ithaca?adjust_creative=NJjwKPgIcF…
## 2 https://www.yelp.com/biz/melodia-flowers-ithaca?adjust_creative=NJjwKPgIcFpc…
## 3 https://www.yelp.com/biz/willow-floral-studios-no-title?adjust_creative=NJjw…
## 4 https://www.yelp.com/biz/best-in-bloom-syracuse-2?adjust_creative=NJjwKPgIcF…
## 5 https://www.yelp.com/biz/melodia-flowers-ithaca?adjust_creative=NJjwKPgIcFpc…
## 6 https://www.yelp.com/biz/sunny-days-ithaca-2?adjust_creative=NJjwKPgIcFpchzB…
## 7 https://www.yelp.com/biz/mockingbird-paperie-ithaca?adjust_creative=NJjwKPgI…
## 8 https://www.yelp.com/biz/bools-flower-shop-ithaca?adjust_creative=NJjwKPgIcF…
## 9 https://www.yelp.com/biz/3-d-light-loose-threads-ithaca?adjust_creative=NJjw…
## 10 https://www.yelp.com/biz/ithacamade-ithaca?adjust_creative=NJjwKPgIcFpchzBhk…
## review_count categories rating coordinates$latitude $longitude transactions
## <int> <list> <dbl> <dbl> <dbl> <list>
## 1 23 <df [1 × 2]> 4.1 42.4 -76.5 <list [0]>
## 2 0 <df [2 × 2]> 0 42.4 -76.5 <list [0]>
## 3 2 <df [2 × 2]> 5 42.5 -76.5 <list [0]>
## 4 0 <df [1 × 2]> 0 43.1 -76.1 <list [0]>
## 5 0 <df [2 × 2]> 0 42.4 -76.5 <list [0]>
## 6 34 <df [3 × 2]> 4.9 42.4 -76.5 <list [0]>
## 7 15 <df [3 × 2]> 3.8 42.4 -76.5 <list [0]>
## 8 23 <df [1 × 2]> 4.1 42.4 -76.5 <list [0]>
## 9 3 <df [3 × 2]> 4 42.4 -76.5 <list [0]>
## 10 2 <df [3 × 2]> 4 42.4 -76.5 <list [0]>
## price location$address1 $address2 $address3 $city $zip_code $country
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 $$ 209 N Aurora St "" "" Ithaca 14850 US
## 2 <NA> 105 Valley Rd <NA> "" Ithaca 14850 US
## 3 <NA> 2255 N Triphammer Rd <NA> "" Ithaca 14850 US
## 4 <NA> 6181 Thompson Rd "Ste 400L" "" Syracuse 13206 US
## 5 <NA> 105 Valley Rd <NA> "" Ithaca 14850 US
## 6 $$ 171 E State St 100 "" "" Ithaca 14850 US
## 7 $$ 144 E State St "" "" Ithaca 14850 US
## 8 $$ 209 N Aurora St "" "" Ithaca 14850 US
## 9 <NA> 118 The Commons "" "" Ithaca 14850 US
## 10 <NA> 215 N Cayuga St "" "" Ithaca 14850 US
## $state $display_address phone display_phone distance
## <chr> <list> <chr> <chr> <dbl>
## 1 NY <chr [2]> "+16072728410" "(607) 272-8410" 532.
## 2 NY <chr [2]> "+19195970187" "(919) 597-0187" 672.
## 3 NY <chr [2]> "+16073390004" "(607) 339-0004" 6332.
## 4 NY <chr [3]> "+13157410220" "(315) 741-0220" 79110.
## 5 NY <chr [2]> "+19195970187" "(919) 597-0187" 1637.
## 6 NY <chr [2]> "+16073195260" "(607) 319-5260" 150.
## 7 NY <chr [2]> "+16073190556" "(607) 319-0556" 104.
## 8 NY <chr [2]> "+16072728410" "(607) 272-8410" 299.
## 9 NY <chr [2]> "" "" 153.
## 10 NY <chr [2]> "+16072721396" "(607) 272-1396" 128.
## business_hours attributes$business_temp_closed $open24_hours
## <list> <lgl> <lgl>
## 1 <df [1 × 3]> NA NA
## 2 <df [1 × 3]> NA NA
## 3 <df [1 × 3]> NA NA
## 4 <df [1 × 3]> NA NA
## 5 <df [1 × 3]> NA NA
## 6 <df [1 × 3]> NA NA
## 7 <df [1 × 3]> NA NA
## 8 <df [1 × 3]> NA NA
## 9 <df [1 × 3]> NA NA
## 10 <df [1 × 3]> NA NA
## $waitlist_reservation $menu_url
## <lgl> <lgl>
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## 7 NA NA
## 8 NA NA
## 9 NA NA
## 10 NA NA
## # ℹ 93 more rows
Analysis
As noted in the table above, there are 1534 businesses in Ithaca in total. For each category, there are 1449 restaurants and 103 flowers & gifts shops in Ithaca. Based on the map below, most of the popular restaurants and flowers shop cluster in the area between E SENECA ST and E GREEN ST.
# Extract coordinates
yelp_sf1 <- yelp_all1 %>%
mutate(x = .$coordinates$longitude,
y = .$coordinates$latitude) %>%
filter(!is.na(x) & !is.na(y)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326)
yelp_sf2 <- yelp_all2 %>%
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_sf1) +
tm_dots(col = "review_count", palette = "Blues", style = "quantile", size = 0.1, alpha = 0.7, title = "Restaurants Review Count") + # Blue gradient for yelp_sf1
tm_shape(yelp_sf2) +
tm_dots(col = "review_count", palette = "Reds", style = "quantile", size = 0.1, alpha = 0.7, title = "Flowers & Gifts Review Count") + # Red gradient for yelp_sf2
tm_layout(legend.outside = TRUE) # Place legend outside the map
save(yelp_sf1, yelp_sf2, file="mini1_data.RData")