1. Introducción y Marco Teórico

El Análisis Factorial Simple (realizado a través del Análisis de Componentes Principales, PCA) es una técnica estadística multivariada de reducción de dimensionalidad. Su objetivo principal en la investigación agronómica es identificar variables no observadas directamente, denominadas factores latentes, que expliquen las interrelaciones y patrones de variabilidad entre un conjunto amplio de mediciones de campo.

En este estudio se analiza un ensayo agronómico en el CAM con 100 parcelas experimentales de maíz (Zea mays), con el propósito de simplificar el conjunto de variables fisiológicas y productivas en un mapa factorial interpretable. Los datos son simulados de un cultivo de maiz porva v508.

2. Definición de Variables Utilizadas

Para la realización de este análisis factorial se utilizaron 6 variables agronómicas continuas:

  1. Rendimiento_t_ha: Rendimiento total de grano seco ajustado por hectárea (expresado en t/ha).
  2. Biomasa_t_ha: Biomasa fresca vegetal acumulada en la parcela al momento de cosecha (expresado en t/ha).
  3. Altura_Planta_cm: Altura media de la planta medida desde la base del tallo hasta la inserción de la espiga (expresado en cm).
  4. Peso_100_Granos_g: Peso seco promedio de 100 granos representativos tomados al azar (expresado en gramos).
  5. Proteina_Grano_pct: Porcentaje de proteína cruda acumulada en el endospermo del grano seco (%).
  6. Almidon_Grano_pct: Porcentaje de almidón acumulado en el grano seco (%).

3. INSTALACIÓN Y CARGA DE LIBRERÍAS

if (!require("readxl")) install.packages("readxl")
## Cargando paquete requerido: readxl
if (!require("dplyr")) install.packages("dplyr")
## Cargando paquete requerido: 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
if (!require("ggplot2")) install.packages("ggplot2")
## Cargando paquete requerido: ggplot2
if (!require("corrplot")) install.packages("corrplot")
## Cargando paquete requerido: corrplot
## corrplot 0.95 loaded
library(readxl)
library(dplyr)
library(ggplot2)
library(corrplot)

4. Carga de los datos desde Excel

Se define la ruta del archivo, se comprueba que exista y se lee la hoja file_path <- “C:/Users/yorhl/Downloads/Datos_Agronomicos_Maiz_Analisis_Factorial.xlsx”y se seleccionan de manera exclusiva las 6 variables continuas definidas en el estudio, omitiendo identificadores secundarios.

# 1. CARGAR LIBRERIAS
library(readxl)
library(dplyr)

# 2. CARGA Y PREPROCESAMIENTO DE DATOS DESDE EXCEL
file_path <- "C:/Users/yorhl/Downloads/Datos_Agronomicos_Maiz_Analisis_Factorial.xlsx"

# Verificar que el archivo exista
if (!file.exists(file_path)) {
  stop("No se encontro el archivo en la ruta: ", file_path)
}

# Leer la hoja de Excel
df_maiz <- read_excel(file_path, sheet = "Datos_Maiz")

# Seleccionar solo las variables cuantitativas agronomicas
var_cols <- c(
  "Rendimiento_t_ha",
  "Biomasa_t_ha",
  "Altura_Planta_cm",
  "Peso_100_Granos_g",
  "Proteina_Grano_pct",
  "Almidon_Grano_pct"
)

# Verificar que existan las columnas
no_encontradas <- setdiff(var_cols, names(df_maiz))

if (length(no_encontradas) > 0) {
  stop("Faltan estas columnas: ",
       paste(no_encontradas, collapse = ", "))
}

# Seleccionar variables
X <- df_maiz %>% select(all_of(var_cols))

# Mostrar resultados
head(X)
## # A tibble: 6 × 6
##   Rendimiento_t_ha Biomasa_t_ha Altura_Planta_cm Peso_100_Granos_g
##              <dbl>        <dbl>            <dbl>             <dbl>
## 1             9.99         45.0             246.              33.1
## 2             7.49         40.6             236.              31.4
## 3            11.3          54.3             265               33.6
## 4            10            49.4             261.              30.5
## 5            12.7          61.0             280.              38.3
## 6            10.7          52.8             259.              37.3
## # ℹ 2 more variables: Proteina_Grano_pct <dbl>, Almidon_Grano_pct <dbl>
View(X)

