¿Qué es la Inteligencia Locacional (Location Intelligence)? La Inteligencia Locacional es el proceso de analizar datos geoespaciales para obtener información valiosa que ayude a la toma de decisiones estratégicas. Utiliza tecnologías como sistemas de información geográfica (GIS), análisis de big data y herramientas de mapeo para identificar patrones, tendencias y relaciones entre ubicaciones y comportamientos humanos.

¿Cómo contribuye el proceso de análisis de Inteligencia Locacional a la Inteligencia de Negocios? La Inteligencia Locacional aporta un valor significativo a la Inteligencia de Negocios al proporcionar información basada en la ubicación. Esto permite a las empresas optimizar la distribución de recursos, identificar oportunidades de mercado, mejorar la experiencia del cliente y gestionar riesgos. A través del análisis de datos geoespaciales, las organizaciones pueden entender mejor el comportamiento del consumidor, detectar áreas de alta demanda y tomar decisiones informadas sobre expansión o logística.

Brevemente describir qué es la herramienta Análisis de Sentimientos / Sentiment Analysis. ¿Por qué es relevante en el desarrollo de la Inteligencia de Negocios? El Análisis de Sentimientos es una técnica de procesamiento de lenguaje natural (NLP) que permite identificar y clasificar emociones y opiniones expresadas en texto. Se utiliza para evaluar la percepción de los clientes sobre productos, servicios o marcas en redes sociales, reseñas y encuestas. En la Inteligencia de Negocios, el Análisis de Sentimientos es crucial porque ayuda a las empresas a comprender mejor la satisfacción del cliente, anticipar tendencias de mercado y mejorar la toma de decisiones basada en la opinión pública. Esto permite a las organizaciones ajustar estrategias, personalizar campañas y fortalecer su relación con los consumidores.

# Lista de paquetes necesarios
packages <- c("dplyr", "Hmisc", "foreign", "openxlsx", "tidyverse",
              "leaflet.extras", "sp", "sf", "maps", "tmap", "spdep", "terra",
              "leaflet", "mapproj", "mapsapi", "spatialreg", "sfdep",
              "tidygeocoder", "mapboxapi", "ggmap", "rgeoda", "ggplot2",
              "corrplot", "RColorBrewer", "leafsync", "htmltools", "rlang",
              "classInt", "gridExtra", "knitr", "tm", "wordcloud", "wordcloud2",
              "googleway", "gmapsdistance", "osrm", "syuzhet", "SnowballC")

# Instalar y cargar paquetes
for(pkg in packages) {
  if (!require(pkg, character.only = TRUE)) {
    install.packages(pkg)
    library(pkg, character.only = TRUE)
  }
}
## Cargando paquete requerido: dplyr
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## Cargando paquete requerido: Hmisc
## 
## Adjuntando el paquete: 'Hmisc'
## The following objects are masked from 'package:dplyr':
## 
##     src, summarize
## The following objects are masked from 'package:base':
## 
##     format.pval, units
## Cargando paquete requerido: foreign
## Cargando paquete requerido: openxlsx
## Cargando paquete requerido: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.5
## ✔ ggplot2   3.5.1     ✔ stringr   1.5.1
## ✔ lubridate 1.9.4     ✔ tibble    3.2.1
## ✔ purrr     1.0.4     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter()    masks stats::filter()
## ✖ dplyr::lag()       masks stats::lag()
## ✖ Hmisc::src()       masks dplyr::src()
## ✖ Hmisc::summarize() masks dplyr::summarize()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Cargando paquete requerido: leaflet.extras
## 
## Cargando paquete requerido: leaflet
## 
## Cargando paquete requerido: sp
## 
## Cargando paquete requerido: sf
## 
## Linking to GEOS 3.13.0, GDAL 3.10.1, PROJ 9.5.1; sf_use_s2() is TRUE
## 
## Cargando paquete requerido: maps
## 
## 
## Adjuntando el paquete: 'maps'
## 
## 
## The following object is masked from 'package:purrr':
## 
##     map
## 
## 
## Cargando paquete requerido: tmap
## 
## Cargando paquete requerido: spdep
## 
## Cargando paquete requerido: spData
## 
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
## 
## Cargando paquete requerido: terra
## 
## terra 1.8.29
## 
## 
## Adjuntando el paquete: 'terra'
## 
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
## 
## 
## The following objects are masked from 'package:Hmisc':
## 
##     describe, mask, zoom
## 
## 
## Cargando paquete requerido: mapproj
## 
## Cargando paquete requerido: mapsapi
## 
## Cargando paquete requerido: spatialreg
## 
## Cargando paquete requerido: Matrix
## 
## 
## Adjuntando el paquete: 'Matrix'
## 
## 
## The following objects are masked from 'package:tidyr':
## 
##     expand, pack, unpack
## 
## 
## 
## Adjuntando el paquete: 'spatialreg'
## 
## 
## The following objects are masked from 'package:spdep':
## 
##     get.ClusterOption, get.coresOption, get.mcOption,
##     get.VerboseOption, get.ZeroPolicyOption, set.ClusterOption,
##     set.coresOption, set.mcOption, set.VerboseOption,
##     set.ZeroPolicyOption
## 
## 
## Cargando paquete requerido: sfdep
## 
## Cargando paquete requerido: tidygeocoder
## 
## Cargando paquete requerido: mapboxapi
## 
## Usage of the Mapbox APIs is governed by the Mapbox Terms of Service.
## Please visit https://www.mapbox.com/legal/tos/ for more information.
## 
## Cargando paquete requerido: ggmap
## 
## ℹ Google's Terms of Service: <https://mapsplatform.google.com>
##   Stadia Maps' Terms of Service: <https://stadiamaps.com/terms-of-service/>
##   OpenStreetMap's Tile Usage Policy: <https://operations.osmfoundation.org/policies/tiles/>
## ℹ Please cite ggmap if you use it! Use `citation("ggmap")` for details.
## 
## Adjuntando el paquete: 'ggmap'
## 
## 
## The following object is masked from 'package:tidygeocoder':
## 
##     geocode
## 
## 
## The following object is masked from 'package:terra':
## 
##     inset
## 
## 
## Cargando paquete requerido: rgeoda
## 
## Cargando paquete requerido: digest
## 
## 
## Adjuntando el paquete: 'rgeoda'
## 
## 
## The following objects are masked from 'package:sfdep':
## 
##     local_g, local_gstar, local_moran
## 
## 
## The following object is masked from 'package:spdep':
## 
##     skater
## 
## 
## Cargando paquete requerido: corrplot
## 
## corrplot 0.95 loaded
## 
## Cargando paquete requerido: RColorBrewer
## 
## Cargando paquete requerido: leafsync
## 
## Cargando paquete requerido: htmltools
## 
## Cargando paquete requerido: rlang
## 
## 
## Adjuntando el paquete: 'rlang'
## 
## 
## The following objects are masked from 'package:purrr':
## 
##     %@%, flatten, flatten_chr, flatten_dbl, flatten_int, flatten_lgl,
##     flatten_raw, invoke, splice
## 
## 
## Cargando paquete requerido: classInt
## 
## Cargando paquete requerido: gridExtra
## 
## 
## Adjuntando el paquete: 'gridExtra'
## 
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
## 
## 
## Cargando paquete requerido: knitr
## 
## 
## Adjuntando el paquete: 'knitr'
## 
## 
## The following object is masked from 'package:terra':
## 
##     spin
## 
## 
## Cargando paquete requerido: tm
## 
## Cargando paquete requerido: NLP
## 
## 
## Adjuntando el paquete: 'NLP'
## 
## 
## The following object is masked from 'package:terra':
## 
##     meta
## 
## 
## The following object is masked from 'package:ggplot2':
## 
##     annotate
## 
## 
## Cargando paquete requerido: wordcloud
## 
## Cargando paquete requerido: wordcloud2
## 
## Cargando paquete requerido: googleway
## 
## Cargando paquete requerido: gmapsdistance
## 
## Cargando paquete requerido: osrm
## 
## Data: (c) OpenStreetMap contributors, ODbL 1.0 - http://www.openstreetmap.org/copyright
## 
## Routing: OSRM - http://project-osrm.org/
## 
## Cargando paquete requerido: syuzhet
## 
## 
## Adjuntando el paquete: 'syuzhet'
## 
## 
## The following object is masked from 'package:terra':
## 
##     rescale
## 
## 
## Cargando paquete requerido: SnowballC
# data analysis 
library(dplyr)            # grammar of data manipulation helping to resolve data manipulation difficulties 
library(Hmisc)            # useful functions for data analysis and high - level graphics
library(foreign)          # read data stored by Minitab, SPSS, Stata
library(openxlsx)         # open, read, write, and edit xlsx files 
library(tidyverse)        # collection of R packages designed for data science

# spatial data analysis 
library(leaflet.extras)   # provides extra functionality to the leaflet R package
library(sp)               # functions for plotting data as maps, spatial selection, methods for retrieving coordinates 
library(sf)               # encode spatial vector data 
library(maps)             # geographic maps
library(tmap)             # generate thematic maps
library(spdep)            # functions to create spatial weights matrices from polygon contiguities
library(terra)            # methods for spatial data analysis 
library(leaflet)          # interactive maps
library(mapproj)          # map projections 
library(mapsapi)          # (additional maps API functions)
library(spatialreg)       # spatial regression models 
library(sfdep)            # interface to 'spdep' for integrating with 'sf' objects and the 'tidyverse'
library(tidygeocoder)     # simplifies getting data from geocoding services
library(mapboxapi)        # Mapbox Navigation APIs (directions, isochrones, route optimization)

# visualization 
library(ggmap)            # spatial data visualization 
library(rgeoda)           # spatial data analysis based on GeoDa software
library(ggplot2)          # Grammar of graphics. Declarative system for creating graphics
library(corrplot)         # visual tool for exploring correlation matrices
library(RColorBrewer)     # offers several color palettes
library(leafsync)         # create small multiples of several leaflet web maps
library(htmltools)        # tools for HTML generation and output 

