Los datos crudos son las mediciones y observaciones originales tal como se recopilaron en el campo o laboratorio. En nuestro caso, tenemos datos de evaluación de un sendero que incluyen mediciones de longitud, ancho, pendiente, y observaciones sobre obstáculos.
Una matriz de datos es la organización estructurada de los datos crudos en formato tabular para análisis estadístico, donde:
Para un análisis eficiente en R, los nombres de variables deben seguir estas reglas:
trail_length en lugar
de Trail Length_ o
. como separadores%, (), #cross_slope en lugar de cs# Cargar librerías necesarias
library(readxl) # Para leer archivos Excel
library(janitor) # Para limpiar nombres de variables
library(tidyverse) # Para manipulación y visualización de datos
library(dplyr) # Para manipulación de datos
library(ggplot2) # Para visualización
library(knitr) # Para tablas
library(DT) # Para tablas interactivas# Leer el archivo Excel
# Nota: Ajustar la ruta del archivo según corresponda
datos_crudos_x <- read_excel("datos_trail.xlsx",
sheet = "Sheet1")
# Mostrar las primeras filas de los datos crudos
head(datos_crudos_x)## # A tibble: 6 × 8
## `Measurement #` `Trail length (m)` Walkable tread width (i…¹ `Cross slope (%)`
## <dbl> <dbl> <dbl> <dbl>
## 1 1 0 88 4.1
## 2 2 5 65 2.4
## 3 3 10 71 2.3
## 4 4 15.0 70 3.7
## 5 5 20 64 5.2
## 6 6 23 62 1.7
## # ℹ abbreviated name: ¹`Walkable tread width (in)`
## # ℹ 4 more variables: `Grade (%)` <dbl>,
## # `Tread obstacles (0= no, 1=yes)` <dbl>, `Type of obstacle` <chr>,
## # Observations <chr>
# ler datos desde archivo .csv
datos_crudos_c <- read.csv("datos_trail.csv")
# Mostrar las primeras filas de los datos crudos
head(datos_crudos_c)## Measurement.. Trail.length..m. Walkable.tread.width..in. Cross.slope....
## 1 1 0.00 88 4.1
## 2 2 5.00 65 2.4
## 3 3 10.00 71 2.3
## 4 4 15.01 70 3.7
## 5 5 20.00 64 5.2
## 6 6 23.00 62 1.7
## Grade.... Tread.obstacles..0..no..1.yes. Type.of.obstacle Observations
## 1 3.5 0 Start of trail
## 2 0.9 0
## 3 8.3 0
## 4 12.0 1 Roots
## 5 13.4 1 Roots
## 6 17.3 0
## Nombres de columnas originales:
## [1] "Measurement #" "Trail length (m)"
## [3] "Walkable tread width (in)" "Cross slope (%)"
## [5] "Grade (%)" "Tread obstacles (0= no, 1=yes)"
## [7] "Type of obstacle" "Observations"
Los nombres originales tienen varios problemas: - Espacios en blanco
- Caracteres especiales como %, (),
# - Inconsistencias en formato
# Usar janitor para limpiar nombres de variables
datos <- datos_crudos_x %>%
clean_names()
# Mostrar nombres limpiados
cat("Nombres de columnas después de clean_names():\n")## Nombres de columnas después de clean_names():
## [1] "measurement_number" "trail_length_m"
## [3] "walkable_tread_width_in" "cross_slope_percent"
## [5] "grade_percent" "tread_obstacles_0_no_1_yes"
## [7] "type_of_obstacle" "observations"
# Renombrar algunas variables para mayor claridad
datos <- datos %>%
rename(
medicion = measurement_number,
longitud_sendero_m = trail_length_m,
ancho_transitable_in = walkable_tread_width_in,
pendiente_transversal_pct = cross_slope_percent,
pendiente_grado_pct = grade_percent,
obstaculos_binario = tread_obstacles_0_no_1_yes,
tipo_obstaculo = type_of_obstacle,
observaciones = observations,
)
# Verificar los nuevos nombres
names(datos)## [1] "medicion" "longitud_sendero_m"
## [3] "ancho_transitable_in" "pendiente_transversal_pct"
## [5] "pendiente_grado_pct" "obstaculos_binario"
## [7] "tipo_obstaculo" "observaciones"
## tibble [137 × 8] (S3: tbl_df/tbl/data.frame)
## $ medicion : num [1:137] 1 2 3 4 5 6 7 8 9 10 ...
## $ longitud_sendero_m : num [1:137] 0 5 10 15 20 ...
## $ ancho_transitable_in : num [1:137] 88 65 71 70 64 62 60 75 72 63 ...
## $ pendiente_transversal_pct: num [1:137] 4.1 2.4 2.3 3.7 5.2 1.7 7.3 3.4 3.8 3.1 ...
## $ pendiente_grado_pct : num [1:137] 3.5 0.9 8.3 12 13.4 ...
## $ obstaculos_binario : num [1:137] 0 0 0 1 1 0 0 1 0 0 ...
## $ tipo_obstaculo : chr [1:137] NA NA NA "Roots" ...
## $ observaciones : chr [1:137] "Start of trail" NA NA NA ...
# Seleccionar solo variables numéricas
variables_numericas <- datos %>%
select_if(is.numeric)
# Resumen de variables numéricas
summary(variables_numericas)## medicion longitud_sendero_m ancho_transitable_in
## Min. : 1 Min. : 0.0 Min. : 0.00
## 1st Qu.: 35 1st Qu.:150.3 1st Qu.: 17.00
## Median : 69 Median :340.2 Median : 41.00
## Mean : 69 Mean :332.5 Mean : 40.16
## 3rd Qu.:103 3rd Qu.:510.3 3rd Qu.: 62.00
## Max. :137 Max. :630.5 Max. :120.00
## pendiente_transversal_pct pendiente_grado_pct obstaculos_binario
## Min. : 0.000 Min. : 0.000 Min. :0.0000
## 1st Qu.: 1.700 1st Qu.: 2.700 1st Qu.:0.0000
## Median : 3.600 Median : 6.300 Median :0.0000
## Mean : 3.837 Mean : 7.068 Mean :0.4672
## 3rd Qu.: 5.700 3rd Qu.:10.500 3rd Qu.:1.0000
## Max. :11.300 Max. :23.800 Max. :1.0000
## Distribución de obstáculos en el sendero:
##
## 0 1
## 73 64
##
## Tipos de obstáculos encontrados:
##
## Pipe Rocks Rocks + Roots Root Roots
## 3 36 3 1 12
## Roots + Pipe Step <NA>
## 2 7 73
# Contar NAs por columna
na_count <- datos %>%
ungroup() %>% # <--- Add this line
summarise_all(~sum(is.na(.))) %>%
pivot_longer(everything(), names_to = "Variable", values_to = "NAs") %>%
arrange(desc(NAs))
na_count %>%
kable(caption = "Cantidad de valores faltantes por variable")| Variable | NAs |
|---|---|
| observaciones | 119 |
| tipo_obstaculo | 73 |
| medicion | 0 |
| longitud_sendero_m | 0 |
| ancho_transitable_in | 0 |
| pendiente_transversal_pct | 0 |
| pendiente_grado_pct | 0 |
| obstaculos_binario | 0 |
# Identificar variables que deberían ser factores
datos_clean <- datos %>%
mutate(
# Convertir obstáculos binario a factor
obstaculos_factor = factor(obstaculos_binario,
levels = c(0, 1),
labels = c("Sin obstáculo", "Con obstáculo")),
# Convertir tipo de obstáculo a factor
tipo_obstaculo_factor = factor(tipo_obstaculo),
# Crear categorías de pendiente
categoria_pendiente = case_when(
pendiente_grado_pct < 5 ~ "Suave (< 5%)",
pendiente_grado_pct >= 5 & pendiente_grado_pct < 15 ~ "Moderada (5-15%)",
pendiente_grado_pct >= 15 ~ "Pronunciada (≥ 15%)"
),
categoria_pendiente = factor(categoria_pendiente,
levels = c("Suave (< 5%)", "Moderada (5-15%)", "Pronunciada (≥ 15%)")),
# Crear categorías de ancho
categoria_ancho = case_when(
ancho_transitable_in < 30 ~ "Estrecho (< 30 in)",
ancho_transitable_in >= 30 & ancho_transitable_in < 60 ~ "Medio (30-60 in)",
ancho_transitable_in >= 60 ~ "Amplio (≥ 60 in)"
),
categoria_ancho = factor(categoria_ancho,
levels = c("Estrecho (< 30 in)", "Medio (30-60 in)", "Amplio (≥ 60 in)"))
)
# Verificar las nuevas variables categóricas
cat("Distribución de categorías de pendiente:\n")## Distribución de categorías de pendiente:
##
## Suave (< 5%) Moderada (5-15%) Pronunciada (≥ 15%)
## 55 71 11
##
## Distribución de categorías de ancho:
##
## Estrecho (< 30 in) Medio (30-60 in) Amplio (≥ 60 in)
## 51 48 38