Preparación de data

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()