# Revisar estructura y dimensiones
str(X)
## tibble [100 × 6] (S3: tbl_df/tbl/data.frame)
##  $ Rendimiento_t_ha  : num [1:100] 9.99 7.49 11.32 10 12.73 ...
##  $ Biomasa_t_ha      : num [1:100] 45 40.5 54.3 49.4 61 ...
##  $ Altura_Planta_cm  : num [1:100] 246 236 265 261 280 ...
##  $ Peso_100_Granos_g : num [1:100] 33.1 31.4 33.6 30.5 38.3 ...
##  $ Proteina_Grano_pct: num [1:100] 9.71 9.6 9.09 8.37 10.8 ...
##  $ Almidon_Grano_pct : num [1:100] 70.8 71.8 72.1 73.8 70.4 ...
dim(X)
## [1] 100   6
# Comprobar valores faltantes
colSums(is.na(X))
##   Rendimiento_t_ha       Biomasa_t_ha   Altura_Planta_cm  Peso_100_Granos_g 
##                  0                  0                  0                  0 
## Proteina_Grano_pct  Almidon_Grano_pct 
##                  0                  0

5. RESUMEN ESTADÍSTICO DE CAMPO

Este paso se calcula la estadística de tendencia central y dispersión como lo es la (Media, Desviación Estándar, Mínimo, Mediana y Máximo). Su propósito principal es verificar que los rangos evaluados se encuentren dentro de los límites biológicos reales del cultivo de maíz.

summary_stats <- X %>%
  summarise(across(everything(), list(
    Media = ~mean(.),
    Desv_Est = ~sd(.),
    Min = ~min(.),
    Mediana = ~median(.),
    Max = ~max(.)
  )))

# Mostrar la tabla transpuesta
t(summary_stats)
##                                   [,1]
## Rendimiento_t_ha_Media       10.273800
## Rendimiento_t_ha_Desv_Est     1.783361
## Rendimiento_t_ha_Min          5.500000
## Rendimiento_t_ha_Mediana     10.400000
## Rendimiento_t_ha_Max         14.500000
## Biomasa_t_ha_Media           50.938000
## Biomasa_t_ha_Desv_Est         7.238772
## Biomasa_t_ha_Min             32.000000
## Biomasa_t_ha_Mediana         52.235000
## Biomasa_t_ha_Max             67.910000
## Altura_Planta_cm_Media      255.878000
## Altura_Planta_cm_Desv_Est    21.472649
## Altura_Planta_cm_Min        195.000000
## Altura_Planta_cm_Mediana    258.650000
## Altura_Planta_cm_Max        315.000000
## Peso_100_Granos_g_Media      33.991700
## Peso_100_Granos_g_Desv_Est    3.671987
## Peso_100_Granos_g_Min        25.150000
## Peso_100_Granos_g_Mediana    33.905000
## Peso_100_Granos_g_Max        43.000000
## Proteina_Grano_pct_Media      9.831700
## Proteina_Grano_pct_Desv_Est   1.092057
## Proteina_Grano_pct_Min        7.200000
## Proteina_Grano_pct_Mediana    9.820000
## Proteina_Grano_pct_Max       12.310000
## Almidon_Grano_pct_Media      71.608400
## Almidon_Grano_pct_Desv_Est    1.331602
## Almidon_Grano_pct_Min        67.940000
## Almidon_Grano_pct_Mediana    71.710000
## Almidon_Grano_pct_Max        74.630000

6. MATRIZ DE CORRELACIÓN DE PEARSON

Se calcula la matriz de correlación lineal de Pearson (\(r\)) entre todas las parejas de variables y se despliega un mapa de calor (heatmap). Esto permite identificar correlaciones previas que justifiquen la aplicación del análisis factorial.

