04 | Tarea: Descarga y Análisis de Datos de Twitter

library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.3     v purrr   0.3.4
## v tibble  3.1.0     v dplyr   1.0.5
## 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(sf)
## Warning: package 'sf' was built under R version 4.0.5
## Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(osmdata)
## Warning: package 'osmdata' was built under R version 4.0.5
## Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.0.5
library(ggmap)
## Warning: package 'ggmap' was built under R version 4.0.5
## Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
## Please cite ggmap if you use it! See citation("ggmap") for details.
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.0.5
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(rtweet)
## Warning: package 'rtweet' was built under R version 4.0.5
## 
## Attaching package: 'rtweet'
## The following object is masked from 'package:purrr':
## 
##     flatten

1. Descargar tweets que se originen en los alrededores de la Ciudad con la que están trabajando.

appname <- "RTWEET"
consumer_key <- "YQqOsmpX7K8IaS6196NQcWqoJ"
consumer_secret <- "yHN5auwcLG45RkYwTlzCp1k8i4mhja7TcC1jgqoHfNoGzTBAeg"
access_token <- "1647986706-qcGidHsNQC9mCBqtTnaGs6KknHsZHPTH0eKzO8M"
access_secret <- "H4JA6KRfx3mKeyU8FS8nv0RLugNvBKfGXNv0x8Uvfy001"
twitter_token <- create_token(
  app = appname,
  consumer_key = consumer_key,
  consumer_secret = consumer_secret,
  access_token = access_token, 
  access_secret = access_secret)
tweets_arg <- search_tweets(q = "Argentina+campeón+América", n = 10000)
names(tweets_arg)
##  [1] "user_id"                 "status_id"              
##  [3] "created_at"              "screen_name"            
##  [5] "text"                    "source"                 
##  [7] "display_text_width"      "reply_to_status_id"     
##  [9] "reply_to_user_id"        "reply_to_screen_name"   
## [11] "is_quote"                "is_retweet"             
## [13] "favorite_count"          "retweet_count"          
## [15] "quote_count"             "reply_count"            
## [17] "hashtags"                "symbols"                
## [19] "urls_url"                "urls_t.co"              
## [21] "urls_expanded_url"       "media_url"              
## [23] "media_t.co"              "media_expanded_url"     
## [25] "media_type"              "ext_media_url"          
## [27] "ext_media_t.co"          "ext_media_expanded_url" 
## [29] "ext_media_type"          "mentions_user_id"       
## [31] "mentions_screen_name"    "lang"                   
## [33] "quoted_status_id"        "quoted_text"            
## [35] "quoted_created_at"       "quoted_source"          
## [37] "quoted_favorite_count"   "quoted_retweet_count"   
## [39] "quoted_user_id"          "quoted_screen_name"     
## [41] "quoted_name"             "quoted_followers_count" 
## [43] "quoted_friends_count"    "quoted_statuses_count"  
## [45] "quoted_location"         "quoted_description"     
## [47] "quoted_verified"         "retweet_status_id"      
## [49] "retweet_text"            "retweet_created_at"     
## [51] "retweet_source"          "retweet_favorite_count" 
## [53] "retweet_retweet_count"   "retweet_user_id"        
## [55] "retweet_screen_name"     "retweet_name"           
## [57] "retweet_followers_count" "retweet_friends_count"  
## [59] "retweet_statuses_count"  "retweet_location"       
## [61] "retweet_description"     "retweet_verified"       
## [63] "place_url"               "place_name"             
## [65] "place_full_name"         "place_type"             
## [67] "country"                 "country_code"           
## [69] "geo_coords"              "coords_coords"          
## [71] "bbox_coords"             "status_url"             
## [73] "name"                    "location"               
## [75] "description"             "url"                    
## [77] "protected"               "followers_count"        
## [79] "friends_count"           "listed_count"           
## [81] "statuses_count"          "favourites_count"       
## [83] "account_created_at"      "verified"               
## [85] "profile_url"             "profile_expanded_url"   
## [87] "account_lang"            "profile_banner_url"     
## [89] "profile_background_url"  "profile_image_url"