# others 
library(rlang)            # frameworks and APIs for programming with R
library(classInt)         # methods for choosing univariate class intervals for mapping or other graphic purposes
library(gridExtra)        # to arrange and combine plots for easy comparison
library(knitr)            # integrates computing and reporting

# Getting access to distance, reviews, and ratings by using Google Maps
library(tm)               # text mining framework
library(wordcloud)        # functionality to create word clouds
library(wordcloud2)       # additional word cloud features
library(googleway)        # access various Google Maps APIs (maps, places, directions, etc.)
library(gmapsdistance)    # calculate distances through Google Maps
# library(hereR)          # geocode and autocomplete addresses or reverse geocode POIs (comentado)
library(osrm)             # compute routes, trips, isochrones, and travel distance matrices

# Text Mining
library(tm)         # text mining functions 
library(syuzhet)    # sentiment analysis using multiple dictionaries
library(SnowballC)  # text stemming functionality
library(wordcloud)  # (ya cargado anteriormente, pero se incluye para asegurar su disponibilidad)
library(wordcloud2) # (ya cargado anteriormente)

Libraries

### LOADING REQUIRED LIBRARIES 
# data analysis 
library(dplyr)            # grammar of data manipulation helping to resolve data manipulation difficulties 
library(Hmisc)            # useful functions for data analysis and high - level graphics
library(foreign)          # read data stored by Minitab, SPSS, Stata
library(openxlsx)         # open, read, write,and edit xlsx files 
library(tidyverse)        # collection of R packages designed for data science

# spatial data analysis 
library(leaflet.extras)   # to provide extra functionality to the leaflet R package
library(sp)               # functions for plotting data as maps, spatial selection, methods for retrieving coordinates 
library(sf)               # encode spatial vector data 
library(maps)             # geographic maps
library(tmap)             # generate thematic maps
library(spdep)            # a collection of functions to create spatial weights matrices from polygon contiguities
library(terra)            # methods for spatial data analysis 
library(leaflet)          # interactive maps
library(mapproj)          # map projections 
library(mapsapi)          # 
library(spatialreg)       # spatial regression models 
library(sfdep)            # an interface to 'spdep' to integrate with 'sf' objects and the 'tidyverse
library(tidygeocoder)     # makes getting data from geocoding services easy
library(mapboxapi)        # 'Mapbox' Navigation APIs, including directions, isochrones, and route optimization.

# visualization 
library(ggmap)            # spatial data visualization 
library(rgeoda)           # spatial data analysis based on software GeoDa
library(ggplot2)          # Grammar of graphics. System for declarative creating graphics
library(corrplot)         # provides a visual exploratory tool on correlation matrix
library(RColorBrewer)     # offers several color palettes
library(leafsync)         # create small multiples of several leaflet web maps
library(htmltools)        # tools for HTML generation and output 

# others 
library(rlang)            # collection of frameworks and APIs for programming with R
library(classInt)         # methods for choosing univariate class intervals for mapping or other graphic purposes
library(gridExtra)        # to arrange and combine plots for easy comparison
library(knitr)            # integrates computing and reporting

### Getting access to distance, reviews, and ratings by using Google Maps
library(tm)               # a framework for text mining applications
library(wordcloud)        # functionality to create pretty word clouds
library(wordcloud2)       # 
library(googleway)        # provides a mechanism to access various Google Maps APIs, including plotting a Google Map from R and overlaying it with shapes and markers, and retrieving data from the places, directions, roads, distances, geocoding, elevation and timezone APIs
library(gmapsdistance)    # allows to calculate distances for a database through Google maps
# library(hereR)          # geocode and autocomplete addresses or reverse geocode POIs using the Geocoder API
library(osrm)             # enables the computation of routes, trips, isochrones and travel distances matrices (travel time and kilometric distance).

### Text Mining
library(tm)         # text mining functions 
library(syuzhet)    # includes four sentiment dictionaries and provides a method for accessing the robust, but computationally expensive, sentiment extraction tool developed in the NLP group at Stanford.
library(SnowballC)
library(wordcloud)
library(wordcloud2)

# library(remotes)
# library(openrouteservice)
# remotes::install_github("GIScience/openrouteservice-r")

GOOGLE MAPS API KEY

Monterrey Restaurant Mapping

# Coordenadas de la zona (por ejemplo, una zona representativa en Monterrey)
latitude  <- 25.649400508114578
longitude <- -100.35583498127765
r <- 8000  # Radio de búsqueda en metros
### Map coordinates of Arboleda (Starting Point)
rest_map <- leaflet() %>% 
  addTiles() %>% 
  setView(lng = longitude, lat = latitude, zoom = 14) %>% 
  addMarkers(lng = longitude, lat = latitude, popup = "Zona de Restaurantes")
rest_map
### Use the google_places function to make a call to the API and save the results
# Realizar búsqueda de "restaurantes" en la zona
search_str <- google_places(search_string = 'restaurantes', 
                            location = c(latitude, longitude), 
                            radius = r, key = gmaps_key)

# Solicitar resultados adicionales (paginación)
search_str_add_one <- google_places(search_string = 'restaurantes', 
                                    location = c(latitude, longitude), 
                                    radius = r, key = gmaps_key, 
                                    page_token = search_str$next_page_token)

search_str_add_two <- google_places(search_string = 'restaurantes', 
                                    location = c(latitude, longitude), 
                                    radius = r, key = gmaps_key, 
                                    page_token = search_str_add_one$next_page_token)
