Maestría en Geomática
Alicia Arévalo Robinson
05.03.2026
Punto 1. ¿Cuáles de los datos obtenidos corresponden a variables cuantitativas (discretas, continuas) cuales son regionalizadas, ¿cuáles a variables cualitativas? Indique la escala de medición a la cual pertenece cada variable.
Punto 2. Construya una tabla y la respectiva gráfica para alguna de las variables cualitativas. Exprese la información en términos absolutos, porcentuales, de un ejemplo de razón.
Variable cualitativa: Uso del suelo (landuse)
library(readxl)
library(ggplot2)
# Cargar dataset
meuse <- read_excel("meuse.xlsx")
# Frecuencias
fa <- table(meuse$landuse) # absolutas
fr <- prop.table(fa) # relativas (proporción)
fap <- cumsum(fa) # absolutas acumuladas
frp <- cumsum(fr) # relativas acumuladas
# Tabla
tabla <- data.frame(
Uso_Suelo = names(fa),
Frec_Absoluta = as.integer(fa),
Frec_Relativa = round(as.numeric(fr), 4),
Frec_Rel_Pct = paste0(round(as.numeric(fr) * 100, 2), "%"),
FA_Acumulada = as.integer(fap)
)
print(tabla, row.names = FALSE)
## Uso_Suelo Frec_Absoluta Frec_Relativa Frec_Rel_Pct FA_Acumulada
## Aa 2 0.0129 1.29% 2
## Ab 8 0.0516 5.16% 10
## Ag 5 0.0323 3.23% 15
## Ah 39 0.2516 25.16% 54
## Am 22 0.1419 14.19% 76
## B 3 0.0194 1.94% 79
## Bw 6 0.0387 3.87% 85
## DEN 1 0.0065 0.65% 86
## Fh 1 0.0065 0.65% 87
## Fw 10 0.0645 6.45% 97
## Ga 3 0.0194 1.94% 100
## NA 1 0.0065 0.65% 101
## SPO 1 0.0065 0.65% 102
## STA 2 0.0129 1.29% 104
## Tv 1 0.0065 0.65% 105
## W 50 0.3226 32.26% 155
tabla$Razon <- round(tabla$Frec_Absoluta / tabla$Frec_Absoluta[tabla$Uso_Suelo == "Ah"], 2)
print(tabla[, c("Uso_Suelo", "Razon")], row.names = FALSE)
## Uso_Suelo Razon
## Aa 0.05
## Ab 0.21
## Ag 0.13
## Ah 1.00
## Am 0.56
## B 0.08
## Bw 0.15
## DEN 0.03
## Fh 0.03
## Fw 0.26
## Ga 0.08
## NA 0.03
## SPO 0.03
## STA 0.05
## Tv 0.03
## W 1.28
La categoría ‘Am’ tiene 0.56 veces la frecuencia de ‘Ah’.
p2 <- ggplot(meuse, aes(x = reorder(landuse, landuse, function(x) -length(x)))) +
geom_bar(fill = "#2E86AB", color = "white", width = 0.7) +
geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.4, size = 3.5) +
labs(title = "Frecuencia de Uso del Suelo – Río Mosa",
x = "Uso del suelo", y = "Frecuencia absoluta") +
theme_minimal(base_size = 13)
p2
Punto 3. Construya una tabla de doble entrada y la respectiva gráfica para analizar conjuntamente las variables uso del suelo y frecuencia. ¿Son independientes las variables?
tabla_doble <- table(meuse$landuse, meuse$ffreq)
tabla_doble
##
## 1 2 3
## Aa 0 1 1
## Ab 8 0 0
## Ag 5 0 0
## Ah 19 14 6
## Am 6 11 5
## B 3 0 0
## Bw 3 1 2
## DEN 0 1 0
## Fh 1 0 0
## Fw 5 4 1
## Ga 3 0 0
## NA 1 0 0
## SPO 0 1 0
## STA 0 2 0
## Tv 0 1 0
## W 30 12 8
meuse$ffreq <- factor(meuse$ffreq,
levels = 1:3,
labels = c("1", "2", "3"))
meuse$landuse <- factor(meuse$landuse)
tabla_doble <- table(meuse$landuse, meuse$ffreq)
df_doble <- as.data.frame.table(tabla_doble)
names(df_doble) <- c("Landuse", "Ffreq", "Frecuencia")
ggplot(df_doble, aes(x = Landuse, y = Frecuencia, fill = Ffreq)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Uso del suelo vs Frecuencia de inundación",
x = "Uso del suelo", y = "Frecuencia", fill = "Inundación") +
theme_minimal()
chi_test <- chisq.test(tabla_doble)
## Warning in chisq.test(tabla_doble): Chi-squared approximation may be incorrect
print(chi_test)
##
## Pearson's Chi-squared test
##
## data: tabla_doble
## X-squared = 42.24, df = 30, p-value = 0.06825
if (chi_test$p.value < 0.05) {
cat("Con p =", round(chi_test$p.value, 4),
"< 0.05, se rechaza la hipótesis de independencia.\n")
cat(" Las variables 'uso del suelo' y 'frecuencia de inundación' no son independientes:\n")
cat(" existe asociación estadísticamente significativa entre ellas.\n\n")
} else {
cat("Con p =", round(chi_test$p.value, 4),
"> 0.05, no se rechaza la hipótesis de independencia.\n")
cat(" Las variables parecen ser independientes.\n\n")
}
## Con p = 0.0682 > 0.05, no se rechaza la hipótesis de independencia.
## Las variables parecen ser independientes.
Punto 4. Para la variable cadmiun o copper realice un análisis exploratorio de datos. El análisis exploratorio de datos debe incluir: tabla de distribución de frecuencia apropiada (límites de cada marca de clase, marca media, frecuencias absolutas, frecuencias relativas; frecuencias absolutas y relativas acumuladas), justifique el número de marcas de clase que selecciono. Interprete la marca de clase más representativa, construya el histograma, polígono de frecuencias, ojiva y grafico circular. Comente los resultados de los gráficos. Además, calcular e interpretar: media aritmética, mediana, moda, desviación típica o estándar, error de estimación para la media, coeficiente de variación; percentil 25, 50, 75 y 69. ¿Qué tipo de simetría tienen los datos? Que puede concluir con respecto a la curtosis. ¿Los datos están agrupados o dispersos?. Construya una caja de bigotes e interprétela. Considera que hay valores atípicos, anómalos. Demuestre o refute que la variable cadmiun o copper tiene distribución normal. Justifique su respuesta.
# Limpiar columnas numéricas (coma decimal a punto)
cols_num <- c("cadmium")
meuse[cols_num] <- lapply(meuse[cols_num], function(x) as.numeric(gsub(",", ".", x)))
Variable cadmium
x <- meuse$cadmium
n <- length(x)
Tabla de distribución de frecuencias
# Regla de Sturges para el número de clases
k <- ceiling(1 + 3.322 * log10(n))
print(k)
## [1] 9
Número de marcas de clase = 9
breaks <- seq(min(x), max(x), length.out = k + 1)
breaks[1] <- breaks[1] - 0.001
breaks[k + 1] <- breaks[k + 1] + 0.001
amplitude <- breaks[2] - breaks[1]
marca_clase <- (breaks[-1] + breaks[-(k+1)]) / 2
fa <- hist(x, breaks = breaks, plot = FALSE)$counts
fr <- fa / n
Fa <- cumsum(fa)
Fr <- cumsum(fr)
tabla_freq <- data.frame(
Clase = 1:k,
LI = round(breaks[-(k+1)], 3),
LS = round(breaks[-1], 3),
MarcaClase = round(marca_clase, 3),
FA = fa,
FR_pct = round(fr * 100, 2),
FA_Acum = Fa,
FR_Acum = round(Fr, 4)
)
names(tabla_freq) <- c("Clase", "L.Inferior", "L.Superior", "M.Clase",
"FA", "FR_pct", "FA_Acum", "FR_Acum")
print(tabla_freq, row.names = FALSE)
## Clase L.Inferior L.Superior M.Clase FA FR_pct FA_Acum FR_Acum
## 1 0.199 2.189 1.194 82 52.90 82 0.5290
## 2 2.189 4.178 3.183 37 23.87 119 0.7677
## 3 4.178 6.167 5.172 6 3.87 125 0.8065
## 4 6.167 8.156 7.161 12 7.74 137 0.8839
## 5 8.156 10.144 9.150 9 5.81 146 0.9419
## 6 10.144 12.133 11.139 5 3.23 151 0.9742
## 7 12.133 14.122 13.128 2 1.29 153 0.9871
## 8 14.122 16.111 15.117 0 0.00 153 0.9871
## 9 16.111 18.101 17.106 2 1.29 155 1.0000
Marca de clase más representativa: 1.194 mg/kg (clase 1,
FA=82).
El intervalo con mayor número de observaciones se centra en 1.194 mg/kg.
`
df_hist <- data.frame(x = x)
p4a <- ggplot(df_hist, aes(x = x)) +
geom_histogram(breaks = breaks, fill = "#2E86AB", color = "white", alpha = 0.8) +
geom_freqpoly(breaks = breaks, color = "#E84855", linewidth = 1) +
labs(title = "Histograma y poligono de frecuencias",
x = "Cadmium (mg/kg)", y = "Frecuencia absoluta") +
theme_minimal(base_size = 13)
p4a
- Ojiva
df_ojiva <- data.frame(
valor = breaks[-1],
FA_Acum = c(Fa)
)
p4b <- ggplot(df_ojiva, aes(x = valor, y = FA_Acum)) +
geom_line(color = "#E84855", linewidth = 1.2) +
geom_point(color = "#E84855", size = 2.5) +
labs(title = "Ojiva – Frecuencia Acumulada",
x = "Cadmium (mg/kg)", y = "Frecuencia absoluta acumulada") +
theme_minimal(base_size = 13)
p4b
- Gráfico circular (pie chart) – primeras 6 clases + resto
pie_data <- tabla_freq[, c("Clase", "FA")]
pie_data$label <- paste0("Clase ", pie_data$Clase,
"\n(", round(pie_data$FA / n * 100, 1), "%)")
p4c <- ggplot(pie_data, aes(x = "", y = FA, fill = factor(Clase))) +
geom_bar(stat = "identity", width = 1, color = "white") +
coord_polar("y") +
scale_fill_brewer(palette = "Blues", name = "Clase") +
#geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 3) +
labs(title = "Grafico circular") +
theme_void(base_size = 13)
p4c
- Estadísticos descriptivos
library(moments)
cat(sprintf(" n = %d\n", n))
## n = 155
cat(sprintf(" Media aritmetica = %.4f mg/kg\n", mean(x)))
## Media aritmetica = 3.2458 mg/kg
cat(sprintf(" Mediana = %.4f mg/kg\n", median(x)))
## Mediana = 2.1000 mg/kg
cat(sprintf(" Moda = %.2f mg/kg\n", as.numeric(names(sort(table(x), decreasing = TRUE)[1]))))
## Moda = 0.20 mg/kg
cat(sprintf(" Desviacion estandar = %.4f mg/kg\n", sd(x)))
## Desviacion estandar = 3.5237 mg/kg
cat(sprintf(" Error estandar media = %.4f mg/kg\n", sd(x) / sqrt(n)))
## Error estandar media = 0.2830 mg/kg
cat(sprintf(" Coeficiente variacion = %.2f %%\n", (sd(x) / mean(x)) * 100))
## Coeficiente variacion = 108.56 %
cat(sprintf(" P25 = %.2f mg/kg\n", quantile(x, 0.25)))
## P25 = 0.80 mg/kg
cat(sprintf(" P50 = %.2f mg/kg\n", quantile(x, 0.50)))
## P50 = 2.10 mg/kg
cat(sprintf(" P69 = %.2f mg/kg\n", quantile(x, 0.69)))
## P69 = 3.10 mg/kg
cat(sprintf(" P75 = %.2f mg/kg\n", quantile(x, 0.75)))
## P75 = 3.85 mg/kg
cat(sprintf(" Asimetria (skewness) = %.4f\n", skewness(x)))
## Asimetria (skewness) = 1.7788
cat(sprintf(" Curtosis (kurtosis) = %.4f (exceso: %.4f)\n", kurtosis(x), kurtosis(x) - 3))
## Curtosis (kurtosis) = 6.1299 (exceso: 3.1299)
p4d <- ggplot(df_hist, aes(y = x, x = "")) +
geom_boxplot(fill = "#AED6F1", color = "#1A5276",
outlier.color = "red", outlier.shape = 16, outlier.size = 2) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 4, color = "#E84855") +
labs(title = "Diagrama de caja y bigotes",
subtitle = "Punto rojo = media; puntos rojos = valores atípicos",
x = "", y = "Cadmium (mg/kg)") +
theme_minimal(base_size = 13)
p4d
- Valores atípicos
lim_inf <- quantile(x, 0.25) - 1.5 * IQR(x)
lim_sup <- quantile(x, 0.75) + 1.5 * IQR(x)
atipicos <- x[x < lim_inf | x > lim_sup]
cat("\n── Valores atípicos ────────────────────────────────\n")
##
## ── Valores atípicos ────────────────────────────────
cat(sprintf(" Límite inferior (Q1 - 1.5·RIC) = %.4f\n", lim_inf))
## Límite inferior (Q1 - 1.5·RIC) = -3.7750
cat(sprintf(" Límite superior (Q3 + 1.5·RIC) = %.4f\n", lim_sup))
## Límite superior (Q3 + 1.5·RIC) = 8.4250
cat(sprintf(" Valores atípicos detectados: %d\n", length(atipicos)))
## Valores atípicos detectados: 15
if (length(atipicos) > 0) {
cat(" Valores:", paste(round(sort(atipicos), 2), collapse = ", "), "\n")
cat(" → Sí existen valores atípicos (anómalos), todos por encima del límite superior.\n")
cat(" Posiblemente corresponden a sitios con contaminación localizada extrema.\n\n")
}
## Valores: 8.6, 8.7, 9.4, 9.4, 9.4, 9.5, 10.8, 10.9, 11.2, 11.7, 12, 12.9, 14.1, 17, 18.1
## → Sí existen valores atípicos (anómalos), todos por encima del límite superior.
## Posiblemente corresponden a sitios con contaminación localizada extrema.