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