search_str$results
##    business_status
## 1      OPERATIONAL
## 2      OPERATIONAL
## 3      OPERATIONAL
## 4      OPERATIONAL
## 5      OPERATIONAL
## 6      OPERATIONAL
## 7      OPERATIONAL
## 8      OPERATIONAL
## 9      OPERATIONAL
## 10     OPERATIONAL
## 11     OPERATIONAL
## 12     OPERATIONAL
## 13     OPERATIONAL
## 14     OPERATIONAL
## 15     OPERATIONAL
## 16     OPERATIONAL
## 17     OPERATIONAL
## 18     OPERATIONAL
## 19     OPERATIONAL
## 20     OPERATIONAL
##                                                                                           formatted_address
## 1                        Av. del Roble 670, Valle del Campestre, 66273 San Pedro Garza García, N.L., Mexico
## 2                   Av Lázaro Cárdenas 2660, Zona Valle Oriente, 66266 San Pedro Garza García, N.L., Mexico
## 3                                      C. Pablo A. de La Garza 3000, Moderna, 64530 Monterrey, N.L., Mexico
## 4                                                 Melchor Ocampo 443, Centro, 64000 Monterrey, N.L., Mexico
## 5                              Av. Humberto Lobo 520, Del Valle, 66220 San Pedro Garza García, N.L., Mexico
## 6          Av. del Roble 680-Interior W209, Valle del Campestre, 66265 San Pedro Garza García, N.L., Mexico
## 7                             Av. Ricardo Margain Zozaya 102, Santa Engracia, 66267 Monterrey, N.L., Mexico
## 8                                            Juan Ignacio Ramón 1102, Centro, 64000 Monterrey, N.L., Mexico
## 9                        Av. José Vasconcelos 150 PB, Del Valle, 66220 San Pedro Garza García, N.L., Mexico
## 10                       Paseo de los Leones 2817, Cumbres 4º. Sector Secc a, 64610 Monterrey, N.L., Mexico
## 11                                    C. Diego de Montemayor 507 Sur, Centro, 64000 Monterrey, N.L., Mexico
## 12 Av. Manuel Gómez Morín 911, Comercial Gómez Morin, Del Valle, 66220 San Pedro Garza García, N.L., Mexico
## 13                      Calz. del Valle 333, Rooftop, Del Valle, 66220 San Pedro Garza García, N.L., Mexico
## 14                       Paseo de los Leones 2205, Cumbres 2o. Sector Secc C, 64610 Monterrey, N.L., Mexico
## 15          Av. Ricardo Margain Zozaya 315, Zona Santa Engracia, 66263 San Pedro Garza García, N.L., Mexico
## 16                      Av. Cto. Frida Kahlo 303, Valle Oriente, 66260 San Pedro Garza García, N.L., Mexico
## 17                   Av. Humberto Lobo 520, Zona Los Callejones, 66228 San Pedro Garza García, N.L., Mexico
## 18                                                Constitución 1257, Mirador, 64070 Monterrey, N.L., Mexico
## 19                                          C. Julián Villagrán 1010, Centro, 64000 Monterrey, N.L., Mexico
## 20                        Eje Metropolitano 10 2400, Zona Loma Larga Oriente, 66278 Monterrey, N.L., Mexico
##    geometry.location.lat geometry.location.lng geometry.viewport.northeast.lat
## 1               25.64986             -100.3553                        25.65129
## 2               25.64725             -100.3272                        25.64867
## 3               25.70205             -100.2873                        25.70341
## 4               25.66580             -100.3127                        25.66719
## 5               25.66440             -100.3836                        25.66568
## 6               25.64975             -100.3566                        25.65122
## 7               25.65861             -100.3525                        25.65996
## 8               25.67015             -100.3048                        25.67152
## 9               25.65137             -100.3681                        25.65272
## 10              25.71869             -100.3851                        25.71998
## 11              25.67129             -100.3059                        25.67265
## 12              25.64871             -100.3605                        25.64997
## 13              25.65544             -100.3623                        25.65670
## 14              25.70856             -100.3732                        25.70987
## 15              25.65296             -100.3525                        25.65410
## 16              25.64530             -100.3223                        25.64651
## 17              25.66385             -100.3834                        25.66515
## 18              25.66804             -100.3329                        25.66927
## 19              25.68549             -100.3219                        25.68684
## 20              25.65053             -100.3337                        25.65195
##    geometry.viewport.northeast.lng geometry.viewport.southwest.lat
## 1                        -100.3540                        25.64859
## 2                        -100.3258                        25.64597
## 3                        -100.2860                        25.70071
## 4                        -100.3113                        25.66449
## 5                        -100.3820                        25.66298
## 6                        -100.3553                        25.64852
## 7                        -100.3512                        25.65726
## 8                        -100.3035                        25.66882
## 9                        -100.3668                        25.65002
## 10                       -100.3838                        25.71728
## 11                       -100.3046                        25.66995
## 12                       -100.3591                        25.64727
## 13                       -100.3609                        25.65400
## 14                       -100.3719                        25.70717
## 15                       -100.3511                        25.65140
## 16                       -100.3210                        25.64381
## 17                       -100.3819                        25.66245
## 18                       -100.3316                        25.66657
## 19                       -100.3205                        25.68414
## 20                       -100.3324                        25.64925
##    geometry.viewport.southwest.lng
## 1                        -100.3567
## 2                        -100.3285
## 3                        -100.2887
## 4                        -100.3140
## 5                        -100.3847
## 6                        -100.3580
## 7                        -100.3539
## 8                        -100.3062
## 9                        -100.3695
## 10                       -100.3865
## 11                       -100.3073
## 12                       -100.3618
## 13                       -100.3636
## 14                       -100.3746
## 15                       -100.3538
## 16                       -100.3237
## 17                       -100.3846
## 18                       -100.3343
## 19                       -100.3232
## 20                       -100.3351
##                                                                             icon
## 1  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 2  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 3  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 4  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 5  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 6  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 7  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 8  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 9  https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 10 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 11 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 12 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 13 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 14 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 15 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 16 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 17 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 18 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 19 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
## 20 https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png
##    icon_background_color
## 1                #FF9E67
## 2                #FF9E67
## 3                #FF9E67
## 4                #FF9E67
## 5                #FF9E67
## 6                #FF9E67
## 7                #FF9E67
## 8                #FF9E67
## 9                #FF9E67
## 10               #FF9E67
## 11               #FF9E67
## 12               #FF9E67
## 13               #FF9E67
## 14               #FF9E67
## 15               #FF9E67
## 16               #FF9E67
## 17               #FF9E67
## 18               #FF9E67
## 19               #FF9E67
## 20               #FF9E67
##                                                        icon_mask_base_uri
## 1  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 2  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 3  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 4  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 5  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 6  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 7  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 8  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 9  https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 10 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 11 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 12 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 13 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 14 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 15 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 16 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 17 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 18 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 19 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
## 20 https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet
##                                     name open_now
## 1                Orfebre Cocina Artesana     TRUE
## 2         Los Hidalgos | Lázaro Cárdenas     TRUE
## 3         Los Primos Restaurante Moderna     TRUE
## 4              Restaurant Los Barandales     TRUE
## 5          EMILIANO RESTAURANTE DE ÉPOCA     TRUE
## 6                             Cantinetta     TRUE
## 7                        La Divina Valle     TRUE
## 8  The Tavern - Restaurant & Board Games     TRUE
## 9                            Mar del Zur     TRUE
## 10                  Patio 11 Restaurante     TRUE
## 11                             La Divina     TRUE
## 12               Mon Paris - Gomez Morin     TRUE
## 13                        Animal Calzada     TRUE
## 14              Restaurante Los Pioneros     TRUE
## 15                          Indio Azteca     TRUE
## 16                             Vernáculo     TRUE
## 17                             Avenida 9     TRUE
## 18                   MIRADOR RESTAURANTE     TRUE
## 19                  Restaurante Callitos     TRUE
## 20                        Lázaro & Diego     TRUE
##                                                                                                                                                                                                                                                                                                                                                                                                                                     photos
## 1           4032, <a href="https://maps.google.com/maps/contrib/116849421231227222416">Leonardo Curioni</a>, AUy1YQ3YKdYWHbo_nz08tIi1D9t6rOC91AHifffEdDWFkLmS-15ZMtsZe4pJq-R157-0juErqVjiskNYACjzxs16ZZ1n76tjZKeV5fuibNd0hLzAWhez7RKezSu6vN1L-8MMBQZ_QzLfp7edrqlM_6gcULfY4sY5iASTBGHc4pz5-flvqw-GYItubQoIiY6O3L4C7aKoQzlWdFHPIp55EZ2RxE5Vzma_p0za_quegVv3yjfjSCF-zhPVvlDKtdWutjDoRTd9wFQhoqpzJTi7nYzg2jDVHpDwpszpXVRbfwNwuK9JWE13h_Y, 3024
## 2              3456, <a href="https://maps.google.com/maps/contrib/101999339273141371558">Pablo Zimbrón</a>, AUy1YQ303y8FEPk1ThauhtCLLwg2qEjA4eYjjVbYaHMH9YVx8dg5Y3HftSAvOiZyEF27vKHpycr9y0JJj6B1Qcw4DFI_8zVgzgVQ8AdF5AOzmjwNZqf99Z0CCF90mjng6UtCNDp36uSHaUfXmp88JgLh5IeXLDlaKQpQJeXTX6Od9VB8Q0lDo0diXcnYl9Op_E58Dndzo--H7pnxc9Lh1ojuEc_cQRDKYne1zR1vCJvBWLpHJM-crB-ba94Dk7USheNnFgjoK3_oabh2fcwFoJ-kQCe3rteOU6YySj22loejkmGed26GoIU, 5184
## 3         1068, <a href="https://maps.google.com/maps/contrib/114968736378910760549">Alonso Torres Díaz</a>, AUy1YQ00y_9RQtqO8vLZk05acgAe4YWhF8rzn6TRH-V5QJnVCqJ_aLLpeo3DnObBchAzVjU2KrE-bDUo8oI4_MTG-UasnU8S9ImEwAWMsuXYzwLKs7EVBBtInO8lXv-P2WPH3uBrms4AEwyR_xKY0Jt-9a1-aisDBEHPIIK_eZgD7eVP3WZW4vmHRaBVP1YmFuP5mNol9foca6V8YzXjvVM9j-WZLEyhSsZglA9-y-O9bwxG963wvDfNgUnIhqEA3WwDwqniMQ_r-d6Kc1qylwvlRK-0sSPBhrgUq1MI_dY2vdTjjfvB6c8, 1900
## 4          3264, <a href="https://maps.google.com/maps/contrib/118364960074005433206">Ezequiel Merecías</a>, AUy1YQ1RSH-ucIjsD84CYI0S3qDCuvxcpXfc-mMKPEZQmD_hgUqlYTkauGMh9WpVvH7dAcYhYx5y0rPUg8-o1Xu0yyFjngyWf29ec0vrZQF_yHyZC7MMYuPBnVZmRzz5gBPApKnH7HNzLKRCFxN1Q-PjhDJMse-O86vm8g-foS19F4J8MLZpFee9vHZ_V6py-0Zk-MmEhPcohcNh1OYzZwGOmUtZNptmqgAKEn3JA1kYZgq4xANK9D2V2Lw9KbnrRE7FJO4KlPjFCeovFXHWG6PAVuziy9KuTL2qIQZgGzLWseaIXcR3yw0, 1836
## 5            4096, <a href="https://maps.google.com/maps/contrib/102599918232929821240">Jonathan Zarate</a>, AUy1YQ0dk7-6OKrKVtLQAw18aAlwUZMpnwopTrUa2oG7TMb35R4inql4dWTjXzRIsNA_Eg9KQoLrSPPodaKnel3IGhfosLnLfYVg-THw2kA-O-8XvcGpseODQzNlo8wAyY9xNLXp66-Ao0imA8pfshtb4XQFDGc8lPjaZ9VT2OlvWXLu-kWJNsK3jd8g7m349Z99Ng38D3NHeshk0SwuSRI0l1yfVwh8zlomDTzdlXGF0SMfc6BCGv-Aqmu7ystV1oG5ULVCvVd1oez-f_bIHMqgcHpNUijPCEbamAaoNgclA2sNVtBKy44, 3072
## 6                     3024, <a href="https://maps.google.com/maps/contrib/108057960730769133075">허성율</a>, AUy1YQ1VhKUzHbM8XrBefx1zwFhcv_UplFbb2ZVx9JOzJhJr498EzAL6gO_YqEzC0Y0bvzK4Ur-MCFzRz557VpD6Jp-Q9hkB5ZyR3mfPFiNN0e9Qbz13tTeKtj8b7v-BAe8QYQjtnPssxkhw2Odsq1uRn0M1fZtGgrswMFnN7nmpXMTBicqCCr5GYU9tjauhz0pzJEIsA_YYkpvYu21lQshFzsiBNEu-Av6ue9ZRtQHBOd3ETdXRSeyf_Zs_CPf8jPqxJl96Iq_54L3qGs33w1NetMFXDN9TYdxcwdYBAjEH709OzgP1qx4, 4032
## 7  2268, <a href="https://maps.google.com/maps/contrib/107501696660074999107">Erick Alejandro Alejandro</a>, AUy1YQ0ZPyo8Q_5fEfXYNiBlV3UmfT66GfoVZ0aw6RPnHT4ujuNU0d9yAzZZDMiJi5bZUZP5MTe2NlibpDCGYLG76hWxKjSLfC22SlfXaMfTjEz9tbWimyzZWASgbQni9zIUF0RlSnhRH2UT4IFD6-EIYVUxHq5dFkGI6aS4GxbxNGj_mR6QEHoaTCRg9geV5UkivuRMwm04tx9RHUKZU_5rF0zyL-XW0WNCU_yuqxKI6wz5dCkV_uxA0_EX-ZD_2PDPeZoHHn-mxe1IilTCgTww4mUV_XtH_sDnd28H4aLgaI2l-kfl4Jw, 4032
## 8                  3024, <a href="https://maps.google.com/maps/contrib/114938977417218940201">Vanessa M</a>, AUy1YQ20-Xru1HdlB7Id9M7cmnxOtk9OnrQBdCogCBg_809nhnQTmdv5w3aNK2-fN31JMd0LDpzVhnmPpkY3cu5ul5k2543HUrZdt8476jqZL1b3kxlMns_qrbvWeRvforyQ5HuQ9JI6glz4wSCnB3kGvtr_dKsO07FcR4tRJQehgG5A566aQM0WG_Pg_NcPUmxdmYTMq1h1ZHwPOqUoEGsfzZC2uk65VqcD1QGC5ML51KiTp4WEyVeHeJA1i6Db7ujTeSh0AYaXiNh6d8YQjW2AceyJ9Z9di9yuwsvwmIedKTbre5jko1E, 4032
## 9                1365, <a href="https://maps.google.com/maps/contrib/112352434945156253351">Mar del Zur</a>, AUy1YQ1K9xQpZpxOFXiURP5PBgBr2GRqg4nhBNQ949ie9APnkjfIGCyZ7efmrkhAyKW2lKCtUMlfdgKJhtlbxQkgfrfa1nzJzTgmAvdgO-XHFfsEfs8pg5jME-AUGRZ4tzyhUjs9T4rKsfg0_1Kg1LTTFGTCPxIKscbQBFjENV-0pSjbg2MoPErxkrLa-TCjZzPGSC9DVVRR6dDC_Ql3IrS0xcZ4yyfPDohBYFmTQ7OsX_OWfxkg5_YhfRWCnn5Xdl1fI5gEPue10QzHYCTgc1_fcfBFK97AycAl42bfyz0iphRYwjNeplk, 2048
## 10             4000, <a href="https://maps.google.com/maps/contrib/102368428107852075593">A Google User</a>, AUy1YQ1QOsKmUl-K2scVh5W4g9vJMGq2ESlQ9FM8uIGtD0IU_KQN4p25zQvWbITPl9asANGih3AxOSgfWRFMjjdwT9hZQXyrsi0ox_8qOe4gL82aUwJuhzbl4bLa8WChkTtkdoAAh2PXynjg7ZSTqAjuryynkL_3A3DPS-cgyiTS9bARfebESlgQIDneUSAd0e3v62lnTozZ5qCdXVqwkJ6HzgbJeRY2O9-FOPPElTY1vl7haPhG5B2vw1a75SPVfoR4NBXa-_vU5IRqbQ4Jbhj5xDPb2hYNI67tItl8U6d9uqbrz_MtJvM, 3000
## 11                   387, <a href="https://maps.google.com/maps/contrib/116130299634293376168">La Divina</a>, AUy1YQ0-zrIIsRk8VpGHsbOh7yaGelfCmN4_1wbmZFACQFaNG6m_S1taMgDAZfUdXJAJYEzWWVy0kpRFTu95Y08WPQfsOVuozCgSE_ppndhZKN-00c65Gh5vacUsDHGjxXKCbUp01YXWlgf_ZYwihomH6ZrQPqu6evCLTAUuNIbEWAuQEs99WrWVHwKwltTWr3z0damhHEDsR3vGW7NY7_ty7rWXCfMn3H0ClpJSMw_lxjd0dRNhIMHjBklzhdPJ00IZVJmQahsdQE-wNI-TvKZsPLTyh4rQfmV46m9QrU5zgsERjKiU5Vk, 580
## 12        4032, <a href="https://maps.google.com/maps/contrib/115138663888560122638">Addiel Cesar Amaro</a>, AUy1YQ3Im0qQBmJJOBvtWpPCiOiTuKo9lbaZ4srE5xqv_VBYwC0h8cOZeoITB5Ws2ZNaXJQu_UCfIzAFPoahzjTFsYSMjuenwAlo8nnCsYAD1ehQ6RPSNyvwfcSxeJCI5eFyTTwQcmlTLoCTvjMWPx25Rcd00aVTD4CerPybhxD90pTFJY9EsdfW7e5racRQglJ4X4ckoFDwhaG-8ELYBcgMx-JD3-fryc-wS1bkiOdRfgA5UrLMz54N4shUspWdwErOx9kho0BTLv4Uu39ZnQNEFHbquZV8mbnatmoKxiNSB0d9RQbmBXM, 3024
## 13             3455, <a href="https://maps.google.com/maps/contrib/104011797007073881764">A Google User</a>, AUy1YQ3hNfuOGreBxlPHUONVMIdZDd94XkWjV-4eRG36fO00hK0e1Pj8b5ASlJHWEAylX49KMAjx5ykD0zQAXMRoZuzD33rL80n9kVba18kK274Z7830Hzi68uoIR6TGNjICdgoUw3vSjZUGeDo-CFl4Bgi_ptQgld6eN0AdmCedydpFHVHRJzJj9wRlJMKL0ZgFqPheaYl0dxwz_IH-uqIFBlsa2KvwJC3_hfYPGAt8dMb27TZEMpJrpz9Poz60ZozOM04QM-nbcouKMelGyZ28JMRblXsQNNS5jgFle6OBQ8yZRRPDLOU, 5183
## 14               2988, <a href="https://maps.google.com/maps/contrib/117114363362812456421">Gael Tobias</a>, AUy1YQ35rBR9EE94_TBRBZ58A0z1hWzlMrpv67Je1lVs8ZLIdKRyqe3OIOgq2ktkZhuA_EVb54bCO2iRz_BJzvPNPgaWxdmRMFqm-76FIsZSwASlQeJHFPFR-qzvu6lvVs075-A30jspUQN7-QUI1Vn0HO1NgW0FooTaxyvqM7Unt2ETYypY77hWb3mibZ6x4qzuRJVwKhi5EWicCxk3lMlqCw9qBvbSgKyatPfSxRsRnCbW8iJCrGIjwFxMCWaMxwE2uJcPWkDk7XDBcx4hK7cNCkR5YFDk4lUuiRsvwPm663QhI8UtJtU, 5312
## 15                3840, <a href="https://maps.google.com/maps/contrib/107475683784640998813">A Google User</a>, AUy1YQ3RdjSPBZAOeICS-jHxn4dWRyKobHonFJ0FXGmd2v54azQeSN0RHppWp3F4B4uS8HBzu78rrWqiEAe5PcaRTR4tCK_MUfWjU0ICDRfjlYP8xqmACXPMHlVM7paJSdrjIGAEA_1q5ies5ibVHc3k97pu0j3KLx12LJmTLtsaMtT2TNJTCQaBbcQ56eBQ9FGOQ2TLjUvVDuP2ZQUtqwEr-KfiEHUOvpOBuTInf2T1080mzqlHWR_kAchwpFxUX3GV3dBtlF6xdb0GUw2fuOSju2uoQ7cCiqd_4ElqbAespBySzFid, 5760
## 16  3024, <a href="https://maps.google.com/maps/contrib/102647107908871038430">alejandro perez Arellano</a>, AUy1YQ1Esgq1GW-T0E7LaobtFoJYRk9xynRiNlHg0t4pwNl7LPTgfcHURmqT2hlHMstqBFkL3foxWWPmeDYs9rICW_3RZYZucdsGfdGSH25yvYxeR2zeptK8aZ-kUjlXAztrisusAvCd-QTvW3PRbH50DNIQqDMng_lWxO54bUsfqnrkKG6s7MN-nRic0g7MKMWX3nJcswDrBSl0b2RMSvGiYJdmU9SB7V7pd6ebTDT_PKAP_C5Ebq8CNcvjxjlyQ2RMxtZsrcEQVTSAD_9b8ud9TR9ElEzMg5nNc9f50ggqeV93LQ20HN0, 4032
## 17           3096, <a href="https://maps.google.com/maps/contrib/107806876957816284815">Mario Estupiñan</a>, AUy1YQ0KITI-62rLutKnwvrkgIfBMmbGmstf2iKTQwofpX1UGQldPKrN5fIwV3tqyi-f8ynFfqM2tzHycyyRL4R1fPtZvs70Mir84s1dJOiWOfiyvPyUca0TNIKnjLsk2eN4L-eTe0RAbGtCSggG8KUF8-A1HNaUeHh_ilRqSx8vNU2bPuyQc7eu3x851yLVFGBOaf8fUaQSHxUji3bcjpDi6PuJiz0DFSyqnNdHPKP189JkTI8-5AE15Z5-aed1y29CddwQmJXXs7LaNNFJ-295Nf71FkTy8KthcT9-uI9FNyeNmZN6x8g, 4128
## 18 3024, <a href="https://maps.google.com/maps/contrib/117199000604440533614">Diego Rodríguez Renovales</a>, AUy1YQ2FOlPZ3nzZcMsCxqRmBfk_bxbUq7hVoFqpt-ow8FNElTRV-kiSdZB6BqvEaZajnLGQaFz4V72tWIT87f3gwKBsYgPko4ZN1PuZTYEH2Vj6yJ46RGsF2iEkWtPG8gwKiEL2Snnj97wcKFSFj7dKL7rk8wGVaqvv_ScuEe5t9U0_PcxWWufeFiibH10ZlIdgCM6H2DWXRMtAiOmcOTRpc_j4zxBSMtIiuJEV8R-hMsN8jVxXlTtk7q_Tc7oDDtmM-4pqtXZpuhSziQ6IU2LWP4ACQYdlhOSyA0EUB5PrQiU0KwqJdyw, 4032
## 19             3024, <a href="https://maps.google.com/maps/contrib/100405151713438318480">alan villalon</a>, AUy1YQ2QkAZYABS9KXNT2XkWEYnihxRrG96aIg_uc4-aWjyaba0Zyk5b0AY9e0ToZzbfK_pDnqllAmuuxyhyf9tjjmRriSNmpVVhxnnCf4_YDteBnUdq3VIpyeps_5xYy3-H1Byrguy5UhWZsfJd6cPsN18JN6ccha00qRPJyH5gLw7MOktvqKRTxPRu4ohXKt4H-mJZDh3u02oMT34j0v-9CEiqrsvpYYEemGfXl_uRZfs7X9He9ivFMVRrOziD65qqT-05iVztI-4b-6Ry8AfD3jYNpy5w_83_ZHpF1O1akQt7yyf4alE, 4032
## 20     9000, <a href="https://maps.google.com/maps/contrib/108328153919985771955">Daniela Botero Ramos</a>, AUy1YQ3YErYxGBW6CpVhptmKFujdHKN7jG_4NF-rFifEWB3ND3uguoAFYR-Rz6DyaWLqH3sJxCyT99OVmYOAK2TeNfDmK-XnzshkJ1zJZ7ti_KX4V4Ekp24DHnQX3ys1kM5EUGXWlZ86nE59EPdGEX_zQDd9AJFF_H0-O4XpPRoT5pQ8u8ctzQDPjCJcENtu8U4DnEGL1ae0wXQLqrctggHe3ZyG7SLKXYL0NEkfLG5cl2zjpz2143CGIfgB6Wpelk2SBAsA-UlIhEdvux1QpyxALfnKdLFosfvTmftzJe39lP3DJcVp-L8, 12000
##                       place_id                    plus_code.compound_code
## 1  ChIJ4dnUvJC9YoYR34PKM6Icy4s JJXV+WV San Pedro Garza García, Nuevo Leon
## 2  ChIJpTfU0EG-YoYRhajF5St9JHM JMWF+V4 San Pedro Garza García, Nuevo Leon
## 3  ChIJL6boF0qVYoYR4r3v00AAgBM              PP27+R2 Monterrey, Nuevo Leon
## 4  ChIJD9BSVy6-YoYRjM8nKTkxfY8              MM8P+CW Monterrey, Nuevo Leon
## 5  ChIJ5_DEYV29YoYRzD4S08H5Cck MJ78+QH San Pedro Garza García, Nuevo Leon
## 6  ChIJVTUMOVe9YoYRARG7lnER_rw JJXV+W8 San Pedro Garza García, Nuevo Leon
## 7  ChIJBS-b4eK9YoYReSW9Sirm2Dc              MJ5X+C2 Monterrey, Nuevo Leon
## 8  ChIJZdCO6Me_YoYRH1tFVoLcZbs              MMCW+33 Monterrey, Nuevo Leon
## 9  ChIJGe_Dzuu9YoYRP6kugxKGW2Y MJ2J+GQ San Pedro Garza García, Nuevo Leon
## 10 ChIJ8z8JzLaXYoYR1o1dfh3IzEo              PJ97+FX Monterrey, Nuevo Leon
## 11 ChIJHYAEQiu-YoYRBTxOvG4CgOE              MMCV+GJ Monterrey, Nuevo Leon
## 12 ChIJU2fHrNy9YoYR-Plh1LCYdik JJXQ+FQ San Pedro Garza García, Nuevo Leon
## 13 ChIJR1gZsYO9YoYRbDLnWdFfczQ MJ4Q+53 San Pedro Garza García, Nuevo Leon
## 14 ChIJPZTddl2WYoYRurrIrQcPvPc              PJ5G+CP Monterrey, Nuevo Leon
## 15 ChIJn4XroOG9YoYRaOGtjfdjMec MJ3X+52 San Pedro Garza García, Nuevo Leon
## 16 ChIJC59z952_YoYRG2kEq7wNApk JMWH+43 San Pedro Garza García, Nuevo Leon
## 17 ChIJtdcPVo-9YoYROLskwF0BYjw MJ78+GJ San Pedro Garza García, Nuevo Leon
## 18 ChIJFcAzyQO-YoYRDlyS2p7ON30              MM98+6V Monterrey, Nuevo Leon
## 19 ChIJbQch_Y2VYoYRzwSLQrW0ss0              MMPH+56 Monterrey, Nuevo Leon
## 20 ChIJc5_0UhO-YoYR6c7sGd1Tu-E              MM28+6G Monterrey, Nuevo Leon
##    plus_code.global_code rating                   reference
## 1            75QXJJXV+WV    4.6 ChIJ4dnUvJC9YoYR34PKM6Icy4s
## 2            75QXJMWF+V4    4.7 ChIJpTfU0EG-YoYRhajF5St9JHM
## 3            75QXPP27+R2    4.6 ChIJL6boF0qVYoYR4r3v00AAgBM
## 4            75QXMM8P+CW    4.6 ChIJD9BSVy6-YoYRjM8nKTkxfY8
## 5            75QXMJ78+QH    4.6 ChIJ5_DEYV29YoYRzD4S08H5Cck
## 6            75QXJJXV+W8    4.6 ChIJVTUMOVe9YoYRARG7lnER_rw
## 7            75QXMJ5X+C2    4.6 ChIJBS-b4eK9YoYReSW9Sirm2Dc
## 8            75QXMMCW+33    4.6 ChIJZdCO6Me_YoYRH1tFVoLcZbs
## 9            75QXMJ2J+GQ    4.8 ChIJGe_Dzuu9YoYRP6kugxKGW2Y
## 10           75QXPJ97+FX    4.6 ChIJ8z8JzLaXYoYR1o1dfh3IzEo
## 11           75QXMMCV+GJ    4.6 ChIJHYAEQiu-YoYRBTxOvG4CgOE
## 12           75QXJJXQ+FQ    4.7 ChIJU2fHrNy9YoYR-Plh1LCYdik
## 13           75QXMJ4Q+53    4.9 ChIJR1gZsYO9YoYRbDLnWdFfczQ
## 14           75QXPJ5G+CP    4.5 ChIJPZTddl2WYoYRurrIrQcPvPc
## 15           75QXMJ3X+52    4.6 ChIJn4XroOG9YoYRaOGtjfdjMec
## 16           75QXJMWH+43    4.6 ChIJC59z952_YoYRG2kEq7wNApk
## 17           75QXMJ78+GJ    4.4 ChIJtdcPVo-9YoYROLskwF0BYjw
## 18           75QXMM98+6V    4.6 ChIJFcAzyQO-YoYRDlyS2p7ON30
## 19           75QXMMPH+56    4.5 ChIJbQch_Y2VYoYRzwSLQrW0ss0
## 20           75QXMM28+6G    4.7 ChIJc5_0UhO-YoYR6c7sGd1Tu-E
##                                                              types
## 1               restaurant, point_of_interest, food, establishment
## 2               restaurant, point_of_interest, food, establishment
## 3               restaurant, point_of_interest, food, establishment
## 4               restaurant, point_of_interest, food, establishment
## 5               restaurant, point_of_interest, food, establishment
## 6               restaurant, point_of_interest, food, establishment
## 7               restaurant, point_of_interest, food, establishment
## 8               restaurant, point_of_interest, food, establishment
## 9               restaurant, point_of_interest, food, establishment
## 10              restaurant, point_of_interest, food, establishment
## 11         restaurant, bar, point_of_interest, food, establishment
## 12              restaurant, point_of_interest, food, establishment
## 13              restaurant, point_of_interest, food, establishment
## 14              restaurant, point_of_interest, food, establishment
## 15              restaurant, point_of_interest, food, establishment
## 16              restaurant, point_of_interest, food, establishment
## 17              restaurant, point_of_interest, food, establishment
## 18              restaurant, point_of_interest, food, establishment
## 19 restaurant, cafe, store, point_of_interest, food, establishment
## 20              restaurant, point_of_interest, food, establishment
##    user_ratings_total price_level
## 1                  48          NA
## 2                3152           3
## 3                1974           2
## 4                  68          NA
## 5                  32          NA
## 6                 359          NA
## 7                 554           3
## 8                 113          NA
## 9                 906           3
## 10                403           2
## 11               1970           2
## 12               1283           2
## 13               7268          NA
## 14               1631           2
## 15               1888           3
## 16                466          NA
## 17               1134           2
## 18               2891           3
## 19                342          NA
## 20               4001           2
# Coordenadas centrales de referencia
lat0 <- 25.649400508114578
lon0 <- -100.35583498127765
offset <- 0.072  # Aproximadamente 8 km en grados

