Note that the directories used to store data are likely different on your computer, and such references will need to be changed before using any such code.

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages ---------------------------------------------------------------------------------------------------------------------- tidyverse 1.3.1 --
v ggplot2 3.3.5     v purrr   0.3.4
v tibble  3.1.2     v dplyr   1.0.7
v tidyr   1.1.3     v stringr 1.4.0
v readr   1.4.0     v forcats 0.5.1
-- Conflicts ------------------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(magrittr)

Attaching package: ‘magrittr’

The following object is masked from ‘package:purrr’:

    set_names

The following object is masked from ‘package:tidyr’:

    extract
df <- read.csv("../../Data/About you (Responses) - Form Responses 1-Edit.csv") %>%
  rename(country_name=Where.did.you.grow.up...country.or.region.,
         cafe=What.is.your.favorite.cafe..coffee.shop..tea.shop..etc....N.A.if.you.don.t.have.one.)
ll <- read_tsv("../../Data/countries_latlon.csv") %>%
  rename(country_name=name)

-- Column specification ---------------------------------------------------------------------------------------------------------------------------------------
cols(
  country = col_character(),
  latitude = col_double(),
  longitude = col_double(),
  name = col_character()
)
df %<>% left_join(ll)
Joining, by = "country_name"
library(leaflet)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
leaflet(df) %>%
  setView(lng = 103.8198, lat = 1.3521, zoom = 1) %>%
  addTiles() %>%
  addMarkers(lng = ~longitude, lat = ~latitude, clusterOptions = markerClusterOptions(), label=~country_name)
NA
# Note: The below code only works when run at SMU
library(jsonlite)

Attaching package: ‘jsonlite’

The following object is masked from ‘package:purrr’:

    flatten
soa_ll <- c(1.2956192, 103.8498277)
find_cafe_ll <- function(coord_ll, radius, keyword) {
  # setup
  coord <- paste(coord_ll[1],coord_ll[2],sep=",")
  baseurl <- "https://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
  # You'll need your own API key on Google Cloud to replicate this.
  # The good news is that the first $200 USD in charges are waived per month.
  api_key <- readRDS('google_maps_api_key.rds')
  
  # query
  q <- paste(baseurl,"input=", URLencode(keyword),"&inputtype=textquery","&locationbias=circle:",radius,"@",coord,"&fields=formatted_address,name,rating,geometry,place_id","&key=",api_key, sep="")

  #print(q)
  
  # GET data
  data1<-fromJSON(q)
  
  # Check if found
  if (data1$status == "ZERO_RESULTS") {
    return(NULL)
  }
  
  # Return as a data.frame
  df_return <- data.frame(cafe=keyword,
                          cafe_name=data1$candidates$name,
                          lat=data1$candidates$geometry$location$lat,
                          long=data1$candidates$geometry$location$lng,
                          place_id=data1$candidates$place_id,
                          address=data1$candidates$formatted_address,
                          rating=ifelse(is.null(data1$candidates$rating), NA, data1$candidates$rating))
  return(df_return)
}

cafes = unique(df$cafe)
cafes = cafes[cafes!="NA" & cafes!="N/A" & cafes != "na" & cafes != "n/a" & !is.na(cafes) & cafes != ""]

if(!file.exists("google_maps_query.rds")) {
  first = T
  for (cafe in cafes) {
    cafe_data <- find_cafe_ll(soa_ll,radius = 1000,cafe)
    if (!is.null(cafe_data)) {
      if (first) {
        df_cafe <- cafe_data
        first <- F
      } else {
        df_cafe <- rbind(df_cafe,cafe_data)
      }
    }
  }
  saveRDS(df_cafe,"google_maps_query.rds")
} else {
  df_cafe <- readRDS("google_maps_query.rds")
}
# Visualize Google maps data
df %>% left_join(df_cafe) %>%
  filter(!is.na(place_id)) %>%
  leaflet() %>%
  setView(lng = 103.8498277, lat = 1.2956192, zoom = 14) %>%
  addTiles() %>%
  addMarkers(lng = ~long, lat = ~lat, clusterOptions = markerClusterOptions(),
             label = ~paste0(cafe_name),
             popup = ~paste0('<div style="font-size:18px; padding:10px; line-height:20px">Query: ',cafe,
                             '<br><a href="https://www.google.com/maps/search/?api=1&query=Google&query_place_id=',place_id,'">Link on Gmaps</a>',
                             '<br>Rating on Gmaps: ',rating,
                             '<br>Address: ',address,'</div>'))