Agrupamos los tweets por país para obtener una cantidad total de tweets en cada uno:

tweets_arg %>% 
  group_by(country_code) %>% 
  summarise(cantidad=n())
## # A tibble: 8 x 2
##   country_code cantidad
##   <chr>           <int>
## 1 AR                 66
## 2 EC                  3
## 3 ES                  2
## 4 MX                  2
## 5 PY                  2
## 6 US                  2
## 7 VE                  1
## 8 <NA>             9916

a. ¿Cómo se distribuye la popularidad de los usuarios? ¿Quiénes son los 5 que más seguidores tienen? Graficar.

options(scipen = 20)
ggplot(tweets_arg) +
    geom_histogram(aes(x = followers_count))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Como podemos observar, el histograma no muy efectivo para visualizar la información. Esto se debe a que hay un enorme volumen de usuarios con poco seguidores y muy pocos usuarios con millones de seguidores: la dispersión de los datos es muy grande. Esto distorsiona la escala del histograma, y dificulta la visualización por la existencia de outliers.

Aplicamos un ranking para ver cuántos seguidores tienen las 5 cuentas con mayores seguidores de la muestra y poder entender mejor este fenómeno.

tweets_arg %>% 
    top_n(5, followers_count) %>% 
    arrange(desc(followers_count)) %>% 
    select(screen_name, followers_count, location, text)
## # A tibble: 5 x 4
##   screen_name   followers_count location     text                               
##   <chr>                   <int> <chr>        <chr>                              
## 1 nytimes              50102910 New York Ci~ "Lionel Messi, al fin campeón con ~
## 2 CNNEE                19910964 En todas pa~ "Las razones de por qué Messi no h~
## 3 CNNEE                19910964 En todas pa~ ".@JPVarsky estuvo en vivo desde e~
## 4 AristeguiOnl~         8865208 Ciudad de M~ "#Video | Italia se corona en la E~
## 5 AristeguiOnl~         8865208 Ciudad de M~ "#Video | \"Messiento campeón, car~

Podemos observar entonces que el usuario con más seguidores (New York Times) más que duplica en seguidores al usuario que aparece segundo en el ranking (CNNEE). A su vez, este usuario más que duplica los seguidores de los usuarios en la posición 3, 4 y 5 del ranking.

b. ¿En qué momento del día se realiza la mayor cantidad de tweets? Graficar.

ts_plot(tweets_arg, "hour")

Podemos observar que hay un pico de tweets el 13 de julio aproximadamente a las 23hs. Si ajustamos el gráfico a la zona horario de Buenos Aires, Argentina, esto se correpsondería con 3hs menos; es decir, el pico se estaría dando el 13 de julio aproximadamente a las 20hs. Se puede obserbar un patrón de aumento a medida que se aproxima el horario de mediodía, y una caída en la cantidad de tweets en la madrugada.

c. Aislando los tweets que poseen coordenadas geográficas (lat y long), crear al menos 1 mapa que muestre posición de los tweets y cantidad de seguidores del usuario que tuitea.

tweets_arg <- lat_lng(tweets_arg, coords = c("coords_coords", "bbox_coords", "geo_coords"))

Filtramos los tweets para eliminar aquellos que no tienen información geográfica.

tweets_arg <- tweets_arg %>% 
    filter(!is.na(lat), !is.na(lng)) %>% 
  filter(country_code=="AR")