# Definir una cuadrícula de centros (malla 3x3) para abarcar toda el área de búsqueda
centers <- data.frame(
  lat = c(lat0,          lat0 + offset, lat0 - offset,
          lat0,          lat0 + offset, lat0 + offset,
          lat0 - offset, lat0 - offset, lat0),
  lon = c(lon0,          lon0,          lon0,
          lon0 + offset, lon0 + offset, lon0 - offset,
          lon0 - offset, lon0 - offset, lon0)
)

r <- 8000  # Radio de búsqueda en metros

# Inicializar data frame para almacenar todos los resultados
all_data <- data.frame()

# Bucle para obtener resultados en cada centro
for(i in 1:nrow(centers)) {
  current_lat <- centers$lat[i]
  current_lon <- centers$lon[i]
  
  # Primera llamada a google_places
  search_str <- google_places(
    search_string = 'restaurantes', 
    location = c(current_lat, current_lon), 
    radius = r, 
    key = gmaps_key
  )
  
  Sys.sleep(2)  # Espera para asegurar la activación del token
  
  # Segunda llamada (si hay token)
  search_str_add_one <- if(!is.null(search_str$next_page_token)) {
    google_places(
      search_string = 'restaurantes', 
      location = c(current_lat, current_lon), 
      radius = r, 
      key = gmaps_key, 
      page_token = search_str$next_page_token
    )
  } else { NULL }
  
  Sys.sleep(2)
  
  # Tercera llamada (si hay token)
  search_str_add_two <- if(!is.null(search_str_add_one) && !is.null(search_str_add_one$next_page_token)) {
    google_places(
      search_string = 'restaurantes', 
      location = c(current_lat, current_lon), 
      radius = r, 
      key = gmaps_key, 
      page_token = search_str_add_one$next_page_token
    )
  } else { NULL }
  
  # Extraer información de cada llamada (primera, segunda y tercera página)
  names1   <- search_str$results$name
  ratings1 <- search_str$results$rating
  total1   <- search_str$results$user_ratings_total
  placeid1 <- search_str$results$place_id
  lat1     <- search_str$results$geometry$location$lat
  lon1     <- search_str$results$geometry$location$lng
  
  names2   <- if(!is.null(search_str_add_one)) search_str_add_one$results$name else c()
  ratings2 <- if(!is.null(search_str_add_one)) search_str_add_one$results$rating else c()
  total2   <- if(!is.null(search_str_add_one)) search_str_add_one$results$user_ratings_total else c()
  placeid2 <- if(!is.null(search_str_add_one)) search_str_add_one$results$place_id else c()
  lat2     <- if(!is.null(search_str_add_one)) search_str_add_one$results$geometry$location$lat else c()
  lon2     <- if(!is.null(search_str_add_one)) search_str_add_one$results$geometry$location$lng else c()
  
  names3   <- if(!is.null(search_str_add_two)) search_str_add_two$results$name else c()
  ratings3 <- if(!is.null(search_str_add_two)) search_str_add_two$results$rating else c()
  total3   <- if(!is.null(search_str_add_two)) search_str_add_two$results$user_ratings_total else c()
  placeid3 <- if(!is.null(search_str_add_two)) search_str_add_two$results$place_id else c()
  lat3     <- if(!is.null(search_str_add_two)) search_str_add_two$results$geometry$location$lat else c()
  lon3     <- if(!is.null(search_str_add_two)) search_str_add_two$results$geometry$location$lng else c()
  
  # Combinar la información del centro actual
  center_data <- data.frame(
    business_name = c(names1, names2, names3),
    business_rating = c(ratings1, ratings2, ratings3),
    user_ratings_total = c(total1, total2, total3),
    place_id = c(placeid1, placeid2, placeid3),
    lat = c(lat1, lat2, lat3),
    lon = c(lon1, lon2, lon3),
    stringsAsFactors = FALSE
  )
  
  all_data <- rbind(all_data, center_data)
}

