En este informe se analiza la Base de Datos de Turismo de Cali (la base seleccionada en la Actividad 112). Cada fila es un turista encuestado que visitó la ciudad en 2021 o 2022. Para cada turista se registró su género, país y departamento de procedencia, rango de edad, motivo del viaje, número de noches, tipo de alojamiento, gasto turístico, el medio por el que conoció el destino y el año.
Objetivo: describir el perfil del turista que visita Cali analizando:
| Tipo de variable | Variable | Escala de medición |
|---|---|---|
| Cualitativa | Género | Nominal |
| Cualitativa | Motivo del viaje | Nominal |
| Cualitativa | Tipo de alojamiento | Nominal |
| Cualitativa | Rango de edad | Ordinal |
| Cuantitativa | Número de noches | Discreta (de razón) |
| Cuantitativa | Gasto turístico generado | Continua (de razón) |
Para cada variable se construye la tabla de frecuencias y se calculan los indicadores estadísticos que corresponden a su tipo:
# Si algún paquete no está instalado, ejecute una vez en la consola:
# install.packages(c("readr", "dplyr", "ggplot2", "knitr", "kableExtra", "stringr"))
library(readr) # lectura del archivo CSV
library(dplyr) # manipulación de datos
library(ggplot2) # gráficos
library(knitr) # tablas
library(kableExtra) # formato de tablas
El archivo usa punto y coma (;) como separador y tiene tildes (codificación UTF-8). Todas las columnas se leen como texto para limpiarlas después con cuidado.
Importante: el archivo
Base de Datos Turismo Cali (1).csvdebe estar en la misma carpeta que este archivo.Rmd.
turismo_raw <- read_delim("Base de Datos Turismo Cali (1).csv",
delim = ";",
locale = locale(encoding = "UTF-8"),
col_types = cols(.default = col_character()),
trim_ws = TRUE)
dim(turismo_raw) # número de filas (turistas) y columnas (variables)
## [1] 1703 10
head(turismo_raw)
## # A tibble: 6 × 10
## GENERO `PAÍS DE PROCEDENCIA` DEPARTAMENTO `RANGO EDAD` `MOTIVO VIAJE` NOCHES
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 MASCULI… COLOMBIA QUINDÍO 39-50 VISITAR A FAM… 2
## 2 FEMENINO COLOMBIA QUINDÍO 39-50 VACACIONES, R… 2
## 3 MASCULI… COLOMBIA QUINDÍO 15-26 VACACIONES, R… 2
## 4 FEMENINO COLOMBIA CAUCA 27-38 VISITAR A FAM… 1
## 5 MASCULI… COLOMBIA CAUCA 27-38 VISITAR A FAM… 1
## 6 FEMENINO COLOMBIA CAUCA 27-38 VISITAR A FAM… 2
## # ℹ 4 more variables: `TIPO ALOJAMIENTO` <chr>,
## # `GASTO TURISTICO GENERADO` <chr>, MEDIO <chr>, AÑO <chr>
La base tiene 1703 turistas y 10 variables.
Al revisar la base aparecen tres problemas que hay que corregir antes de analizar:
"SIN INFORMACION". Se convierten a
NA (dato faltante en R) para que no aparezcan como si
fueran una categoría más."2,021" y las noches como texto.GASTO TURISTICO GENERADO mezcla dos formas de registro:
150 o 500), es decir, en miles de
pesos (150 = $150.000);"1,500,000").# Función auxiliar: vacíos y "SIN INFORMACION" pasan a NA
a_na <- function(x) {
x <- trimws(x)
x[x == "" | toupper(x) == "SIN INFORMACION"] <- NA
x
}
turismo <- turismo_raw %>%
mutate(across(everything(), a_na)) %>%
transmute(
genero = GENERO,
pais = `PAÍS DE PROCEDENCIA`,
departamento = DEPARTAMENTO,
edad = factor(`RANGO EDAD`,
levels = c("15-26", "27-38", "39-50", "51-62", "mas de 63"),
ordered = TRUE), # variable ordinal
motivo = `MOTIVO VIAJE`,
alojamiento = `TIPO ALOJAMIENTO`,
medio = MEDIO,
anio = as.integer(gsub(",", "", `AÑO`)),
noches = as.numeric(NOCHES),
# Gasto: se quitan las comas; si el valor es >= 1.000.000 está en pesos
# y se divide entre 1.000 para dejarlo en miles de pesos.
gasto_num = as.numeric(gsub(",", "", `GASTO TURISTICO GENERADO`)),
gasto = ifelse(gasto_num >= 1e6, gasto_num / 1000, gasto_num)
) %>%
select(-gasto_num)
# Número de datos faltantes por variable
colSums(is.na(turismo)) %>% kable(col.names = "Datos faltantes (NA)") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "condensed"),
latex_options = c("striped", "hold_position"))
| Datos faltantes (NA) | |
|---|---|
| genero | 1 |
| pais | 54 |
| departamento | 151 |
| edad | 50 |
| motivo | 74 |
| alojamiento | 147 |
| medio | 1 |
| anio | 0 |
| noches | 156 |
| gasto | 0 |
Los análisis de cada variable se hacen con los casos
válidos, es decir, sin contar los NA.
Una tabla de frecuencias tiene estas columnas:
Las frecuencias acumuladas solo tienen sentido cuando las categorías tienen un orden natural (variables ordinales o cuantitativas). En las variables nominales no se incluyen.
# Tabla de frecuencias para variables cualitativas
tabla_frec <- function(x, nombre, ordenar = TRUE, acumuladas = FALSE) {
x <- x[!is.na(x)]
t <- as.data.frame(table(x), stringsAsFactors = FALSE)
names(t) <- c(nombre, "ni")
if (ordenar) t <- t[order(-t$ni), ]
t$fi <- round(100 * t$ni / sum(t$ni), 2)
if (acumuladas) {
t$Ni <- cumsum(t$ni)
t$Fi <- round(100 * t$Ni / sum(t$ni), 2)
}
total <- t[1, ]; total[1, ] <- NA
total[[nombre]] <- "Total"; total$ni <- sum(t$ni); total$fi <- 100
t <- rbind(t, total)
rownames(t) <- NULL
names(t)[names(t) == "fi"] <- "fi (%)"
if (acumuladas) names(t)[names(t) == "Fi"] <- "Fi (%)"
t
}
mostrar <- function(t, titulo) {
kable(t, caption = titulo, align = c("l", rep("r", ncol(t) - 1)),
format.args = list(big.mark = ".", decimal.mark = ",")) %>%
kable_styling(full_width = FALSE,
bootstrap_options = c("striped", "hover", "condensed"),
latex_options = c("striped", "hold_position")) %>%
column_spec(1, width = "8cm") %>%
row_spec(nrow(t), bold = TRUE)
}
# Coeficiente de asimetría y curtosis.
# Se escriben aquí con las fórmulas de los momentos para no depender de
# ningún paquete adicional. m_k es el momento central de orden k:
# m_k = sum((x - media)^k) / n
# Asimetría = m3 / m2^(3/2) Curtosis = m4 / m2^2
skewness <- function(x) {
x <- x[!is.na(x)]; n <- length(x); m <- mean(x)
(sum((x - m)^3) / n) / (sum((x - m)^2) / n)^(3/2)
}
kurtosis <- function(x) {
x <- x[!is.na(x)]; n <- length(x); m <- mean(x)
(sum((x - m)^4) / n) / ((sum((x - m)^2) / n)^2)
}
# Moda (el valor que más se repite)
moda <- function(x) {
x <- x[!is.na(x)]
tt <- table(x)
names(tt)[tt == max(tt)]
}
# Indicadores estadísticos para variables cuantitativas
indicadores <- function(x) {
x <- x[!is.na(x)]
q <- quantile(x, c(0.25, 0.50, 0.75, 0.90))
data.frame(
Indicador = c("n (datos válidos)", "Media", "Mediana", "Moda",
"Mínimo", "Máximo", "Rango",
"Cuartil 1 (Q1)", "Cuartil 3 (Q3)", "Rango intercuartílico (RIC)",
"Percentil 90", "Varianza", "Desviación estándar",
"Coeficiente de variación (%)",
"Coeficiente de asimetría", "Curtosis (exceso)"),
Valor = c(length(x), mean(x), median(x), as.numeric(moda(x)[1]),
min(x), max(x), max(x) - min(x),
q[1], q[3], q[3] - q[1], q[4],
var(x), sd(x), 100 * sd(x) / mean(x),
skewness(x), kurtosis(x) - 3)
)
}
# Tabla de frecuencias por intervalos para variables cuantitativas
tabla_intervalos <- function(x, cortes, etiquetas, nombre) {
x <- x[!is.na(x)]
clase <- cut(x, breaks = cortes, labels = etiquetas,
right = TRUE, include.lowest = TRUE)
t <- tabla_frec(clase, nombre, ordenar = FALSE, acumuladas = TRUE)
# Marca de clase = punto medio del intervalo (no aplica a la clase abierta)
t
}
¿Qué mide? El sexo que declaró el turista. Es una variable cualitativa nominal: sus categorías no tienen orden.
tab_genero <- tabla_frec(turismo$genero, "Género")
mostrar(tab_genero, "Tabla 1. Distribución de los turistas por género")
| Género | ni | fi (%) |
|---|---|---|
| FEMENINO | 869 | 51,06 |
| MASCULINO | 833 | 48,94 |
| Total | 1.702 | 100,00 |
turismo %>% filter(!is.na(genero)) %>%
count(genero) %>% mutate(p = n / sum(n)) %>%
ggplot(aes(x = genero, y = n, fill = genero)) +
geom_col(width = 0.6, show.legend = FALSE) +
geom_text(aes(label = paste0(n, " (", round(100 * p, 1), "%)")), vjust = -0.4) +
scale_fill_manual(values = c("#E07A5F", "#3D5A80")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.12))) +
labs(title = "Turistas por género", x = NULL, y = "Número de turistas") +
theme_minimal()
Indicador: la moda es FEMENINO.
Interpretación: entre los turistas que visitaron Cali hay un poco más de mujeres (51,06 %) que de hombres (48,94 %). La diferencia es de apenas unos puntos porcentuales, así que el turismo hacia la ciudad está prácticamente equilibrado por género: ninguno de los dos grupos domina.
¿Qué mide? La razón principal por la que el turista viajó a Cali. Es cualitativa nominal.
tab_motivo <- tabla_frec(turismo$motivo, "Motivo del viaje")
mostrar(tab_motivo, "Tabla 2. Distribución de los turistas según el motivo del viaje")
| Motivo del viaje | ni | fi (%) |
|---|---|---|
| VACACIONES, RECREO Y OCIO | 704 | 43,22 |
| VISITAR A FAMILIARES Y/O AMIGOS | 647 | 39,72 |
| TURISMO ESPIRITUAL: ACTIVIDADES RELIGIOSAS Y ESPIRITUALES | 58 | 3,56 |
| VENDER BIENES O PRESTAR SERVICIOS COMO REPRESENTANTE DE EMPRESA QUE NO ES DEL VALLE O COMO INDEPENDIENTE | 45 | 2,76 |
| TURISMO DE NEGOCIOS: REALIZAR INVERSIÓN, VENDER Y/O COMPRAR BIENES O PRESTAR SERVICIOS | 39 | 2,39 |
| DE PASO | 28 | 1,72 |
| OTRO. | 28 | 1,72 |
| ASISTIR A EVENTOS DEPORTIVOS COMO DEPORTISTA O COMO ASISTENTE | 23 | 1,41 |
| SALUD, BIENESTAR Y ATENCIÓN MÉDICA (INCLUYE LA CIRUGÍA ESTÉTICA) | 17 | 1,04 |
| COMPRAR BIENES O SERVICIOS PARA EMPRESAS QUE NO ES DEL VALLE O COMO INDEPENDIENTE | 16 | 0,98 |
| TURISMO DE NATURALEZA: APROVECHAMIENTO DE LA NATURALEZA, AVISTAMIENTO DE FLORA Y FAUNA. | 9 | 0,55 |
| ASISTIR A EVENTOS CULTURALES COMO ARTISTA O COMO ASISTENTE | 7 | 0,43 |
| EDUCACIÓN / FORMACIÓN | 5 | 0,31 |
| ASISTIR O DICTAR CONFERENCIA, PONENTE EN CONGRESO, FERIA COMERCIAL O EXPOSICIÓN | 3 | 0,18 |
| Total | 1.629 | 100,00 |
Hay muchas categorías con muy pocos casos. Para que el gráfico se lea mejor, las categorías con menos del 3 % se agrupan en “Otros motivos”:
turismo %>% filter(!is.na(motivo)) %>%
mutate(motivo = ifelse(motivo %in% names(which(prop.table(table(motivo)) < 0.03)),
"OTROS MOTIVOS", motivo)) %>%
count(motivo) %>% mutate(p = n / sum(n)) %>%
ggplot(aes(x = reorder(motivo, n), y = n)) +
geom_col(fill = "#3D5A80") +
geom_text(aes(label = paste0(round(100 * p, 1), "%")), hjust = -0.15, size = 3.5) +
coord_flip() +
scale_x_discrete(labels = function(x) stringr::str_wrap(x, 40)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.12))) +
labs(title = "Motivo principal del viaje a Cali", x = NULL, y = "Número de turistas") +
theme_minimal()
Indicador: la moda es VACACIONES, RECREO Y OCIO.
Interpretación: dos motivos concentran la mayoría de los viajes:
Juntos suman alrededor del 82,9 % de los turistas con información. Los motivos relacionados con negocios, salud, eventos o educación pesan muy poco. Esto muestra que Cali recibe sobre todo turismo de ocio y turismo familiar, y que el turismo corporativo y de eventos todavía tiene espacio para crecer.
¿Qué mide? Dónde se hospedó el turista durante su estadía. Es cualitativa nominal.
tab_aloj <- tabla_frec(turismo$alojamiento, "Tipo de alojamiento")
mostrar(tab_aloj, "Tabla 3. Distribución de los turistas según el tipo de alojamiento")
| Tipo de alojamiento | ni | fi (%) |
|---|---|---|
| CASA FAMILIARES / AMIGOS | 660 | 42,42 |
| HOTEL | 580 | 37,28 |
| NINGUNO. | 143 | 9,19 |
| CASA / CABAÑA DE VACACIONES / APARTAMENTO ARRENDADO | 71 | 4,56 |
| HOSTAL / ALBERGUE / REFUGIO / POSADA TURÍSTICA | 35 | 2,25 |
| CAMPING / GLAMPING | 17 | 1,09 |
| APARTAHOTEL | 13 | 0,84 |
| CASA / CABAÑA DE VACACIONES/ APARTAMENTO PROPIO | 11 | 0,71 |
| HABITACIÓN SIN PAGAR EN VIVIENDA FAMILIAR QUE NO ES ALLEGADA MÍA | 11 | 0,71 |
| FINCA AGRO TURÍSTICA / ALOJAMIENTO RURAL | 7 | 0,45 |
| OTRO | 6 | 0,39 |
| APARTAMENTO DE LA OFICINA | 1 | 0,06 |
| CENTRO VACACIONAL / RESORT | 1 | 0,06 |
| Total | 1.556 | 100,00 |
turismo %>% filter(!is.na(alojamiento)) %>%
mutate(alojamiento = ifelse(alojamiento %in% names(which(prop.table(table(alojamiento)) < 0.02)),
"OTROS ALOJAMIENTOS", alojamiento)) %>%
count(alojamiento) %>% mutate(p = n / sum(n)) %>%
ggplot(aes(x = reorder(alojamiento, n), y = n)) +
geom_col(fill = "#E07A5F") +
geom_text(aes(label = paste0(round(100 * p, 1), "%")), hjust = -0.15, size = 3.5) +
coord_flip() +
scale_x_discrete(labels = function(x) stringr::str_wrap(x, 40)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.12))) +
labs(title = "Tipo de alojamiento utilizado", x = NULL, y = "Número de turistas") +
theme_minimal()
Indicador: la moda es CASA FAMILIARES / AMIGOS.
Interpretación: la opción más frecuente es quedarse en casa de familiares o amigos (42,42 %), seguida muy de cerca por el hotel (37,28 %). Esto coincide con lo que se vio en el motivo del viaje: una parte grande de los turistas viene a visitar familia y se hospeda con ella, sin pagar alojamiento. La categoría “Ninguno” corresponde a visitantes que no pasaron la noche en la ciudad (excursionistas o turistas de paso). Alternativas como hostales, apartahoteles, glamping o fincas agroturísticas tienen una participación muy baja.
¿Qué mide? El grupo de edad del turista. Es cualitativa ordinal: las categorías sí tienen un orden (de menor a mayor edad). Por eso esta tabla sí incluye frecuencias acumuladas y la tabla no se ordena por frecuencia, sino por el orden natural de las edades.
tab_edad <- tabla_frec(turismo$edad, "Rango de edad", ordenar = FALSE, acumuladas = TRUE)
mostrar(tab_edad, "Tabla 4. Distribución de los turistas por rango de edad")
| Rango de edad | ni | fi (%) | Ni | Fi (%) |
|---|---|---|---|---|
| 15-26 | 288 | 17,42 | 288 | 17,42 |
| 27-38 | 746 | 45,13 | 1.034 | 62,55 |
| 39-50 | 447 | 27,04 | 1.481 | 89,59 |
| 51-62 | 124 | 7,50 | 1.605 | 97,10 |
| mas de 63 | 48 | 2,90 | 1.653 | 100,00 |
| Total | 1.653 | 100,00 |
turismo %>% filter(!is.na(edad)) %>%
count(edad) %>% mutate(p = n / sum(n)) %>%
ggplot(aes(x = edad, y = n)) +
geom_col(fill = "#98C1D9", color = "#3D5A80") +
geom_text(aes(label = paste0(round(100 * p, 1), "%")), vjust = -0.4) +
scale_y_continuous(expand = expansion(mult = c(0, 0.12))) +
labs(title = "Turistas por rango de edad", x = "Rango de edad (años)",
y = "Número de turistas") +
theme_minimal()
Indicadores:
Interpretación: el turista típico de Cali es un adulto joven. El grupo de 27 a 38 años es el más numeroso (45,13 %). La columna \(F_i\) muestra que el 89,59 % de los turistas tiene 50 años o menos, mientras que los mayores de 63 años son una proporción muy pequeña.
Para las variables cuantitativas hay muchos valores distintos, por lo que la tabla de frecuencias se construye agrupando los datos en intervalos (clases).
La regla de Sturges, \(k = 1 + 3{,}322 \log_{10}(n)\), propone intervalos de igual amplitud. Sin embargo, estas dos variables son muy asimétricas: la mayoría de los datos son pequeños y unos pocos son muy grandes. Con intervalos de igual amplitud casi todos los turistas quedarían en la primera clase y el resto de clases estarían casi vacías. Por eso se usan intervalos con sentido práctico (por ejemplo, “una noche”, “una semana”, “de 200 a 500 mil pesos”), que resumen mejor la información.
k_noches <- 1 + 3.322 * log10(sum(!is.na(turismo$noches)))
k_gasto <- 1 + 3.322 * log10(sum(!is.na(turismo$gasto)))
c(Sturges_noches = round(k_noches, 1), Sturges_gasto = round(k_gasto, 1))
## Sturges_noches Sturges_gasto
## 11,6 11,7
¿Qué mide? Cuántas noches pasó el turista en Cali. Es cuantitativa discreta: solo toma valores enteros (0, 1, 2, …). El valor 0 corresponde a visitantes que no pernoctaron.
tab_noches <- tabla_intervalos(
turismo$noches,
cortes = c(-Inf, 0, 1, 3, 7, 15, 30, Inf),
etiquetas = c("0 (no pernoctó)", "1", "2 a 3", "4 a 7", "8 a 15", "16 a 30", "Más de 30"),
nombre = "Noches"
)
mostrar(tab_noches, "Tabla 5. Distribución de los turistas según el número de noches")
| Noches | ni | fi (%) | Ni | Fi (%) |
|---|---|---|---|---|
| 0 (no pernoctó) | 175 | 11,31 | 175 | 11,31 |
| 1 | 186 | 12,02 | 361 | 23,34 |
| 2 a 3 | 457 | 29,54 | 818 | 52,88 |
| 4 a 7 | 326 | 21,07 | 1.144 | 73,95 |
| 8 a 15 | 268 | 17,32 | 1.412 | 91,27 |
| 16 a 30 | 121 | 7,82 | 1.533 | 99,10 |
| Más de 30 | 14 | 0,90 | 1.547 | 100,00 |
| Total | 1.547 | 100,00 |
ind_noches <- indicadores(turismo$noches)
ind_noches %>% mutate(Valor = round(Valor, 2)) %>%
kable(caption = "Tabla 6. Indicadores estadísticos del número de noches",
format.args = list(big.mark = ".", decimal.mark = ",")) %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "condensed"),
latex_options = c("striped", "hold_position"))
| Indicador | Valor |
|---|---|
| n (datos válidos) | 1.547,00 |
| Media | 6,18 |
| Mediana | 3,00 |
| Moda | 2,00 |
| Mínimo | 0,00 |
| Máximo | 102,00 |
| Rango | 102,00 |
| Cuartil 1 (Q1) | 2,00 |
| Cuartil 3 (Q3) | 8,00 |
| Rango intercuartílico (RIC) | 6,00 |
| Percentil 90 | 15,00 |
| Varianza | 78,70 |
| Desviación estándar | 8,87 |
| Coeficiente de variación (%) | 143,50 |
| Coeficiente de asimetría | 4,25 |
| Curtosis (exceso) | 28,73 |
p1 <- turismo %>% filter(!is.na(noches), noches <= 40) %>%
ggplot(aes(x = noches)) +
geom_histogram(binwidth = 1, fill = "#3D5A80", color = "white") +
geom_vline(aes(xintercept = mean(turismo$noches, na.rm = TRUE), color = "Media"),
linewidth = 1, linetype = "dashed") +
geom_vline(aes(xintercept = median(turismo$noches, na.rm = TRUE), color = "Mediana"),
linewidth = 1) +
scale_color_manual(values = c(Media = "#E07A5F", Mediana = "#2A9D8F"), name = NULL) +
labs(title = "Histograma del número de noches (hasta 40 noches)",
x = "Número de noches", y = "Número de turistas") +
theme_minimal() + theme(legend.position = "top")
p1
turismo %>% filter(!is.na(noches)) %>%
ggplot(aes(x = noches, y = "")) +
geom_boxplot(fill = "#98C1D9", outlier.color = "#E07A5F", outlier.alpha = 0.5) +
labs(title = "Diagrama de caja del número de noches", x = "Número de noches", y = NULL) +
theme_minimal()
¿Qué mide? Cuánto dinero gastó el turista durante su visita a Cali, en miles de pesos colombianos. Es cuantitativa continua.
tab_gasto <- tabla_intervalos(
turismo$gasto,
cortes = c(-Inf, 200, 500, 1000, 2000, 5000, Inf),
etiquetas = c("0 a 200", "Más de 200 a 500", "Más de 500 a 1.000",
"Más de 1.000 a 2.000", "Más de 2.000 a 5.000", "Más de 5.000"),
nombre = "Gasto (miles de COP)"
)
mostrar(tab_gasto, paste("Tabla 7. Distribución de los turistas según",
"el gasto turístico (miles de COP)"))
| Gasto (miles de COP) | ni | fi (%) | Ni | Fi (%) |
|---|---|---|---|---|
| 0 a 200 | 321 | 18,85 | 321 | 18,85 |
| Más de 200 a 500 | 351 | 20,61 | 672 | 39,46 |
| Más de 500 a 1.000 | 734 | 43,10 | 1.406 | 82,56 |
| Más de 1.000 a 2.000 | 173 | 10,16 | 1.579 | 92,72 |
| Más de 2.000 a 5.000 | 90 | 5,28 | 1.669 | 98,00 |
| Más de 5.000 | 34 | 2,00 | 1.703 | 100,00 |
| Total | 1.703 | 100,00 |
ind_gasto <- indicadores(turismo$gasto)
ind_gasto %>% mutate(Valor = round(Valor, 2)) %>%
kable(caption = "Tabla 8. Indicadores estadísticos del gasto turístico (miles de COP)",
format.args = list(big.mark = ".", decimal.mark = ",")) %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "condensed"),
latex_options = c("striped", "hold_position"))
| Indicador | Valor |
|---|---|
| n (datos válidos) | 1.703,00 |
| Media | 1.098,92 |
| Mediana | 800,00 |
| Moda | 900,00 |
| Mínimo | 0,00 |
| Máximo | 60.000,00 |
| Rango | 60.000,00 |
| Cuartil 1 (Q1) | 350,00 |
| Cuartil 3 (Q3) | 1.000,00 |
| Rango intercuartílico (RIC) | 650,00 |
| Percentil 90 | 2.000,00 |
| Varianza | 8.487.827,43 |
| Desviación estándar | 2.913,39 |
| Coeficiente de variación (%) | 265,11 |
| Coeficiente de asimetría | 13,78 |
| Curtosis (exceso) | 236,45 |
turismo %>% filter(!is.na(gasto), gasto <= 5000) %>%
ggplot(aes(x = gasto)) +
geom_histogram(binwidth = 100, boundary = 0, fill = "#E07A5F", color = "white") +
geom_vline(aes(xintercept = mean(turismo$gasto, na.rm = TRUE), color = "Media"),
linewidth = 1, linetype = "dashed") +
geom_vline(aes(xintercept = median(turismo$gasto, na.rm = TRUE), color = "Mediana"),
linewidth = 1) +
scale_color_manual(values = c(Media = "#3D5A80", Mediana = "#2A9D8F"), name = NULL) +
labs(title = "Histograma del gasto turístico (hasta 5 millones de pesos)",
x = "Gasto (miles de COP)", y = "Número de turistas") +
theme_minimal() + theme(legend.position = "top")
turismo %>% filter(!is.na(gasto)) %>%
ggplot(aes(x = gasto, y = "")) +
geom_boxplot(fill = "#F2CC8F", outlier.color = "#E07A5F", outlier.alpha = 0.5) +
scale_x_log10(labels = function(x) format(x, big.mark = ".", decimal.mark = ",",
scientific = FALSE)) +
labs(title = "Diagrama de caja del gasto turístico (escala logarítmica)",
x = "Gasto (miles de COP, escala log)", y = NULL) +
theme_minimal()
Nota: el diagrama de caja usa escala logarítmica porque algunos gastos llegan a decenas de millones y, en escala normal, la caja quedaría aplastada contra el cero. Los turistas con gasto 0 no aparecen en la escala logarítmica.
Para enriquecer el análisis se cruzan una variable cualitativa con las variables cuantitativas: ¿cuánto gastan y cuántas noches se quedan los turistas según su motivo de viaje? Se usan los motivos con al menos 20 turistas y se comparan con la mediana, porque es resistente a los valores atípicos.
turismo %>%
filter(!is.na(motivo)) %>%
group_by(`Motivo del viaje` = motivo) %>%
summarise(Turistas = n(),
`Mediana noches` = median(noches, na.rm = TRUE),
`Media noches` = round(mean(noches, na.rm = TRUE), 1),
`Mediana gasto (miles COP)` = median(gasto, na.rm = TRUE),
`Media gasto (miles COP)` = round(mean(gasto, na.rm = TRUE), 0)) %>%
filter(Turistas >= 20) %>%
arrange(desc(`Mediana gasto (miles COP)`)) %>%
kable(caption = "Tabla 9. Noches y gasto según el motivo del viaje",
format.args = list(big.mark = ".", decimal.mark = ",")) %>%
kable_styling(full_width = FALSE, latex_options = c("striped", "hold_position")) %>%
column_spec(1, width = "6cm") %>% column_spec(2:6, width = "1.8cm")
| Motivo del viaje | Turistas | Mediana noches | Media noches | Mediana gasto (miles COP) | Media gasto (miles COP) |
|---|---|---|---|---|---|
| TURISMO DE NEGOCIOS: REALIZAR INVERSIÓN, VENDER Y/O COMPRAR BIENES O PRESTAR SERVICIOS | 39 | 4 | 10,6 | 1.500 | 2.866 |
| VISITAR A FAMILIARES Y/O AMIGOS | 647 | 6 | 8,2 | 900 | 1.227 |
| VACACIONES, RECREO Y OCIO | 704 | 3 | 5,2 | 500 | 1.027 |
| VENDER BIENES O PRESTAR SERVICIOS COMO REPRESENTANTE DE EMPRESA QUE NO ES DEL VALLE O COMO INDEPENDIENTE | 45 | 3 | 6,7 | 500 | 890 |
| ASISTIR A EVENTOS DEPORTIVOS COMO DEPORTISTA O COMO ASISTENTE | 23 | 4 | 8,2 | 200 | 3.285 |
| DE PASO | 28 | 0 | 0,5 | 200 | 232 |
| TURISMO ESPIRITUAL: ACTIVIDADES RELIGIOSAS Y ESPIRITUALES | 58 | 1 | 1,7 | 200 | 325 |
| OTRO. | 28 | 1 | 2,3 | 0 | 39 |
Interpretación: el turismo de negocios tiene el gasto mediano más alto (alrededor de $1.500.000), aunque es un grupo pequeño. Los turistas que visitan familiares se quedan más noches (mediana de 6) y gastan más ($900.000) que los que vienen de vacaciones (3 noches y $500.000). Los visitantes de paso casi no pernoctan y son los que menos gastan. En casi todos los motivos la media es mayor que la mediana, lo que confirma la asimetría positiva que se vio antes.
Una tabla de contingencia (tabla de doble entrada) permite ver cómo se relacionan dos variables cualitativas. Aquí se muestra el tipo de alojamiento según el motivo, para los dos motivos principales (porcentajes por columna):
sub <- turismo %>%
filter(motivo %in% c("VACACIONES, RECREO Y OCIO", "VISITAR A FAMILIARES Y/O AMIGOS"),
alojamiento %in% c("HOTEL", "CASA FAMILIARES / AMIGOS", "NINGUNO.",
"CASA / CABAÑA DE VACACIONES / APARTAMENTO ARRENDADO"))
round(100 * prop.table(table(sub$alojamiento, sub$motivo), margin = 2), 1) %>%
kable(caption = paste("Tabla 10. Tipo de alojamiento según el motivo del viaje",
"(porcentaje por columna)")) %>%
kable_styling(full_width = FALSE, latex_options = c("striped", "hold_position")) %>%
column_spec(1, width = "7cm") %>% column_spec(2:3, width = "3.5cm")
| VACACIONES, RECREO Y OCIO | VISITAR A FAMILIARES Y/O AMIGOS | |
|---|---|---|
| CASA / CABAÑA DE VACACIONES / APARTAMENTO ARRENDADO | 10,3 | 0,2 |
| CASA FAMILIARES / AMIGOS | 19,3 | 74,1 |
| HOTEL | 53,1 | 24,8 |
| NINGUNO. | 17,2 | 0,9 |
Interpretación: la mayoría de los turistas que vienen de vacaciones usa el hotel (cerca del 53 %), mientras que la mayoría de los que vienen a visitar familiares se hospeda en casa de sus familiares o amigos (cerca del 74 %). Esto tiene impacto económico: el turismo de vacaciones genera más demanda para la industria hotelera, mientras que el turismo familiar deja su gasto en otros sectores (comercio, restaurantes, transporte).