bbox_tweets <- make_bbox(lon = tweets_arg$lng, lat = tweets_arg$lat)
mapa_tweets <- get_stamenmap(bbox_tweets, zoom = 6)
## Source : http://tile.stamen.com/terrain/6/19/36.png
## Source : http://tile.stamen.com/terrain/6/20/36.png
## Source : http://tile.stamen.com/terrain/6/21/36.png
## Source : http://tile.stamen.com/terrain/6/22/36.png
## Source : http://tile.stamen.com/terrain/6/19/37.png
## Source : http://tile.stamen.com/terrain/6/20/37.png
## Source : http://tile.stamen.com/terrain/6/21/37.png
## Source : http://tile.stamen.com/terrain/6/22/37.png
## Source : http://tile.stamen.com/terrain/6/19/38.png
## Source : http://tile.stamen.com/terrain/6/20/38.png
## Source : http://tile.stamen.com/terrain/6/21/38.png
## Source : http://tile.stamen.com/terrain/6/22/38.png
## Source : http://tile.stamen.com/terrain/6/19/39.png
## Source : http://tile.stamen.com/terrain/6/20/39.png
## Source : http://tile.stamen.com/terrain/6/21/39.png
## Source : http://tile.stamen.com/terrain/6/22/39.png
## Source : http://tile.stamen.com/terrain/6/19/40.png
## Source : http://tile.stamen.com/terrain/6/20/40.png
## Source : http://tile.stamen.com/terrain/6/21/40.png
## Source : http://tile.stamen.com/terrain/6/22/40.png

Hacemos el mapa base

ggmap(mapa_tweets)

A continuación localizamos geográficamente los tweets:

ggmap(mapa_tweets) +
    geom_point(data = tweets_arg, aes(x = lng, y = lat))

Le asignamos al mapa la infomración de cantidad de seguidores de cada cuenta que twiteó y tamaño según la cantidad de retwiteos que tuvo para obtener un mapa más informativo y poder detectar la relevancia de cada observación:

ggmap(mapa_tweets) +
    geom_point(data = tweets_arg %>% arrange(followers_count), aes(x = lng, y = lat, color = followers_count, size = retweet_count))+
    scale_color_distiller(palette = "Spectral")+
    theme_void()

A continuación queremos ver cuál es el usuario que más retweets tuvo, su ubicación y la cantidad de seguidores.

tweets_arg %>%
  filter(retweet_count==max(retweet_count)) %>% 
  select(screen_name, retweet_count, followers_count, location, text)
## # A tibble: 2 x 5
##   screen_name retweet_count followers_count location       text                 
##   <chr>               <int>           <int> <chr>          <chr>                
## 1 NicoMai10               5            3271 ""             "\U0001f1e6\U0001f1f~
## 2 fcandeias               5           10310 "Ciudad Autón~ "Vení, pasá. Mete un~

Ahora, filtramos para ver la mismo información que anteriormente, pero con el usuario que más seguidores tiene:

tweets_arg %>%
  filter(followers_count==max(followers_count)) %>% 
  select(screen_name, retweet_count, followers_count, location, text)
## # A tibble: 1 x 5
##   screen_name retweet_count followers_count location       text                 
##   <chr>               <int>           <int> <chr>          <chr>                
## 1 fcandeias               5           10310 Ciudad Autóno~ "Vení, pasá. Mete un~

Para tener un mapa más interactivo e informativo, utilizamos el mapa leaflet.

set.seed(123)

sample <- tweets_arg %>%
  sample_frac(1)
leaflet(sample) %>% 
    addTiles() %>%
    addMarkers()
## Assuming "lng" and "lat" are longitude and latitude, respectively
leaflet(sample %>% arrange(followers_count)) %>% 
    addTiles() %>%
    addProviderTiles(providers$CartoDB.DarkMatter) %>%
    addCircleMarkers(popup = paste("User:", sample$screen_name, "<br>",
                           "Followers:", sample$followers_count, "<br>",
                           "Tweet:", sample$text),
                     color = ~colorNumeric(palette = "viridis", domain = sample$followers_count)(followers_count)) %>% 
    addLegend(title = "seguidores", pal = colorNumeric(palette = "viridis", domain = sample$followers_count), values = ~followers_count)
## Assuming "lng" and "lat" are longitude and latitude, respectively