# Eliminar duplicados basados en place_id
data <- all_data[!duplicated(all_data$place_id), ]

# Mostrar la cantidad de observaciones recolectadas
cat("Número total de observaciones:", nrow(data))
## Número total de observaciones: 193
### The page_token is the way to tell Google to return the next 20 results in the search instead of only the first 40
# Seleccionar las 10 mejores y 10 peores evaluaciones
data_top_ratings <- data %>% slice_max(business_rating, n = 10)
data_low_ratings <- data %>% slice_min(business_rating, n = 10)
# Top 10 Restaurantes con mejores ratings
top_ratings_plot <- ggplot(data_top_ratings, aes(x = reorder(business_name, business_rating), y = business_rating)) +
  geom_bar(stat = "identity", fill = "lightblue") + 
  labs(title = "Restaurantes - Top 10 Ratings", subtitle = "Zona de Estudio") + 
  coord_flip()
top_ratings_plot

# Top 10 Restaurantes con mayor número de votos
top_users_plot <- ggplot(data_top_ratings, aes(x = reorder(business_name, user_ratings_total), y = user_ratings_total)) + 
  geom_bar(stat = "identity", fill = "lightblue") +
  labs(title = "Restaurantes - Top 10 User Ratings", subtitle = "Zona de Estudio") + 
  coord_flip()