Joining, by = "cafe"
library(waffle)
library(rlang)

Attaching package: ‘rlang’

The following objects are masked from ‘package:jsonlite’:

    flatten, unbox

The following object is masked from ‘package:magrittr’:

    set_names

The following objects are masked from ‘package:purrr’:

    %@%, as_function, flatten, flatten_chr, flatten_dbl, flatten_int, flatten_lgl, flatten_raw, invoke, list_along, modify, prepend, splice
output_waffle_gg = function(data, cut=3, title="", ...) {
  dots <- ensyms(...)
  data2 <- data %>%
    select(!!!dots) %>%  # This is a quosure.  
    unlist()
  data2 <- data.frame(cats=data2)
  data2 %<>%
    filter(cats != '') %>%
    group_by(cats) %>%
    mutate(count = n()) %>%
    slice(1) %>%
    ungroup()
  cut = 0
  cells_cut = 0
  while (nrow(data2) > 10) {
    cut <- cut + 1
    cells_cut = cells_cut + sum(filter(data2,count <= cut)$count)
    data2 %<>% filter(count > cut)
  }
  data2 %>%
    ggplot(aes(fill=cats, values=count)) +
    geom_waffle(color="white", n_rows=5, size=1.125) + 
    scale_x_discrete(expand=c(0,0)) +
    scale_y_discrete(expand=c(0,0)) + 
    ggthemes::scale_fill_tableau(name=NULL) + 
    labs(title=title, x = paste0("1 square is 1 response; Only responses with >",cut," (",cells_cut," items omitted)"))
}
df %>% output_waffle_gg(cut=2, "", Hobby.Norm1, Hobby.Norm2, Hobby.Norm3)

df %>% output_waffle_gg(3, "", Pro.Norm1, Pro.Norm2)

df %>% output_waffle_gg(3, "", Con.Norm1)

