La base de datos “Movies Box Office Dataset (2000-2024)” es un conjunto de datos abierto, extraído de Kaggle y publicado por Aditya Jilla, recoge información detallada sobre el rendimiento de taquilla de películas estrenadas entre los años 2000 y 2024. Este dataset permite analizar tendencias en la industria cinematográfica, identificar patrones en la recaudación y evaluar el impacto de diversos factores en el éxito de una película. Incluye variables clave como el título de la película, el año de lanzamiento, el género, la recaudación tanto a nivel doméstico como internacional, el presupuesto de producción, la calificación de la audiencia, el país de origen y el idioma principal. Al proporcionar datos sobre la taquilla a nivel mundial, este conjunto de datos es ideal para estudios comparativos entre películas, géneros y períodos de tiempo, permitiendo analizar cómo han evolucionado las preferencias del público y qué características están asociadas con un mayor éxito comercial.
Además, se llevará a cabo una revisión exhaustiva de los valores faltantes, se detectarán y tratarán outliers, y se aplicarán técnicas de limpieza de datos, todo con el fin de preparar adecuadamente el conjunto de datos, con el fin de asegurar que la calidad del conjunto de datos sea adecuada para un análisis oportuno y eficiente.
Para garantizar la correcta lectura de la base de datos en R, se utilizó la función read.csv(), la cual permite cargar archivos en formato CSV de manera eficiente. Se implementó file.choose() para facilitar la selección del archivo sin necesidad de especificar manualmente la ruta. Además, se estableció fileEncoding = “UTF-8” para evitar problemas con caracteres especiales y header = TRUE para asegurar que la primera fila se interprete como los nombres de las columnas. Esta configuración permite manipular los datos sin inconvenientes y facilita el análisis exploratorio.
# Cargar la base de datos en la variable "datos"
datos <- read.csv(file.choose(),
sep=",",
header=TRUE,
fileEncoding = "UTF-8")
# Inspección de la estructura del dataset
library(kableExtra)
kable(datos[1:20, ], caption= "Tabla 1: DataSet ") %>%
kable_styling(full_width = F) %>%
column_spec(2, width = "20em") %>%
scroll_box(width = "900px", height = "450px")
Rank | Release.Group | X.Worldwide | X.Domestic | Domestic.. | X.Foreign | Foreign.. | Year | Genres | Rating | Vote_Count | Original_Language | Production_Countries |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Mission: Impossible II | 546388108 | 215409889 | 39.4 | 330978219 | 60.6 | 2000 | Adventure, Action, Thriller | 6.126/10 | 6741 | en | United States of America |
2 | Gladiator | 460583960 | 187705427 | 40.8 | 272878533 | 59.2 | 2000 | Action, Drama, Adventure | 8.217/10 | 19032 | en | United Kingdom, United States of America |
3 | Cast Away | 429632142 | 233632142 | 54.4 | 196000000 | 45.6 | 2000 | Adventure, Drama | 7.663/10 | 11403 | en | United States of America |
4 | What Women Want | 374111707 | 182811707 | 48.9 | 191300000 | 51.1 | 2000 | Comedy, Romance | 6.45/10 | 3944 | en | United Kingdom, United States of America |
5 | Dinosaur | 349822765 | 137748063 | 39.4 | 212074702 | 60.6 | 2000 | Animation, Family, Adventure | 6.544/10 | 2530 | en | United States of America |
6 | How the Grinch Stole Christmas | 345842198 | 260745620 | 75.4 | 85096578 | 24.6 | 2000 | Family, Comedy, Fantasy | 6.8/10 | 7591 | en | Germany, United States of America |
7 | Meet the Parents | 330444045 | 166244045 | 50.3 | 164200000 | 49.7 | 2000 | Comedy, Romance | 6.675/10 | 5916 | en | United States of America |
8 | The Perfect Storm | 328718434 | 182618434 | 55.6 | 146100000 | 44.4 | 2000 | Action, Adventure, Drama, Thriller | 6.466/10 | 2312 | en | United States of America |
9 | X-Men | 296339528 | 157299718 | 53.1 | 139039810 | 46.9 | 2000 | Adventure, Action, Science Fiction | 7.005/10 | 11355 | en | United States of America |
10 | What Lies Beneath | 291420351 | 155464351 | 53.3 | 135956000 | 46.7 | 2000 | Drama, Horror, Mystery, Thriller | 6.416/10 | 1818 | en | United States of America |
11 | Scary Movie | 278019771 | 157019771 | 56.5 | 121000000 | 43.5 | 2000 | Comedy | 6.364/10 | 6984 | en | United States of America |
12 | Charlie’s Angels | 264105545 | 125305545 | 47.4 | 138800000 | 52.6 | 2000 | Action, Adventure, Comedy, Crime, Thriller | 5.836/10 | 4148 | en | United States of America |
13 | Erin Brockovich | 256271286 | 125595205 | 49.0 | 130676081 | 51.0 | 2000 | Drama | 7.4/10 | 3198 | en | United States of America |
14 | Unbreakable | 248118121 | 95011339 | 38.3 | 153106782 | 61.7 | 2000 | Thriller, Drama, Mystery | 7.143/10 | 9281 | en | United States of America |
15 | Gone in 60 Seconds | 237202299 | 101648571 | 42.9 | 135553728 | 57.1 | 2000 | Action, Crime, Thriller | 6.433/10 | 4438 | en | United States of America |
16 | Chicken Run | 224834564 | 106834564 | 47.5 | 118000000 | 52.5 | 2000 | Animation, Comedy, Family | 6.822/10 | 5040 | en | France, United Kingdom, United States of America |
17 | Vertical Limit | 215663859 | 69243859 | 32.1 | 146420000 | 67.9 | 2000 | Adventure, Action, Thriller | 6.011/10 | 1025 | en | Germany, United States of America |
18 | The Patriot | 215294342 | 113330342 | 52.6 | 101964000 | 47.4 | 2000 | Drama, History, War, Action | 7.183/10 | 3926 | en | Germany, United States of America |
19 | Crouching Tiger, Hidden Dragon | 213525736 | 128078872 | 60.0 | 85446864 | 40.0 | 2000 | Adventure, Drama, Action, Romance | 7.43/10 | 3213 | zh | Hong Kong, Taiwan, United States of America |
20 | Miss Congeniality | 212742720 | 106807667 | 50.2 | 105935053 | 49.8 | 2000 | Comedy, Crime, Action | 6.531/10 | 3900 | en | United States of America |
dim(datos)
## [1] 5000 13
El resultado muestra un data frame con 5.000 observaciones(filas) y 13 variables(columnas). Este tamaño de muestra es suficiente para realizar un análisis significativo, ya que permite identificar patrones y relaciones en los datos.
names(datos)
## [1] "Rank" "Release.Group" "X.Worldwide"
## [4] "X.Domestic" "Domestic.." "X.Foreign"
## [7] "Foreign.." "Year" "Genres"
## [10] "Rating" "Vote_Count" "Original_Language"
## [13] "Production_Countries"
sapply(datos, class)
## Rank Release.Group X.Worldwide
## "integer" "character" "numeric"
## X.Domestic Domestic.. X.Foreign
## "numeric" "numeric" "numeric"
## Foreign.. Year Genres
## "numeric" "integer" "character"
## Rating Vote_Count Original_Language
## "character" "numeric" "character"
## Production_Countries
## "character"
Cualitativas/categóricas:
Release Group: El título de la película o serie de películas.
Genres: Los géneros asociados a la película (por ejemplo, acción, drama, comedia).
Original Language: El idioma principal de la película.
Production Countries: Los países donde se produjo la película.
Cuantitativas/númericas:
Rank: La clasificación global de la película basada en los ingresos de taquilla en todo el mundo.
Worldwide: Ingresos totales de taquilla de la película en todo el mundo
Domestic: Ingresos totales de taquilla nacional (local)
Domestic %: Porcentaje de los ingresos mundiales generados en el país.
Foreign: Ingresos totales de la taquilla extranjera (internacional)
Foreign %: Porcentaje de ingresos mundiales generados en mercados extranjeros.
Year: Año de estreno de la película.
Rating: Calificación media del público según TMDB (por ejemplo, 7,5/10).
Vote Count: The number of votes the movie received on TMDB.
str(datos)
## 'data.frame': 5000 obs. of 13 variables:
## $ Rank : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Release.Group : chr "Mission: Impossible II" "Gladiator" "Cast Away" "What Women Want" ...
## $ X.Worldwide : num 5.46e+08 4.61e+08 4.30e+08 3.74e+08 3.50e+08 ...
## $ X.Domestic : num 2.15e+08 1.88e+08 2.34e+08 1.83e+08 1.38e+08 ...
## $ Domestic.. : num 39.4 40.8 54.4 48.9 39.4 75.4 50.3 55.6 53.1 53.3 ...
## $ X.Foreign : num 3.31e+08 2.73e+08 1.96e+08 1.91e+08 2.12e+08 ...
## $ Foreign.. : num 60.6 59.2 45.6 51.1 60.6 24.6 49.7 44.4 46.9 46.7 ...
## $ Year : int 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 ...
## $ Genres : chr "Adventure, Action, Thriller" "Action, Drama, Adventure" "Adventure, Drama" "Comedy, Romance" ...
## $ Rating : chr "6.126/10" "8.217/10" "7.663/10" "6.45/10" ...
## $ Vote_Count : num 6741 19032 11403 3944 2530 ...
## $ Original_Language : chr "en" "en" "en" "en" ...
## $ Production_Countries: chr "United States of America" "United Kingdom, United States of America" "United States of America" "United Kingdom, United States of America" ...
A continuación se presenta la tabla de operacionalización de variables utilizando el paquete knitr, que organiza la clasificación de las variables según su tipo y subtipo:
operacionalizacion <- data.frame(
Variable = c("Rank", "Worldwide", "Domestic", "Domestic %", "Foreign", "Foreign %",
"Year", "Rating", "Vote Count", "Release Group", "Genres",
"Original Language", "Production Countries"),
Definición = c(
"Posición de la película en el ranking de recaudación global.",
"Ingresos totales de la película a nivel mundial.",
"Ingresos obtenidos en el mercado doméstico (país de origen).",
"Porcentaje de los ingresos mundiales obtenidos en el mercado doméstico.",
"Ingresos obtenidos en mercados internacionales.",
"Porcentaje de los ingresos mundiales obtenidos en mercados internacionales.",
"Año de estreno de la película.",
"Calificación promedio en TMDB basada en la opinión de los usuarios.",
"Cantidad total de votos recibidos en TMDB.",
"Nombre de la película o de la franquicia a la que pertenece.",
"Géneros asociados a la película.",
"Idioma principal en el que fue filmada la película.",
"País o países donde se produjo la película."
),
Naturaleza = c("Cuantitativa discreta", "Cuantitativa continua", "Cuantitativa continua",
"Cuantitativa continua", "Cuantitativa continua", "Cuantitativa continua",
"Cuantitativa discreta", "Cuantitativa continua", "Cuantitativa discreta",
"Cualitativa", "Cualitativa", "Cualitativa",
"Cualitativa"),
Nivel_de_Medicion = c("De razón", "De razón", "De razón",
"De razón", "De razón", "De razón",
"De razón", "De razón", "De razón",
"Nominal", "Nominal", "Nominal", "Nominal"),
Criterio_Clasificacion = c("Numeración entre [1-200].",
"Valor numérico en dólares.",
"Valor numérico en dólares.",
"Porcentaje entre 0% y 100%.",
"Valor numérico en dólares.",
"Porcentaje entre 0% y 100%.",
"Número entero entre 2000 y 2024.",
"Número decimal en escala de 0 a 10.",
"Número entero que indica la cantidad de votos.",
"Cadena de caracteres con el nombre oficial de la película o franquicia.",
"Categorías establecidas: Acción, Drama, Comedia, etc.",
"Códigos ISO 639-1 de idioma (ej. 'en', 'es').",
"Códigos de país en formato ISO 3166-1 alpha-2 (ej. 'US', 'FR')."
),
stringsAsFactors = FALSE # Para evitar que se conviertan en factores
)
operacionalizacion %>%
kbl(caption = "Tabla de Operacionalización de Variables") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed", "responsive"),
font_size = 14, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#0073C2FF") %>%
row_spec(1:nrow(operacionalizacion), background = "lightgray")
Variable | Definición | Naturaleza | Nivel_de_Medicion | Criterio_Clasificacion |
---|---|---|---|---|
Rank | Posición de la película en el ranking de recaudación global. | Cuantitativa discreta | De razón | Numeración entre [1-200]. |
Worldwide | Ingresos totales de la película a nivel mundial. | Cuantitativa continua | De razón | Valor numérico en dólares. |
Domestic | Ingresos obtenidos en el mercado doméstico (país de origen). | Cuantitativa continua | De razón | Valor numérico en dólares. |
Domestic % | Porcentaje de los ingresos mundiales obtenidos en el mercado doméstico. | Cuantitativa continua | De razón | Porcentaje entre 0% y 100%. |
Foreign | Ingresos obtenidos en mercados internacionales. | Cuantitativa continua | De razón | Valor numérico en dólares. |
Foreign % | Porcentaje de los ingresos mundiales obtenidos en mercados internacionales. | Cuantitativa continua | De razón | Porcentaje entre 0% y 100%. |
Year | Año de estreno de la película. | Cuantitativa discreta | De razón | Número entero entre 2000 y 2024. |
Rating | Calificación promedio en TMDB basada en la opinión de los usuarios. | Cuantitativa continua | De razón | Número decimal en escala de 0 a 10. |
Vote Count | Cantidad total de votos recibidos en TMDB. | Cuantitativa discreta | De razón | Número entero que indica la cantidad de votos. |
Release Group | Nombre de la película o de la franquicia a la que pertenece. | Cualitativa | Nominal | Cadena de caracteres con el nombre oficial de la película o franquicia. |
Genres | Géneros asociados a la película. | Cualitativa | Nominal | Categorías establecidas: Acción, Drama, Comedia, etc. |
Original Language | Idioma principal en el que fue filmada la película. | Cualitativa | Nominal | Códigos ISO 639-1 de idioma (ej. ‘en’, ‘es’). |
Production Countries | País o países donde se produjo la película. | Cualitativa | Nominal | Códigos de país en formato ISO 3166-1 alpha-2 (ej. ‘US’, ‘FR’). |
Antes de proceder con el análisis exploratorio, se llevó a cabo una limpieza de datos para garantizar la calidad y confiabilidad de los resultados. Este proceso incluyó la identificación y tratamiento de valores faltantes, asegurando así un conjunto de datos adecuado para el análisis.
Nota: Si bien los outliers suelen tratarse o eliminarse en algunos análisis, en este caso es importante considerar su relevancia.
Se evaluó la presencia de valores faltantes en cada una de las variables:
colSums(is.na(datos))
## Rank Release.Group X.Worldwide
## 0 0 0
## X.Domestic Domestic.. X.Foreign
## 0 0 0
## Foreign.. Year Genres
## 0 0 0
## Rating Vote_Count Original_Language
## 0 170 0
## Production_Countries
## 0
Hemos identificado que los valores nulos en nuestro dataset están presentes únicamente en la variable Vote_Count Dado que los datos faltantes pueden afectar el análisis y la interpretación de los resultados, es importante determinar la mejor estrategia para su tratamiento.
Para ello, analizaremos la distribución de los valores en esta columna y compararemos la media y la mediana. Si la distribución es simétrica y no presenta valores extremos, utilizaremos la media para imputar los valores faltantes. Sin embargo, si la variable muestra sesgo o contiene outliers significativos, la mediana será una mejor opción.
summary(datos$Vote_Count)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0 205.2 1035.5 2531.6 3065.0 36753.0 170
hist(datos$Vote_Count, main="Distribución de Vote_Count", col="orange", breaks=30)
El análisis de esta variable muestra que su distribución está altamente sesgada a la derecha, con valores extremos que indican la presencia de valores atípicos.
Dado que la media es sensible a los valores atípicos, utilizarla para imputar los valores faltantes podría distorsionar los datos. En cambio, la mediana es una mejor opción, ya que es menos afectada por los valores atípicos y representa con mayor precisión la tendencia central de la variable.
datos$Vote_Count[is.na(datos$Vote_Count)] <- median(datos$Vote_Count, na.rm = TRUE)
Con esta imputación, aseguramos que los datos faltantes sean tratados de manera robusta, evitando que los valores extremos introduzcan sesgos en los análisis posteriores.
A continuación, procederemos a verificar la correcta imputación de los valores nulos.
sum(is.na(datos$Vote_Count))
## [1] 0
data_omit <- na.omit(datos)
ggp1 <- ggplot(data.frame(value=datos$Vote_Count), aes(x=value)) +
geom_histogram(fill="#FD0000", color="#E52521", alpha=0.9) +
ggtitle("Original data") +
xlab("Vote_Count") + ylab("Frequency") +
theme_ipsum() +
theme(plot.title = element_text(size=15))
ggp2 <- ggplot(data.frame(value=data_omit$Vote_Count), aes(x=value)) +
geom_histogram(fill="#43B047", color="#049DCB", alpha=0.9) +
ggtitle("Reemplazado por Mediana") +
xlab("Vote_Count") + ylab("Frequency") +
theme_ipsum() +
theme(plot.title = element_text(size=15))
grid.arrange(ggp1, ggp2, ncol = 2)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
En esta sección se presenta el Resumen Estadístico del dataset. El análisis de las variables cualitativas se realiza mediante tablas de frecuencia y diagramas de barras, que muestran la distribución de las categorías en cada una. Esto es esencial para identificar cómo se distribuyen las observaciones entre las distintas categorías.
Por otro lado, el análisis de las variables cuantitativas incluye un resumen estadístico que muestra medidas como la media, mediana, mínimo, máximo y los cuartiles. Estas medidas son clave para comprender la dispersión y tendencia central de los datos numéricos.
# Resumen estadístico detallado
describe(datos)
## vars n mean sd median
## Rank 1 5000 100.50 57.74 100.50
## Release.Group* 2 5000 2476.38 1429.50 2472.50
## X.Worldwide 3 5000 119213693.21 200524343.22 48446575.00
## X.Domestic 4 5000 44725232.97 77270255.71 17984212.00
## Domestic.. 5 5000 35.74 30.66 37.05
## X.Foreign 6 5000 74488092.74 133493209.86 30194438.00
## Foreign.. 7 5000 64.26 30.65 62.95
## Year 8 5000 2012.00 7.21 2012.00
## Genres* 9 5000 625.95 357.22 641.00
## Rating* 10 5000 874.39 509.46 880.50
## Vote_Count 11 5000 2480.72 3888.06 1035.50
## Original_Language* 12 5000 11.33 7.74 8.00
## Production_Countries* 13 5000 360.46 146.77 428.00
## trimmed mad min max range
## Rank 100.50 74.13 1 200 199
## Release.Group* 2475.78 1836.20 1 4955 4954
## X.Worldwide 73234312.39 45680791.13 1666028 2799439100 2797773072
## X.Domestic 27606016.52 26663392.71 0 936662225 936662225
## Domestic.. 33.29 43.59 0 100 100
## X.Foreign 43728724.38 31159440.96 0 1993811448 1993811448
## Foreign.. 66.71 43.59 0 100 100
## Year 2012.00 8.90 2000 2024 24
## Genres* 627.65 357.31 1 1318 1317
## Rating* 875.98 610.09 1 1830 1829
## Vote_Count 1599.73 1400.32 0 36753 36753
## Original_Language* 9.69 0.00 1 36 35
## Production_Countries* 385.23 68.20 1 511 510
## skew kurtosis se
## Rank 0.00 -1.20 0.82
## Release.Group* 0.00 -1.20 20.22
## X.Worldwide 4.49 30.70 2835842.46
## X.Domestic 3.98 23.63 1092766.44
## Domestic.. 0.31 -1.03 0.43
## X.Foreign 4.69 34.22 1887879.08
## Foreign.. -0.31 -1.03 0.43
## Year 0.00 -1.20 0.10
## Genres* -0.08 -0.90 5.05
## Rating* -0.03 -1.07 7.20
## Vote_Count 3.14 12.97 54.99
## Original_Language* 2.06 3.78 0.11
## Production_Countries* -1.12 -0.03 2.08
Para analizar las variables cualitativas del conjunto de datos, se generaron tablas de frecuencia para Género, Idioma Original y País de Producción. Estas tablas muestran las 10 categorías más frecuentes en cada caso, seguidas de una fila agregada con la categoría “Otros” para agrupar el resto de los valores menos frecuentes. Finalmente, se incluyó una fila correspondiente a la moda, que representa la categoría con mayor aparición dentro de cada variable.
NOTA: No se generó una tabla de frecuencia para la variable Release Group, ya que esta contiene nombres únicos de películas. Dado que cada película tiene un título distinto, su frecuencia es generalmente 1 en la mayoría de los casos, lo que haría que la tabla de frecuencias no sea útil para el análisis.
resumen_categorico <- function(variable, nombre_variable, moda, top_n = 10) {
variable <- unlist(strsplit(as.character(variable), ", "))
frecuencias <- as.data.frame(table(variable)) %>%
arrange(desc(Freq)) %>%
rename(Categoria = variable, Frecuencia_Absoluta = Freq)
total_frecuencia <- sum(frecuencias$Frecuencia_Absoluta)
frecuencias <- frecuencias %>%
mutate(Frecuencia_Relativa = round((Frecuencia_Absoluta / total_frecuencia) * 100, 2),
Frecuencia_Acumulada = cumsum(Frecuencia_Absoluta))
if (nrow(frecuencias) > top_n) {
otros <- sum(frecuencias$Frecuencia_Absoluta[(top_n+1):nrow(frecuencias)])
frecuencias <- frecuencias[1:top_n, ]
frecuencias <- rbind(frecuencias,
data.frame(Categoria = "Otros",
Frecuencia_Absoluta = otros,
Frecuencia_Relativa = round((otros / total_frecuencia) * 100, 2),
Frecuencia_Acumulada = sum(frecuencias$Frecuencia_Absoluta) + otros))
frecuencias <- rbind(frecuencias,
data.frame(Categoria = "Total",
Frecuencia_Absoluta = total_frecuencia,
Frecuencia_Relativa = 100,
Frecuencia_Acumulada = ""))
frecuencias <- rbind(frecuencias,
data.frame(Categoria = moda,
Frecuencia_Absoluta = "",
Frecuencia_Relativa = "",
Frecuencia_Acumulada = ""))
}
tabla_kable <- frecuencias %>%
kbl(caption = paste("Resumen de frecuencias para", nombre_variable), digits = 2, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue") %>%
row_spec(nrow(frecuencias) - 2, bold = TRUE, color = "white", background = "darkgrey") %>%
row_spec(nrow(frecuencias) - 1, bold = TRUE, color = "black", background = "lightgrey") %>%
row_spec(nrow(frecuencias), bold = TRUE, color = "white", background = "darkblue")
return(tabla_kable)
}
resumen_categorico(datos$Genres, "Género", "Moda: Drama")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
Drama | 2009 | 15.6 | 2009 |
Comedy | 1907 | 14.8 | 3916 |
Action | 1384 | 10.74 | 5300 |
Adventure | 1063 | 8.25 | 6363 |
Thriller | 1060 | 8.23 | 7423 |
Romance | 844 | 6.55 | 8267 |
Crime | 699 | 5.43 | 8966 |
Family | 694 | 5.39 | 9660 |
Fantasy | 634 | 4.92 | 10294 |
Science Fiction | 514 | 3.99 | 10808 |
Otros | 2074 | 16.1 | 12882 |
Total | 12882 | 100 | |
Moda: Drama |
resumen_categorico(datos$Original_Language, "Idioma Original", "Moda: English (en)")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
en | 3271 | 67.72 | 3271 |
ja | 369 | 7.64 | 3640 |
zh | 280 | 5.8 | 3920 |
fr | 203 | 4.2 | 4123 |
ko | 194 | 4.02 | 4317 |
hi | 92 | 1.9 | 4409 |
de | 77 | 1.59 | 4486 |
es | 63 | 1.3 | 4549 |
cn | 61 | 1.26 | 4610 |
it | 56 | 1.16 | 4666 |
Otros | 164 | 3.4 | 4830 |
Total | 4830 | 100 | |
Moda: English (en) |
resumen_categorico(datos$Production_Countries, "País de Producción", "Moda: United States of America")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
United States of America | 3153 | 43.72 | 3153 |
United Kingdom | 616 | 8.54 | 3769 |
France | 454 | 6.3 | 4223 |
Japan | 436 | 6.05 | 4659 |
China | 394 | 5.46 | 5053 |
Germany | 362 | 5.02 | 5415 |
Canada | 243 | 3.37 | 5658 |
South Korea | 214 | 2.97 | 5872 |
Hong Kong | 191 | 2.65 | 6063 |
India | 158 | 2.19 | 6221 |
Otros | 991 | 13.74 | 7212 |
Total | 7212 | 100 | |
Moda: United States of America |
Análisis:
- El género más frecuente en la base de datos es Drama, con 2,009
películas, representando el 15.6% del total. Le siguen Comedy (14.8%) y
Action (10.74%). Los géneros menos frecuentes incluyen Science Fiction
(3.99%). La categoría “Otros” agrupa géneros con menor presencia (2,074
películas).
- El idioma predominante es inglés (en), con el 67.72% de las películas,
lo que indica un fuerte dominio de esta lengua en la industria
cinematográfica. Otros idiomas como japonés (ja) (7.64%) y chino (zh)
(5.8%) también tienen cierta representación. Los demás idiomas tienen
frecuencias relativamente bajas.
- Los Estados Unidos dominan la producción con 43.72% de las películas,
seguidos por Reino Unido (8.54%) y Francia (6.3%). Los países con menor
representación en el top 10 incluyen India (2.19%). La categoría “Otros”
agrupa el 13.74% de las películas, indicando una dispersión de
producciones en diversos países.
datos_separados <- datos %>%
separate_rows(Genres, sep = ",\\s*") # Divide los géneros correctamente
freq_genres <- datos_separados %>%
count(Genres, sort = TRUE) %>%
top_n(12, n)
ggplot(freq_genres, aes(x = reorder(Genres, n), y = n, fill = n)) +
geom_bar(stat = "identity", show.legend = FALSE) +
scale_fill_viridis_c(option = "plasma") +
coord_flip() +
geom_text(aes(label = n), hjust = -0.2, size = 5, color = "black") +
expand_limits(y = max(freq_genres$n) * 1.2) +
labs(title = "🎬 Distribución de Géneros de Películas",
x = "Géneros",
y = "Frecuencia") +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 18),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "#F8F8F8", color = NA))
datos_filtrados <- datos %>%
filter(Original_Language != "", !is.na(Original_Language)) # Elimina valores vacíos o NA
freq_language <- datos_filtrados %>%
count(Original_Language, name = "Freq") %>%
mutate(Percentage = round((Freq / sum(Freq)) * 100, 1)) %>%
arrange(Freq) %>%
slice_tail(n = 15)
# Graficar
ggplot(freq_language, aes(x = reorder(Original_Language, Freq), y = Freq, fill = Freq)) +
geom_bar(stat = "identity", color = "black") +
geom_text(aes(label = paste(Freq, "(", Percentage, "%)", sep = "")), hjust = -0.18, size = 4) +
scale_fill_viridis_c(option = "magma", direction = -1) +
labs(title = "Distribución de Idiomas Originales en Películas",
x = "Idiomas",
y = "Frecuencia") +
theme_minimal(base_size = 16) +
theme(panel.grid.major = element_line(color = "grey90"),
panel.border = element_rect(color = "grey50", fill = NA),
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1)) +
expand_limits(y = max(freq_language$Freq) * 1.2) +
coord_flip()
A continuación se visualiza un diccionarios con el idioma correspondiente a las abreviaciones en la base de datos:
df_idiomas <- data.frame(
Código = c("en", "ja", "zh", "fr", "ko", "hi", "de", "es", "cn", "it", "ru", "tr", "te", "sv"),
Idioma = c("Inglés", "Japonés", "Chino", "Francés", "Coreano", "Hindi",
"Alemán", "Español", "Chino (simplificado)", "Italiano",
"Ruso", "Turco", "Telugu", "Sueco")
)
df_idiomas %>%
gt() %>%
tab_header(
title = "Diccionario de Abreviaciones de Idiomas"
) %>%
cols_align(align = "center", columns = everything()) %>%
tab_style(
style = list(
cell_borders(sides = "all", weight = px(1)),
cell_fill(color = "#f5f5f5")
),
locations = cells_body()
)
Diccionario de Abreviaciones de Idiomas | |
Código | Idioma |
---|---|
en | Inglés |
ja | Japonés |
zh | Chino |
fr | Francés |
ko | Coreano |
hi | Hindi |
de | Alemán |
es | Español |
cn | Chino (simplificado) |
it | Italiano |
ru | Ruso |
tr | Turco |
te | Telugu |
sv | Sueco |
df_paises <- as.data.frame(table(unlist(strsplit(as.character(datos$Production_Countries), ", "))))
colnames(df_paises) <- c("Production_Countries", "Frecuencia")
df_paises <- df_paises %>% arrange(desc(Frecuencia))
top_paises <- head(df_paises, 10)
ggplot(top_paises, aes(x = Frecuencia, y = reorder(Production_Countries, Frecuencia), fill = Frecuencia)) +
geom_col() +
geom_text(aes(label = Frecuencia), hjust = -0.2, fontface = "bold", size = 4) +
expand_limits(x = max(top_paises$Frecuencia) * 1.2) +
scale_fill_gradient(low = "yellow", high = "blue") +
labs(title = "Distribución de Países de Producción",
x = "Frecuencia",
y = "Países") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 16))
Para analizar las variables cuantitativas del conjunto de datos, se calcularon estadísticas descriptivas como la media, mediana, desviación estándar, mínimo y máximo. Estas métricas permiten comprender la distribución y variabilidad de cada variable. Además, se realiza el analisis de medidas de tendencia central y de dispersión.
datos_numericos <- datos[, sapply(datos, is.numeric)]
summary(datos_numericos)
## Rank X.Worldwide X.Domestic Domestic..
## Min. : 1.00 Min. :1.666e+06 Min. : 0 Min. : 0.00
## 1st Qu.: 50.75 1st Qu.:2.466e+07 1st Qu.: 92752 1st Qu.: 0.20
## Median :100.50 Median :4.845e+07 Median : 17984212 Median : 37.05
## Mean :100.50 Mean :1.192e+08 Mean : 44725233 Mean : 35.74
## 3rd Qu.:150.25 3rd Qu.:1.198e+08 3rd Qu.: 53868472 3rd Qu.: 57.80
## Max. :200.00 Max. :2.799e+09 Max. :936662225 Max. :100.00
## X.Foreign Foreign.. Year Vote_Count
## Min. :0.000e+00 Min. : 0.00 Min. :2000 Min. : 0.0
## 1st Qu.:1.371e+07 1st Qu.: 42.20 1st Qu.:2006 1st Qu.: 226.5
## Median :3.019e+07 Median : 62.95 Median :2012 Median : 1035.5
## Mean :7.449e+07 Mean : 64.26 Mean :2012 Mean : 2480.7
## 3rd Qu.:7.212e+07 3rd Qu.: 99.80 3rd Qu.:2018 3rd Qu.: 2939.0
## Max. :1.994e+09 Max. :100.00 Max. :2024 Max. :36753.0
# Calcular la matriz de correlación
correlation_matrix <- cor(datos[, c("X.Worldwide", "X.Domestic", "X.Foreign", "Vote_Count")], use = "complete.obs")
# Visualizar la matriz de correlación
library(reshape2)
library(ggplot2)
correlation_melted <- melt(correlation_matrix)
ggplot(correlation_melted, aes(Var1, Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "blue", high = "red", mid = "white", limit = c(-1, 1), name="Correlación") +
theme_minimal() +
labs(title = "Mapa de Calor de Correlación")
Relaciones clave:
datos_filtrados <- datos$X.Worldwide[is.finite(datos$X.Worldwide) & !is.na(datos$X.Worldwide)] # Eliminar valores no finitos
# Definir los intervalos
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE), max(datos_filtrados, na.rm = TRUE), length.out = 10), include.lowest = TRUE)
# Calcular las frecuencias absoluta, relativa y acumulada
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
# Crear la tabla de frecuencias
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2) # En porcentaje
)
# Fila al final con los totales
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
# Mostrar la tabla usando kable
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable X.Worldwide", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[1.67e+06,3.13e+08] | 4542 | 4542 | 90.84 |
(3.13e+08,6.23e+08] | 287 | 4829 | 5.74 |
(6.23e+08,9.34e+08] | 107 | 4936 | 2.14 |
(9.34e+08,1.25e+09] | 41 | 4977 | 0.82 |
(1.25e+09,1.56e+09] | 14 | 4991 | 0.28 |
(1.56e+09,1.87e+09] | 3 | 4994 | 0.06 |
(1.87e+09,2.18e+09] | 3 | 4997 | 0.06 |
(2.18e+09,2.49e+09] | 1 | 4998 | 0.02 |
(2.49e+09,2.8e+09] | 2 | 5000 | 0.04 |
Total | 5000 | NA | 100.00 |
La distribución de las recaudaciones globales de las películas muestra una alta concentración en valores bajos, con la mayoría de las películas generando ingresos moderados, mientras que un pequeño porcentaje alcanza cifras significativamente más altas. Esto refleja una distribución desigual en la industria, donde unas pocas películas muy exitosas dominan el mercado, mientras que la mayoría se quedan con ingresos más modestos. La mayor parte del total de recaudaciones está agrupada en un pequeño número de películas de gran éxito, mientras que el resto tiene un rendimiento más equilibrado o bajo.
datos_filtrados <- datos$Domestic[is.finite(datos$Domestic) & !is.na(datos$Domestic)] # Eliminar valores no finitos
# Definir los intervalos
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE), max(datos_filtrados, na.rm = TRUE), length.out = 10), include.lowest = TRUE)
# Calcular las frecuencias absoluta, relativa y acumulada
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
# Crear la tabla de frecuencias
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2) # En porcentaje
)
# Fila al final con los totales
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
# Mostrar la tabla usando kable
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Domestic", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0,11.1] | 1689 | 1689 | 33.78 |
(11.1,22.2] | 208 | 1897 | 4.16 |
(22.2,33.3] | 415 | 2312 | 8.30 |
(33.3,44.4] | 610 | 2922 | 12.20 |
(44.4,55.6] | 711 | 3633 | 14.22 |
(55.6,66.7] | 494 | 4127 | 9.88 |
(66.7,77.8] | 348 | 4475 | 6.96 |
(77.8,88.9] | 231 | 4706 | 4.62 |
(88.9,100] | 294 | 5000 | 5.88 |
Total | 5000 | NA | 100.00 |
La distribución de las recaudaciones domésticas de las películas está concentrada en valores bajos, con un 33.78% de las películas obteniendo ingresos dentro del primer intervalo (0 a 11.1). Aunque hay una distribución más variada, la mayoría de las películas tienen ingresos relativamente bajos, con una disminución gradual en la frecuencia a medida que aumentan las recaudaciones.
datos_filtrados <- datos$Foreign[is.finite(datos$Foreign) & !is.na(datos$Foreign)] # Eliminar valores no finitos
# Definir los intervalos
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE), max(datos_filtrados, na.rm = TRUE), length.out = 10), include.lowest = TRUE)
# Calcular las frecuencias absoluta, relativa y acumulada
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
# Crear la tabla de frecuencias
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2) # En porcentaje
)
# Fila al final con los totales
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
# Mostrar la tabla usando kable
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Foreign", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0,11.1] | 294 | 294 | 5.88 |
(11.1,22.2] | 231 | 525 | 4.62 |
(22.2,33.3] | 348 | 873 | 6.96 |
(33.3,44.4] | 494 | 1367 | 9.88 |
(44.4,55.6] | 711 | 2078 | 14.22 |
(55.6,66.7] | 610 | 2688 | 12.20 |
(66.7,77.8] | 415 | 3103 | 8.30 |
(77.8,88.9] | 208 | 3311 | 4.16 |
(88.9,100] | 1689 | 5000 | 33.78 |
Total | 5000 | NA | 100.00 |
La distribución de las recaudaciones internacionales de las películas está más equilibrada en comparación con el mercado doméstico. Si bien la mayor parte de las películas aún se concentran en intervalos de recaudación más bajos, existe una mayor proporción de películas con altos ingresos en el mercado internacional.
datos_filtrados <- datos$Vote_Count[is.finite(datos$Vote_Count) & !is.na(datos$Vote_Count)] # Eliminar valores no finitos
# Definir los intervalos
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE), max(datos_filtrados, na.rm = TRUE), length.out = 10), include.lowest = TRUE)
# Calcular las frecuencias absoluta, relativa y acumulada
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
# Crear la tabla de frecuencias
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2) # En porcentaje
)
# Fila al final con los totales
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
# Mostrar la tabla usando kable
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Vote_Count", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0,4.08e+03] | 4099 | 4099 | 81.98 |
(4.08e+03,8.17e+03] | 534 | 4633 | 10.68 |
(8.17e+03,1.23e+04] | 190 | 4823 | 3.80 |
(1.23e+04,1.63e+04] | 87 | 4910 | 1.74 |
(1.63e+04,2.04e+04] | 47 | 4957 | 0.94 |
(2.04e+04,2.45e+04] | 29 | 4986 | 0.58 |
(2.45e+04,2.86e+04] | 7 | 4993 | 0.14 |
(2.86e+04,3.27e+04] | 4 | 4997 | 0.08 |
(3.27e+04,3.68e+04] | 3 | 5000 | 0.06 |
Total | 5000 | NA | 100.00 |
La distribución del número de votos muestra que una gran parte de las películas recibe pocos votos, con más del 80% de las películas concentradas en los primeros intervalos, lo que sugiere que la mayoría de las películas no alcanzan un nivel alto de popularidad en términos de votos.
# Función para calcular la moda
moda <- function(x) {
uniq <- unique(na.omit(x))
uniq[which.max(tabulate(match(x, uniq)))]
}
# Calcular media, moda y mediana para X.Worldwide
media_X.Worldwide <- mean(datos$X.Worldwide, na.rm = TRUE)
mediana_X.Worldwide <- median(datos$X.Worldwide, na.rm = TRUE)
moda_X.Worldwide <- moda(datos$X.Worldwide)
# Calcular media, moda y mediana para Domestic
media_Domestic <- mean(datos$Domestic, na.rm = TRUE)
mediana_Domestic <- median(datos$Domestic, na.rm = TRUE)
moda_Domestic <- moda(datos$Domestic)
# Calcular media, moda y mediana para Year
media_Year <- mean(datos$Year, na.rm = TRUE)
mediana_Year <- median(datos$Year, na.rm = TRUE)
moda_Year <- moda(datos$Year)
# Calcular media, moda y mediana para Foreign
media_Foreign <- mean(datos$Foreign, na.rm = TRUE)
mediana_Foreign <- median(datos$Foreign, na.rm = TRUE)
moda_Foreign <- moda(datos$Foreign)
# Calcular media, moda y mediana para Vote_Count
media_Vote_Count <- mean(datos$Vote_Count, na.rm = TRUE)
mediana_Vote_Count <- median(datos$Vote_Count, na.rm = TRUE)
moda_Vote_Count <- moda(datos$Vote_Count)
# Redondear las medias a 2 decimales y asegurarse de que no estén en notación científica
resultados <- data.frame(
Variable = c("X.Worldwide", "Domestic", "Year", "Foreign", "Vote Count"),
Media = c(
format(media_X.Worldwide, scientific = FALSE, digits = 2),
format(media_Domestic, scientific = FALSE, digits = 2),
format(media_Year, scientific = FALSE, digits = 2),
format(media_Foreign, scientific = FALSE, digits = 2),
format(media_Vote_Count, scientific = FALSE, digits = 2)
),
Mediana = c(
format(mediana_X.Worldwide, scientific = FALSE, digits = 2),
format(mediana_Domestic, scientific = FALSE, digits = 2),
format(mediana_Year, scientific = FALSE, digits = 2),
format(mediana_Foreign, scientific = FALSE, digits = 2),
format(mediana_Vote_Count, scientific = FALSE, digits = 2)
),
Moda = c(moda_X.Worldwide, moda_Domestic, moda_Year, moda_Foreign, moda_Vote_Count)
)
# Mostrar la tabla utilizando kableExtra
library(kableExtra)
kable(resultados, col.names = c("Variable", "Media", "Mediana", "Moda")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F) %>%
row_spec(0, bold = TRUE, color = "white", background = "#4CAF50") %>%
row_spec(1:5, background = "#f5f5f5")
Variable | Media | Mediana | Moda |
---|---|---|---|
X.Worldwide | 119213693 | 48446575 | 32800000.0 |
Domestic | 36 | 37 | 0.0 |
Year | 2012 | 2012 | 2000.0 |
Foreign | 64 | 63 | 100.0 |
Vote Count | 2481 | 1036 | 1035.5 |
Asimetría en la variable Worldwide
La variable Year muestra una distribución sin sesgo
Vote Count tiene una distribución altamente sesgada
# Calcular medidas de dispersión para X.Worldwide
rango_X.Worldwide <- range(datos$X.Worldwide, na.rm = TRUE)
varianza_X.Worldwide <- var(datos$X.Worldwide, na.rm = TRUE)
sd_X.Worldwide <- sd(datos$X.Worldwide, na.rm = TRUE)
cv_X.Worldwide <- sd_X.Worldwide / mean(datos$X.Worldwide, na.rm = TRUE)
# Calcular medidas de dispersión para Domestic
rango_Domestic <- range(datos$Domestic, na.rm = TRUE)
varianza_Domestic <- var(datos$Domestic, na.rm = TRUE)
sd_Domestic <- sd(datos$Domestic, na.rm = TRUE)
cv_Domestic <- sd_Domestic / mean(datos$Domestic, na.rm = TRUE)
# Calcular medidas de dispersión para Foreign
rango_Foreign <- range(datos$Foreign, na.rm = TRUE)
varianza_Foreign <- var(datos$Foreign, na.rm = TRUE)
sd_Foreign <- sd(datos$Foreign, na.rm = TRUE)
cv_Foreign <- sd_Foreign / mean(datos$Foreign, na.rm = TRUE)
# Calcular medidas de dispersión para Vote_Count
rango_Year <- range(datos$Vote_Count, na.rm = TRUE)
varianza_Year <- var(datos$Vote_Count, na.rm = TRUE)
sd_Year <- sd(datos$Vote_Count, na.rm = TRUE)
cv_Year <- sd_Year / mean(datos$Vote_Count, na.rm = TRUE)
# Crear el dataframe con todas las medidas
tabla_dispersion <- data.frame(
Variable = c("X.Worldwide", "Domestic", "Foreign", "Vote Count"),
Rango = c(paste(rango_X.Worldwide[1], "-", rango_X.Worldwide[2]),
paste(rango_Domestic[1], "-", rango_Domestic[2]),
paste(rango_Foreign[1], "-", rango_Foreign[2]),
paste(rango_Year[1], "-", rango_Year[2])),
Varianza = c(format(varianza_X.Worldwide, scientific = FALSE, digits = 4),
format(varianza_Domestic, scientific = FALSE, digits = 4),
format(varianza_Foreign, scientific = FALSE, digits = 4),
format(varianza_Year, scientific = FALSE, digits = 4)),
`Desviación Estándar` = c(format(sd_X.Worldwide, scientific = FALSE, digits = 4),
format(sd_Domestic, scientific = FALSE, digits = 4),
format(sd_Foreign, scientific = FALSE, digits = 4),
format(sd_Year, scientific = FALSE, digits = 4)),
`Coeficiente de Variación` = c(format(cv_X.Worldwide, scientific = FALSE, digits = 4),
format(cv_Domestic, scientific = FALSE, digits = 4),
format(cv_Foreign, scientific = FALSE, digits = 4),
format(cv_Year, scientific = FALSE, digits = 4))
)
# Mostrar la tabla con kable
library(kableExtra)
tabla_dispersion %>%
kbl(caption = "Medidas de Dispersión para Variables Cuantitativas", digits = 4, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
Variable | Rango | Varianza | Desviación.Estándar | Coeficiente.de.Variación |
---|---|---|---|---|
X.Worldwide | 1666028 - 2799439100 | 40210012222775640 | 200524343 | 1.682 |
Domestic | 0 - 100 | 939.9 | 30.66 | 0.8578 |
Foreign | 0 - 100 | 939.7 | 30.65 | 0.4771 |
Vote Count | 0 - 36753 | 15117008 | 3888 | 1.567 |
Worldwide tiene el mayor rango, lo que indica una enorme variabilidad en la recaudación de las películas. Su varianza es extremadamente alta, lo que significa que los valores están muy dispersos con respecto a la media. La desviación estándar también es grande, reafirmando la alta variabilidad en los ingresos de las películas. Y el Coeficiente de variación indica que, en proporción a la media, hay una gran dispersión.
En Domestic el rango es más limitado, ya que probablemente esté en una escala porcentual. La varianza y desviación estándar son moderadas en comparación con la recaudación mundial. Por ultimo, el Coeficiente de variación sugiere que la dispersión en relación con la media es moderada.
Foreign parece ser una variable más estable en comparación con Domestic y X.Worldwide. Aunque la variabilidad absoluta es similar a Domestic, en términos relativos los ingresos internacionales muestran una menor dispersión, lo que sugiere una mayor consistencia en el rendimiento de las películas en mercados extranjeros.
Vote Count es una variable con altísima dispersión, lo que indica que la cantidad de votos está muy desbalanceada entre películas. Algunas reciben miles de valoraciones, mientras que otras casi ninguna. Esto sugiere una distribución desigual de la atención del público, lo cual es común en la industria del cine, donde ciertos títulos dominan el interés general.
library(ggplot2)
library(reshape2)
# Crear un dataframe con solo las variables relevantes
datos_ingresos <- datos[, c("X.Worldwide", "X.Domestic", "X.Foreign")]
# Transformar los datos a formato largo para el boxplot
datos_largos_ingresos <- melt(datos_ingresos, variable.name = "Ingreso", value.name = "Valor")
## No id variables; using all as measure variables
# Crear el boxplot para los ingresos
ggplot(datos_largos_ingresos, aes(x = Ingreso, y = Valor)) +
geom_boxplot() +
labs(title = "Comparación de Ingresos de Taquilla",
x = "Tipo de Ingreso",
y = "Valor de Ingreso") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
library(ggplot2)
# Histograma de ingresos mundiales
ggplot(datos, aes(x = X.Worldwide)) +
geom_histogram(binwidth = 50000000, fill = "blue", color = "black") +
labs(title = "Distribución de Ingresos Mundiales", x = "Ingresos Mundiales", y = "Frecuencia")
# Histograma de ingresos domésticos
ggplot(datos, aes(x = X.Domestic)) +
geom_histogram(binwidth = 50000000, fill = "green", color = "black") +
labs(title = "Distribución de Ingresos Domésticos", x = "Ingresos Domésticos", y = "Frecuencia")
# Histograma de ingresos extranjeros
ggplot(datos, aes(x = X.Foreign)) +
geom_histogram(binwidth = 50000000, fill = "red", color = "black") +
labs(title = "Distribución de Ingresos Extranjeros", x = "Ingresos Extranjeros", y = "Frecuencia")
Anotaciones:
library(nortest)
# Prueba de Anderson-Darling para las tres variables
ad_worldwide <- ad.test(datos$X.Worldwide)
ad_foreign <- ad.test(datos$X.Foreign)
ad_domestic <- ad.test(datos$X.Domestic)
ad_worldwide
##
## Anderson-Darling normality test
##
## data: datos$X.Worldwide
## A = 706.49, p-value < 2.2e-16
ad_foreign
##
## Anderson-Darling normality test
##
## data: datos$X.Foreign
## A = 743.17, p-value < 2.2e-16
ad_domestic
##
## Anderson-Darling normality test
##
## data: datos$X.Domestic
## A = 564.58, p-value < 2.2e-16
datos_porcentajes <- datos[, c("Domestic..", "Foreign..")]
datos_largos_porcentajes <- melt(datos_porcentajes, variable.name = "Porcentaje", value.name = "Valor")
## No id variables; using all as measure variables
ggplot(datos_largos_porcentajes, aes(x = Porcentaje, y = Valor)) +
geom_boxplot() +
labs(title = "Comparación de Porcentajes de Ingresos de Taquilla",
x = "Tipo de Porcentaje",
y = "Porcentaje de Ingresos") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
library(reshape2)
# Seleccionar las variables y transformarlas a formato largo
datos_porcentajes <- datos[, c("Domestic..", "Foreign..")]
datos_largos <- melt(datos_porcentajes, variable.name = "Tipo", value.name = "Valor")
## No id variables; using all as measure variables
# Crear un histograma comparativo
ggplot(datos_largos, aes(x = Valor, fill = Tipo)) +
geom_histogram(position = "identity", alpha = 0.5, bins = 30) +
labs(title = "Comparación de Domestic % y Foreign %",
x = "Porcentaje",
y = "Frecuencia") +
theme_minimal()
Anotaciones:
Los histogramas y los boxplots de las variables Domestic % y Foreign %, revelan una distribución marcadamente asimétrica y alejada de la normalidad, Domestic % cuenta con un sesgo positivo, lo que nos indica que la mayoría de las películas generan bajos porcentajes de sus ingresos en el mercado doméstico, pero algunas excepciones logran recaudar una gran parte localmente, lo que explicaría que la cola de la distribución se extienda hacia la derecha, indicando la presencia de valores atípicamente altos.
Por otro lado, Foreign % tiene un sesgo negativo o a la izquierda, lo que nos da a entender que la mayoría de las películas obtienen una gran parte de sus ingresos en mercados internacionales, es decir, dependen de los ingresos extranjeros para alcanzar grandes cifras en taquilla. Los boxplots también nos evidencian que la mediana de Foreign % es mayor, confirmando que esta tiene valores típicamente mayores a Domestic % y se complementan, puesto que si una sube, la otra baja.
En conclusión, estos resultados sugieren que el éxito global de una película está más determinado por su desempeño en mercados extranejeros
En otro orden de ideas, es evidente que estas variables no siguen una distribución normal; sin embargo, realizaremos la prueba de normalidad de Anderson-Darling para verificarlo:
library(nortest)
# Prueba de Anderson-Darling para las tres variables
ad_foreignp <- ad.test(datos$Foreign)
ad_domesticp <- ad.test(datos$Domestic)
ad_foreignp
##
## Anderson-Darling normality test
##
## data: datos$Foreign
## A = 146.83, p-value < 2.2e-16
ad_domesticp
##
## Anderson-Darling normality test
##
## data: datos$Domestic
## A = 146.99, p-value < 2.2e-16
library(ggplot2)
datos$Rating <- as.numeric(gsub("/10", "", datos$Rating))
ggplot(datos, aes(y = Rating)) +
geom_boxplot() +
labs(title = "Boxplot de Rating",
x = "Rating",
y = "Valor de Rating") +
theme_minimal()
## Warning: Removed 170 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
ggplot(datos, aes(x = Rating)) +
geom_histogram(binwidth = 0.2, fill = "skyblue", color = "black", alpha = 0.7) +
labs(title = "Histograma de Rating",
x = "Rating (Calificación Media)",
y = "Frecuencia") +
theme_minimal()
## Warning: Removed 170 rows containing non-finite outside the scale range
## (`stat_bin()`).
library(nortest)
datos$Rating <- as.numeric(gsub("/10", "", datos$Rating))
ad_rating <- ad.test(datos$Rating)
ad_rating
##
## Anderson-Darling normality test
##
## data: datos$Rating
## A = 45.239, p-value < 2.2e-16
En este punto, evaluaremos si el género de una película influye directamente en las ganancias internacionales obtenidas. Para ello, nos centraremos en tres géneros específicos y analizaremos si las medias de sus ganancias internacionales presentan diferencias significativas.
Usaremos como grupo de interés la variable “Género” y “Foreign” para determinar las ganancias internacionales de cada película.
Antes de aplicar las pruebas estadísticas, evaluaremos la distribución de los datos para determinar si se ajustan a una distribución normal. Esto es crucial porque la normalidad de los datos guiará la elección de la prueba estadística adecuada (paramétrica o no paramétrica).
Como ya se comprobó antes, la variable Foreign
no cumple
el supuesto de normalidad, por lo cual utilizaremos la prueba de
Kruskal-Wallis en lugar de la prueba de ANOVA, ya que la primera es una
alternativa no paramétrica que no requiere que los datos sigan una
distribución normal.
Primero realizaré una filtración de los géneros de las películas, puesto que se encuentran juntas entre comas.
#Separamos los géneros
Generos_Separados <- unlist(strsplit(as.character(datos$Genres), split = ", "))
#Contamos cuantas películas hay
Frecuencia_Absoluta <- table(Generos_Separados)
#Calculamos la frecuencia relativa
Frecuencia_Relativa <- prop.table(Frecuencia_Absoluta)
#Agrupamos todo en Data Frame
Tabla_Final <- data.frame(Genero = names(Frecuencia_Absoluta), Frecuencia_Absoluta = as.numeric(Frecuencia_Absoluta), Frecuencia_Relativa = round(100 * as.numeric(Frecuencia_Relativa), 2)) #Multiplicamos por 100 para convertilo en porcentaje y lo redondeamos a dos cifras.
colnames(Tabla_Final)[colnames(Tabla_Final) == "Frecuencia_Absoluta"] <- "Frecuencia Absoluta"
colnames(Tabla_Final)[colnames(Tabla_Final) == "Frecuencia_Relativa"] <- "Frecuencia Relativa"
#Hacemos una tabla con la función "kable"
Tabla_Frecuencia <- kable(Tabla_Final, align = "c") %>%
kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed", "responsive"),
font_size = 15, fixed_thead = TRUE) %>%
column_spec(1, bold = TRUE, width = "10em") %>%
column_spec(2, width = "10em") %>%
column_spec(3, width = "10em") %>%
row_spec(0, bold = TRUE, background = "#9eb5d9", color = "black")
Tabla_Frecuencia
Genero | Frecuencia Absoluta | Frecuencia Relativa |
---|---|---|
Action | 1384 | 10.74 |
Adventure | 1063 | 8.25 |
Animation | 498 | 3.87 |
Comedy | 1907 | 14.80 |
Crime | 699 | 5.43 |
Documentary | 79 | 0.61 |
Drama | 2009 | 15.60 |
Family | 694 | 5.39 |
Fantasy | 634 | 4.92 |
History | 293 | 2.27 |
Horror | 436 | 3.38 |
Music | 152 | 1.18 |
Mystery | 431 | 3.35 |
Romance | 844 | 6.55 |
Science Fiction | 514 | 3.99 |
Thriller | 1060 | 8.23 |
TV Movie | 7 | 0.05 |
War | 144 | 1.12 |
Western | 34 | 0.26 |
Como podemos ver, ya hemos separado los géneros de las películas, lo que nos permitirá contar cuántas películas corresponden a cada género. A continuación, nos enfocaremos en el otro grupo de interés, que son las ganancias internacionales de las películas. Para ello, procederemos a filtrar las películas según su género y analizaremos las ganancias correspondientes a cada grupo.
GananciasGenero <- rep(datos$X.Foreign, sapply(strsplit(as.character(datos$Genres), split = ", "), length))
#Juntamos los géneros y las ganancias de las películas en un Data Frame
Data_Frame_Ganancias_Generos <- data.frame(Genero = Generos_Separados, Ganancias = GananciasGenero)
#Las agrupamos por genero
Agrupacion_Ganancias_Generos <- aggregate(Ganancias ~ Genero, data = Data_Frame_Ganancias_Generos, sum)
# Formateamos las ganancias con puntos y comas para la tabla
Agrupacion_Ganancias_Generos$Ganancias_formateadas <- comma(Agrupacion_Ganancias_Generos$Ganancias)
colnames(Agrupacion_Ganancias_Generos)[colnames(Agrupacion_Ganancias_Generos) == "Ganancias_formateadas"] <- "Ganancia"
# Creamos la tabla con la columna de ganancias formateadas
Tabla_Frecuencia3 <- kable(Agrupacion_Ganancias_Generos[, c("Genero", "Ganancia")],
caption = "Tabla: Ganancias Totales por Genero", align = "c") %>%
kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed", "responsive"),
font_size = 15, fixed_thead = TRUE) %>%
column_spec(1, bold = TRUE, width = "10em") %>%
column_spec(2, width = "10em") %>%
row_spec(0, bold = TRUE, background = "#00b08e", color = "black")
# Mostrar la tabla
Tabla_Frecuencia3
Genero | Ganancia |
---|---|
Action | 165,951,686,864 |
Adventure | 168,387,139,689 |
Animation | 61,501,072,956 |
Comedy | 120,154,492,707 |
Crime | 40,170,061,703 |
Documentary | 1,827,471,543 |
Drama | 102,252,519,801 |
Family | 75,375,365,889 |
Fantasy | 81,244,594,839 |
History | 16,554,412,413 |
Horror | 20,272,217,062 |
Music | 8,148,949,877 |
Mystery | 23,721,062,500 |
Romance | 42,095,656,530 |
Science Fiction | 82,247,553,450 |
Thriller | 72,920,927,337 |
TV Movie | 129,380,542 |
War | 12,760,889,331 |
Western | 1,913,719,532 |
# Crear gráfico de barras con las ganancias numéricas, pero con etiquetas formateadas
ggplot(Agrupacion_Ganancias_Generos, aes(x = reorder(Genero, -Ganancias), y = Ganancias, fill = Genero)) +
geom_bar(stat = "identity") +
labs(title = "Ganancias Totales por Genero", x = "Genero", y = "Ganancia Total") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_y_continuous(labels = scales::comma) # Formateamos las etiquetas del eje Y con puntos y comas
De acuerdo con la tabla, podemos observar que los géneros comedia, acción y aventura son los que generaron mayores ganancias. Por lo tanto, nos centraremos en estos tres géneros. A simple vista, podríamos suponer que el género que más generó será el que tenga la mediana más alta. Vamos a comprobar esta hipótesis calculando la media y la mediana de las ganancias para cada género:
# Filtrar los géneros en los que estamos interesados
Generos_Seleccionados <- c("Action", "Adventure", "Comedy")
# Filtrar los datos que contienen esos géneros
Data_Filtrada <- subset(Data_Frame_Ganancias_Generos, Genero %in% Generos_Seleccionados)
# Calcular la media y la mediana de las ganancias por género
Estadisticas_Ganancias_Filtradas <- aggregate(Ganancias ~ Genero, data = Data_Filtrada,
FUN = function(x) c(Mediana = median(x, na.rm = TRUE)))
# Convertir la matriz de estadísticas en columnas separadas
Estadisticas_Ganancias_Filtradas <- data.frame(Genero = Estadisticas_Ganancias_Filtradas$Genero,
Medianas = Estadisticas_Ganancias_Filtradas$Ganancias)
# Formatear los valores con comas
Estadisticas_Ganancias_Filtradas$Mediana <- comma(Estadisticas_Ganancias_Filtradas$Medianas)
# Crear la tabla con kable
Tabla_Estadisticas_Filtradas <- kable(Estadisticas_Ganancias_Filtradas[, c("Genero", "Mediana")],
caption = "Tabla: Mediana de Ganancias (Action, Adventure, Comedy)",
align = "c") %>%
kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed", "responsive"),
font_size = 15, fixed_thead = TRUE) %>%
column_spec(1, bold = TRUE, width = "10em") %>%
column_spec(2, width = "10em") %>%
row_spec(0, bold = TRUE, background = "#ffcc00", color = "black")
# Mostrar la tabla
Tabla_Estadisticas_Filtradas
Genero | Mediana |
---|---|
Action | 48,478,541 |
Adventure | 61,153,455 |
Comedy | 27,302,268 |
# Gráfico de barras para la mediana de ganancias
ggplot(Estadisticas_Ganancias_Filtradas, aes(x = reorder(Genero, -Medianas), y = Medianas, fill = Genero)) +
geom_bar(stat = "identity") +
labs(title = "Mediana de Ganancias por Género", x = "Género", y = "Mediana de Ganancia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_y_continuous(labels = scales::comma)
Como podemos observar, la mediana se sigue acomodando a los indicios que obtuvimos antes. Sin embargo, veamos si esta diferencia en las distribuciones (o en las medianas) es en realidad significativa con la prueba de Kruskal.
# Filtrar los géneros en los que estamos interesados
Generos_Seleccionados <- c("Action", "Adventure", "Comedy")
# Filtrar los datos que contienen esos géneros
Data_Filtrada <- subset(Data_Frame_Ganancias_Generos, Genero %in% Generos_Seleccionados)
# Realizar la prueba de Kruskal-Wallis
kruskal_test <- kruskal.test(Ganancias ~ Genero, data = Data_Filtrada)
kruskal_test
##
## Kruskal-Wallis rank sum test
##
## data: Ganancias by Genero
## Kruskal-Wallis chi-squared = 310.49, df = 2, p-value < 2.2e-16
El valor p obtenido es menor que 0.05, lo que nos lleva a rechazar la hipótesis nula. Esto indica que existen diferencias significativas entre las medianas de los géneros de películas (acción, comedia y aventura) en cuanto a sus ganancias internacionales. En consecuencia, podemos concluir que las ganancias internacionales varían de manera significativa según el género de la película.
# Realizar la prueba de Dunn
dunn_result <- dunn.test(Data_Filtrada$Ganancias, Data_Filtrada$Genero,
kw = TRUE, label = TRUE, list = TRUE)
## Kruskal-Wallis rank sum test
##
## data: x and group
## Kruskal-Wallis chi-squared = 310.4948, df = 2, p-value = 0
##
##
## Comparison of x by group
## (No adjustment)
## Col Mean-|
## Row Mean | Action Adventur
## ---------+----------------------
## Adventur | -3.592213
## | 0.0002*
## |
## Comedy | 13.12019 15.93132
## | 0.0000* 0.0000*
##
##
## List of pairwise comparisons: Z statistic (p-value)
## ----------------------------------------
## Action - Adventure : -3.592213 (0.0002)*
## Action - Comedy : 13.12019 (0.0000)*
## Adventure - Comedy : 15.93132 (0.0000)*
##
## alpha = 0.05
## Reject Ho if p <= alpha/2
# Mostrar el resultado de la prueba
dunn_result
## $chi2
## [1] 310.4948
##
## $Z
## [1] -3.592214 13.120198 15.931321
##
## $P
## [1] 1.639405e-04 1.261376e-39 1.920784e-57
##
## $P.adjusted
## [1] 1.639405e-04 1.261376e-39 1.920784e-57
##
## $comparisons
## [1] "Action - Adventure" "Action - Comedy" "Adventure - Comedy"
Como vemos, la p adquiere un valor menor a 0.05 para todos los géneros. Lo que nos lleva a la conclusión de que todos son diferentes entre sí.
De acuerdo a todo lo anterior, podemos destacar las siguientes conclusiones:
Media y Mediana:
Aunque en algunos casos calcular solo la media y la mediana no es
suficiente para determinar si existe una diferencia significativa entre
los grupos, en este análisis vimos que ambos indicadores nos señalaron
la presencia de diferencias significativas entre los tres géneros de
películas seleccionados.
Prueba de Kruskal:
La prueba de Kruskal nos permitió verificar que la distribución es
diferente en todos los géneros comparados, indicando que existe una
diferencia significativa en las ganancias internacionales entre los
géneros de películas de acción, comedia y aventura.
Rendimiento de los Géneros:
Es interesante observar que, aunque el género de comedia tuvo más
películas que el género de acción, la prueba de Kruskal mostró que
existía una diferencia significativa entre ambos. Esto nos lleva a
inferir que, a pesar de que las películas de acción eran menos en
número, su rendimiento fue superior, lo que sugiere que estaban mejor
valoradas (Rating) y, por lo tanto, generaban más dinero. Además, se
podría decir que la diferencia no fue producto del azar, lo que nos
permite concluir que el género puede llegar a tener un impacto en las
ganancias internacionales de las películas.
A continuación se desea hacer una comparativa del volumen de producción de peliculas por país divido en 3 intervalos. De 2000 a 2009, de 2010 a 2019 y 2020 en adelante. El objetivo es analizar cambios en los niveles de producción en distintos paises y analizar un posible crecimiento o decrecimento en los mismos.
df_paises$Production_Countries <- trimws(df_paises$Production_Countries)
df_paises_con_year <- datos %>%
filter(!is.na(Production_Countries)) %>%
mutate(Production_Countries = trimws(Production_Countries)) %>%
separate_rows(Production_Countries, sep = ", ") %>%
group_by(Production_Countries, Year) %>%
summarise(Numero_Peliculas = n()) %>%
ungroup()
## `summarise()` has grouped output by 'Production_Countries'. You can override
## using the `.groups` argument.
produccion_pais <- df_paises_con_year %>%
filter(Year >= 2000 & Year <= 2009) %>%
group_by(Production_Countries) %>%
summarise(Total_Peliculas = sum(Numero_Peliculas))
mapa <- joinCountryData2Map(produccion_pais, joinCode = "NAME", nameJoinColumn = "Production_Countries")
## 56 codes from your data successfully matched countries in the map
## 2 codes from your data failed to match with a country code in the map
## 187 codes from the map weren't represented in your data
mapCountryData(mapa, nameColumnToPlot = "Total_Peliculas",
catMethod = "fixedWidth", mapTitle = "Volumen de Películas por País",
colourPalette = "terrain")
produccion_pais <- df_paises_con_year %>%
filter(Year >= 2000 & Year <= 2009 & Production_Countries != 'United States of America') %>%
group_by(Production_Countries) %>%
summarise(Total_Peliculas = sum(Numero_Peliculas))
mapa <- joinCountryData2Map(produccion_pais, joinCode = "NAME", nameJoinColumn = "Production_Countries")
## 55 codes from your data successfully matched countries in the map
## 2 codes from your data failed to match with a country code in the map
## 188 codes from the map weren't represented in your data
mapCountryData(mapa, nameColumnToPlot = "Total_Peliculas",
catMethod = "fixedWidth", mapTitle = "Volumen de Películas por País",
colourPalette = "terrain")
Si analizamos detenidamente los gráficos anteriores podemos notar que el volumen de producción de Estados Unidos destaca enormemente generando una disminución en la visibilidad de los demás países. Dado a que el objetivo es tener una visión equilibrada entre los todos países, se decidió excluir a Estados Unidos de las demás comparativas para poder destacar a los demás lugares que han tenido una participación proporcionalmente menor en la industria cinematográfica mundial.
produccion_pais <- df_paises_con_year %>%
filter(Year >= 2010 & Year <= 2019 & Production_Countries != 'United States of America') %>%
group_by(Production_Countries) %>%
summarise(Total_Peliculas = sum(Numero_Peliculas))
mapa <- joinCountryData2Map(produccion_pais, joinCode = "NAME", nameJoinColumn = "Production_Countries")
## 55 codes from your data successfully matched countries in the map
## 2 codes from your data failed to match with a country code in the map
## 188 codes from the map weren't represented in your data
mapCountryData(mapa, nameColumnToPlot = "Total_Peliculas",
catMethod = "fixedWidth", mapTitle = "Volumen de Películas por País",
colourPalette = "terrain")
produccion_pais <- df_paises_con_year %>%
filter(Year >= 2020 & Production_Countries != 'United States of America') %>%
group_by(Production_Countries) %>%
summarise(Total_Peliculas = sum(Numero_Peliculas))
mapa <- joinCountryData2Map(produccion_pais, joinCode = "NAME", nameJoinColumn = "Production_Countries")
## 55 codes from your data successfully matched countries in the map
## 1 codes from your data failed to match with a country code in the map
## 188 codes from the map weren't represented in your data
mapCountryData(mapa, nameColumnToPlot = "Total_Peliculas",
catMethod = "fixedWidth", mapTitle = "Volumen de Películas por País",
colourPalette = "terrain")
Los gráficos anteriores permiten hacer un análisis interesante sobre el crecimiento de la producción de películas en el continente asiático. Se ve a inicios de los 2000 que los paises con mayor presencia en este continente eran Japón y Corea del Sur. En esa época se destacaba más Europa como centro de la producción de entretenimiento, sin embargo en la década de 2010 a 2019 vemos un crecimiento notable en países como India y China. A inicios de la década 2020 - presente se ve una concentración en Japón como el país con mayor volumen de películas en la industria.
df_paises_con_year <- datos %>%
filter(!is.na(Production_Countries), !is.na(`X.Worldwide`)) %>%
mutate(Production_Countries = trimws(Production_Countries)) %>%
separate_rows(Production_Countries, sep = ", ") %>%
group_by(Production_Countries, Year) %>%
summarise(Ingreso_Medio = mean(`X.Worldwide`, na.rm = TRUE)) %>%
ungroup()
## `summarise()` has grouped output by 'Production_Countries'. You can override
## using the `.groups` argument.
ingresos_pais <- df_paises_con_year %>%
filter(Year >= 2000 & Year <= 2009) %>%
group_by(Production_Countries) %>%
summarise(Ingreso_Medio = mean(Ingreso_Medio, na.rm = TRUE))
ingresos_pais$Production_Countries <- trimws(ingresos_pais$Production_Countries)
mapa <- joinCountryData2Map(ingresos_pais,
joinCode = "NAME",
nameJoinColumn = "Production_Countries")
## 56 codes from your data successfully matched countries in the map
## 2 codes from your data failed to match with a country code in the map
## 187 codes from the map weren't represented in your data
mapCountryData(mapa,
nameColumnToPlot = "Ingreso_Medio",
catMethod = "log",
mapTitle = "Ingreso Medio por País de Producción (2000-2009)",
colourPalette = "heat")
## Warning in rwmGetClassBreaks(dataCategorised, catMethod = catMethod, numCats = numCats, : classification method should be set to one of :fixedWidth diverging quantiles pretty logFixedWidth categorical
## setting to fixedWidth as default
df_paises_con_title <- datos %>%
filter(!is.na(Production_Countries)) %>%
mutate(Production_Countries = trimws(Production_Countries)) %>%
separate_rows(Production_Countries, sep = ", ") %>%
filter(Production_Countries == "New Zealand") %>%
group_by(Production_Countries, `Release.Group`) %>%
summarise(Titles = (`Release.Group`), .groups = 'drop')
df_paises_con_title %>%
select(Production_Countries, `Release.Group`) %>%
kable("html", caption = "Películas de Nueva Zelanda por Grupo de Lanzamiento") %>%
kable_styling(
full_width = FALSE,
position = "center",
font_size = 12,
) %>%
row_spec(0, bold = TRUE) %>% # Aplica negrita en la fila de encabezados
column_spec(1, bold = TRUE, background = "#f7f7f7") %>%
column_spec(2, background = "#e9f5f5") %>%
scroll_box(width = "100%", height = "100%")
Production_Countries | Release.Group |
---|---|
New Zealand | 10,000 BC |
New Zealand | 30 Days of Night |
New Zealand | Boy |
New Zealand | District 9 |
New Zealand | Evil Dead Rise |
New Zealand | Jojo Rabbit |
New Zealand | King Kong |
New Zealand | Mortal Engines |
New Zealand | Next Goal Wins |
New Zealand | The Adventures of Tintin |
New Zealand | The Hobbit: An Unexpected Journey |
New Zealand | The Hobbit: The Battle of the Five Armies |
New Zealand | The Hobbit: The Desolation of Smaug |
New Zealand | The Last Samurai |
New Zealand | The Lord of the Rings: The Fellowship of the Ring |
New Zealand | The Lord of the Rings: The Return of the King |
New Zealand | The Lord of the Rings: The Two Towers |
New Zealand | The Lord of the Rings: The War of the Rohirrim |
New Zealand | The Lovely Bones |
New Zealand | The World’s Fastest Indian |
New Zealand | Whale Rider |
New Zealand | Yogi Bear |
Aquí ocurre algo interesante, New Zealand no es el país que más destaca a nivel mundial por su participación en la industria. Sin embargo, ha sido hogar de importantes y reconocidas sagas como el Señor de los anillos y el Hobbit. La combinación de un numero pequeño de peliculas pero de gran éxito mundial hace que se pueda mantener un promedio alto de ingresos para la industria.
ingresos_pais <- df_paises_con_year %>%
filter(Year >= 2010 & Year <= 2019) %>%
group_by(Production_Countries) %>%
summarise(Ingreso_Medio = mean(Ingreso_Medio, na.rm = TRUE))
# Ahora el mapa
mapa <- joinCountryData2Map(ingresos_pais,
joinCode = "NAME",
nameJoinColumn = "Production_Countries")
## 56 codes from your data successfully matched countries in the map
## 2 codes from your data failed to match with a country code in the map
## 187 codes from the map weren't represented in your data
mapCountryData(mapa,
nameColumnToPlot = "Ingreso_Medio",
catMethod = "log",
mapTitle = "Ingreso medio por País de Producción",
colourPalette = "heat")
## Warning in rwmGetClassBreaks(dataCategorised, catMethod = catMethod, numCats = numCats, : classification method should be set to one of :fixedWidth diverging quantiles pretty logFixedWidth categorical
## setting to fixedWidth as default
ingresos_pais <- df_paises_con_year %>%
filter(Year >= 2020) %>%
group_by(Production_Countries) %>%
summarise(Ingreso_Medio = mean(Ingreso_Medio, na.rm = TRUE))
# Ahora el mapa
mapa <- joinCountryData2Map(ingresos_pais,
joinCode = "NAME",
nameJoinColumn = "Production_Countries")
## 56 codes from your data successfully matched countries in the map
## 1 codes from your data failed to match with a country code in the map
## 187 codes from the map weren't represented in your data
mapCountryData(mapa,
nameColumnToPlot = "Ingreso_Medio",
catMethod = "log",
mapTitle = "Ingreso medio por País de Producción",
colourPalette = "heat")
## Warning in rwmGetClassBreaks(dataCategorised, catMethod = catMethod, numCats = numCats, : classification method should be set to one of :fixedWidth diverging quantiles pretty logFixedWidth categorical
## setting to fixedWidth as default
En esta comparativa ocurre algo interesante. Si bien se nota en la gráfica anterior, Japón es el país líder en la producción de películas (excluyendo a USA), sin embargo, no es el país con el ingreso medio más alto en sus producciones. Si se analiza detenidamente, se puede notar que en la primera década México, Rusia, India, Corea del Sur y varios países de Europa lideran en esta comparativa, sin embargo con el paso de los años, el ingreso medio más alto se concentra en China, que tambien se destaca como uno de los paises con mayor producción a nivel mundial de películas.
# Filtrar los datos por los idiomas seleccionados
datos_filtrados_idiomas <- datos %>%
filter(Original_Language %in% c("en", "ja", "zh", "fr", "ko"))
# Gráfico de comparación de ingresos internacionales por idioma
ggplot(datos_filtrados_idiomas,
aes(x = Year, color = Original_Language, group = Original_Language)) +
geom_point(stat = "count", size = 3) + # Puntos
geom_line(stat = "count", size = 1) + # Líneas
labs(title = "Evolución de la Producción de Películas por Idioma",
x = "Año", y = "Cantidad de Películas") +
theme_minimal() +
scale_color_manual(values = c("en" = "blue", "ja" = "red", "zh" = "green", "fr" = "purple", "ko" = "orange"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
El resultado obtenido luego de comparar el volumen de producción a lo largo de la historia no sorprende. De forma indiscutible, el inglés domina en la escena mundial. Lo anterior tiene sentido teniendo en cuenta que es el país que más produce peliculas en el mundo. Luego, representando a Asia y Europa, siguen el japonés, mandarín, frances y coreano, con números bastante similares.
A lo largo del análisis exploratorio de datos (EDA), se examinaron diversas características de las películas con el objetivo de identificar patrones en su distribución según género, idioma original y país de producción. Se observan tendencias claras en la industria cinematográfica a lo largo de los años 2000 a 2024:
Factores que influyen en el éxito financiero de las
películas
País de origen y volumen de producción:
- Estados Unidos domina ampliamente la producción de películas a nivel
mundial, lo que explica su presencia constante en las películas con
mayor recaudación. Al excluir a EE.UU., se observa una distribución más
equilibrada, con Japón, China e India emergiendo como centros de
producción clave en sus respectivas regiones. Un caso interesante es
Nueva Zelanda, que, a pesar de producir pocas películas, ha sido el
hogar de grandes éxitos como El Señor de los Anillos y El Hobbit, lo que
demuestra que la cantidad de películas producidas no siempre se
correlaciona directamente con el éxito financiero.
Recaudación y rentabilidad por país:
- Si bien Japón lidera la producción de películas en Asia, no es el país
con el mayor ingreso medio por película. Durante la primera década de
los 2000, países como México, Rusia, India y Corea del Sur mostraron
altos ingresos promedio en sus producciones. A partir de la década de
2010, China ha aumentado su presencia tanto en términos de volumen de
producción como en recaudación promedio, consolidándose como un actor
clave en la industria.
Influencia del idioma en la recaudación:
- No sorprende que el inglés sea el idioma dominante en la industria
cinematográfica, dado el volumen de producción de Hollywood y su
influencia global. Sin embargo, otros idiomas como el japonés, mandarín,
francés y coreano han mantenido una presencia estable en la industria,
reflejando la importancia de los mercados regionales y la expansión del
cine asiático y europeo.
Se ha identificado un cambio significativo en la producción y recaudación de películas a lo largo de los años. Mientras que en los primeros años del siglo XXI la industria cinematográfica estaba dominada por Estados Unidos y Europa, a partir de la década de 2010 se observa un crecimiento notable de Asia, con China y Japón tomando un papel protagonista. La industria cinematográfica ha pasado de estar centralizada en Hollywood a una distribución más diversificada, donde el cine asiático y de otros países ha logrado captar una mayor audiencia global.
El análisis confirma que la industria cinematográfica tiene una distribución desigual, con una fuerte concentración de películas en ciertos géneros, idiomas y países. Esto tiene implicaciones importantes para la diversidad del contenido disponible, el acceso de producciones de otros países a mercados internacionales y el impacto cultural de las películas en la audiencia global. Dado que el objetivo era explorar las principales características de las películas en términos de producción y distribución, podemos concluir que existe un claro predominio del cine angloparlante, con el género Drama como el más recurrente. Estos hallazgos pueden ser útiles para comprender tendencias de la industria y para futuras investigaciones sobre el impacto de estos factores en la taquilla y el consumo del público.