top_users_plot

# Restaurantes con ratings más bajos
low_ratings_plot <- ggplot(data_low_ratings, aes(x = reorder(business_name, business_rating), y = business_rating)) + 
  geom_bar(stat = "identity", fill = "lightpink") + 
  labs(title = "Restaurantes - Low 10 Ratings", subtitle = "Zona de Estudio") + 
  coord_flip()
low_ratings_plot

# Restaurantes con menor número de votos
low_users_plot <- ggplot(data_low_ratings, aes(x = reorder(business_name, user_ratings_total), y = user_ratings_total)) + 
  geom_bar(stat = "identity", fill = "lightpink") + 
  labs(title = "Restaurantes - Low 10 User Ratings", subtitle = "Zona de Estudio") + 
  coord_flip()
low_users_plot

# Mapa de calor para restaurantes con mejores ratings
register_google(key = gmaps_key)
ggmap(get_googlemap(center = c(lon = longitude, lat = latitude), zoom = 13)) +
  stat_density2d(data = data_top_ratings, aes(lon, lat, fill = after_stat(level)), 
                 geom = "polygon", alpha = 0.40) +
  scale_fill_gradient(low = "green", high = "red", guide = "none") +
  labs(x = '', y = '', title = "Zona - Restaurantes con Mejores Ratings")
## ℹ <https://maps.googleapis.com/maps/api/staticmap?center=25.649401,-100.355835&zoom=13&size=640x640&scale=2&maptype=terrain&key=xxx-TzTcERfzJ3o>
## Warning: Removed 5 rows containing non-finite outside the scale range
## (`stat_density2d()`).

# Mapa de calor para restaurantes con peores ratings
ggmap(get_googlemap(center = c(lon = longitude, lat = latitude), zoom = 13)) +
  stat_density2d(data = data_low_ratings, aes(lon, lat, fill = after_stat(level)), 
                 geom = "polygon", alpha = 0.42) +
  scale_fill_gradient(low = "green", high = "red", guide = "none") +
  labs(x = '', y = '', title = "Zona - Restaurantes con Peores Ratings")
## ℹ <https://maps.googleapis.com/maps/api/staticmap?center=25.649401,-100.355835&zoom=13&size=640x640&scale=2&maptype=terrain&key=xxx-TzTcERfzJ3o>
## Warning: Removed 6 rows containing non-finite outside the scale range
## (`stat_density2d()`).

# Cargar librerías necesarias
library(tm)
library(wordcloud2)
library(magrittr)
## 
## Adjuntando el paquete: 'magrittr'
## The following object is masked from 'package:rlang':
## 
##     set_names
## The following object is masked from 'package:ggmap':
## 
##     inset
## The following objects are masked from 'package:terra':
## 
##     extract, inset
## The following object is masked from 'package:purrr':
## 
##     set_names
## The following object is masked from 'package:tidyr':
## 
##     extract
library(htmltools)
library(ggplot2)

# Recuperar detalles de los 10 mejores restaurantes (top ratings)
reviews_top <- lapply(data_top_ratings$place_id[1:10], function(pid) {
  google_place_details(place_id = pid, key = gmaps_key)
})

# Recuperar detalles de los 10 restaurantes con peores ratings (low ratings)
reviews_low <- lapply(data_low_ratings$place_id[1:10], function(pid) {
  google_place_details(place_id = pid, key = gmaps_key)
})

# Configurar la localización a español (puede variar según el sistema)
Sys.setlocale("LC_ALL", "es_ES.UTF-8")
## [1] "LC_COLLATE=es_ES.UTF-8;LC_CTYPE=es_ES.UTF-8;LC_MONETARY=es_ES.UTF-8;LC_NUMERIC=C;LC_TIME=es_ES.UTF-8"
# Función para extraer el texto de las reviews de cada objeto
extract_reviews <- function(review_list) {
  textos <- lapply(review_list, function(x) {
    if (!is.null(x$result$reviews)) {
      iconv(x$result$reviews$text, to = "UTF-8")
    } else {
      NULL
    }
  })
  unlist(textos, use.names = FALSE)
}

# Extraer los textos de las reviews para top y low ratings
top_reviews_text <- extract_reviews(reviews_top)
low_reviews_text <- extract_reviews(reviews_low)

# Crear corpus a partir del vector de textos
top_reviews_corpus <- Corpus(VectorSource(top_reviews_text))
low_reviews_corpus <- Corpus(VectorSource(low_reviews_text))

# Función para limpiar el texto
limpiar_corpus <- function(corpus) {
  corpus %>%
    tm_map(content_transformer(tolower)) %>%
    tm_map(removeNumbers) %>%
    tm_map(removePunctuation) %>%
    tm_map(stripWhitespace) %>%
    tm_map(removeWords, stopwords("english"))
}

# Limpiar ambos corpus
top_reviews_corpus <- limpiar_corpus(top_reviews_corpus)
## Warning in tm_map.SimpleCorpus(., content_transformer(tolower)): transformation
## drops documents
## Warning in tm_map.SimpleCorpus(., removeNumbers): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., removePunctuation): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., stripWhitespace): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., removeWords, stopwords("english")):
## transformation drops documents
low_reviews_corpus <- limpiar_corpus(low_reviews_corpus)
## Warning in tm_map.SimpleCorpus(., content_transformer(tolower)): transformation
## drops documents
## Warning in tm_map.SimpleCorpus(., removeNumbers): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., removePunctuation): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., stripWhitespace): transformation drops
## documents
## Warning in tm_map.SimpleCorpus(., removeWords, stopwords("english")):
## transformation drops documents
# Construir la matriz de términos y dataframe para top reviews
dtm_top <- TermDocumentMatrix(top_reviews_corpus)
matrix_top <- as.matrix(dtm_top)
words_top <- sort(rowSums(matrix_top), decreasing = TRUE)
words_top_df <- data.frame(
  word = names(words_top),
  freq = as.numeric(words_top)
)

# Construir la matriz de términos y dataframe para low reviews
dtm_low <- TermDocumentMatrix(low_reviews_corpus)
matrix_low <- as.matrix(dtm_low)
words_low <- sort(rowSums(matrix_low), decreasing = TRUE)
words_low_df <- data.frame(
  word = names(words_low),
  freq = as.numeric(words_low)
)

# Generar la nube de palabras para las top reviews
top_wordcloud <- wordcloud2(
  data  = words_top_df, 
  color = "random-dark", 
  size  = 0.6, 
  shape = "circle"
)

# Generar la nube de palabras para las low reviews
low_wordcloud <- wordcloud2(
  data  = words_low_df, 
  color = "random-dark", 
  size  = 0.6, 
  shape = "circle"
)

# Mostrar wordclouds con títulos usando tagList de htmltools
top_display <- tagList(
  h3("Nube de Palabras: Mejores Reseñas"),
  top_wordcloud
)

low_display <- tagList(
  h3("Nube de Palabras: Peores Reseñas"),
  low_wordcloud
)