LS0tDQp0aXRsZTogIkNvZGUgZm9yIFNlc3Npb24gMiBFeHRyYSINCmF1dGhvcjogIkRyLiBSaWNoYXJkIE0uIENyb3dsZXkiDQpkYXRlOiAiIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rDQotLS0NCg0KTm90ZSB0aGF0IHRoZSBkaXJlY3RvcmllcyB1c2VkIHRvIHN0b3JlIGRhdGEgYXJlIGxpa2VseSBkaWZmZXJlbnQgb24geW91ciBjb21wdXRlciwgYW5kIHN1Y2ggcmVmZXJlbmNlcyB3aWxsIG5lZWQgdG8gYmUgY2hhbmdlZCBiZWZvcmUgdXNpbmcgYW55IHN1Y2ggY29kZS4NCg0KYGBge3IsIG1lc3NhZ2U9Rn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShtYWdyaXR0cikNCmRmIDwtIHJlYWQuY3N2KCIuLi8uLi9EYXRhL0Fib3V0IHlvdSAoUmVzcG9uc2VzKSAtIEZvcm0gUmVzcG9uc2VzIDEtRWRpdC5jc3YiKSAlPiUNCiAgcmVuYW1lKGNvdW50cnlfbmFtZT1XaGVyZS5kaWQueW91Lmdyb3cudXAuLi5jb3VudHJ5Lm9yLnJlZ2lvbi4sDQogICAgICAgICBjYWZlPVdoYXQuaXMueW91ci5mYXZvcml0ZS5jYWZlLi5jb2ZmZWUuc2hvcC4udGVhLnNob3AuLmV0Yy4uLi5OLkEuaWYueW91LmRvbi50LmhhdmUub25lLikNCmxsIDwtIHJlYWRfdHN2KCIuLi8uLi9EYXRhL2NvdW50cmllc19sYXRsb24uY3N2IikgJT4lDQogIHJlbmFtZShjb3VudHJ5X25hbWU9bmFtZSkNCmRmICU8PiUgbGVmdF9qb2luKGxsKQ0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZ9DQpsaWJyYXJ5KGxlYWZsZXQpDQpsZWFmbGV0KGRmKSAlPiUNCiAgc2V0VmlldyhsbmcgPSAxMDMuODE5OCwgbGF0ID0gMS4zNTIxLCB6b29tID0gMSkgJT4lDQogIGFkZFRpbGVzKCkgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gfmxvbmdpdHVkZSwgbGF0ID0gfmxhdGl0dWRlLCBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCksIGxhYmVsPX5jb3VudHJ5X25hbWUpDQogIA0KYGBgDQoNCmBgYHtyfQ0KIyBOb3RlOiBUaGUgYmVsb3cgY29kZSBvbmx5IHdvcmtzIHdoZW4gcnVuIGF0IFNNVQ0KbGlicmFyeShqc29ubGl0ZSkNCnNvYV9sbCA8LSBjKDEuMjk1NjE5MiwgMTAzLjg0OTgyNzcpDQpmaW5kX2NhZmVfbGwgPC0gZnVuY3Rpb24oY29vcmRfbGwsIHJhZGl1cywga2V5d29yZCkgew0KICAjIHNldHVwDQogIGNvb3JkIDwtIHBhc3RlKGNvb3JkX2xsWzFdLGNvb3JkX2xsWzJdLHNlcD0iLCIpDQogIGJhc2V1cmwgPC0gImh0dHBzOi8vbWFwcy5nb29nbGVhcGlzLmNvbS9tYXBzL2FwaS9wbGFjZS9maW5kcGxhY2Vmcm9tdGV4dC9qc29uPyINCiAgIyBZb3UnbGwgbmVlZCB5b3VyIG93biBBUEkga2V5IG9uIEdvb2dsZSBDbG91ZCB0byByZXBsaWNhdGUgdGhpcy4NCiAgIyBUaGUgZ29vZCBuZXdzIGlzIHRoYXQgdGhlIGZpcnN0ICQyMDAgVVNEIGluIGNoYXJnZXMgYXJlIHdhaXZlZCBwZXIgbW9udGguDQogIGFwaV9rZXkgPC0gcmVhZFJEUygnZ29vZ2xlX21hcHNfYXBpX2tleS5yZHMnKQ0KICANCiAgIyBxdWVyeQ0KICBxIDwtIHBhc3RlKGJhc2V1cmwsImlucHV0PSIsIFVSTGVuY29kZShrZXl3b3JkKSwiJmlucHV0dHlwZT10ZXh0cXVlcnkiLCImbG9jYXRpb25iaWFzPWNpcmNsZToiLHJhZGl1cywiQCIsY29vcmQsIiZmaWVsZHM9Zm9ybWF0dGVkX2FkZHJlc3MsbmFtZSxyYXRpbmcsZ2VvbWV0cnkscGxhY2VfaWQiLCIma2V5PSIsYXBpX2tleSwgc2VwPSIiKQ0KDQogICNwcmludChxKQ0KICANCiAgIyBHRVQgZGF0YQ0KICBkYXRhMTwtZnJvbUpTT04ocSkNCiAgDQogICMgQ2hlY2sgaWYgZm91bmQNCiAgaWYgKGRhdGExJHN0YXR1cyA9PSAiWkVST19SRVNVTFRTIikgew0KICAgIHJldHVybihOVUxMKQ0KICB9DQogIA0KICAjIFJldHVybiBhcyBhIGRhdGEuZnJhbWUNCiAgZGZfcmV0dXJuIDwtIGRhdGEuZnJhbWUoY2FmZT1rZXl3b3JkLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjYWZlX25hbWU9ZGF0YTEkY2FuZGlkYXRlcyRuYW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsYXQ9ZGF0YTEkY2FuZGlkYXRlcyRnZW9tZXRyeSRsb2NhdGlvbiRsYXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmc9ZGF0YTEkY2FuZGlkYXRlcyRnZW9tZXRyeSRsb2NhdGlvbiRsbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlX2lkPWRhdGExJGNhbmRpZGF0ZXMkcGxhY2VfaWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3M9ZGF0YTEkY2FuZGlkYXRlcyRmb3JtYXR0ZWRfYWRkcmVzcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF0aW5nPWlmZWxzZShpcy5udWxsKGRhdGExJGNhbmRpZGF0ZXMkcmF0aW5nKSwgTkEsIGRhdGExJGNhbmRpZGF0ZXMkcmF0aW5nKSkNCiAgcmV0dXJuKGRmX3JldHVybikNCn0NCg0KY2FmZXMgPSB1bmlxdWUoZGYkY2FmZSkNCmNhZmVzID0gY2FmZXNbY2FmZXMhPSJOQSIgJiBjYWZlcyE9Ik4vQSIgJiBjYWZlcyAhPSAibmEiICYgY2FmZXMgIT0gIm4vYSIgJiAhaXMubmEoY2FmZXMpICYgY2FmZXMgIT0gIiJdDQoNCmlmKCFmaWxlLmV4aXN0cygiZ29vZ2xlX21hcHNfcXVlcnkucmRzIikpIHsNCiAgZmlyc3QgPSBUDQogIGZvciAoY2FmZSBpbiBjYWZlcykgew0KICAgIGNhZmVfZGF0YSA8LSBmaW5kX2NhZmVfbGwoc29hX2xsLHJhZGl1cyA9IDEwMDAsY2FmZSkNCiAgICBpZiAoIWlzLm51bGwoY2FmZV9kYXRhKSkgew0KICAgICAgaWYgKGZpcnN0KSB7DQogICAgICAgIGRmX2NhZmUgPC0gY2FmZV9kYXRhDQogICAgICAgIGZpcnN0IDwtIEYNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGRmX2NhZmUgPC0gcmJpbmQoZGZfY2FmZSxjYWZlX2RhdGEpDQogICAgICB9DQogICAgfQ0KICB9DQogIHNhdmVSRFMoZGZfY2FmZSwiZ29vZ2xlX21hcHNfcXVlcnkucmRzIikNCn0gZWxzZSB7DQogIGRmX2NhZmUgPC0gcmVhZFJEUygiZ29vZ2xlX21hcHNfcXVlcnkucmRzIikNCn0NCmBgYA0KDQpgYGB7ciwgbWVzc2FnZT1GfQ0KIyBWaXN1YWxpemUgR29vZ2xlIG1hcHMgZGF0YQ0KZGYgJT4lIGxlZnRfam9pbihkZl9jYWZlKSAlPiUNCiAgZmlsdGVyKCFpcy5uYShwbGFjZV9pZCkpICU+JQ0KICBsZWFmbGV0KCkgJT4lDQogIHNldFZpZXcobG5nID0gMTAzLjg0OTgyNzcsIGxhdCA9IDEuMjk1NjE5Miwgem9vbSA9IDE0KSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSB+bG9uZywgbGF0ID0gfmxhdCwgY2x1c3Rlck9wdGlvbnMgPSBtYXJrZXJDbHVzdGVyT3B0aW9ucygpLA0KICAgICAgICAgICAgIGxhYmVsID0gfnBhc3RlMChjYWZlX25hbWUpLA0KICAgICAgICAgICAgIHBvcHVwID0gfnBhc3RlMCgnPGRpdiBzdHlsZT0iZm9udC1zaXplOjE4cHg7IHBhZGRpbmc6MTBweDsgbGluZS1oZWlnaHQ6MjBweCI+UXVlcnk6ICcsY2FmZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj48YSBocmVmPSJodHRwczovL3d3dy5nb29nbGUuY29tL21hcHMvc2VhcmNoLz9hcGk9MSZxdWVyeT1Hb29nbGUmcXVlcnlfcGxhY2VfaWQ9JyxwbGFjZV9pZCwnIj5MaW5rIG9uIEdtYXBzPC9hPicsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+UmF0aW5nIG9uIEdtYXBzOiAnLHJhdGluZywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj5BZGRyZXNzOiAnLGFkZHJlc3MsJzwvZGl2PicpKQ0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZ9DQpsaWJyYXJ5KHdhZmZsZSkNCmxpYnJhcnkocmxhbmcpDQoNCm91dHB1dF93YWZmbGVfZ2cgPSBmdW5jdGlvbihkYXRhLCBjdXQ9MywgdGl0bGU9IiIsIC4uLikgew0KICBkb3RzIDwtIGVuc3ltcyguLi4pDQogIGRhdGEyIDwtIGRhdGEgJT4lDQogICAgc2VsZWN0KCEhIWRvdHMpICU+JSAgIyBUaGlzIGlzIGEgcXVvc3VyZS4gIA0KICAgIHVubGlzdCgpDQogIGRhdGEyIDwtIGRhdGEuZnJhbWUoY2F0cz1kYXRhMikNCiAgZGF0YTIgJTw+JQ0KICAgIGZpbHRlcihjYXRzICE9ICcnKSAlPiUNCiAgICBncm91cF9ieShjYXRzKSAlPiUNCiAgICBtdXRhdGUoY291bnQgPSBuKCkpICU+JQ0KICAgIHNsaWNlKDEpICU+JQ0KICAgIHVuZ3JvdXAoKQ0KICBjdXQgPSAwDQogIGNlbGxzX2N1dCA9IDANCiAgd2hpbGUgKG5yb3coZGF0YTIpID4gMTApIHsNCiAgICBjdXQgPC0gY3V0ICsgMQ0KICAgIGNlbGxzX2N1dCA9IGNlbGxzX2N1dCArIHN1bShmaWx0ZXIoZGF0YTIsY291bnQgPD0gY3V0KSRjb3VudCkNCiAgICBkYXRhMiAlPD4lIGZpbHRlcihjb3VudCA+IGN1dCkNCiAgfQ0KICBkYXRhMiAlPiUNCiAgICBnZ3Bsb3QoYWVzKGZpbGw9Y2F0cywgdmFsdWVzPWNvdW50KSkgKw0KICAgIGdlb21fd2FmZmxlKGNvbG9yPSJ3aGl0ZSIsIG5fcm93cz01LCBzaXplPTEuMTI1KSArIA0KICAgIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kPWMoMCwwKSkgKw0KICAgIHNjYWxlX3lfZGlzY3JldGUoZXhwYW5kPWMoMCwwKSkgKyANCiAgICBnZ3RoZW1lczo6c2NhbGVfZmlsbF90YWJsZWF1KG5hbWU9TlVMTCkgKyANCiAgICBsYWJzKHRpdGxlPXRpdGxlLCB4ID0gcGFzdGUwKCIxIHNxdWFyZSBpcyAxIHJlc3BvbnNlOyBPbmx5IHJlc3BvbnNlcyB3aXRoID4iLGN1dCwiICgiLGNlbGxzX2N1dCwiIGl0ZW1zIG9taXR0ZWQpIikpDQp9DQpgYGANCg0KYGBge3J9DQpkZiAlPiUgb3V0cHV0X3dhZmZsZV9nZyhjdXQ9MiwgIiIsIEhvYmJ5Lk5vcm0xLCBIb2JieS5Ob3JtMiwgSG9iYnkuTm9ybTMpDQpgYGANCg0KYGBge3J9DQpkZiAlPiUgb3V0cHV0X3dhZmZsZV9nZygzLCAiIiwgUHJvLk5vcm0xLCBQcm8uTm9ybTIpDQpgYGANCg0KYGBge3J9DQpkZiAlPiUgb3V0cHV0X3dhZmZsZV9nZygzLCAiIiwgQ29uLk5vcm0xKQ0KYGBgDQoNCg==