Vamos a preparar la data, primero le vamos a subir la base de datos y hacer los cambios que creamos convenientes
# Cargar archivo CSV
datos <- read_csv("data/datset_unl_laposta.csv")
## Rows: 823 Columns: 24
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (14): fecha, hora, plataforma, enlace_post, tipo_ contenido, elemento_di...
## dbl (8): 1, 2, 3, 4, 5, 6, 7, reproducciones
## num (2): comentarios, reacciones
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Ver las primeras filas
head(datos)
## # A tibble: 6 × 24
## fecha hora plataforma enlace_post `tipo_ contenido` elemento_diferenciador
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 01/05/2… 8:16… Facebook https://ww… Imagen Texto corto (-200 car…
## 2 01/05/2… 8:16… X (Twitte… https://x.… Imagen Texto largo (+200 car…
## 3 01/05/2… 8:46… X (Twitte… https://x.… Imagen Texto corto (-200 car…
## 4 01/05/2… 8:46… Facebook https://ww… Imagen Texto largo (+200 car…
## 5 01/05/2… 9:28… X (Twitte… https://x.… Video Texto corto (-200 car…
## 6 01/05/2… 10:2… X (Twitte… https://x.… Reel Pregunta al público ❓
## # ℹ 18 more variables: titulo_post <chr>, comentarios <dbl>, reacciones <dbl>,
## # `1` <dbl>, `2` <dbl>, `3` <dbl>, `4` <dbl>, `5` <dbl>, `6` <dbl>,
## # `7` <dbl>, alcance_views <chr>, reproducciones <dbl>, compartidos <chr>,
## # tematica <chr>, sentimiento <chr>, comentarios_destacados <chr>,
## # copy_post <chr>, responsable <chr>
datos %>%
select(fecha, hora) %>%
head(15) %>%
kable()
fecha | hora |
---|---|
01/05/2025 | 8:16:00 a.m. |
01/05/2025 | 8:16:00 a.m. |
01/05/2025 | 8:46:00 a.m. |
01/05/2025 | 8:46:00 a.m. |
01/05/2025 | 9:28:00 a.m. |
01/05/2025 | 10:29:00 a.m. |
01/05/2025 | 10:39:00 a.m. |
01/05/2025 | 11:28:00 a.m. |
01/05/2025 | 11:28:00 a.m. |
01/05/2025 | 11:47:00 a.m. |
01/05/2025 | 12:04:00 p.m. |
01/05/2025 | 12:05:00 p.m. |
01/05/2025 | 12:16:00 p.m. |
01/05/2025 | 12:58:00 p.m. |
01/05/2025 | 3:56:00 p.m. |
Se hace el cambio del formato de fecha
datos$fecha <- as.Date(datos$fecha, format = "%d/%m/%Y")
datos %>%
select(fecha, hora) %>%
head(15) %>%
kable()
fecha | hora |
---|---|
2025-05-01 | 8:16:00 a.m. |
2025-05-01 | 8:16:00 a.m. |
2025-05-01 | 8:46:00 a.m. |
2025-05-01 | 8:46:00 a.m. |
2025-05-01 | 9:28:00 a.m. |
2025-05-01 | 10:29:00 a.m. |
2025-05-01 | 10:39:00 a.m. |
2025-05-01 | 11:28:00 a.m. |
2025-05-01 | 11:28:00 a.m. |
2025-05-01 | 11:47:00 a.m. |
2025-05-01 | 12:04:00 p.m. |
2025-05-01 | 12:05:00 p.m. |
2025-05-01 | 12:16:00 p.m. |
2025-05-01 | 12:58:00 p.m. |
2025-05-01 | 3:56:00 p.m. |
Se limpia la base se corrige errores de los datos
datos <- datos %>%
mutate(
hora_limpia = str_to_upper(hora), # Todo en mayúsculas
hora_limpia = str_replace_all(hora_limpia, "\\.", ":"), # Reemplazar puntos por dos puntos
hora_limpia = str_trim(hora_limpia), # Eliminar espacios sobrantes
hora_limpia = str_replace(hora_limpia, "P\\:M\\:|PM", "PM"), # Uniformar PM
hora_limpia = str_replace(hora_limpia, "A\\:M\\:|AM", "AM") # Uniformar AM
)
Para convertir en horas de 12 horas, las horas que estan en 24 horas y con PM
# Si tiene AM/PM, usar parse_date_time con formato 12h
datos <- datos %>%
mutate(
hora_estandar = case_when(
str_detect(hora_limpia, "AM|PM") ~ parse_date_time(hora_limpia, orders = c("I:M:S p", "I:M p", "I p")),
TRUE ~ parse_date_time(hora_limpia, orders = c("H:M:S", "H:M"))
)
)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `hora_estandar = case_when(...)`.
## Caused by warning:
## ! 115 failed to parse.
datos$solo_hora <- format(datos$hora_estandar, "%H:%M:%S")
hay que limpiar las horas que estan mal escritas:
# Cargar librerías necesarias
library(dplyr)
library(stringr)
library(lubridate)
# Función para limpiar y convertir hora_limpia
limpiar_hora_limpia <- function(hora_str) {
hora_str <- str_to_upper(hora_str)
hora_str <- str_replace_all(hora_str, "\\.", ":")
hora_str <- str_trim(hora_str)
# Quitar AM/PM si ya está en formato 24h
hora_str <- ifelse(
str_detect(hora_str, "^1[3-9]|^2[0-3]") & str_detect(hora_str, "PM|AM"),
str_remove(hora_str, "\\s*(PM|AM)"),
hora_str
)
# Convertir a hora estandar
hora_estandar <- case_when(
str_detect(hora_str, "AM|PM") ~ parse_date_time(hora_str, orders = c("I:M:S p", "I:M p", "I p")),
TRUE ~ parse_date_time(hora_str, orders = c("H:M:S", "H:M"))
)
return(hora_estandar)
}
# Aplicar la transformación al dataframe
datos <- datos %>%
mutate(
hora_estandar = limpiar_hora_limpia(hora_limpia),
solo_hora = format(hora_estandar, "%H:%M:%S")
)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `hora_estandar = limpiar_hora_limpia(hora_limpia)`.
## Caused by warning:
## ! 115 failed to parse.
# Vista previa del resultado
head(select(datos, hora_limpia, solo_hora))
## # A tibble: 6 × 2
## hora_limpia solo_hora
## <chr> <chr>
## 1 8:16:00 AM 08:16:00
## 2 8:16:00 AM 08:16:00
## 3 8:46:00 AM 08:46:00
## 4 8:46:00 AM 08:46:00
## 5 9:28:00 AM 09:28:00
## 6 10:29:00 AM 10:29:00
Ahora solo extraigo la hora de publicación:
datos <- datos %>%
mutate(hora_publicacion = hour(hms(solo_hora)))
Ahora veo la frecuencia de publicación por hora
table(datos$hora_publicacion) # Frecuencia por hora
##
## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
## 3 7 1 3 4 6 6 6 31 58 67 107 84 32 36 39 34 58 36 20
## 20 21 22 23
## 38 18 14 6
Hago el grafico de publicación por hora:
library(ggplot2)
ggplot(datos, aes(x = hora_publicacion)) +
geom_bar(fill = "steelblue") +
labs(title = "Publicaciones por hora del día",
x = "Hora del día",
y = "Cantidad de publicaciones") +
scale_x_continuous(breaks = 0:23) +
theme_minimal()
## Warning: Removed 109 rows containing non-finite outside the scale range
## (`stat_count()`).
Vamos a graficar por fecha y por plataforma:
library(ggplot2)
ggplot(datos, aes(x = fecha, fill = plataforma)) +
geom_bar(position = "stack") +
labs(title = "Publicaciones por fecha y plataforma",
x = "Fecha",
y = "Número de publicaciones",
fill = "Plataforma") +
theme_minimal()