#Estadística descriptiva
#Variable cuantitativa continua: Amoniaco
#Autor: Llumitasig Daniela
#Fecha: 30/05/2026
library(gt)
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
datos<-read.csv("~/Documentos R/TABLAS A/city_day (2).csv")
anomiaco<-datos$NH3
#Extraccion de los "-" de la variable Benzene debido a que son valores inexistentes,
# para un mejor analisis, cambia tamaño muestral de 29531 a 19203
datos$NH3[datos$NH3 == "-"] <- NA
datos$NH3 <- as.numeric(datos$NH3)
amoniaco <- na.omit(datos$NH3)
#Filtrar NH3
amoniaco <- subset(datos$NH3, datos$NH3 >= 0)
length(amoniaco)
## [1] 19203
# Calcular el mínimo y máximo de NH3
min_amoniaco <- min(amoniaco)
max_amoniaco <- max(amoniaco)
min_amoniaco
## [1] 0.01
max_amoniaco
## [1] 352.89
#Calcular rango
R <- max_amoniaco - min_amoniaco
#Calcular intervalos
K <- floor(1 + 3.33 * log10(length(amoniaco)))
K
## [1] 15
#Calcular amplitud
A <-R/K
#Limite inferior
Li <- round(seq(from = min_amoniaco,
to = max_amoniaco - A,
by = A), 2)
#Limite superior
Ls <- round(Li + A, 2)
#Marca de clase
Mc <- (Li+Ls)/2
Mc
## [1] 11.775 35.305 58.825 82.355 105.875 129.405 152.925 176.455 199.975
## [10] 223.505 247.025 270.555 294.075 317.605 341.125
# Vector vacío para guardar las frecuencias de cada clase
ni <- c()
for (i in 1:K) {
if (i < K) {
# Para las primeras clases: [Li , Ls)
ni[i] <- length(subset(amoniaco, amoniaco >= Li[i] & amoniaco < Ls[i]))
} else {
# Para la última clase: [Li , Ls]
ni[i] <- length(subset(amoniaco, amoniaco >= Li[i] & amoniaco <= Ls[i]))
}
}
N <- sum(ni)
hi <- (ni / N) * 100
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))
Intervalo <- paste0("[", round(Li,2), " - ", round(Ls,2), ")")
Intervalo[length(Intervalo)] <- paste0("[", round(Li[length(Li)],2), " - ",
round(Ls[length(Ls)],2), "]")
TDF_amoniaco <- data.frame(
Intervalo = Intervalo,
Mc = round(Mc, 2),
ni = ni,
hi = round(hi, 2),
Ni_asc = Ni_asc,
Ni_desc = Ni_desc,
Hi_asc = round(Hi_asc, 2),
Hi_desc = round(Hi_desc, 2)
)
# Crear fila de totales para amoniaco
totales <- data.frame(
Intervalo = "Totales",
Mc = "-",
ni = sum(ni),
hi = round(sum(hi), 2),
Ni_asc = "-",
Ni_desc = "-",
Hi_asc= "-",
Hi_desc = "-"
)
TDF_amoniaco <- rbind(TDF_amoniaco, totales)
# Tabla 1
TDF_amoniaco %>%
gt() %>%
tab_header(
title = md("*Tabla Nro. 1*"),
subtitle = md("*Distribución de frecuencias de la concentración de amoniaco en el estudio de calidad del aire en la India*")
) %>%
tab_source_note(
source_note = md("Autor: Grupo 1
\n Fuente:https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
) %>%
tab_options(
table.border.top.color = "black",
table.border.bottom.color = "black",
table.border.top.style = "solid",
table.border.bottom.style = "solid",
column_labels.border.top.color = "black",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = px(2),
row.striping.include_table_body = TRUE,
heading.border.bottom.color = "black",
heading.border.bottom.width = px(2),
table_body.hlines.color = "gray",
table_body.border.bottom.color = "black"
)
| Tabla Nro. 1 | |||||||
| Distribución de frecuencias de la concentración de amoniaco en el estudio de calidad del aire en la India | |||||||
| Intervalo | Mc | ni | hi | Ni_asc | Ni_desc | Hi_asc | Hi_desc |
|---|---|---|---|---|---|---|---|
| [0.01 - 23.54) | 11.78 | 12403 | 64.59 | 12403 | 19203 | 64.59 | 100 |
| [23.54 - 47.07) | 35.3 | 4775 | 24.87 | 17178 | 6800 | 89.45 | 35.41 |
| [47.06 - 70.59) | 58.83 | 1306 | 6.80 | 18484 | 2025 | 96.26 | 10.55 |
| [70.59 - 94.12) | 82.36 | 305 | 1.59 | 18789 | 719 | 97.84 | 3.74 |
| [94.11 - 117.64) | 105.88 | 176 | 0.92 | 18965 | 414 | 98.76 | 2.16 |
| [117.64 - 141.17) | 129.4 | 85 | 0.44 | 19050 | 238 | 99.2 | 1.24 |
| [141.16 - 164.69) | 152.93 | 43 | 0.22 | 19093 | 153 | 99.43 | 0.8 |
| [164.69 - 188.22) | 176.45 | 43 | 0.22 | 19136 | 110 | 99.65 | 0.57 |
| [188.21 - 211.74) | 199.98 | 22 | 0.11 | 19158 | 67 | 99.77 | 0.35 |
| [211.74 - 235.27) | 223.5 | 10 | 0.05 | 19168 | 45 | 99.82 | 0.23 |
| [235.26 - 258.79) | 247.02 | 11 | 0.06 | 19179 | 35 | 99.88 | 0.18 |
| [258.79 - 282.32) | 270.56 | 5 | 0.03 | 19184 | 24 | 99.9 | 0.12 |
| [282.31 - 305.84) | 294.08 | 15 | 0.08 | 19199 | 19 | 99.98 | 0.1 |
| [305.84 - 329.37) | 317.6 | 3 | 0.02 | 19202 | 4 | 99.99 | 0.02 |
| [329.36 - 352.89] | 341.12 | 1 | 0.01 | 19203 | 1 | 100 | 0.01 |
| Totales | - | 19203 | 100.00 | - | - | - | - |
| Autor: Grupo 1
Fuente:https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india |
|||||||
# PROCESO DE SIMPLIFICACIÓN PARA NH3 (10 intervalos)
# 1. Mínimo y máximo
min_nh3 <- floor(min(amoniaco, na.rm = TRUE))
max_nh3 <- ceiling(max(amoniaco, na.rm = TRUE))
# 2. Amplitud para 10 intervalos
A_ajustada <- ceiling((max_nh3 - min_nh3) / 10)
# 3. Definir breaks (11 puntos = 10 intervalos)
mis_breaks <- seq(
from = min_nh3,
by = A_ajustada,
length.out = 11
)
# 4. Histograma con los nuevos breaks
histo_amoniaco <- hist(
amoniaco,
breaks = mis_breaks,
plot = FALSE
)
# 5. Límites de clase
Lis <- histo_amoniaco$breaks[1:(length(histo_amoniaco$breaks)-1)]
Lss <- histo_amoniaco$breaks[2:length(histo_amoniaco$breaks)]
# 6. Marca de clase
MCs <- (Lis + Lss) / 2
# 7. Frecuencias
nis <- histo_amoniaco$counts
his <- (nis / sum(nis)) * 100
# 8. Frecuencias acumuladas
Nis_asc <- cumsum(nis)
His_asc <- cumsum(his)
Nis_desc <- rev(cumsum(rev(nis)))
His_desc <- rev(cumsum(rev(his)))
# 9. Intervalos como texto
Intervalos <- paste0(
"[", round(Lis, 2),
" - ",
round(Lss, 2),
")"
)
# Último intervalo cerrado
Intervalos[length(Intervalos)] <- paste0(
"[",
round(Lis[length(Lis)], 2),
" - ",
round(Lss[length(Lss)], 2),
"]"
)
# 10. Crear tabla simplificada
TDF_amoniacosimplificado <- data.frame(
Intervalo = Intervalos,
MC = round(MCs, 2),
ni = nis,
hi = round(his, 2),
Ni_asc = Nis_asc,
Hi_asc = round(His_asc, 2),
Ni_desc = Nis_desc,
Hi_desc = round(His_desc, 2)
)
# 11. Fila de totales
totaless <- data.frame(
Intervalo = "Totales",
MC = "-",
ni = sum(nis),
hi = round(sum(his), 2),
Ni_asc = "-",
Hi_asc = "-",
Ni_desc = "-",
Hi_desc = "-"
)
# 12. Agregar totales
TDF_amoniacosimplificado <- rbind(
TDF_amoniacosimplificado,
totaless
)
# TABLA 2
TDF_amoniacosimplificado %>%
gt() %>%
tab_header(
title = md("*Tabla Nro. 2*"),
subtitle = md("*Distribución de frecuencia simplificada de concentración de amoniaco en el estudio de calidad del aire en la India*")
) %>%
tab_source_note(
source_note = md("Autor: Grupo 1
\nFuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
) %>%
tab_options(
table.border.top.color = "black",
table.border.bottom.color = "black",
table.border.top.style = "solid",
table.border.bottom.style = "solid",
column_labels.border.top.color = "black",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = px(2),
row.striping.include_table_body = TRUE,
heading.border.bottom.color = "black",
heading.border.bottom.width = px(2),
table_body.hlines.color = "gray",
table_body.border.bottom.color = "black"
)
| Tabla Nro. 2 | |||||||
| Distribución de frecuencia simplificada de concentración de amoniaco en el estudio de calidad del aire en la India | |||||||
| Intervalo | MC | ni | hi | Ni_asc | Hi_asc | Ni_desc | Hi_desc |
|---|---|---|---|---|---|---|---|
| [0 - 36) | 18 | 15608 | 81.28 | 15608 | 81.28 | 19203 | 100 |
| [36 - 72) | 54 | 2896 | 15.08 | 18504 | 96.36 | 3595 | 18.72 |
| [72 - 108) | 90 | 412 | 2.15 | 18916 | 98.51 | 699 | 3.64 |
| [108 - 144) | 126 | 143 | 0.74 | 19059 | 99.25 | 287 | 1.49 |
| [144 - 180) | 162 | 63 | 0.33 | 19122 | 99.58 | 144 | 0.75 |
| [180 - 216) | 198 | 38 | 0.20 | 19160 | 99.78 | 81 | 0.42 |
| [216 - 252) | 234 | 18 | 0.09 | 19178 | 99.87 | 43 | 0.22 |
| [252 - 288) | 270 | 11 | 0.06 | 19189 | 99.93 | 25 | 0.13 |
| [288 - 324) | 306 | 12 | 0.06 | 19201 | 99.99 | 14 | 0.07 |
| [324 - 360] | 342 | 2 | 0.01 | 19203 | 100 | 2 | 0.01 |
| Totales | - | 19203 | 100.00 | - | - | - | - |
| Autor: Grupo 1
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india |
|||||||
# Histograma de Ozono con poligono de frecuencia
hist(amoniaco,
breaks = mis_breaks,
main = "Gráfica Nro. 1\nHistograma con el polígono de frecuencias de Amoniaco\n en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Amoniaco (µg/m³)",
ylab = "Cantidad",
col = "#D8BFD8",
xaxt = "n",
cex.main = 0.9,
ylim = c(0, max(histo_amoniaco$counts) * 1.1))
# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)
# Redibujar histograma encima de la cuadrícula
hist(amoniaco,breaks = mis_breaks,col = "#D8BFD8",add = TRUE)
# Polígono de frecuencias
lines(MCs, nis,
type = "o",
col = "red3",
pch = 16,
lwd = 2)
# Eje X personalizado
axis(1,at = mis_breaks,labels = round(mis_breaks, 0),las = 1,cex.axis = 0.9)
#Histograma generado por RStudio
# 1. Creamos el histograma y guardamos la información
histo_amoniaco <- hist(
amoniaco,
breaks = mis_breaks,
plot = FALSE
)
# 2. Creamos el marco del gráfico
hist(
amoniaco,
breaks = mis_breaks,
main = "Gráfica Nro. 2\nDistribución de la concentración de Amoniaco
presente en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Amoniaco (µg/m³)",
ylab = "Cantidad",
col = "#D8BFD8",
ylim = c(0, max(histo_amoniaco$counts) * 1.1),,
xaxt = "n",
cex.main = 0.9
)
# 3. Agregamos las líneas de la cuadrícula
abline(
v = mis_breaks,
col = "gray70",
lty = 2,
lwd = 0.8
)
abline(
h = axTicks(2),
col = "gray70",
lty = 2,
lwd = 0.8
)
# 4. Redibujamos el histograma encima para que las barras queden al frente
hist(
amoniaco,
breaks = mis_breaks,
col = "#D8BFD8",
add = TRUE
)
# 5. Creamos el eje X personalizado
axis(
1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9
)
# Histograma con relación a la totalidad de los datos Amoniaco
hist(
amoniaco,
breaks = mis_breaks,
main = "Gráfica Nro. 3\nDistribución de la concentración de Amoniaco
presente en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Amoniaco (µg/m³)",
ylab = "Cantidad",
col = "#D8BFD8",
ylim = c(0, length(amoniaco)), # Eje Y hasta el tamaño muestral
xaxt = "n",
cex.main = 0.9
)
# Líneas de cuadrícula verticales
abline(
v = mis_breaks,
col = "gray70",
lty = 2,
lwd = 0.8
)
# Líneas de cuadrícula horizontales
abline(
h = axTicks(2),
col = "gray70",
lty = 2,
lwd = 0.8
)
# Redibujar histograma encima de la cuadrícula
hist(
amoniaco,
breaks = mis_breaks,
col = "#D8BFD8",
add = TRUE
)
# Eje X personalizado
axis(
1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9
)
# Histograma que genera RStudio porcentual
plot(histo_amoniaco,
freq = FALSE,
main = "Gráfica Nro. 4\nDistribución porcentual de concentración de Amoniaco
presente en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Amoniaco (µg/m³)",
ylab = "Porcentaje ",
xaxt = "n",
cex.main = 1,
ylim = c(0, max(his) * 1.1))
# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)
# Barras porcentuales
rect(histo_amoniaco$breaks[-length(histo_amoniaco$breaks)],
0,
histo_amoniaco$breaks[-1],
his,
col = "#D8BFD8",
border = "black")
# Eje X personalizado
axis(1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9)
# Histograma porcentual con respecto al total
plot(histo_amoniaco,
freq = FALSE,
main = "Gráfica Nro. 5\nDistribución porcentual de concentración de Amoniaco
presente en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Amoniaco (µg/m³)",
ylab = "Porcentaje",
xaxt = "n",
cex.main = 1,
ylim = c(0, 100))
# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)
# Barras porcentuales
rect(histo_amoniaco$breaks[-length(histo_amoniaco$breaks)],
0,
histo_amoniaco$breaks[-1],
his,
col = "#D8BFD8",
border = "black")
# Eje X personalizado
axis(1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9)
# Diagrama de caja del Amoniaco
boxplot(amoniaco,
horizontal = TRUE,
main = "Gráfica Nro. 6\nDistribución de la concentración de Amoniaco
en el estudio de la calidad del aire en la India (2015-2020)",
xlab = "Ozono (µg/m³)",
col = "#D8BFD8",
border = "black",
cex.main = 0.9)
# Cuadrícula
abline(v = axTicks(1),
col = "gray70",
lty = 2,
lwd = 0.8)
# Ojivas ascendente y descendente
plot(Lss, Nis_asc,
type = "o",
pch = 16,
col = "peachpuff",
lwd = 2,
main = "Gráfica Nro. 7\nDistribución de frecuencia ascendete y descendente
de la concentración de amoniaco",
xlab = "Amoniaco (µg/m³)",
ylab = "Frecuencia",
ylim = c(0, max(Nis_asc)),
xaxt = "n",
cex.main = 0.9)
# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)
# Ojiva descendente
lines(Lss, Nis_desc,
type = "o",
pch = 16,
col = "lightblue",
lwd = 2)
# Eje X personalizado
axis(1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9)
# Leyenda
legend("right",
legend = c("Ojiva ascendente", "Ojiva descendente"),
col = c("peachpuff", "lightblue"),
lwd = 2,
pch = 16)
## Ojiva porcentuales
# Ojivas porcentuales ascendente y descendente
plot(Lss, His_asc,
type = "o",
pch = 16,
col = "peachpuff",
lwd = 2,
main = "Gráfica Nro. 8\nDistribución de frecuencia ascendete y descendente
de la concentración de amoniaco",
xlab = "Amoniaco (µg/m³)",
ylab = "Porcentaje",
ylim = c(0, 100),
xaxt = "n",
cex.main = 0.9)
# Cuadrícula
abline(v = mis_breaks,
col = "gray70",
lty = 2,
lwd = 0.8)
abline(h = axTicks(2),
col = "gray70",
lty = 2,
lwd = 0.8)
# Ojiva descendente
lines(Lss, His_desc,
type = "o",
pch = 16,
col = "lightblue",
lwd = 2)
# Eje X personalizado
axis(1,
at = mis_breaks,
labels = round(mis_breaks, 0),
las = 1,
cex.axis = 0.9)
# Leyenda
legend("right",
legend = c("Ojiva ascendente", "Ojiva descendente"),
col = c("peachpuff", "lightblue"),
lwd = 2,
pch = 16)
library(e1071)
## Warning: package 'e1071' was built under R version 4.5.3
#Indicadores de posición
#Media aritmetica
X <- sum(amoniaco) / length(amoniaco)
X
## [1] 23.48348
#Mediana
Me <- median(amoniaco)
Me
## [1] 15.85
# Moda
Mo <- "[0,36]"
Mo
## [1] "[0,36]"
#Porque la tabla simplificada, la clase número 1 en el intervalo [0,36] tiene la frecuencia más alta.
#La mayor frecuencia es 15608, que está en la posición 1 del vector
# Indicadores de dispersión
# Varianza
var<- var(amoniaco)
var
## [1] 659.682
# Desviación estandar
sd <- sd(amoniaco)
sd
## [1] 25.68427
# Coeficiente de variación (%)
CV <- (sd / X) * 100
CV
## [1] 109.3717
# Indicadores de forma
# Coeficiente de asimetria
install.packages("e1071")
## Warning: package 'e1071' is in use and will not be installed
library(e1071)
As <- skewness(amoniaco)
As
## [1] 4.083355
# Curtosis
library(e1071)
Cu <- kurtosis(amoniaco)
Cu
## [1] 27.95379
# Outliers
cajaBigotes <- boxplot(amoniaco, plot = FALSE)
outliers <- cajaBigotes$out
min(outliers)
## [1] 62.2
max(outliers)
## [1] 352.89
length(outliers)
## [1] 1015
Variable<-"amoniaco"
Rango<-Rango <- "[0.01, 352.89]"
VA <- paste0(
length(outliers),
" (",
round(min(outliers), 2),
" – ",
round(max(outliers), 2),
")"
)
tabla_indicadores <- data.frame(
Variable = c("Amoniaco"),
Rango = paste0("[", min(amoniaco), "; ", max(amoniaco), "]"),
X = X,
Me = round(Me, 2),
Mo = Mo,
V = round(var, 2),
Sd = round(sd, 2),
CV = CV,
As = round(As, 2),
K = round(K, 2),
"Valores Atípicos" = "1015 [62.2 ; 352.89]"
)
library(knitr)
kable(
tabla_indicadores,
align = "c",
caption = "Conclusiones de la variable Amoniaco"
)
| Variable | Rango | X | Me | Mo | V | Sd | CV | As | K | Valores.Atípicos |
|---|---|---|---|---|---|---|---|---|---|---|
| Amoniaco | [0.01; 352.89] | 23.48348 | 15.85 | [0,36] | 659.68 | 25.68 | 109.3717 | 4.08 | 15 | 1015 [62.2 ; 352.89] |
En conclusión:
La variable Amoniaco dada en (µg/ m3) fluctúa entre 0,01 y 582,89 (µg/m3), y sus valores giran entorno a 15.85 con una desviación estándar de 25,68 (µg/m3) siendo un conjunto de valores muy heterogéneos. Los valores se acumulan de manera fuerte en la parte media a alta de la variable, dejando ver un sesgo positivo Con la presencia de 1015 valores atípicos en el intervalo de 62.2 a 352.89 (µg/m3). Por todo lo anterior el compotamiento de la variable es medianamente buena para el ambiente, sin embrgo la presencia de valores atípicos muy marcados representan un riesgo.