# Imprimir en la salida las nubes de palabras
print(top_display)
## <h3>Nube de Palabras: Mejores Reseñas</h3>
## <div class="wordcloud2 html-widget html-fill-item" id="htmlwidget-fd8253cc1708b5c848fd" style="width:960px;height:500px;"></div>
## <script type="application/json" data-for="htmlwidget-fd8253cc1708b5c848fd">{"x":{"word":["food","good","service","great","place","restaurant","recommend","attentive","experience","monterrey","delicious","highly","atmosphere","dining","amazing","staff","also","dishes","quality","back","spot","like","made","excellent","waiter","perfect","everything","meal","truly","sushi","definitely","exceptional","nice","incredible","really","dish","friendly","just","cooked","menu","breakfast","fresh","recommendations","small","taste","went","overall","presented","special","make","awesome","even","well","mochomos","visit","beautiful","can","lot","options","prices","several","say","absolutely","ambiance","flavorful","outstanding","topnotch","loved","’s","feel","vibe","will","every","attention","get","dessert","flavor","tried","curry","french","quick","come","try","pleasant","finish","memorable","ordered","rib","fantastic","sweet","better","prepared","sauce","wonderful","flavors","one","sure","’re","salmon","best","look","way","signature","octopus","super","rolls","seafood","eat","gave","outdoor","parking","recommended","touch","worth","chef","pleasure","thank","welcome","find","mexico","expectations","inviting","looking","server","perfection","feels","high","relaxed","roll","short","tuna","beautifully","knowledgeable","making","night","preferences","sashimi","unique","still","tigre","detail","top","dinner","happy","today","’m","fan","anyone","can’t","chocolate","delightful","different","toptier","know","little","next","portion","sonoran","trying","without","providing","cocktail","professional","chilaquiles","experiences","extra","impressive","decent","outside","style","perfectly","tasty","fish","tacos","shrimp","time","view","crepes","modern","pick","plenty","tables","enough","moment","nothing","ate","bit","delighted","original","variety","impeccable","level","start","came","celebrate","fernando","host","los","simply","end","favorite","gyozas","share","truffled","absolute","balance","first","piece","reservation","julio","carlos","accommodating","intimate","music","return","waiting","desserts","warm","welcoming","general","meat","anything","old","pablo","think","able","appetizer","chicken","cozy","spanish","tamarind","care","choice","ended","mustvisit","setting","slightly","standout","stood","suggestion","always","authentic","craving","cuisine","don’t","ensure","exactly","eye","felt","goes","isn’t","musttry","point","servers","side","something","sphere","started","stay","times","tortillas","veggies","wants","youre","drink","hector","almendra","ever","marco","architecture","creating","dedication","ensuring","forward","needed","offering","stands","added","hit","monterey","draw","’ll","decorations","pieces","chefs","crafting","customize","dietary","found","impressed","ingredients","meals","provided","quickly","remarkable","returning","showcased","three","vegan","option","serving","temperature","big","brought","coconut","incredibly","’ve","oysters","bad","plate","sliced","spring","terrace","use","two","ones","build","cafe","coffee","decoration","detailed","indoor","lemonade","plant","plaza","resembles","scratch","services","spaces","surprisingly","visiting","across","advise","crêperie","everyone","holiday","knowledge","lucky","moreover","pastries","proposed","abroad","address","complete","france","manager","partner","recipe","choices","smiling","confidently","enhanced","exceeded","fantastic—every","home","perfect—warm","visitor","wellprepared","wellsuited","wish","amamos","bday","excelente","isaac","las","melissa","mis","respetos","buttered","chutoro","couple","couples","dimly","edamame","finally","freshly","grated","groups","hamachi","highpark","lit","nigiri’s","shared","wasabi","comfort","coming","elegance","gem","hotaku","incredible—fresh","welcomed","based","explains","luis","mantequilla","nigiri","pez","recommends","rob","timers","animal","guys","help","jovanny","spicy","attending","damian","diego","drinks","def","fabulous","gustavo","truffle","accepted","arrived","charles","dante","flying","grill","hour","immediately","immensely","kitchen","late","lomo","makes","morales","oscar","pepper","show","smells","smokey","sour","sparks","surrounded","thanks","walk","answered","captain","job","notch","questions","real","rosa","salvador","couldnt","details","america","birthday","couldn’t","else","states","tonight","united","years","communicate","complex","dark","described","flaming","lovely","portions","robust","smiles","year","“chic”","“cool”","another","beef","brighter","cauliflower","celebration","cheese","complaint","created","crispness","crunch","depth","dim","dined","dinner—rich","eating","fried","highlight—roasted","impossible","indulgent","lighting","moody","offer","paired","preferred","recently","rich","sampled","savory","sesame","stop","stylish","surprising","taken","tender","throughout","annoying","ask","attitudes","bill","birthdays","break","catch","certain","check","control","cross","date","dealbreaker","decor","deliver","finale","fingers","flair","flip","folks","friends","grand","hard","harina","hitch","juicy","keep","kick","kind","laugh","let","mexican","might","mind","mostly","multiple","nights","northern","otherwise","patience","pear","portion”","salad","seem","sides","sizes","skimpy","slows","somewhere","specializes","stellar","strong","treat","walking","want","whole","wow","“diet","called","change","close","expensive","havenhad","life","machomos","must","negra","paloma","penny","perejil","rdz","received","unmatched","explaining","fooddrinks","form","hits","hopefully","sever","🕲","miguel","recommend⭐️⭐️⭐️⭐️⭐️","description","name","gerardo","relaxing","ryoshi","adds","building","bursting","clear","consistently","crafted","despite","destination","efficient","elegant","enjoyable","entire","eyes","feast","ignacio","juan","mirrored","played","reasonable","role","significant","smooth","space","stunning","thought","value","australia","bang","delicious🕳","limited","literally","person","right","delicious—perfectly","energy","fryda’s","positive","spoton","wait","walked","yahir","crayons","hangover","need","colourful","expected","guests","however","invited","picture","used","wood","ability","accommodate","adding","adjusting","adventures","allowing","amazed","amidst","array","aspect","available","basking","became","beyond","buds","burst","cater","catering","combination","cravings","creations","creativity","culinary","customizable","day","delight","delve","demonstrated","discovering","enjoy","evident","fact","flexibility","freedom","goto","heart","highlight","innovation","kickstart","layer","let’s","liked","lived","mile","mouths","needs","now","particular","personalized","plantbased","poured","range","rating","refreshing","reputation","requests","resulting","savor","seating","seeking","selection","selections","soul","spice","starting","strike","substituting","surpassed","surroundings","tailor","tantalizing","things","toppings","trip","visits—","weather","whether","⭐⭐⭐⭐⭐","although","area","average","becomes","chairs","cold","colorfully","comment","cost","customer","dare","decorated","degrees","easel","furnishing","half","heaters","husband","khalo","lightweight","located","low","mall","open","oriented","pay","plastic","plates","preference","putting","regards","rolling","section","shows","since","south","together","uncomfortable","upscale","“unsafe”","beginning","brunch","engaging","enhancing","jared","manner","alberto","campechana","especially","try🕲","asked","jaime","killed","props","revilla","huge","exquisite","honest","mario","people","perspective","serve","art","baby","bone","ceviches","corn","marrow","mashed","michelin","play","potato","sculpture","star","tier","town","toy","divine","far","flawlessly","mango","mixing","pictured","rice","soup","spiced","weeks","work","decadent","occasions","totoaba","ambience","business","ceviche","eager","feedback","private","requirements","basic","believe","blew","bountiful","comfortable","complimented","covered","cream","creative","crunchy","crust","del","deliciousness","desert","deserts","disappoint","done","entrees","fans","greens","grilled","habanero","ice","improvement","ingredient","inside","items","jamaica","long","lots","main","mar","minds","mister","mix","never","often","orders","pad","pics","plan","playful","possibilities","raw","remind","ruin","see","sherbet","simple","starters","subpar","take","tamarindo","thai","thinly","took","unfortunately","version","workfare","zur","tempura","wednesday","almost","bothered","closing","hours","left","running","sunday","thing","asian","bajatype","doubt","frittertype","jamaizcal","lobster","mixology","nuevo","others","pacific","peruvian","price","puerto","refined","rock","scallops","seasoning","taco","toast","types","bottle","normal","sauces","september","seriously","terrible","chips","consistency","fail","fast","large","leche","mixed","texture","tripe","wouldnt"],"freq":[35,28,28,24,22,19,19,17,16,15,13,12,12,12,11,11,10,10,9,9,9,9,9,9,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"fontFamily":"Segoe UI","fontWeight":"bold","color":"random-dark","minSize":0,"weightFactor":3.085714285714286,"backgroundColor":"white","gridSize":0,"minRotation":-0.7853981633974483,"maxRotation":0.7853981633974483,"shuffle":true,"rotateRatio":0.4,"shape":"circle","ellipticity":0.65,"figBase64":null,"hover":null},"evals":[],"jsHooks":{"render":[{"code":"function(el,x){\n                        console.log(123);\n                        if(!iii){\n                          window.location.reload();\n                          iii = False;\n\n                        }\n  }","data":null}]}}</script>
print(low_display)
## <h3>Nube de Palabras: Peores Reseñas</h3>
## <div class="wordcloud2 html-widget html-fill-item" id="htmlwidget-0eb8df7cab9201b176ff" style="width:960px;height:500px;"></div>
## <script type="application/json" data-for="htmlwidget-0eb8df7cab9201b176ff">{"x":{"word":["good","food","place","service","tacos","great","also","best","delicious","ordered","back","time","will","nice","just","restaurant","excellent","flavor","prices","special","tried","like","get","pizza","shrimp","super","cake","definitely","better","order","tasty","first","asked","come","eat","much","never","made","terrible","lunch","little","really","fries","pastor","monterrey","boneless","forgot","went","everything","variety","drinks","inside","area","atmosphere","got","meat","night","people","dinner","recommend","anything","bad","came","ceviche","dont","check","waiter","can","mexican","friendly","fresh","staff","ive","one","plastic","parking","house","lasagna","buffalo","quiet","crispy","served","well","birthday","bring","different","even","none","overall","price","reservation","second","warm","worth","customer","lack","loved","wide","’s","find","perfect","temperature","available","sure","dishes","didnt","thing","barbacoa","city","else","later","needed","said","still","want","drink","glass","hour","menu","mxn","surprisingly","music","near","restaurants","large","portions","quite","chocolate","cocktail","lots","bill","pork","disappointed","found","full","campechanas","straight","helpful","pretty","ever","thats","trompo","taco","break","windows","wanted","big","high","burger","cool","italian","oven","sauce","use","coctails","promotion","affordable","breaded","delight","fillet","juicy","true","average","buñuelos","celebrate","enough","friend’s","going","make","rice","specified","though","three","types","avoid","building","cost","deplorable","focus","hostes","nasty","places","waiters","cocktails","couple","times","trying","looking","prefer","view","excellentmusic","par","🟤","adventure","avocado","bit","burguer","doubt","fresnos","los","might","options","raw","show","try","wine","chicken","horrible","kfc","selection","tasteless","tenders","wings","beers","quality","across","brought","checked","cilantro","common","delay","drove","extra","kept","limes","onion","put","receiving","refills","sense","smh","visiting","“sorry","”","diaz","dry","enfermo","hawaii","iso","mal","margarita","muy","oxxo","risk","sick","stomach","tiny","advertising","anyway","blew","charged","flag","half","kids","meal","posters","racist","seemed","supposed","walls","choice","keep","peso","solid","standard","tip","aesthetically","bar","beer","cheap","consider","dive","narrow","part","room","unkempt","upstairs","wasnt","ambient","antibacterial","choices","compared","covid","entering","free","gives","however","lastly","offer","offers","others","responsibility","takes","towards","attentive","family","local","low","morelos","plaza","huge","sopes","staple","terrace","two","windy","awesome","birria","black","dollars","flavorful","joney","late","open","quesa","walker","🏯","burrito","cevice","guacamole","impressive","reasonable","twice","worthy","happy","canada","casual","class","courteous","earls","experience","flavour","guest","joeys","met","nonspanish","often","partnerdate","patient","pleasant","professional","relaxed","requests","shopping","similar","somewhere","speaking","stopped","style","superb","surprise","ultra","way","days","feels","french","haven’t","preferred","prepared","quickly","several","since","tasted","waffle","fatty","clean","fast","mostly","practical","rather","another","centertamarind","cintermex","convention","example","guess","hadanother","mei","mexicans","ridiculously","sweet","water","worst","attended","basically","bathroom","color","greasy","red","services","🄡","absolutely","safe","arrogant","car","last","leave","opinion","pacifica","resinncial","valet","vandalism","buns","need","tequila","wear","women","comments","arracheras","banana","breakfasts","cajeta","deli","dessert","dough","expensive","far","flour","goat","gringa","milk","miss","outstanding","pecans","please","pricevalue","regret","relation","sandwiches","sweetened","tortas","traditional","trust","wife","wont","mushroom","overpriced","amount","arrives","chairs","charge","cocacola","end","lemonade","napkins","small","space","tables","tell","usd","used","watch","whatsoever","empty","long","took","cakes","children","grandchildren","know","let","pan","cheesy","cooked","cozy","crust","enjoyed","environment","fantastic","fruit","hot","intimate","kitchen","looked","modern","mushrooms","picky","promptly","real","refreshing","salad","seen","server","side","simple","sodas","spaghetti","teenager","around","awful","dying","lemonades","reviewed","someone","spot","thirst","vegetarian","wish","🚺","brick","freshlymade","italianthemed","vibrant","wonderful","recommended","allover","beef","blend","fired","gas","give","highly","mexico","rare","spit","unique","wood","among","frequent","playita","banf","cactus","day","etcetera","horse","name","oldies","playing","rising","river","sun","theyve","thursdays","yellow","ambiance","wait","improve"],"freq":[28,21,19,17,11,11,8,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"fontFamily":"Segoe UI","fontWeight":"bold","color":"random-dark","minSize":0,"weightFactor":3.857142857142857,"backgroundColor":"white","gridSize":0,"minRotation":-0.7853981633974483,"maxRotation":0.7853981633974483,"shuffle":true,"rotateRatio":0.4,"shape":"circle","ellipticity":0.65,"figBase64":null,"hover":null},"evals":[],"jsHooks":{"render":[{"code":"function(el,x){\n                        console.log(123);\n                        if(!iii){\n                          window.location.reload();\n                          iii = False;\n\n                        }\n  }","data":null}]}}</script>
# Crear gráfico de barras para las palabras más usadas (top reviews)
top_bar <- head(words_top_df, 10)
bar_top <- ggplot(top_bar, aes(x = reorder(word, freq), y = freq)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  labs(title = "Top 10 palabras en Mejores Reseñas", x = "Palabras", y = "Frecuencia") +
  theme_minimal()

# Crear gráfico de barras para las palabras más usadas (low reviews)
low_bar <- head(words_low_df, 10)
bar_low <- ggplot(low_bar, aes(x = reorder(word, freq), y = freq)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  labs(title = "Top 10 palabras en Peores Reseñas", x = "Palabras", y = "Frecuencia") +
  theme_minimal()

# Imprimir los gráficos de barras
print(bar_top)

print(bar_low)

# ---------------------------
# Nueva Sección: Análisis de Reviews y Sentimientos para Todos los Negocios
# ---------------------------

# 1. Obtener las reviews de todos los negocios de 'data'
# Se asume que 'data' contiene la columna 'place_id' de cada negocio.
all_reviews_list <- lapply(data$place_id, function(pid) {
  google_place_details(place_id = pid, key = gmaps_key)
})
Sys.sleep(2)  # Pausa para evitar problemas de rate limit

# Función para extraer el texto de las reviews de cada objeto
extract_reviews <- function(review_list) {
  textos <- lapply(review_list, function(x) {
    if (!is.null(x$result$reviews)) {
      # Convertir a UTF-8 para evitar problemas de encoding
      iconv(x$result$reviews$text, to = "UTF-8")
    } else {
      NULL
    }
  })
  unlist(textos, use.names = FALSE)
}

all_reviews_text <- extract_reviews(all_reviews_list)

# Verificar si se encontraron reviews

  # 2. Procesamiento de Texto: Nube de Palabras y Gráfico de Barras de Palabras Más Usadas
  library(tm)
  library(wordcloud2)
  library(ggplot2)
    # Cargar librerías necesarias
  library(tm)
  library(wordcloud2)
  library(ggplot2)
  library(syuzhet)
  
  # Crear corpus a partir de los textos de las reviews
  reviews_corpus <- Corpus(VectorSource(all_reviews_text))
  
  # Función para limpiar el corpus
  reviews_corpus <- tm_map(reviews_corpus, content_transformer(tolower))
## Warning in tm_map.SimpleCorpus(reviews_corpus, content_transformer(tolower)):
## transformation drops documents
  reviews_corpus <- tm_map(reviews_corpus, removeNumbers)
## Warning in tm_map.SimpleCorpus(reviews_corpus, removeNumbers): transformation
## drops documents
  reviews_corpus <- tm_map(reviews_corpus, removePunctuation)
## Warning in tm_map.SimpleCorpus(reviews_corpus, removePunctuation):
## transformation drops documents
  reviews_corpus <- tm_map(reviews_corpus, stripWhitespace)
## Warning in tm_map.SimpleCorpus(reviews_corpus, stripWhitespace): transformation
## drops documents
  reviews_corpus <- tm_map(reviews_corpus, removeWords, c(stopwords("english"), "food"))
## Warning in tm_map.SimpleCorpus(reviews_corpus, removeWords,
## c(stopwords("english"), : transformation drops documents
  # Crear matriz de términos
  dtm_all <- TermDocumentMatrix(reviews_corpus)
  matrix_all <- as.matrix(dtm_all)
  words_all <- sort(rowSums(matrix_all), decreasing = TRUE)
  words_all_df <- data.frame(word = names(words_all), freq = as.numeric(words_all))
  
  # Nube de palabras
  wordcloud_all <- wordcloud2(data = words_all_df, color = "random-dark", size = 0.6, shape = "circle")
  
  # Gráfico de barras de las 10 palabras más usadas
  top_words <- head(words_all_df, 10)
  bar_words <- ggplot(top_words, aes(x = reorder(word, freq), y = freq)) +
    geom_bar(stat = "identity", fill = "steelblue") +
    coord_flip() +
    labs(title = "Top 10 Palabras Más Usadas en Reviews", x = "Palabras", y = "Frecuencia") +
    theme_minimal()
  
  # Mostrar nube de palabras y gráfico de barras
  print(wordcloud_all)
  print(bar_words)

  # Análisis de Emociones y Sentimiento con syuzhet
  emotion_scores <- get_nrc_sentiment(all_reviews_text)
  emotion_totals <- colSums(emotion_scores)
  emotion_df <- data.frame(emotion = names(emotion_totals), count = as.numeric(emotion_totals))
  
  # Gráfico de barras para la distribución de emociones
  emotion_bar <- ggplot(emotion_df, aes(x = reorder(emotion, count), y = count)) +
    geom_bar(stat = "identity", fill = "coral") +
    coord_flip() +
    labs(title = "Distribución de Emociones en Reviews (syuzhet)", x = "Emociones", y = "Total") +
    theme_minimal()
  
  # Calcular sentimiento neto con método correcto de syuzhet
  sentiment_values <- get_sentiment(all_reviews_text, method = "syuzhet")
  
  # Histograma del sentimiento neto
  sentiment_hist <- ggplot(data.frame(sentiment = sentiment_values), aes(x = sentiment)) +
    geom_histogram(binwidth = 0.1, fill = "skyblue", color = "black") +
    labs(title = "Histograma de Sentimiento Neto de Reviews", 
         x = "Sentimiento Neto (Escala Syuzhet)", y = "Frecuencia") +
    theme_minimal()
  
  # Clasificación de Reviews: Positivo, Negativo y Neutral con syuzhet
  sentiment_category <- ifelse(sentiment_values > 0, "Positivo",
                               ifelse(sentiment_values < 0, "Negativo", "Neutral"))
  
  sentiment_dist <- as.data.frame(table(sentiment_category))
  colnames(sentiment_dist) <- c("Sentimiento", "Count")
  
  # Gráfico de pastel para la distribución de sentimientos
  pie_chart <- ggplot(sentiment_dist, aes(x = "", y = Count, fill = Sentimiento)) +
    geom_bar(width = 1, stat = "identity") +
    coord_polar("y", start = 0) +
    labs(title = "Distribución de Reviews por Sentimiento", x = "", y = "") +
    theme_void()
  
  # Mostrar gráficos de emociones y sentimientos
  print(emotion_bar)

  print(sentiment_hist)

  print(pie_chart)