matriz_corr <- cor(X)

# Visualización gráfica de la matriz de correlación
corrplot(matriz_corr, 
         method = "color", 
         type = "upper", 
         addCoef.col = "black", 
         tl.col = "black", 
         tl.srt = 45,
         title = "Matriz de Correlación entre Variables de Maíz", 
         mar = c(0,0,2,0))

# 7. ANÁLISIS FACTORIAL / COMPONENTES PRINCIPALES (PCA) Las variables se estandarizan mediante Z-score (scale()) para evitar sesgos por las diferentes unidades de medida (cm, t/ha, %). Posteriormente, se extraen los factores latentes principales utilizando la descomposición en componentes principales (prcomp()).

# Estandarización de variables
X_scaled <- scale(X)

# Extracción de factores
pca_res <- prcomp(X_scaled, center = TRUE, scale. = TRUE)

# Varianza Explicada por cada factor
var_exp <- (pca_res$sdev^2 / sum(pca_res$sdev^2)) * 100
var_acum <- cumsum(var_exp)

cat(sprintf("Factor 1 (Vigor y Rendimiento): %.2f%% de varianza\n", var_exp[1]))
## Factor 1 (Vigor y Rendimiento): 61.63% de varianza
cat(sprintf("Factor 2 (Calidad Nutricional): %.2f%% de varianza\n", var_exp[2]))
## Factor 2 (Calidad Nutricional): 35.34% de varianza
cat(sprintf("Varianza Acumulada (F1 + F2):   %.2f%%\n", var_acum[2]))
## Varianza Acumulada (F1 + F2):   96.97%
# Cargas factoriales (Factor Loadings)
loadings_df <- as.data.frame(pca_res$rotation[, 1:2])
colnames(loadings_df) <- c("Factor_1_Vigor_Rendimiento", "Factor_2_Calidad_Nutricional")

print(round(loadings_df, 3))
##                    Factor_1_Vigor_Rendimiento Factor_2_Calidad_Nutricional
## Rendimiento_t_ha                        0.440                       -0.340
## Biomasa_t_ha                            0.462                       -0.290
## Altura_Planta_cm                        0.452                       -0.320
## Peso_100_Granos_g                       0.483                        0.232
## Proteina_Grano_pct                      0.282                        0.563
## Almidon_Grano_pct                      -0.275                       -0.572

7. MAPA PERCEPTUAL FACTORIAL (BIPLOT EN ggplot2)

Se construye la representación gráfica del espacio bidimensional definido por los dos primeros factores latentes utilizando ggplot2. Cada variable se proyecta como un vector que señala la dirección y fuerza de su asociación con los ejes.

loadings_df$Variable <- rownames(loadings_df)

ggplot(loadings_df, aes(x = Factor_1_Vigor_Rendimiento, y = Factor_2_Calidad_Nutricional)) +
  # Vectores/flechas de las variables
  geom_segment(aes(x = 0, y = 0, xend = Factor_1_Vigor_Rendimiento, yend = Factor_2_Calidad_Nutricional),
               arrow = arrow(length = unit(0.3, "cm")), color = "#2b5c8f", linewidth = 1.1) +
  # Etiquetas de las variables
  geom_label(aes(label = Variable), color = "#800000", fontface = "bold", fill = "white") +
  # Ejes de referencia
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") +
  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50") +
  # Límites del plano
  xlim(-1.2, 1.2) + ylim(-1.2, 1.2) +
  # Títulos y etiquetas
  labs(
    title = "Plano Factorial de Variables Agronómicas en Maíz (Zea mays)",
    subtitle = "Análisis Factorial Simple mediante Componentes Principales",
    x = sprintf("Factor 1: Vigor Vegetativo y Rendimiento (%.1f%% Varianza)", var_exp[1]),
    y = sprintf("Factor 2: Calidad y Composición de Grano (%.1f%% Varianza)", var_exp[2])
  ) +
  theme_minimal(base_family = "sans") +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray30"),
    axis.title = element_text(face = "bold", size = 10)
  )

8: Conclusiones