library(rtweet)
## Warning: package 'rtweet' was built under R version 3.6.1
library(tidyverse)
## Registered S3 methods overwritten by 'ggplot2':
## method from
## [.quosures rlang
## c.quosures rlang
## print.quosures rlang
## Registered S3 method overwritten by 'rvest':
## method from
## read_xml.response xml2
## -- Attaching packages -------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.1.1 v purrr 0.3.2
## v tibble 2.1.1 v dplyr 0.8.0.1
## v tidyr 0.8.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.4.0
## -- Conflicts ----------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x purrr::flatten() masks rtweet::flatten()
## x dplyr::lag() masks stats::lag()
library(ggmap)
## Warning: package 'ggmap' was built under R version 3.6.1
## Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
## Please cite ggmap if you use it! See citation("ggmap") for details.
# El nombre que le asgnamos a la app en el formulario de autorización
appname <- "Parkify"
## consumer key (en el ejemplo no es una clave real, usar la verdadera)
consumer_key <- "xzhy9GOWU87ZJr0sx2e4vK5PN"
## consumer secret (en el ejemplo no es un clave real, usar la verdadera)
consumer_secret <- "ESzyrthGVuNHG2avZ30Dr1xNgXrACjezMIAPlwOvlLaF8a1nhb"
Vamos a buscar tweets que mencionen alguno de los términos “UVA”, “hipotecario”, “escrituras”, “inmuebles” o “inmobiliario”, en un radio de 10 millas (~16 km) en torno obelisco de la Ciudad de Buenos Aires.
El parámetro n = 3000 es para limitar la búsqueda a los primeros 3000 tweets hallados.
El parámetro include_rts = FALSE descarta retweets
tweets.BA <- search_tweets(q = "UVA OR escrituras OR hipotecario OR inmuebles OR inmobiliario",
geocode = "-34.603722,-58.381592,10mi",
include_rts = FALSE,
n = 3000,
retryonratelimit = TRUE)
## Registered S3 method overwritten by 'openssl':
## method from
## print.bytes Rcpp
Obtenemos un top 5 de los tweets más populares (con más seguidores), su procedencia, y el contenido del tweet:
tweets.BA %>%
top_n(5, retweet_count) %>%
arrange(desc(retweet_count)) %>%
select(screen_name, followers_count, location, text)
## # A tibble: 5 x 4
## screen_name followers_count location text
## <chr> <int> <chr> <chr>
## 1 mauriciomacri 4909590 Buenos Aires~ NO HABRÁ AUMENTO PARA LAS FA~
## 2 mauriciomacri 4909590 Buenos Aires~ El Estado se hará cargo de l~
## 3 frigerioroge~ 479639 Buenos Aires~ El Gobierno Nacional aportar~
## 4 frigerioroge~ 479639 Buenos Aires~ Esta medida alcanza a más de~
## 5 frigerioroge~ 479639 Buenos Aires~ #AHORA Junto a @ivankerr com~
Los tweets con mayor impacto fueron comunicaciones oficiales del paquete de medidas de emergencia tras las elecciones PASO.
Por otro lado podemos ver el horario del dia en que se realiza la mayor cantidad de tweets, los diferentes dias de la semana
ts_plot(tweets.BA, "hours")
El pico de actividad (dentro de la muestra que tomamos) se da el jueves 15 a la noche. Se ve tambien que el fin de semana hay poca actividad
Para ver la popularidad de los usuarios, obtenemos un top 5 de los usuarios más populares (con más seguidores), su procedencia, y el contenido del tweet:
tweets.BA %>%
top_n(5, followers_count) %>%
arrange(desc(followers_count)) %>%
select(screen_name, followers_count, location, text)
## # A tibble: 6 x 4
## screen_name followers_count location text
## <chr> <int> <chr> <chr>
## 1 mauriciomac~ 4909590 Buenos Aires,~ El Estado se hará cargo de l~
## 2 mauriciomac~ 4909590 Buenos Aires,~ NO HABRÁ AUMENTO PARA LAS FA~
## 3 clarincom 2901591 Buenos Aires,~ Créditos UVA: el Gobierno ev~
## 4 clarincom 2901591 Buenos Aires,~ Créditos UVA: a cuántos port~
## 5 clarincom 2901591 Buenos Aires,~ @frigeriorogelio @CaroStanle~
## 6 clarincom 2901591 Buenos Aires,~ Créditos UVA: el Gobierno ev~
Y la distribución
ggplot(tweets.BA)+
geom_histogram(aes(x = followers_count))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Se ve como la gran mayoria de usuarios tiene pocos o nada de followers, y unos pocos ´Tweetstars´ concentran muchisimos. Este tipo de distribución se ve en otras redes sociales, como YouTube, donde unos pocos usuarios generan los contenidos consumidos por la mayoria. Recientemente esta minoría, los Youtubers, se unieron al sindicato de comercio mas grande de Europa y exigen a la empresa ser tratados como socios.
FairTube: The YouTubers Union Is Not Messing Around
Para aislar los tweets que poseen coordenadas geográficas (lat y long), crear mapas que muestren posición de los tweets y cantidad de seguidores del usuario que tuitea.
Primero creamos una función que extrae los valores de lat y long del campo problemático
coordenadas <- function(campo_coordenadas) {
extraer_coordenadas <- function(lista_coords) {
data_frame(lon = lista_coords[1],
lat = lista_coords[2])
}
map_df(campo_coordenadas, extraer_coordenadas)
}
Y con una cadena de funciones extraemos los datos de georeferenciamiento, los agregamos al dataframe en sus propias columnas, y por último descartamos los campos en formato lista:
tweets_prop <- tweets.BA %>%
cbind(coordenadas(tweets.BA$coords_coords)) %>%
select(-geo_coords, -coords_coords, -bbox_coords)
## Warning: `data_frame()` is deprecated, use `tibble()`.
## This warning is displayed once per session.
Antes de visualizar, filtramos nuestros tweets para conservar sólo los que contienen coordenadas exactas de posición.
tweets_prop_geo <- tweets_prop %>%
filter(!is.na(lat), !is.na(lon))
El resultado evidencia que lso tweets georeferenciados son sólo una pequeña fracción del total que se produce:
nrow(tweets_prop_geo)
## [1] 6
Corremos al paquete ggmap
library(ggmap)
delimitamos los bordes externos del boundinbox vamos a usar las coordenadas de la guia ya que al ser muy pocas las observaciones que obtuvimos en esta busqueda, el zoom del bbox genera una imagen con mucho zoom y baja calidad
load(url("https://bitsandbricks.github.io/data/tweets_transporte.RData"))
coordenadas <- function(campo_coordenadas) {
extraer_coordenadas <- function(lista_coords) {
data_frame(lon = lista_coords[1],
lat = lista_coords[2])
}
map_df(campo_coordenadas, extraer_coordenadas)
}
tweets_transporte <- tweets_transporte %>%
cbind(coordenadas(tweets_transporte$coords_coords)) %>%
select(-geo_coords, -coords_coords, -bbox_coords)
tweets_transporte_geo <- tweets_transporte %>%
filter(!is.na(lat), !is.na(lon))
bbox <- c(min(tweets_transporte_geo$lon),
min(tweets_transporte_geo$lat),
max(tweets_transporte_geo$lon),
max(tweets_transporte_geo$lat))
Descargamos la base del mapa
mimapa <- get_stamenmap(bbox)
## Source : http://tile.stamen.com/terrain/10/344/616.png
## Source : http://tile.stamen.com/terrain/10/345/616.png
## Source : http://tile.stamen.com/terrain/10/346/616.png
## Source : http://tile.stamen.com/terrain/10/344/617.png
## Source : http://tile.stamen.com/terrain/10/345/617.png
## Source : http://tile.stamen.com/terrain/10/346/617.png
graficamos con el paquete ggpmap
ggmap(mimapa)
mimapa_terrain_lines <- get_stamenmap(bbox, maptype = "terrain-lines")
## Source : http://tile.stamen.com/terrain-lines/10/344/616.png
## Source : http://tile.stamen.com/terrain-lines/10/345/616.png
## Source : http://tile.stamen.com/terrain-lines/10/346/616.png
## Source : http://tile.stamen.com/terrain-lines/10/344/617.png
## Source : http://tile.stamen.com/terrain-lines/10/345/617.png
## Source : http://tile.stamen.com/terrain-lines/10/346/617.png
mimapa_toner_lite <- get_stamenmap(bbox, maptype = "toner-lite")
## Source : http://tile.stamen.com/toner-lite/10/344/616.png
## Source : http://tile.stamen.com/toner-lite/10/345/616.png
## Source : http://tile.stamen.com/toner-lite/10/346/616.png
## Source : http://tile.stamen.com/toner-lite/10/344/617.png
## Source : http://tile.stamen.com/toner-lite/10/345/617.png
## Source : http://tile.stamen.com/toner-lite/10/346/617.png
mimapa_watercolor <- get_stamenmap(bbox, maptype = "watercolor")
## Source : http://tile.stamen.com/watercolor/10/344/616.jpg
## Source : http://tile.stamen.com/watercolor/10/345/616.jpg
## Source : http://tile.stamen.com/watercolor/10/346/616.jpg
## Source : http://tile.stamen.com/watercolor/10/344/617.jpg
## Source : http://tile.stamen.com/watercolor/10/345/617.jpg
## Source : http://tile.stamen.com/watercolor/10/346/617.jpg
ggmap(mimapa_terrain_lines)
mapa_BA <- get_stamenmap(bbox, maptype = "toner-lite")
ggmap(mapa_BA)
y ahora agragamos la capa de tweets
ggmap(mapa_BA) +
geom_point(data = tweets_prop_geo, aes(x = lon, y = lat))
y diferenciamos por cantidad de seguidores y de retweets
ggmap(mapa_BA) +
geom_point(data = tweets_prop_geo,
aes(x = lon, y = lat, color = followers_count, size = retweet_count),
alpha = .5) +
scale_color_distiller(palette = "Spectral")