Introducción

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:

Paquetes y carga de datos

# 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).csv debe 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.

Limpieza de datos

Al revisar la base aparecen tres problemas que hay que corregir antes de analizar:

  1. Datos faltantes: en varias variables hay celdas vacías o con el texto "SIN INFORMACION". Se convierten a NA (dato faltante en R) para que no aparezcan como si fueran una categoría más.
  2. Números guardados como texto: el año viene escrito como "2,021" y las noches como texto.
  3. Unidades distintas en el gasto: la variable GASTO TURISTICO GENERADO mezcla dos formas de registro:
    • la mayoría de los valores está entre 0 y 950 (por ejemplo 150 o 500), es decir, en miles de pesos (150 = $150.000);
    • los gastos de un millón o más están escritos en pesos completos con separador de miles (por ejemplo "1,500,000").
    Ningún valor escrito en pesos es menor a 1.000.000 y ningún valor en miles es mayor a 950, así que las dos escalas no se cruzan. Para tener una sola unidad, todo el gasto se expresa en miles de pesos colombianos (miles de COP): los valores en pesos se dividen entre 1.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.

Funciones auxiliares para las tablas de frecuencia

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
}

Análisis de variables cualitativas

Género

¿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")
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.

Motivo del viaje

¿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")
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:

  • Vacaciones, recreo y ocio (43,22 %)
  • Visitar a familiares y/o amigos (39,72 %)

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.

Tipo de alojamiento

¿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")
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.

Rango de edad

¿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")
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:

  • Moda: 27-38 años.
  • Mediana: como la variable es ordinal, se puede calcular la mediana: es la categoría donde la frecuencia relativa acumulada (\(F_i\)) llega o pasa el 50 %. La mediana es 27-38 años.

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.

Análisis de variables cuantitativas

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

Número de noches

¿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.

Tabla de frecuencias

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")
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

Indicadores estadísticos

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"))
Tabla 6. Indicadores estadísticos del número de noches
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()

Interpretación

  • Tendencia central: en promedio un turista se queda 6,18 noches, pero la mediana es 3 noches: la mitad de los turistas se queda 3 noches o menos. La moda es 2 noches. Que la media sea mucho mayor que la mediana indica que unos pocos turistas con estadías muy largas (hasta 102 noches) “jalan” el promedio hacia arriba. En este caso la mediana representa mejor al turista típico.
  • Posición: el 25 % de los turistas se queda 2 noches o menos (Q1), el 75 % se queda 8 o menos (Q3) y solo el 10 % supera las 15 noches.
  • Dispersión: la desviación estándar es de 8,87 noches y el coeficiente de variación es 143,5 %. Un CV por encima del 30 % se considera alto, así que el número de noches es muy heterogéneo: conviven visitas de un día con estadías de varias semanas.
  • Forma: el coeficiente de asimetría es positivo (4,25), es decir, la distribución tiene sesgo a la derecha: la mayoría de los datos son pequeños y hay una “cola” larga de estadías largas. La curtosis en exceso (28,73) es mayor que 0 (distribución leptocúrtica): los datos se concentran alrededor de pocos valores y hay más valores extremos de lo que tendría una distribución normal. El diagrama de caja lo confirma con los puntos atípicos a la derecha.
  • Conclusión: según la Tabla 5, la mayoría de los turistas hace estadías cortas, de una semana o menos (73,95 % acumulado hasta 7 noches).

Gasto turístico generado

¿Qué mide? Cuánto dinero gastó el turista durante su visita a Cali, en miles de pesos colombianos. Es cuantitativa continua.

Tabla de frecuencias

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)"))
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

Indicadores estadísticos

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"))
Tabla 8. Indicadores estadísticos del gasto turístico (miles de COP)
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.

Interpretación

  • Tendencia central: el gasto promedio es de $1.098.920 pesos, pero la mediana es $800.000: la mitad de los turistas gastó esa cantidad o menos. El valor más frecuente (moda) es $900.000. La media es mucho más alta que la mediana porque hay turistas que gastaron cifras muy grandes (máximo $60.000.000) y esos pocos valores suben el promedio. Por eso la mediana es el mejor resumen del gasto de un turista típico.
  • Posición: el 25 % de los turistas gastó hasta $350.000 y el 75 % hasta $1.000.000. El 50 % central de los turistas gastó entre esos dos valores (RIC = $650.000).
  • Dispersión: la desviación estándar ($2.913.388) es incluso mayor que la media, y el coeficiente de variación es 265,1 %. Es una dispersión extremadamente alta: el gasto varía muchísimo de un turista a otro, y la media sola no alcanza para describirlo.
  • Forma: la asimetría es fuertemente positiva (13,78) y la curtosis es muy alta (236,45). La distribución se concentra en valores bajos y tiene una cola derecha muy larga, con valores atípicos (gastos de 10 a 60 millones), que podrían ser viajes de negocios, grupos familiares o tratamientos médicos.
  • Conclusión: según la Tabla 7, el 82,56 % de los turistas gastó un millón de pesos o menos, y apenas una pequeña fracción gastó más de 5 millones.

Análisis complementario: relación entre variables

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")
Tabla 9. Noches y gasto según el motivo del viaje
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")
Tabla 10. Tipo de alojamiento según el motivo del viaje (porcentaje por columna)
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).

Conclusiones

  1. Perfil del turista: el turista típico que visita Cali es un adulto joven de 27 a 38 años, sin diferencia importante entre hombres y mujeres, que viene principalmente de vacaciones o a visitar familiares y amigos.
  2. Alojamiento: las opciones más usadas son la casa de familiares o amigos y el hotel. Esto confirma el peso del turismo familiar, que casi no usa la oferta de alojamiento pagado.
  3. Estadía: la mayoría hace visitas cortas (mediana de 3 noches), aunque hay estadías muy largas que suben el promedio a 6,18 noches.
  4. Gasto: el turista típico gasta alrededor de $800.000 pesos (mediana). El gasto es muy desigual: pocos turistas gastan cifras muy grandes, lo que produce una distribución con fuerte asimetría positiva y un coeficiente de variación muy alto.
  5. Lección estadística: en variables asimétricas y con valores atípicos, como las noches y el gasto, la media no es un buen resumen. Es mejor informar la mediana y los cuartiles, y acompañarlos con medidas de dispersión y forma.
  6. Recomendación: para aumentar el gasto turístico en la ciudad convendría fortalecer segmentos que hoy pesan poco, como el turismo de negocios, eventos y salud, y promocionar opciones de alojamiento distintas al hotel y a la casa familiar.