Existe un debate en torno a la cantidad de m2 que deberían existir por habitante en la ciudad, y de cuan lejos estamos del celebre índice de la OMS de 10m2 de EEVV/hab.
Mas allá de la relación sup.EEVV/hab ¿Podemos ponderar cuan buenos son esos EEVV? Valorar la calidad de un Espacio Verde público es complejo porque se deben tomar en cuenta muchos componentes: balance de superficies, equipamiento, iluminación, cercanía a transporte público, cantidad de visitantes, asoleamiento, etc.
Para hacer una primera aproximación, vamos a tomar la cantidad de arboles en EEVV como indicador de calidad del espacio, partiendo de la simplificacion de que un EEVV con muchos árboles es mejor que uno con pocos.
Vamos a trabajar con los datasets de BA Datos Abiertos, usando el de árbolado en espacios verdes. Existe un dataset complementario de arbolado de alineacion (calles), pero por ahora usaremos solo el primero.
barrios <- st_read('http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson')
comunas <- st_read('https://bitsandbricks.github.io/data/CABA_comunas.geojson')
Arb.EEVV <- read.csv('C:/MEU (DiTella)/2019 - A2/2 Trimestre/MU115 - Ciencia de datos 2/Datos2/BA/Arbolado EEVV/arbolado-en-espacios-verdes.csv', encoding = "UTF-8")
Vamos a graficar la info de Árboles en EEVV
ggplot() +
geom_sf(data = barrios) +
geom_point(data = Arb.EEVV,
aes(x = long, y = lat),
alpha = .3,
color = "Dark Olive Green")+
labs(title = "Arbolado de Buenos Aires",
subtitle = "Ciudad Autónoma de Buenos Aires, 2018")
Si queremos sectorizar los datos para analizarlos por cada barrio podemos realizar un join espacial.
Pero primero tenemos que filtrar el CSV para sacar las entradas sin coordenadas, en caso de que las hubiera, y luego transformamos el dataframe en uno espacial.
Arb.EEVV <- Arb.EEVV %>%
filter(!is.na(lat), !is.na(long)) %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
Realizamos el join espacial
EEVV.barrios <- st_join(Arb.EEVV, barrios)
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
Ahora que agregamos la información del barrio y comuna a cada registro de Arbol en espacios verdes, podemos analizar la cantidad de arboles en eevv por barrio o comuna.
Creamos un contador de Arboles en EEVV por Comuna
conteo.arbcom <- EEVV.barrios %>%
group_by(comuna, tipo_folla, origen) %>%
summarise(cantidad = n())
veamos las variables resultantes del nuevo dataset conteo
names(conteo.arbcom)
## [1] "comuna" "tipo_folla" "origen" "cantidad" "geometry"
Lo vamos a usar para armar un grafico que muestre la cantidad por comuna, diferenciando especies exóticas de nativas.
La incorporación de especies nativas de la ecoregión a los espacios públicos es un debate que está tomando mucha relevancia en las ciudades, ya que tienen un menor consumo hídrico, se adaptan mejor a los cambios de temperatura y promueven la biodiversidad.
ggplot(conteo.arbcom) +
geom_bar(aes(x = as.factor(comuna), weight = cantidad, fill = origen))+
coord_flip()+
labs(title = "Distribución de arboles en EEVV segun comuna",
subtitle = "Composición por Origen",
x = "Comuna",
y = "Cantidad de Árboles",
caption = "Fuente: Elaboración propia en base a datos de BA Data")+
theme_minimal()
A grandes rasgos podemos observar que las comunas 1, 8 y 14 están muy por encima de las demás en cantidad de árboles por EEVV. Tambien podemos ver que en en la mayoría de las comunas hay una fuerte prevalencia de especies exóticas.
Para graficar esta info en el mapa primero vamos a realizar un join para volcar la cantidad a cada comuna
conteo.arbcom2 <- EEVV.barrios %>%
group_by(comuna) %>%
summarise(cantidad = n())
conteo.arbcom2 <- rename(conteo.arbcom2, "comunas" = "comuna")
Realizamos el join
comunas.v2 <- st_join(comunas, conteo.arbcom2)
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
Y finalmente graficamos la cantidad de arboles en EEVV por comunas
ggplot() +
geom_sf(data = comunas.v2, aes(fill = cantidad)) +
scale_fill_viridis_c()+
geom_sf_label(data = comunas,
aes(label = comunas)) +
theme_void()+
labs(title = "Cantidad de arboles en EEVV por Comunas",
subtitle = "Ciudad Autónoma de Buenos Aires, 2018",
fill = "Cantidad",
caption = "Fuente: BA Datos")
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may
## not give correct results for longitude/latitude data
Hay que tener en cuenta que las comunas que mejor performan son las que tienen reservas ecológicas o grandes parques (Reserva Costanera sur, Reserva Lago Lugano, Parque Tres de Febrero). Las comunas 3 y 5, que son las que peor rankean, tienen muy pocos m2 de EEVV, y por lo tanto dificilmente puedan tener muchos árboles. Pero esto no nos habla del rendimiento de árboles por EEVV.
Para conseguir la relacion arbol/m2 verde, siguiendo el criterio que adoptamos al empezar el ejercicio, vamos a usar el dataset de espacios verdes.
EEVV <- read.csv('C:/MEU (DiTella)/2019 - A2/2 Trimestre/MU115 - Ciencia de datos 2/Datos2/BA/EEVV/espacio-verde-publico.csv', encoding = "UTF-8")
Obtenemos un dataframe resumen con los m2 verdes totales por comuna. Vamos a expresar los totales en hectáreas, para evitar trabajar con números tan grandes.
EEVV <- EEVV %>%
select("comunas", "area") %>%
group_by(comunas) %>%
summarise(total_Ha_verde = sum(area) / 10000 )
Ordenamos por Superficie verde de mayor a menor
EEVV %>%
arrange(desc(total_Ha_verde))
## # A tibble: 16 x 2
## comunas total_Ha_verde
## <dbl> <dbl>
## 1 8 421.
## 2 1 326.
## 3 14 222.
## 4 13 174.
## 5 10 124.
## 6 12 101.
## 7 9 71.7
## 8 4 61.3
## 9 7 36.2
## 10 2 33.1
## 11 6 21.4
## 12 15 20.8
## 13 11 11.8
## 14 3 3.48
## 15 5 2.09
## 16 0 0.718
Calculamos la superficie total
EEVV %>%
summarise(Total = sum(total_Ha_verde))
## # A tibble: 1 x 1
## Total
## <dbl>
## 1 1632.
Graficamos la superficie verde por comuna
ggplot(EEVV) +
geom_bar(aes(x = as.factor(comunas), weight = total_Ha_verde))+
coord_flip()+
labs(title = "Distribución de EEVV Público por comuna",
subtitle = "Expresado en Hectáreas",
x = "Comuna",
y = "Superficie",
caption = "Fuente: Elaboración propia en base a datos de BA Data")+
theme_minimal()
Los resultados que arroja el dataset difieren de aquellos publicados por el Anuario Estadistico 2017 (Dirección General de Estadísticas y Censos del GCBA). Es posible que el anuario contemple todos los EEVV de la ciudad, y no solo los EEVV públicos (usados para este ejercicio).
Por Ultimo, vamos a unir la info de EV a la de arbolado
comunas.v3 <- left_join(comunas.v2, EEVV)
## Joining, by = "comunas"
Generamos el indice de Arboles Totales / Sup. Verde, para cada comuna
comunas.v4 <- mutate(comunas.v3, indice = cantidad / total_Ha_verde)
Graficamos
ggplot() +
geom_sf(data = comunas.v4, aes(fill = indice)) +
scale_fill_viridis_c()+
geom_sf_label(data = comunas,
aes(label = comunas)) +
theme_void()+
labs(title = "Indice Arbolado / Sup. Verde por Comunas",
subtitle = "Ciudad Autónoma de Buenos Aires, 2018",
fill = "Cantidad",
caption = "Fuente: BA Datos")
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may
## not give correct results for longitude/latitude data
comunas.v5 <- comunas.v4 %>% st_set_geometry(NULL) %>%
arrange(desc(indice))
comunas.v5$barrios <- as.factor(comunas.v5$barrios)
comunas.v5$barrios <- factor(comunas.v5$barrios, levels = comunas.v5$barrios[order(comunas.v5$indice)])
ggplot(comunas.v5) +
geom_bar(aes(x=barrios, weight = indice, fill = indice)) +
labs(title = "Indice Arbolado / Sup. Verde por Comunas",
x = "Barrios",
y = "Indice") +
theme(axis.text.x = element_text(angle = 90, size = 6)) +
scale_fill_viridis_c()
Este enfoque evitaría penalizar a las comunas con poco espacio verde, y se centraría en la proporción arbolada de los EEVV, independientemente de la superficie de los mismos.
El PROCREAR está terminando su proyecto más grande y ambicioso a nivel nacional, el conjunto de viviendas conocido como Estación Buenos Aires, en el límite entre Parque Patricios y Barracas. El complejo está conformado por 56 edificios que albergan 2369 viviendas de diferentes tipologías, que oscilan entre 30 y 100 m2, y se calcula que recibirán cerca de 10.000 nuevos vecinos.
Teniendo en cuenta las dimensiones del proyecto, y por la relevancia que tiene para la zona sur de la ciudad, seria oportuno relizar un estudio de la zona para
bbox <- getbb("Parque Patricios, Ciudad Autonoma de Buenos Aires")
bbox
## min max
## x -58.41340 -58.38989
## y -34.64862 -34.62723
bbox_poly <- getbb("Parque Patricios, Ciudad Autonoma de Buenos Aires", format_out = "sf_polygon")
leaflet(bbox_poly) %>%
addTiles() %>%
addPolygons()
patricios <- opq(bbox) %>%
add_osm_feature(key = "highway")
patricios <- patricios %>%
osmdata_sf()
patricios
## Object of class 'osmdata' with:
## $bbox : -34.6486151,-58.4133954,-34.6272312,-58.3898933
## $overpass_call : The call submitted to the overpass API
## $meta : metadata including timestamp and version numbers
## $osm_points : 'sf' Simple Features Collection with 1654 points
## $osm_lines : 'sf' Simple Features Collection with 519 linestrings
## $osm_polygons : 'sf' Simple Features Collection with 7 polygons
## $osm_multilines : NULL
## $osm_multipolygons : NULL
calles <- patricios$osm_lines
head(calles)
ggplot() +
geom_sf(data = calles)
Aplicamos el polygono para limpiar lo que esta por fuera
calles <- st_intersection(calles, bbox_poly)
## although coordinates are longitude/latitude, st_intersection assumes that they are planar
## Warning: attribute variables are assumed to be spatially constant
## throughout all geometries
Y graficamos nuevamente
ggplot() +
geom_sf(data = calles)
Ahora que tenemos las calles, vamos a usar la informacion que tienen
Vamos a usar maxspeed para ver la velocidad de las vias de circulación
Primero tenemos que pasar la info a dato numeral
calles <- calles %>%
mutate(maxspeed = as.numeric(maxspeed),
lanes = ifelse(is.na(lanes), 1, as.numeric(lanes)))
Ahora graficamos
ggplot(calles) +
geom_sf(aes(color = maxspeed), alpha = 0.5) +
scale_color_viridis_c() +
labs(title = "Parque Patricios",
subtitle = "Vías de circulación",
caption = "fuente: OpenStreetMap",
color = "Velocidad máxima")
Que otras cosas podemos mapear?
names(calles)
## [1] "osm_id" "name" "access"
## [4] "addr.interpolation" "area" "bench"
## [7] "bicycle" "bicycle_road" "bridge"
## [10] "bus" "bus.lanes" "busway.right"
## [13] "crossing" "cycleway" "cycleway.left"
## [16] "foot" "footway" "gauge"
## [19] "hazard" "highway" "horse"
## [22] "incline" "lanes" "lanes.backward"
## [25] "lanes.forward" "layer" "lit"
## [28] "maxspeed" "maxspeed.conditional" "motor_vehicle"
## [31] "motor_vehicle.lanes" "note" "oneway"
## [34] "oneway.bicycle" "opposite_track" "public_transport"
## [37] "railway" "segregated" "service"
## [40] "shelter" "short_name" "sidewalk"
## [43] "sorting_name" "source" "source.maxspeed"
## [46] "surface" "tactile_paving" "traffic_calming"
## [49] "turn.lanes" "vehicle" "geometry"
Podemos graficar tambien calles por cantidad de carriles
ggplot(calles) +
geom_sf(aes(size = lanes)) +
labs(title = "Parque Patricios",
subtitle = "Cantidad de carriles",
caption = "fuente: OpenStreetMap",
size = "Cantidad de carriles")
Teniendo en cuenta que se trata de una zona logística de galpones y circulación de tráfico pesado, donde pronto aumentará la circulación de peatones, se podría usar el plano de velocidades máximas y ancho de calles para ver donde sería oportuno colocar semaforos, o reductores de velocidad.
Los dos mapas superpuestos:
ggplot(calles) +
geom_sf(aes(size = lanes)) +
geom_sf(aes(color = maxspeed), alpha = 0.5) +
labs(title = "Parque Patricios",
subtitle = "Velocidad y Cantidad de carriles",
caption = "fuente: OpenStreetMap",
color = "Velocidad Maxima",
size = "Cantidad de carriles")
Agregamos los semaforos
semaforo <- opq(bbox) %>%
add_osm_feature(key = "highway", value = "traffic_signals") %>%
osmdata_sf()
A diferencia de las calles, para los semaforos queremos los puntos unicamente
semaforo <- st_intersection(semaforo$osm_points, bbox_poly)
## although coordinates are longitude/latitude, st_intersection assumes that they are planar
## Warning: attribute variables are assumed to be spatially constant
## throughout all geometries
Graficamos el mapa anterior con la superposición de semaforos
ggplot(calles) +
geom_sf(aes(size = lanes)) +
geom_sf(aes(color = maxspeed), alpha = 0.5) +
geom_sf(data = semaforo,
color = "red")+
labs(title = "Parque Patricios",
subtitle = "Velocidad y Cantidad de carriles",
caption = "fuente: OpenStreetMap",
color = "Velocidad Maxima",
size = "Cantidad de carriles")
Se nota una concentración de semaforos sobre las avenidas, Un buen lugar para agregar semáforo podría ser en la Av. Amancio Alcorta, que no cuenta con ninguno en el tramo de +400m entre Lavardén y Colonia.
ggplot(calles) +
geom_sf(aes(size = lanes)) +
geom_sf(aes(color = maxspeed), alpha = 0.5) +
geom_sf(data = semaforo,
color = "red")+
geom_sf_label(data = calles%>%
filter (name == "Lavardén" | name == "Avenida Colonia"),
aes(label = name), size = 2)+
labs(title = "Parque Patricios",
subtitle = "Velocidad y Cantidad de carriles",
caption = "fuente: OpenStreetMap",
color = "Velocidad Maxima",
size = "Cantidad de carriles")
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may
## not give correct results for longitude/latitude data
Tambien podemos traer informacion de equipamientos y amenidades urbanas, veamos los cafes
cafe <- opq(bbox) %>%
add_osm_feature(key = "amenity", value = "cafe") %>%
osmdata_sf()
A diferencia de las calles, para los Cafes queremos los puntos unicamente
cafe <- st_intersection(cafe$osm_points, bbox_poly)
## although coordinates are longitude/latitude, st_intersection assumes that they are planar
## Warning: attribute variables are assumed to be spatially constant
## throughout all geometries
Y ahora podemos mapear
ggplot() +
geom_sf(data = calles,
color = "darkslateblue") +
geom_sf(data = cafe,
color = "red")
La oferta es bastante restringida, y se concentra en su mayoría entorno al Parque de los Patricios y la avenida Brasil. Si bien el proyecto de Estacion Buenos Aires contempla 73 locales comerciales, sería bueno que la oferta se atomize en el entorno para que la gente ´salga´ del complejo y evitar el efecto de aghetización que se produjo en otros complejos como Lugano I y II.
La info de OMS tiene otros atributos de interes como el nombre del local, si tienen delivery, si son franquicia, mesas en la vereda y horarios de cierre.
ggplot() +
geom_sf(data = calles,
color = "darkslateblue") +
geom_sf(data = cafe,
aes(color = takeaway)) +
geom_sf_label(data = cafe,
aes(label = name), size = 3)
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may
## not give correct results for longitude/latitude data
Por último, vamos a buscar un atributo que podamos comparar con la base de datos de BA DATA, para contrastar la información. Vamos a epxlorar la info de estaciones de servicio que se encuentra disponible tanto en OSM como en BA Data.
ES <- opq(bbox) %>%
add_osm_feature(key = "amenity", value = "fuel") %>%
osmdata_sf()
aislamos
ES <- st_intersection(ES$osm_points, bbox_poly)
## although coordinates are longitude/latitude, st_intersection assumes that they are planar
## Warning: attribute variables are assumed to be spatially constant
## throughout all geometries
mapeamos
ggplot() +
geom_sf(data = calles,
color = "darkslateblue") +
geom_sf(data = ES,
color = "red")
A pesar de que son pocas, vamos a crear un contador
ES.c <- ES %>%
summarise(cantidad = n())
summary(ES.c)
## cantidad geometry
## Min. :17 MULTIPOINT :1
## 1st Qu.:17 epsg:4326 :0
## Median :17 +proj=long...:0
## Mean :17
## 3rd Qu.:17
## Max. :17
Por algun motivo, algunas estaciones de servicio se estan contando mas de una vez. Se puede ver tanto en el mapa (las que se suporponen aparecen mas grandes) como en el conteo, donde aparecen 17 en lugar de 6.
Veamos la base de datos de BA
barrios <- st_read('http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson')
## Reading layer `barrios_badata' from data source `http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson' using driver `GeoJSON'
## Simple feature collection with 48 features and 4 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
ES.BA <- read.csv('C:/MEU (DiTella)/Ciencia de datos 2/BA/ES/estaciones_servicio_caba.csv', encoding = "UTF-8")
ggplot() +
geom_sf(data = barrios) +
geom_point(data = ES.BA,
aes(x = long, y = lat),
alpha = .3,
color = "red")
Filtramos
ES.BA <- ES.BA %>%
filter(!is.na(long), !is.na(lat)) %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
Realizamos el join espacial
ES.barrios <- st_join(ES.BA, barrios)
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
Creamos un contador de Estaciones de Servicio por barrio
ES.barrio.c <- ES.barrios %>%
group_by(barrio.x) %>%
summarise(cantidad = n())
Visualizamos datos
ggplot(ES.barrio.c) +
geom_bar(aes(x = barrio.x, weight = cantidad))+
coord_flip()
Vamos a filtrar los datos para quedarnos unicamente con los de Parque Patricios
seleccion <- filter(ES.barrio.c, barrio.x == "Parque Patricios")
summary(seleccion)
## barrio.x cantidad geometry
## Parque Patricios:1 Min. :4 MULTIPOINT :1
## :0 1st Qu.:4 epsg:4326 :0
## Agronomia :0 Median :4 +proj=long...:0
## Almagro :0 Mean :4
## Balvanera :0 3rd Qu.:4
## Barracas :0 Max. :4
## (Other) :0
Parque Patricios cuenta con 4 Estaciones de Servicio
Grafiquemos las estaciones de servicio de ambos dataset en un mismo plano, verde las de BA Datos, y Rojo las de OSM.
ggplot() +
geom_sf(data = calles,
color = "darkslateblue") +
geom_sf(data = ES,
color = "red", size = 5)+
geom_sf(data = seleccion,
color = "green")
Estarian faltando 2 estaciones de servicio en el dataset de BA Datos
Revisamos en google street view para ver si efectivamente existian esas estaciones
¿Por que faltan Estaciones de Servicios en el dataset oficial de BA? La última actualizacion del archivo de BA Data es de mayo del 2019 y las estaciones parecen viejas por lo que debería ser otro motivo.
Vamos a buscar tweets que mencionen alguno de los términos “parque”, “plaza”, “arbolado” o “arboles” en un radio de 10 millas (~16 km) en torno obelisco de la Ciudad de Buenos Aires.
El parámetro n = 5000 es para limitar la búsqueda a los primeros 5000 tweets hallados.
El parámetro include_rts = FALSE descarta retweets
tweets.BA <- search_tweets(q = "parque OR plaza OR arbolado OR arboles",
geocode = "-34.603722,-58.381592,10mi",
include_rts = FALSE,
n = 5000,
retryonratelimit = TRUE)
## Registered S3 method overwritten by 'openssl':
## method from
## print.bytes Rcpp
Exploramos el contenido
names(tweets.BA)
## [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"
Obtenemos un top 5 de los tweets más populares (con más retweets), su procedencia, y el contenido del tweet:
tweets.BA %>%
top_n(5, retweet_count) %>%
arrange(desc(retweet_count)) %>%
select(screen_name, retweet_count, location, text)
## # A tibble: 5 x 4
## screen_name retweet_count location text
## <chr> <int> <chr> <chr>
## 1 MagaliNarvaja 7248 Buenos Aires, ~ unas ganas de tener a una pe~
## 2 Lautiroman19~ 2512 Buenos Aires, ~ AHORA. Impresionante. Plaza ~
## 3 WolffWaldo 1928 Buenos Aires, ~ "El #8SApoyamosALaLeona por~
## 4 zlotomarcelo 1543 Ciudad Autónom~ El macrismo repartiendo merc~
## 5 mauriciomacri 1062 Buenos Aires, ~ En vivo desde Córdoba: el Pr~
El tweet de magalí buscando gente nueva fue el mas popular. De los 4 puestos siguientes, 3 eran de carácter político.
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, "days")
El pico de actividad (dentro de la muestra que tomamos) se da el Sabado 31/8 y el domingo 8/9.
tweets.dia <- tweets.BA %>%
mutate(dia = as.Date(substr(created_at, 1,10))) %>%
filter(dia == as.Date("2019-08-10"))
Podemos ver la actividad según pasan las horas de un determinado día, tomamos como ejemplo el dia Sabado 31/8, cuando se produjo el pico semanal
tweets.BA %>%
mutate(dia = as.Date(substr(created_at, 1,10))) %>%
filter(dia == as.Date("2019-08-31")) %>%
ts_plot("hours")
La actividad se dispara despues del mediodía.
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: 7 x 4
## screen_name followers_count location text
## <chr> <int> <chr> <chr>
## 1 mauriciomac~ 4935311 Buenos Aires,~ En vivo desde Córdoba: el Pr~
## 2 clarincom 2911466 Buenos Aires,~ Tras cinco meses de obras in~
## 3 clarincom 2911466 Buenos Aires,~ "Tragedia en el parque nacio~
## 4 clarincom 2911466 Buenos Aires,~ Sigue la polémica en Tierra ~
## 5 clarincom 2911466 Buenos Aires,~ Tras dos años de reclamo vec~
## 6 clarincom 2911466 Buenos Aires,~ María Eugenia Vidal tendrá s~
## 7 clarincom 2911466 Buenos Aires,~ Mejoran una plaza de Villa A~
En este caso, a diferencia del top5 de retweets, los 5 primeros son de caracter político.
Veamos la distribución las cuentas mas populares
options(scipen = 20)
ggplot(tweets.BA)+
geom_histogram(aes(x = followers_count))+
labs(title = "Distribución de popularidad",
x = "Cantidad followers",
y = "Cuentas") +
theme_minimal()
## `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
Vamos a 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_EEVV <- 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_EEVV_geo <- tweets_EEVV %>%
filter(!is.na(lat), !is.na(lon))
El resultado evidencia que los tweets georeferenciados son sólo una pequeña fracción del total que se produce:
nrow(tweets_EEVV_geo)
## [1] 351
Delimitamos los bordes externos del boundinbox
bbox <- c(min(tweets_EEVV_geo$lon),
min(tweets_EEVV_geo$lat),
max(tweets_EEVV_geo$lon),
max(tweets_EEVV_geo$lat))
require(leaflet)
gama <- colorNumeric(palette = "plasma",
domain = tweets_EEVV_geo$followers_count)
leaflet(tweets_EEVV_geo) %>%
addTiles() %>%
addCircleMarkers(popup = ~text,
color = ~gama(followers_count)) %>%
addLegend(title = "Popularidad", pal = gama, values = ~followers_count)
## Assuming "lon" and "lat" are longitude and latitude, respectively
El tweet del usuario mas popular, un runner que nos regala la siguiente postal desde el Parque 3 de Febrero:
"Pasadas en la mañana de Palermo. Los días no pueden ser más lindos, espectacular el cielo del Parque. Mi gente a pleno. Tarea cumplida. #skechersargentina #correrayuda #correrparavivir… https://t.co/ps4Bn7VysJ"