Descripción

Este código reorganiza los datos de varias matrices (individuos × variables), cada una correspondiente a una ocasión distinta, en un único arreglo de tres vías destinado a la estimación de modelos Tucker3. Cada pestaña del archivo representa una de esas ocasiones y, al finalizar el proceso, se obtiene un arreglo de tres vías listo para su preprocesamiento. Este bloque de código lleva a cabo el siguiente flujo de trabajo para preparar los datos de entrada de un modelo Tucker3:

  1. Lectura de las matrices por ocasión
    Se importan las hojas de un archivo (por ejemplo, un Excel) donde cada pestaña contiene una matriz de datos de dimensión \(I \times J\) (individuos × variables) correspondiente a un momento u “ocasión” distinta.

  2. Verificación y homogeneización
    Antes de ensamblar el arreglo tridimensional, el código comprueba que todas las matrices compartan el mismo número de filas (\(I\)) y columnas (\(J\)). Si alguna hoja difiere en dimensiones, se genera un aviso para corregir la fuente de datos.

  3. Construcción del arreglo 3-vías
    A partir de la lista de matrices homogéneas, se utiliza una función (por ejemplo, abind()) o un bucle manual para “apilar” cada ocasión a lo largo de la tercera dimensión. El resultado es un objeto de tipo array con dimensiones
    \[ I \times J \times K \]
    donde:

    • \(I\) = número de individuos
    • \(J\) = número de variables
    • \(K\) = número de ocasiones (pestañas)
Figura 1: Reorganización de los datos.

Figura 1: Reorganización de los datos.

Código en R

1. Instalación de paquetes

install.packages("dplyr")
install.packages("readxl")
install.packages("tidyr")
install.packages("openxlsx")
install.packages("writexl")

2. Carga de librerías

library(readxl)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library(openxlsx)
library(writexl)

3. Lectura y limpieza de datos

#Nota: Recordar actualizar su directorio! 

archivo_original <- "BD_VBA_2024.xlsx"
hojas <- excel_sheets(archivo_original)

# Leer cada hoja y limpiar filas con NA en la primera columna
datos_actividad <- lapply(hojas, function(hoja) {
  df <- read_excel(archivo_original, sheet = hoja, col_names = TRUE) %>%
    as.data.frame()

  # Elimina filas donde la primera columna es NA
  df <- df[!is.na(df[[1]]), ]

  # Fija la primera columna como rownames y la elimina
  rownames(df) <- df[[1]]
  df <- df[-1]
  df
})
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## New names:
## • `` -> `...1`
# Nombrar la lista según las hojas
names(datos_actividad) <- hojas

4. Verificación de consistencia de individuos

# Obtener los nombres de fila de cada hoja
individuos_por_hoja <- lapply(datos_actividad, rownames)
base_individuos <- individuos_por_hoja[[1]]
diferencias <- list()

for (hoja in names(individuos_por_hoja)) {
  if (!setequal(base_individuos, individuos_por_hoja[[hoja]])) {
    diferencias[[hoja]] <- list(
      solo_en_base = setdiff(base_individuos, individuos_por_hoja[[hoja]]),
      solo_en_hoja = setdiff(individuos_por_hoja[[hoja]], base_individuos)
    )
  }
}

if (length(diferencias) > 0) {
  print("Diferencias encontradas entre hojas:")
  print(diferencias)
} else {
  print("Todos los individuos coinciden en todas las hojas.")
}
## [1] "Todos los individuos coinciden en todas las hojas."

5. Unificación de departamentos y reorganización por año

# Todos los departamentos presentes en al menos una hoja
todos_departamentos <- unique(unlist(individuos_por_hoja))

# Se asume que las columnas de la primera hoja son los años
años <- colnames(datos_actividad[[1]])

# Lista para guardar los data frames reorganizados
datos_por_año <- list()

for (año in años) {
  # Data frame base con todos los departamentos como rownames
  df_año <- data.frame(row.names = todos_departamentos)

  for (act in names(datos_actividad)) {
    df_act <- datos_actividad[[act]]

    if (año %in% colnames(df_act)) {
      vec <- rep(NA, length(todos_departamentos))
      names(vec) <- todos_departamentos
      vec[rownames(df_act)] <- df_act[[año]]
      df_año[[act]] <- vec
    } else {
      df_año[[act]] <- NA_real_
    }
  }

  # Asegurar tipo numérico
  df_año <- df_año %>% mutate(across(everything(), as.numeric))

  # Almacenar
  datos_por_año[[año]] <- df_año
}

6. Exportación a un nuevo archivo Excel

archivo_nuevo <- "ruta_directorio"
write_xlsx(datos_por_año, path = archivo_nuevo)