Este es un archivo R Markdown (.Rmd):
mezcla texto explicativo con bloques de código de R (las zonas grises
que empiezan con ```{r}).
Tienes dos formas de usarlo en clase:
Ctrl + Enter). Ideal para
principiantes..Rmd en
RStudio y presiona el botón Knit. R ejecutará todo el
código y generará un informe en HTML con los resultados y las gráficas
incrustadas.Todo el código de este documento fue probado y funciona. Si algo falla, casi siempre es porque falta instalar un paquete (ver la siguiente sección).
En R, un paquete es una caja de herramientas que
alguien ya programó. Solo se instala una vez (con
install.packages) y se carga en cada
sesión (con library).
# EJECUTA ESTO UNA SOLA VEZ (quita el # y córrelo en la consola).
# Requiere conexión a internet. Puede tardar unos minutos.
install.packages(c("agricolae", # datos y estadística clásica del agro
"agridat", # +390 conjuntos de datos agrícolas reales
"ggplot2", # el paquete estrella para gráficos
"dplyr")) # para resumir y manipular tablas
# ESTO SÍ se ejecuta cada vez que abres R:
library(agricolae)
library(agridat)
library(ggplot2)
library(dplyr)
¿Qué contienen?
agricolae: paquete peruano (UNAM La Molina) hecho
específicamente para investigación agrícola. Trae datos como
sweetpotato (camote), cotton (algodón) y
soil (análisis de suelos).agridat: una enciclopedia con 392 conjuntos de
datos reales de experimentos agrícolas (maíz, soya, trigo,
plagas, suelos, etc.).ggplot2: para construir gráficos “por capas”, sumando
elementos con el símbolo +.dplyr: para calcular promedios por grupo de forma muy
legible (usa el operador %>%).Regla de oro: antes de graficar o calcular nada, mira cómo son tus datos.
Usaremos sweetpotato de agricolae: un
experimento donde se midió el rendimiento
(yield) de camote bajo 4 tratamientos
virales (virus).
data(sweetpotato) # carga el conjunto de datos en memoria
head(sweetpotato) # muestra las primeras filas
## virus yield
## 1 cc 28.5
## 2 cc 21.7
## 3 cc 23.0
## 4 fc 14.9
## 5 fc 10.6
## 6 fc 13.1
str(sweetpotato) # estructura: qué variables hay y de qué tipo
## 'data.frame': 12 obs. of 2 variables:
## $ virus: Factor w/ 4 levels "cc","fc","ff",..: 1 1 1 2 2 2 3 3 3 4 ...
## $ yield: num 28.5 21.7 23 14.9 10.6 13.1 41.8 39.2 28 38.2 ...
dim(sweetpotato) # número de filas y columnas
## [1] 12 2
Interpretación de str:
virus es un factor (variable
categórica) con 4 niveles: cc, fc,
ff, oo.yield es numérica (el rendimiento
medido).summary(sweetpotato$yield) # mínimo, máximo, media, mediana, cuartiles
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 10.60 20.00 28.25 27.62 38.45 41.80
mean(sweetpotato$yield) # media (promedio)
## [1] 27.625
median(sweetpotato$yield) # mediana
## [1] 28.25
sd(sweetpotato$yield) # desviación estándar (qué tan dispersos están los datos)
## [1] 11.07874
Casi siempre queremos comparar tratamientos. Con dplyr
calculamos, para cada virus, el número de datos, la
media, la desviación estándar y el error estándar (la
media dividida por la raíz de n):
resumen <- sweetpotato %>%
group_by(virus) %>%
summarise(
n = n(),
media = mean(yield),
de = sd(yield),
ee = sd(yield) / sqrt(n()) # error estándar de la media
)
resumen
## # A tibble: 4 × 5
## virus n media de ee
## <fct> <int> <dbl> <dbl> <dbl>
## 1 cc 3 24.4 3.61 2.08
## 2 fc 3 12.9 2.16 1.25
## 3 ff 3 36.3 7.33 4.23
## 4 oo 3 36.9 4.3 2.48
Ya se ve que los tratamientos ff y oo
rinden más que cc y fc. Vamos a
visualizarlo.
La lógica de ggplot2 siempre es la misma:
ggplot(datos, aes(x = ..., y = ...)) + # 1) qué variables van en cada eje
geom_XXX() + # 2) qué tipo de gráfico (puntos, cajas, barras...)
labs(...) + # 3) títulos y nombres de ejes
theme_minimal() # 4) apariencia
Ideal para comparar la distribución de una variable numérica entre varios grupos. La caja muestra el 50 % central de los datos; la línea del medio es la mediana.
ggplot(sweetpotato, aes(x = virus, y = yield, fill = virus)) +
geom_boxplot(alpha = 0.8) +
geom_jitter(width = 0.12, alpha = 0.5) + # agrega los puntos reales, desplazados
labs(title = "Rendimiento de camote por tratamiento viral",
x = "Tratamiento (virus)",
y = "Rendimiento (kg/parcela)") +
theme_minimal() +
theme(legend.position = "none") # ocultamos la leyenda (es redundante)
Cómo leerlo: cajas más altas = mayor rendimiento. Cajas más “largas” = datos más dispersos. Los puntos por fuera de los bigotes serían valores atípicos.
Para “barras de promedios” el orden correcto es: 1) calcular
las medias, 2) graficarlas. Aquí usamos un experimento de
control de plagas (beall.webworms de
agridat): se contó el número de gusanos por parcela con y
sin insecticida (spray).
data(beall.webworms)
# 1) calculamos la media y el error estándar por grupo
res_plaga <- beall.webworms %>%
group_by(spray) %>%
summarise(media = mean(y),
ee = sd(y) / sqrt(n()))
res_plaga
## # A tibble: 2 × 3
## spray media ee
## <fct> <dbl> <dbl>
## 1 N 1.13 0.0527
## 2 Y 0.458 0.0292
# 2) graficamos las medias como barras, con barras de error
ggplot(res_plaga, aes(x = spray, y = media, fill = spray)) +
geom_col(width = 0.6) + # barras a partir de valores ya calculados
geom_errorbar(aes(ymin = media - ee, ymax = media + ee), # barras de error (± 1 EE)
width = 0.2) +
scale_x_discrete(labels = c("N" = "Sin insecticida",
"Y" = "Con insecticida")) +
labs(title = "Número medio de gusanos por parcela",
x = NULL,
y = "Gusanos por parcela (media ± EE)") +
theme_minimal() +
theme(legend.position = "none")
Interpretación agronómica: el insecticida reduce a menos de la mitad la población media de gusanos. Las barras de error, cortas y sin traslape, sugieren que la diferencia es consistente.
Nota importante:
geom_col()dibuja la altura que TÚ le das (las medias que calculaste). No lo confundas congeom_bar(), que por defecto cuenta filas.
Sirve para ver la relación entre dos variables
numéricas. Usaremos australia.soybean
(agridat): contenido de proteína
vs. aceite en granos de soya.
Primero medimos la correlación con un número, r, entre
-1 y 1:
data(australia.soybean)
# Coeficiente de correlación de Pearson
r <- cor(australia.soybean$protein, australia.soybean$oil)
round(r, 3)
## [1] -0.758
# Prueba estadística: ¿la correlación es significativa?
cor.test(australia.soybean$protein, australia.soybean$oil)
##
## Pearson's product-moment correlation
##
## data: australia.soybean$protein and australia.soybean$oil
## t = -24.956, df = 462, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.7939767 -0.7160695
## sample estimates:
## cor
## -0.75771
r es cercano a -0.76: correlación
negativa y fuerte. Ahora el gráfico, con una línea de
tendencia (geom_smooth):
ggplot(australia.soybean, aes(x = protein, y = oil)) +
geom_point(alpha = 0.5, color = "darkgreen") +
geom_smooth(method = "lm", se = TRUE, color = "black") + # recta de regresión
labs(title = paste0("Proteína vs. aceite en soya (r = ", round(r, 2), ")"),
x = "Proteína (%)",
y = "Aceite (%)") +
theme_minimal()
Interpretación: a mayor proteína, menor aceite. Es una relación conocida en mejoramiento de soya: seleccionar por más proteína tiende a bajar el aceite. La recta resume esa tendencia.
Cuando tienes muchas variables numéricas (por
ejemplo un análisis de suelos completo), un mapa de calor muestra todas
las correlaciones de un vistazo. Usamos soil de
agricolae.
data(soil)
# Elegimos algunas propiedades del suelo
variables <- c("pH", "MO", "CIC", "P", "K", "clay", "sand", "Ca", "Mg")
# Matriz de correlaciones -> tabla larga para ggplot
matriz <- round(cor(soil[, variables]), 2)
tabla <- as.data.frame(as.table(matriz))
names(tabla) <- c("Var1", "Var2", "cor")
ggplot(tabla, aes(x = Var1, y = Var2, fill = cor)) +
geom_tile(color = "white") +
geom_text(aes(label = cor), size = 3) +
scale_fill_gradient2(low = "#b2182b", mid = "white", high = "#2166ac",
midpoint = 0, limits = c(-1, 1)) +
labs(title = "Correlación entre propiedades del suelo",
x = NULL, y = NULL, fill = "r") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Cómo leerlo: azul = correlación positiva, rojo =
negativa. Por ejemplo, clay (arcilla) y sand
(arena) están fuertemente correlacionadas de forma negativa: donde hay
más de una, hay menos de la otra.
Esto es un poco más avanzado, pero es el pan de cada día en
la experimentación agropecuaria. El ANOVA responde:
¿las diferencias entre tratamientos son reales o pura
casualidad? Y la prueba de Tukey (HSD) de
agricolae nos dice cuáles tratamientos difieren,
agrupándolos con letras.
# ¿El rendimiento del camote depende del virus?
modelo <- aov(yield ~ virus, data = sweetpotato)
summary(modelo) # si Pr(>F) < 0.05, hay diferencias significativas
## Df Sum Sq Mean Sq F value Pr(>F)
## virus 3 1170.2 390.1 17.34 0.000733 ***
## Residuals 8 179.9 22.5
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Comparación de medias con letras (a, b, c...)
comparacion <- HSD.test(modelo, "virus", group = TRUE)
comparacion$groups
## yield groups
## oo 36.90000 a
## ff 36.33333 ab
## cc 24.40000 bc
## fc 12.86667 c
Cómo leer las letras: tratamientos que comparten una letra no difieren significativamente; los que no comparten ninguna letra sí difieren. Así se reportan resultados en artículos y tesis del agro.
Para practicar con los mismos paquetes (todos los datos ya están instalados):
agricolae::cotton
(rendimiento de algodón por sitio), calcula la media y la desviación
estándar de yield para cada site. Pista:
cambia virus por site y
sweetpotato por cotton en el código de la
Sección 4.yield según
site en cotton. ¿Qué sitio rinde más?beall.webworms,
compara el número medio de gusanos según trt (tratamiento)
en lugar de spray.agridat::lasrosas.corn
(maíz de precisión en Argentina), grafica la dispersión entre nitrógeno
aplicado (nitro) y rendimiento (yield), y
calcula su correlación.lasrosas.corn, haz un boxplot
del rendimiento (yield) según el nivel de nitrógeno
(nf).agricolae y
agridat son fuentes confiables y muy
usadas en docencia agropecuaria. Con
data(package = "agridat") puedes ver la lista completa de
sus 392 conjuntos de datos.agridat incluye varios: australia.soybean,
nass.soybean, davidian.soybean,
gauch.soy, pacheco.soybean, entre otros.soymap: no corresponde a un
paquete estándar de datos en CRAN que se pueda verificar, así que en
este material se reemplazó por los datos de soya de agridat
(ya probados). Si tienes una fuente concreta para soymap,
compártela y adaptamos los ejemplos.Para ver la ficha de ayuda de cualquier conjunto de datos y entender
sus variables, usa ?:
?sweetpotato
?australia.soybean
?lasrosas.corn