library(tidyverse)
library(gridExtra)
<- unlist(strsplit("la noche en la que suplico que no
frase salga el sol", " "))
# Crear el data frame
<- data.frame(
datos palabra = frase,
tiempo = seq(0, length(frase) - 1),
pitch = runif(length(frase), min=80, max=90),
intensidad = runif(length(frase), min=70, max=85)
%>%filter(palabra!="")%>%mutate(tiempo=row_number())
)
# Create the plot with labels
<- ggplot(datos) +
plot geom_point(aes(x = tiempo, y = pitch, color = "Pitch")) +
geom_smooth(aes(x = tiempo, y = pitch, color = "Pitch")) +
geom_text(aes(x = tiempo, y = pitch, label = palabra), vjust = -1,
hjust = 0.5, size = 3.5, check_overlap = TRUE) +
geom_point(aes(x = tiempo, y = intensidad, color = "Intensidad")) +
geom_smooth(aes(x = tiempo, y = intensidad, color = "Intensidad")) +
labs(color = "Variable") + # Add text labels above points
theme_minimal()
plot
Estadística aplicada con R: visualización y validación de datos poblacionales pragmáticos y fonéticos
![]() |
![]() |
Material de carácter gratuito diseñado para el uso de investigadores en lingüística, sobre todo a quienes se inician en la investigación con datos.
Email: adrian.cabedo@uv.es
Copyright y derechos:
Estadística aplicada con R: Visualización y validación de datos poblacionales pragmáticos y fonéticos by Adrián Cabedo Nebot is licensed under CC BY 4.0
1 Sobre estos materiales
Este libro de materiales, con finalidad didáctica, ofrece un primer acercamiento al análisis y explotación de bases de datos lingüísticas con R; con ello se pretende ofrecer un modo dee superar las limitaciones de herramientas convencionales como Excel y Google Sheets. Los lectores adquirirán una mejor comprensión de R, un lenguaje de programación dirigido al análisis de datos. Además, explorarán técnicas estadísticas avanzadas para visualizar y analizar datos lingüísticos y poblacionales.
Los contenidos incluyen:
Introducción a R: fundamentos del lenguaje y su entorno de programación.
Visualización de datos con GGplot2: creación de visualizaciones descriptivas atracticas.
Análisis categórico: aplicación de Mosaicplot y pruebas de chi cuadrado para investigar relaciones categóricas entre variables nominales.
Análisis multidimensional: identificación de patrones en datos mediante análisis de correspondencias múltiple.
Árboles de decisión: utilización para tomar decisiones basadas en datos y explorar relaciones no lineales.
Mapas de calor: visualización de correlaciones y tendencias en datos numéricos.
Los materiales ofrecen de un modo didáctico y resumido aspectos abordados en esta referencia bibliográfica (sobre todo, los referentes a la sección de estadística inferencial).
- Cabedo Nebot, A. (2021). Fundamentos de estadística con R para lingüistas. Tirant Lo Blanch.
Todo lo relacionado con la presentación de la visualización descriptiva, las tareas de limpieza o filtrado y los ejercicios de estos materiales son documentación nueva.
1.1 Objetivos específicos
A partir de los contenidos anteriores, por tanto, pueden desarrollase los siguientes objetivos:
Adquirir habilidades avanzadas en el manejo de bases de datos lingüísticas más allá de las hojas de cálculo tradicionales como Excel o Google Sheets.
Familiarizarse con el programa R, aprendiendo los conceptos básicos de programación y análisis de datos en este entorno.
Desarrollar la capacidad de representar datos de manera efectiva utilizando técnicas de visualización avanzadas, incluyendo barras, lolipops, diagramas de caja y líneas temporales utilizando GGplot2 en R.
Adquirir estrategias de análisis de datos, como el uso de diversas técnicas estadísticas y de visualización; por ejemplo, Mosaicplot y pruebas de chi cuadrado para explorar relaciones entre variables categóricas, análisis de correspondencias múltiples y análisis de componentes para identificar patrones en datos multidimensionales, la construcción de árboles de decisiones para tomar decisiones basadas en datos y la exploración de relaciones no lineales, así como la generación de mapas de calor para visualizar patrones de correlación y tendencias en datos numéricos.
1.2 Conocimientos previos
Se recomienda a las personas interesadas en seguir estos materiales que tengan un conocimiento básico de programas de hojas de datos como, por ejemplo, Excel o, al menos, que conozcan su estructura general. También es recomendable que hayan realizado investigaciones previas con datos y que conozcan los fundamentos de la estadística y del método científico.
Generalmente, el investigador que se inicia en el análisis de datos lingüísticos no tiene una formación previa en estadística. Por ello, este material se ha diseñado para ser accesible a personas sin experiencia previa en el uso de R, pero que deseen adquirir habilidades avanzadas en el análisis de datos mediante lenguaje de programación. Aun así, es recomendable conocer la estructura de filas, columnas y celdas de una hoja de cálculo.
1.3 Formación previa en estadística general y el método científico
1.4 Requisitos técnicos
Para seguir estos materiales es necesario que el usuario instale R (https://cran.rediris.es/) y RStudio (https://posit.co/download/rstudio-desktop) en su ordenador. Ambos son programas gratuitos y pueden instalarse en Linux, Windows y Mac.
También existe la posibilidad de acceder a una versión gratuita online de RStudio en https://posit.cloud/.
1.5 Sobre los datos utilizados de ejemplo
En este documentoo, emplearemos datos lingüísticos, específicamente datos pragmáticos y fonéticos, como ejemplos prácticos para aprender a usar R y desarrollar habilidades avanzadas en estadística. No obstante, es crucial entender que el objetivo principal de este libro va más allá de los datos lingüísticos. Las técnicas y pruebas que se enseñarán aquí son universales y aplicables a una variedad de datos en distintos campos y disciplinas. Nuestro propósito es formar investigadores de datos competentes y versátiles, capaces de abordar y resolver problemas utilizando R y métodos estadísticos, sin importar el tipo de datos con el que trabajen en el futuro.
1.6 Bibliografía recomendada
Este mismo documento.
Cabedo Nebot, A. (2021). Fundamentos de estadística con R para lingüistas. Tirant Lo Blanch.
Gries, S. Th. (2021). Statistics for Linguistics with R: A Practical Introduction. De Gruyter. https://doi.org/10.1515/9783110718256
Levshina, N. (2015). How to do Linguistics with R: Data exploration and statistical analysis. John Benjamins Publishing Company.
Moore, D. S., & McCabe, G. P. (1999). Introduction to the practice of statistics. W.H. Freeman.
Navarro, D. (2015). Learning statistics with R: A tutorial for psychology students and other beginners. (. University of Adelaide. https://learningstatisticswithr.com/
1.7 ¿Dónde voy cuando me atasco y no consigo generar algún gráfico, calcular algún método estadístico…?
Cuando te atascas, lo mejor es buscar ayuda en la comunidad de R. Hay muchos foros y sitios web donde puedes encontrar respuestas a tus preguntas. Algunos de los lugares más populares para obtener ayuda con R son:
2 Y hubo un principio…
Todo en la vida tiene un principio. También la investigación en datos; hay un momento concreto en el que simplemente se necesita la cuantificación de los datos para poder analizarlos. No obstante, en investigación filológica o lingüística se tiene muchas veces una consideración negativa hacia la estadística, aunque es un mal positivamente necesario. La estadística es una herramienta que nos permite cuantificar y analizar datos de manera objetiva y rigurosa. Sin ella, no podríamos hacer inferencias válidas sobre nuestras muestras de datos ni sacar conclusiones significativas de ellos.
Si es necesario aplicar estadística en nuestra investigación, es importante hacerlo de manera correcta y rigurosa. Esto implica entender los conceptos básicos de la estadística, saber cómo aplicar los métodos estadísticos adecuados a nuestros datos y ser capaz de interpretar los resultados de manera adecuada.
2.1 ¿Qué hago en mi investigación?
Muchos jóvenes lingüistas (y no tan jóvenes) se plantean qué estudiar, qué investigar, qué hacer con sus datos. Sobre todo, esto suele suceder al terminar el grado y comenzar estudios de máster o de doctorado. Por tanto, lo importante aquí, más incluso que el estudio estadístico, es saber qué investigar y de qué manera. La elección de un tema o disciplina será, normalmente, la que nos determinará el futuro profesional. Por tanto, es importante elegir bien.
Images created by an AI from OpenAI
2.2 ¿Por qué analizar datos?
El análisis de datos es muy habitual en la actualidad. Grandes compañías como Google, Facebook, Amazon o Netflix utilizan el análisis de datos para tomar decisiones estratégicas y mejorar sus productos y servicios. En el ámbito académico, el análisis de datos es esencial para la investigación científica y la toma de decisiones basada en evidencias. En la vida cotidiana, el análisis de datos nos ayuda a entender mejor el mundo que nos rodea y a tomar decisiones informadas sobre nuestra salud, finanzas, educación y otros aspectos de nuestra vida.
Image created by an AI from OpenAI
2.3 ¿Cómo siente un lingüista la estadística?
Las tres imágenes de más abajo, generadas con inteligencia artificial, reflejan el terror que muchos estudiantes de lingüística sienten al enfrentarse a la estadística. Sin embargo, la estadística es una herramienta poderosa que puede ayudarnos a entender mejor los datos y a tomar decisiones informadas en nuestra investigación. Con la formación adecuada y la práctica, la estadística puede ser una aliada valiosa en nuestro trabajo como lingüistas.
Los investigadores jóvenes sienten una cierta traición hacia sí mismos cuando se enfrentan a la estadística. Se trata de una disciplina que, en principio, no tiene nada que ver con la lingüística, pero que puede ser necesaria en algún momento de la carrera investigadora.
![]() |
![]() |
![]() |
Images created by an AI from OpenAI
3 Sobre R
R es un lenguaje de programación y un entorno de desarrollo para análisis estadístico y visualización de datos. Es un software libre y de código abierto que se utiliza ampliamente en la investigación científica, la academia y la industria para realizar análisis de datos, modelado estadístico, visualización de datos y generación de informes. Las posibilidades de uso son muy amplias:
4 Sobre R (II)
Vale, pero, ¿qué hace realmente R? Ponme un ejemplo. De acuerdo, veamos una imagen como la siguiente:
Figura extraída con GGplot2. Curva melódica y de intensidad del enunciado la noche en la que no salga el sol
En la Figura anterior, se visualiza la curva melódica y de intensidad del enunciado la noche en la que no salga el sol, un enunciado extraído de una canción de Enrique Iglesias. En el eje x (sí, el horizontal) se representa el tiempo, en el eje y (sí, el vertical) se representa la frecuencia fundamental (pitch) y la intensidad. Cada punto representa una palabra del enunciado y la curva suavizada muestra la tendencia general de la curva.
Esta es una de las muchas posibilidades que ofrece R para visualizar datos. En este caso, se ha utilizado el paquete ggplot2, uno de los más populares y versátiles para la visualización de datos en R. Como se verá más abajo, las posibilidades de visualización en R son casi infinitas y permiten crear gráficos detallados y personalizados para explorar y presentar datos de la manera más adecuada para nuestros intereses de investigación.
5 ¿Qué más puedo hacer con R?
R no solo sirve para crear gráficos o realizar pruebas estadísticas, sino que también puede ser utilizado para realizar análisis de texto, crear documentos científicos, programar scripts que realicen funciones de manera automática, crear aplicaciones web para consultar datos, entre otras muchas funcionalidades. Por ejemplo, hace casi 6 años que no utilizo Microsoft Word, ya que R me permite crear documentos científicos de manera más eficiente, personalizada y puedo integrar directamente los gráficos y los análisis estadísticos sin tener que copiar y pegarlos cada vez. De hecho, este propio libro de materiales está escrito en R, concretamente con el paquete Quarto.
A continuación, se presentan algunas de las posibilidades que ofrece R:
Escribir documentos científicos mediante Rmarkdown o Quarto (este mismo documento ha sido escrito en R).
Exportar tus documentos a varios formatos: PDF, Word o Powerpoint.
Modificación de las plantillas. Ejemplo: los artículos de la revista Normas de la UV se generan a partir de una plantilla de Quarto.
Programar scripts que realicen funciones de manera automática. Por ejemplo, abre todos los archivos de una carpeta e impórtalos.
Crear aplicaciones web para consultar datos e incluso corpus lingüísticos. Ej.:
6 ¿Por qué RStudio?
RStudio es un programa que sirve de “caparazón” para R. Permite que muchas tareas sean más sencillas y rápidas. También es multiplataforma.
RStudio es un entorno de desarrollo integrado (IDE) para R.
RStudio simplifica la programación en R y mejora la productividad del usuario.
RStudio es gratuito y de código abierto.
RStudio es multiplataforma (Windows, Mac y Linux).
7 Bases de datos lingüísticas de ejemplo
En este libro se usarán dos bases de datos lingüísticas para ejemplificar los análisis estadísticos y la visualización de datos con R. Las bases de datos son las siguientes:
- Base de datos Idiolectal. Se trata de la base de datos utilizada para realizar el siguiente artículo:
Cabedo Nebot, A. Análisis melódico del habla como herramienta distintiva para el perfil idiolectal de hablantes. Revista da ABRALIN, [S. l.], v. 21, n. 2, p. 48–70, 2022. DOI: https://doi.org/10.25189/rabralin.v21i2.2103.
Recoge datos de tonemas de los mismos cinco hablantes en dos géneros discursivos distintos (podcast y entrevista).
Base de datos Fonocortesía. Se trata de la base de datos recogida para el proyecto Fonocortesía, dirigida por el catedrático Antonio Hidalgo Navarro en el marco del proyecto de investigación Fonocortesía, subvencionado por Ministerio de Ciencia, Innovación y Universidades (FFI2009-07034). Con esta base de datos se han realizado diferentes investigaciones de las que destacamos la siguiente:
Cabedo Nebot A. y Hidalgo Navarro A. (2023). Caracterización fónica de la (des)cortesía en el español hablado de Valencia. Aproximación cualitativo-cuantitativa. Círculo de Lingüística Aplicada a la Comunicación, 93, 131-149. https://doi.org/10.5209/clac.82314
8 Uso de Excel o Google Sheets
Por experiencia, muchos investigadores en lingüística utilizan Excel o Google Sheets para almacenar y analizar datos. Sin embargo, estos programas tienen limitaciones en cuanto a la cantidad de datos que pueden manejar y las operaciones estadísticas que pueden realizar. Además, no son tan flexibles ni potentes como R para el análisis de datos.
De todos modos, es cierto que algunas investigaciones solo requieren un análisis básico de los datos, por lo que Excel o Google Sheets pueden ser suficientes. Si solo queremos extraer un gráficos sencillo de barras, por ejemplo, o calcular la media de una variable, Excel o Google Sheets pueden ser una buena opción. Sin embargo, si queremos realizar análisis estadísticos más avanzados, como regresiones, análisis de varianza o análisis de componentes principales, R es mejor opción.
Formato tabular. Filas y columnas.
Organización de datos.
Pocos datos
Tablas dinámicas para estadística básica.
Limitaciones: no permite realizar análisis estadísticos avanzados.
8.1 Métodos de exploración avanzada en Excel o Google Sheets
A medio camino entre la hoja de cálculo clásica y R, estaría la opción de “tabla dinámica” que podemos encontrar en Excel o Google Sheets.
Tablas dinámicas: “Una tabla dinámica es una herramienta avanzada para calcular, resumir y analizar datos que le permite ver comparaciones, patrones y tendencias en ellos. Las tablas dinámicas funcionan de forma un poco distinta dependiendo de la plataforma que use para ejecutar Excel.” (extraído de: https://support.microsoft.com/es-es/office/crear-una-tabla-din%C3%A1mica-para-analizar-datos-de-una-hoja-de-c%C3%A1lculo-a9a84538-bfe9-40a9-a8e9-f99134456576)
8.2 Ejercicio
Explora la base de datos Idiolectal y la base de datos Fonocortesía en Excel o Google Sheets.
9 Definir la construcción de la base de datos (estructura)
La construcción de la base de datos es un paso fundamental en cualquier investigación. La base de datos debe estar bien estructurada y organizada para que los análisis posteriores sean precisos y fiables. En el caso de las bases de datos lingüísticas, es importante tener en cuenta las variables que se van a analizar y cómo se van a medir. Por ejemplo, si estamos analizando la cortesía en el habla, es importante definir qué variables vamos a utilizar para medir la cortesía (por ejemplo, la frecuencia fundamental, la intensidad, la duración, etc.) y cómo vamos a codificarlas (por ejemplo, si vamos a utilizar escalas numéricas, categóricas, etc.).
flowchart LR A[Investigación] --> B(Base de datos) B --> C{Variables} C --> D[elemento de análisis] C --> E[F0 media] C --> F[Intensidad media] C --> G[Cortesía] C --> H[...]
Figura. Proceso de construcción de la base de datos.
Cuando la base de datos tiene una estructura definida, es más fácil realizar análisis estadísticos y visualizaciones de datos. He sido testigo de muchas investigaciones en las que se ha tenido que volver a recoger los datos porque no estaban bien estructurados o porque no se habían definido las variables de manera adecuada. Por tanto, es importante dedicar tiempo y esfuerzo a la construcción de la base de datos para asegurarse de que los datos sean fiables y válidos.
10 Uso general de R
En esta sección se presentan algunas de las funcionalidades básicas de R que se utilizarán en los ejemplos prácticos de este libro. Estas funcionalidades incluyen la instalación de librerías, la carga de datos, la visualización de datos y la manipulación de datos. A continuación, se presentan los pasos básicos para comenzar a trabajar con R.
10.1 Instalar librerías
En R, una librería es un conjunto de funciones y datos que se utilizan para realizar tareas específicas. Existen muchas librerías en R que se pueden utilizar para realizar análisis estadísticos, visualizaciones de datos, manipulación de datos, etc. El proceso de instalar librerías en R es muy sencillo. Solo tienes que ejecutar el siguiente comando:
install.packages("tidyverse")
install.packages("FactoMineR")
install.packages("factoextra")
install.packages("partykit")
install.packages("randomForest")
install.packages("DataExplorer")
install.packages("heatmap.2")
install.packages("corrplot")
install.packages("ggwordcloud")
10.2 Cargar librerías
Cada vez que reinicies R, tendrás que cargar las librerías que necesitas para trabajar. Para cargar una librería en R, simplemente tienes que ejecutar el siguiente comando:
library(tidyverse)
library(corrplot)
library(FactoMineR)
library(factoextra)
library(partykit)
library(randomForest)
library(gplots)
library(ggwordcloud)
10.3 Importar datos
Para importar datos en R, puedes utilizar la función read_csv()
del paquete readr
. Esta función te permite importar datos en formato CSV, que es un formato de archivo de texto que se utiliza para almacenar datos tabulares. También puedes importar datos en otros formatos, como Excel, utilizando las funciones correspondientes del paquete readxl
. Incluso en R Studio puedes importar datos directamente desde Excel o Google Sheets, con la opción File > Import Dataset > From Excel.
library(readxl)
<- read_xlsx("databases/corpus.xlsx") fonocortesia
10.4 Conoce la estructura de tus datos: str o summary
Conocer la estructura de la base de datos es importante, sobre todo, para cerciorarnos de que los datos se han importado correctamente y para saber de qué tipo son. Algunas importaciones podrían no ser correctas y, por tanto, es importante conocer la estructura de los datos. Por ejemplo, aunque no es muy frecuente, podría darse el error de que una variable numérica se importara como variable de carácter o viceversa. Para ello, podemos utilizar las funciones str()
y summary()
.
Ejemplo de str para las primeras cinco columnas:
str(fonocortesia[,c(1:5)])
tibble [282 × 5] (S3: tbl_df/tbl/data.frame)
$ Conversacion : chr [1:282] "VALESCO 114A" "VALESCO 130A" "VALESCO 194A" "VALESCO 114A" ...
$ Cortes_Descortes: chr [1:282] "descortés" "descortés" "descortés" "descortés" ...
$ Llama_Atencion : chr [1:282] "acento;entonación;velocidad de habla" "acento;duración;entonación" "acento;duración;velocidad de habla" "acento;entonación;velocidad de habla" ...
$ Mediodeexpresion: chr [1:282] "Fórmulas indirectas" "Atenuación" "Intensificación" "Intensificación" ...
$ F0_Inicial : num [1:282] 227 213 242 148 249 ...
Ejemplo de summary para las primeras cinco columnas:
summary(fonocortesia[,c(1:5)])
Conversacion Cortes_Descortes Llama_Atencion Mediodeexpresion
Length:282 Length:282 Length:282 Length:282
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
F0_Inicial
Min. : 0.0
1st Qu.:161.8
Median :219.7
Mean :212.7
3rd Qu.:252.2
Max. :490.0
NA's :42
10.5 Citar en R
En R, puedes citar paquetes y funciones utilizando la función citation()
. Por ejemplo, para citar el paquete tidyverse
, puedes ejecutar el siguiente comando:
citation()
To cite R in publications use:
R Core Team (2024). _R: A Language and Environment for Statistical
Computing_. R Foundation for Statistical Computing, Vienna, Austria.
<https://www.R-project.org/>.
A BibTeX entry for LaTeX users is
@Manual{,
title = {R: A Language and Environment for Statistical Computing},
author = {{R Core Team}},
organization = {R Foundation for Statistical Computing},
address = {Vienna, Austria},
year = {2024},
url = {https://www.R-project.org/},
}
We have invested a lot of time and effort in creating R, please cite it
when using it for data analysis. See also 'citation("pkgname")' for
citing R packages.
citation("tidyverse")
To cite package 'tidyverse' in publications use:
Wickham H, Averick M, Bryan J, Chang W, McGowan LD, François R,
Grolemund G, Hayes A, Henry L, Hester J, Kuhn M, Pedersen TL, Miller
E, Bache SM, Müller K, Ooms J, Robinson D, Seidel DP, Spinu V,
Takahashi K, Vaughan D, Wilke C, Woo K, Yutani H (2019). "Welcome to
the tidyverse." _Journal of Open Source Software_, *4*(43), 1686.
doi:10.21105/joss.01686 <https://doi.org/10.21105/joss.01686>.
A BibTeX entry for LaTeX users is
@Article{,
title = {Welcome to the {tidyverse}},
author = {Hadley Wickham and Mara Averick and Jennifer Bryan and Winston Chang and Lucy D'Agostino McGowan and Romain François and Garrett Grolemund and Alex Hayes and Lionel Henry and Jim Hester and Max Kuhn and Thomas Lin Pedersen and Evan Miller and Stephan Milton Bache and Kirill Müller and Jeroen Ooms and David Robinson and Dana Paige Seidel and Vitalie Spinu and Kohske Takahashi and Davis Vaughan and Claus Wilke and Kara Woo and Hiroaki Yutani},
year = {2019},
journal = {Journal of Open Source Software},
volume = {4},
number = {43},
pages = {1686},
doi = {10.21105/joss.01686},
}
10.6 Data frames
Un data frame es una estructura de datos en R que se utiliza para almacenar datos en forma tabular. Es similar a una matriz, pero cada columna puede contener un tipo de datos diferente.
data.frame(
cortesia = c("cortés", "descortés", "cortés"),
f0_media = c(145, 187, 135),
sexo = c("Hombre", "Mujer", "Hombre")
)
cortesia f0_media sexo
1 cortés 145 Hombre
2 descortés 187 Mujer
3 cortés 135 Hombre
Los data frames se pueden visualizar en RStudio en la pestaña “Environment” o escribiendo el nombre del data frame en la consola. Para mejorar la visualización, puedes usar la función View()
.
11 Tareas de limpieza y manipulación de datos
La limpieza y manipulación de datos es una parte esencial del análisis de datos. Los datos pueden contener errores, valores ausenetes o vacíos, valores atípicos y otros problemas que pueden afectar la validez y fiabilidad de los análisis. Por tanto, es importante realizar tareas de limpieza y manipulación de datos para asegurarse de que los datos sean precisos y fiables. Por ejemplo, un error consciente en la base de datos Fonocortesía es que hay un valor “desconocido” en la variable Cortes_Descortes.
Entre las tareas de limpieza y revisión de datos, se pueden incluir las siguientes:
Revisión y corrección de valores ausentes:
Identificar y manejar los valores no disponibles (
NA
en R).Decidir si imputar los valores ausentes con la media, mediana, moda, o algún otro método, o eliminar las filas/columnas con esos valores vacíos.
Detección y manejo de valores atípicos:
Identificar valores atípicos o outliers que pueden distorsionar el análisis. Por ejemplo, un valor de de F0 de un hablante de 600 Hz puede proceder de una distorsión acústica, de influencia ambiental, de una canción, de un golpe que coincide con la persona hablando…
Decidir si eliminar, transformar o tratar de otra manera estos valores.
Estandarización y normalización de datos:
Estandarizar unidades de medida para asegurarse de que sean consistentes. Por cierto, en corpus lingüísticos es habitual trabajar con frecuencias normalizadas por millón de palabras; en fonética, por ejemplo, la melodía se normaliza mediante el uso de semitonos, ya que neutralizan la diferencia tonal biológica entre hombres y mujeres.
Normalizar o estandarizar variables si es necesario para ciertos tipos de análisis.
Conversión de tipos de datos:
- Asegurarse de que los datos estén en los tipos adecuados (por ejemplo, convertir variables categóricas a factores en R).
Revisión de la coherencia de los datos:
Verificar que no haya inconsistencias en los datos (por ejemplo, un valor de edad negativo).
Asegurar que los valores categóricos estén correctamente codificados y no haya variaciones como “Hombre” y “hombre”.
Eliminación de duplicados:
- Identificar y eliminar registros duplicados que puedan afectar el análisis.
Corrección de errores tipográficos y de entrada de datos:
- Revisar y corregir errores tipográficos o de entrada manual en los datos.
Creación de variables derivadas:
- Crear nuevas variables que puedan ser útiles para el análisis, como agregar una variable que represente la diferencia entre dos fechas (edad, duración, etc.).
Filtrado de datos irrelevantes:
Eliminar columnas o filas que no sean relevantes para el análisis específico.
Una conducta habitual en bases de datos lingüísticas es repetir la información en varias columnas. Por ejemplo, en la base de datos Fonocortesía, las variables curva melódica y tonema refieren prácticamente el mismo fenómeno.
11.1 ¿Qué es Tidyverse?
Para las tareas de limpieza o de transformación en R, se puede utilizar el paquete tidyverse
. Este paquete es una colección de paquetes de R diseñados para la ciencia de datos:
Colección de paquetes de R diseñados para la ciencia de datos.
dplyr: manipulación de datos.
ggplot2: visualización de datos.
tidyr: limpieza de datos.
readr: importación de datos.
…
11.2 Ver y filtrar datos
En ocasiones, puede ser útil ver los datos para identificar posibles problemas o errores. Para filtrar los datos, podemos utilizar la función filter()
para seleccionar las filas que cumplan ciertas condiciones.
- Ver los datos (table)
- Filtrar datos (filter)
- El operador
%>%
se utiliza para encadenar funciones en R. Se lee de izquierda a derecha, lo que facilita la lectura del código. - El operador
==
se utiliza para comparar si dos valores son iguales. - EL operador
!=
se utiliza para comparar si dos valores son diferentes. - El operador
<-
se utiliza para crear un nuevo objeto (variable, dataframe…) en R.
En el siguiente bloque de código se utilizan los comandos mencionados anteriormente:
table(fonocortesia$Cortes_Descortes)
cortés desconocido descortés
135 1 146
%>%filter(Cortes_Descortes=="desconocido") fonocortesia
# A tibble: 1 × 36
Conversacion Cortes_Descortes Llama_Atencion Mediodeexpresion F0_Inicial
<chr> <chr> <chr> <chr> <dbl>
1 VALESCO 194A desconocido entonación desconocido 296
# ℹ 31 more variables: F0_Final <dbl>, F0_Media <dbl>, F0_Maxima <dbl>,
# F0_Minima <dbl>, Intensidad_Maxima <dbl>, Intensidad_Minima <dbl>,
# Intensidad_Primera <dbl>, Intensidad_Ultima <dbl>, Intensidad_Media <dbl>,
# Silabas <dbl>, Duracion <dbl>, Duracion_Pausa_Anterior <dbl>,
# Duracion_Pausa_Posterior <dbl>, Continuacion_Pausa <chr>,
# Curva_Melodica <chr>, Otro_Curva_Melodica <chr>,
# Inflexion_Local_Interna <chr>, Tonema <chr>, Unidad_Del_Discurso <chr>, …
table(fonocortesia$Cortes_Descortes)
cortés desconocido descortés
135 1 146
<- fonocortesia%>%filter(Cortes_Descortes!="desconocido") fonocortesia_filt
11.3 Seleccionar columnas: select
Para seleccionar columnas específicas de un data frame en R, se puede utilizar la función select()
del paquete dplyr
. Esta función permite seleccionar las columnas que se desean mantener en el data frame y descartar las que no son necesarias.
Es recomendable almacenar el resultado de la función select()
en un nuevo objeto para no perder los datos originales. Por ejemplo, si hacemos esto:
fonocortesia <- fonocortesia %>%select(F0_Media, Duracion)
Estaremos sobreescribiendo la base de datos original. Si queremos mantener la base de datos original, podemos hacer esto:
fonocortesia_sel <- fonocortesia %>%select(F0_Media, Duracion)
<- fonocortesia%>%select(Cortes_Descortes, F0_Media,
fonocortesia_sel Intensidad_Media)
11.4 Ordenar datos: arrange
Para ordenar los datos en R, se puede utilizar la función arrange()
del paquete dplyr
. Esta función permite ordenar los datos en función de una o varias columnas. Por ejemplo, si queremos ordenar los datos por la columna F0_Media
, podemos hacer lo siguiente:
<- fonocortesia%>%arrange(F0_Media) fonocortesia_ord
11.5 Reordernar columnas:: relocate
Para reordenar las columnas de un data frame en R, se puede utilizar la función relocate()
del paquete dplyr
. Esta función permite mover una columna a una posición específica en el data frame. Por ejemplo, si queremos mover la columna Cortes_Descortes
después de la columna Intensidad_Media
, podemos hacer lo siguiente:
<- fonocortesia%>%relocate(Cortes_Descortes,
fonocortesia_reord2 .after = Intensidad_Media)
11.6 Crear nuevas columnas: mutate
Para crear nuevas columnas en un data frame en R, se puede utilizar la función mutate()
del paquete dplyr
. Esta función permite crear nuevas columnas a partir de las columnas existentes. Por ejemplo, si queremos crear una nueva columna que contenga el valor en semitonos de la columna F0_Media
, podemos ejecutar el siguiente comando:
<- fonocortesia%>%mutate(F0_media_norm =
fonocortesia_nueva 12*log2(F0_Media/1))
Igual que al seleccionar o filtrar hay que almacenar el resultado en un nuevo objeto para no perder los datos originales. Si en el código anterior hubiéramos hecho fonocortesia_nueva <- fonocortesia %>%mutate(F0_media = 12*log2(F0_Media/1))
, estaríamos sobreescribiendo la variable F0_Media.
11.6.1 Crear columnas usando varias columnas mediante suma de variables
Podemos crear nuevas variables realizando cualquier operación matemática: suma, resta, multiplicación, división, etc. Por ejemplo, si queremos crear una nueva columna que contenga la suma de las columnas F0_Media
e Intensidad_Media
, podemos ejecutar el siguiente código:
<- fonocortesia%>%mutate(Nueva_columna =
fonocortesia_nueva2 + Intensidad_Media) ) (F0_Media
11.6.2 Crear columnas usando varias columnas mediante media de variables
La media puede computarse de varias maneras. Por ejemplo, si queremos crear una nueva columna que contenga la media de las columnas F0_Media
e Intensidad_Media
, podemos ejecutar el siguiente código, aunque también existe la función mean()
:
<- fonocortesia%>%mutate(Nueva_columna =
fonocortesia_nueva3 + Intensidad_Media)/2) (F0_Media
11.6.3 Crear columnas usando varias columnas usando rowwise
Normalmente, las funciones de dplyr
operan por columnas. Sin embargo, a veces es necesario operar por filas. Para ello, se puede utilizar la función rowwise()
. Por ejemplo, si queremos crear una nueva columna que contenga la media de dos celdas contiguas, puede ejecutarse este código:
<- fonocortesia%>%rowwise()%>%
fonocortesia_nueva4 mutate(Nueva_columna = mean(c(F0_Media, Intensidad_Media),na.rm=T))
11.6.4 Crear una columna de índice usando row_number
Para crear una columna de índice en un data frame en R, se puede utilizar la función row_number()
. Esta función asigna un número único a cada fila del data frame. Por ejemplo, si queremos crear una columna de índice en el data frame fonocortesia
, se realizaría de la siguiente manera:
<- fonocortesia%>%mutate(id=row_number()) fonocortesia_nueva5
11.6.5 Crear columnas usando condiciones
R, como lenguaje de programación, permite aplicar secuencias de computación condicional. Por ejemplo, si queremos crear una nueva columna que contenga el valor “Intensificación” si la columna Mediodeexpresion
es igual a “Intensificación” y “Atenuación” en caso contrario, podemos ejecutar siguiente código que aparece más abajo. Esto serviría para normalizar la variable Medio de expresión que disponía inicialmente de 16 categorías. Puedes comprobarlo ejecutando table(fonocortesia$Mediodeexpresion)
:
<- fonocortesia%>%mutate(Medio_nuevo =
fonocortesia_nueva3 ifelse(Mediodeexpresion=="Intensificación",
"Intensificación",
"Atenuación"))
11.6.6 Crear columnas usando paste
Otra opción interesante es la de combinar columnas en una nueva columna. Por ejemplo, si queremos crear una nueva columna que contenga la concatenación de las columnas Cortes_Descortes
y Mediodeexpresion
, podemos ejecutar el siguiente código:
<- fonocortesia%>%mutate(Nueva_columna =
fonocortesia_nueva4 paste(Cortes_Descortes,
Mediodeexpresion, sep = "_"))
head(fonocortesia_nueva4$Nueva_columna)
[1] "descortés_Fórmulas indirectas" "descortés_Atenuación"
[3] "descortés_Intensificación" "descortés_Intensificación"
[5] "descortés_Intensificación" "cortés_Intensificación;Humor"
11.7 Agrupar datos: group_by
Las agrupaciones son realmente importantes en R. Permiten calcular medias, sumas, desviaciones típicas, etc. por grupos. Por ejemplo, si queremos calcular la media de la columna F0_Media
y de la columna Intensidad_Media
por grupo de la columna Cortes_Descortes
, podemos ejecutar el siguiente código:
<- fonocortesia%>%group_by(Cortes_Descortes)%>%
fonocortesia_agrup mutate(F0_media_mean = mean(F0_Media,na.rm = T),
Intensidad_media_mean = mean(Intensidad_Media,na.rm = T))
head(fonocortesia_agrup)%>%select(Cortes_Descortes, F0_Media,
Intensidad_Media, F0_media_mean, Intensidad_media_mean)
# A tibble: 6 × 5
# Groups: Cortes_Descortes [2]
Cortes_Descortes F0_Media Intensidad_Media F0_media_mean Intensidad_media_mean
<chr> <dbl> <dbl> <dbl> <dbl>
1 descortés 298 85 230. 75.9
2 descortés 174. 78 230. 75.9
3 descortés 315 81 230. 75.9
4 descortés 224 85 230. 75.9
5 descortés 226. 83 230. 75.9
6 cortés 295 80 199. 77.6
11.8 Resumir datos: summarise
A diferencia de la creación de nuevas columnas, la función summarise()
se utiliza para resumir los datos. Por ejemplo, si queremos calcular la media de la columna F0_Media
y de la columna Intensidad_Media
por grupo de la columna Cortes_Descortes
, podemos ejecutar el siguiente código:
<- fonocortesia%>%group_by(Cortes_Descortes)%>%
fonocortesia_resumen summarise(F0_media_mean = mean(F0_Media,na.rm = T),
Intensidad_media_mean = mean(Intensidad_Media,na.rm = T))
head(fonocortesia_resumen)
# A tibble: 3 × 3
Cortes_Descortes F0_media_mean Intensidad_media_mean
<chr> <dbl> <dbl>
1 cortés 199. 77.6
2 desconocido 299 82
3 descortés 230. 75.9
12 Visualización de datos
En esta sección, aprenderemos a visualizar datos utilizando el paquete ggplot2 en R. GGplot2 es una librería de visualización de datos en R que permite crear gráficos de alta calidad de manera sencilla y flexible.
12.1 ¿Por qué visualizar datos?
Visualizar datos es una parte fundamental del análisis de datos. Las visualizaciones permiten explorar los datos, identificar patrones y tendencias, comunicar resultados y conclusiones, y tomar decisiones adecuadas y coherentes. Las visualizaciones efectivas pueden ayudar a resumir y presentar datos de manera clara y concisa; esto facilita la interpretación y comprensión de los datos.
Images created by an AI from OpenAI
12.2 ¿Qué es ggplot2?
GGplot2 es una librería de visualización de datos en R que permite crear gráficos de alta calidad de manera sencilla y flexible. GGplot2 se basa en la gramática de gráficos, un enfoque que descompone los gráficos en componentes básicos (datos, estética, geometría, estadísticas y facetas) y permite construir gráficos complejos combinando estos componentes de manera intuitiva.
La curva de aprendizaje para el uso de Ggplot2 puede ser un poco inclinada.
12.3 Tipos de gráficos
Los gráficos más comunes que se pueden crear con ggplot2 incluyen: gráfico de barras, gráfico de líneas, gráfico de dispersión, gráfico de violín, gráfico de áreas, gráfico de burbujas, gráfico de donut, gráfico de lolipop, gráfico de mapa de calor, gráfico de densidad, gráfico de correlaciones, gráfico de árbol…
12.3.1 Gráficos de barras
El gráfico de barras es uno de lo más utilizados en investigaciones primerizas, dado que permite visualizar la frecuencia de una variable categórica.
En las siguientes subsecciones se presentan varios ejemplos de gráficos de barras utilizando la base de datos Fonocortesía.
12.3.1.1 Barras 1
Este es el modo más simple de crear un gráfico de barras en ggplot2. En este caso, se muestra la frecuencia de la variable Cortes_Descortes
.
ggplot(fonocortesia, aes(x=Cortes_Descortes)) +
geom_bar(stat="count")
12.3.1.2 Barras 2
En este caso, se muestra la frecuencia de la variable Cortes_Descortes
agrupada por la variable Mediodeexpresion
. Como se comentaba en secciones anteriores, esta visualización es de difícil acceso, ya que la variable Mediodeexpresion
tiene 16 categorías. En este caso, la visualización nos indica que esta variable debe ser procesada de otra manera o que se debe simplificar.
%>% ggplot(aes(x=Cortes_Descortes, fill=Mediodeexpresion)) +
fonocortesiageom_bar(stat="count")
12.3.1.3 Barras 3
En el siguiente gráfico de barras, se muestra la frecuencia de la variable Cortes_Descortes
agrupada por la variable Tonema
. En este caso, la variable Tonema
tiene 5 categorías, lo que facilita la visualización. El proceso facet_wrap permite dividir la visualización en cinco gráficos, uno por cada categoría de la variable Tonema
.
%>% ggplot(aes(x=Cortes_Descortes, fill=Tonema)) +
fonocortesiascale_x_discrete(guide = guide_axis(n.dodge=3))+
geom_bar(stat="count") + facet_wrap(~Tonema)
12.3.1.4 Barras 4
El siguiente gráfico de barras muestra la frecuencia de la variable Cortes_Descortes
agrupada por la variable Mediodeexpresion
. En este caso, se ha utilizado la función coord_flip()
para girar el gráfico y facilitar la lectura de las etiquetas.
%>% ggplot(aes(x=Mediodeexpresion, fill=Cortes_Descortes)) +
fonocortesiageom_bar(stat="count") + coord_flip()
12.3.1.5 Barras 5
En el siguiente gráfico de barras, se muestra la frecuencia de la variable Cortes_Descortes
agrupada por la variable Mediodeexpresion
. En este caso, se ha utilizado la función geom_text()
para añadir etiquetas con el número de observaciones y el porcentaje de cada categoría.
<- fonocortesia%>%group_by(Cortes_Descortes,Mediodeexpresion)%>%
data summarise(Total = sum(n())) %>%
mutate(Percentage = Total / sum(Total) * 100)
ggplot(data, aes(x=Cortes_Descortes,y=Percentage,
fill=Mediodeexpresion))+
geom_bar(stat="identity") + geom_text(
aes(label = paste(Total, "(", sprintf("%.1f%%", Percentage), ")",
sep = "")),
position = position_stack(vjust = 0.5),
size = 2 # Adjust text size
+ coord_flip() )
Si reducimos el número de variantes para la variable Mediodeexpresion
, la visualización es más clara:
ggplot(data%>%filter(Mediodeexpresion%in%
c("Atenuación","Intensificación","desconocido")), aes(x=Cortes_Descortes,y=Percentage, fill=Mediodeexpresion))+
geom_bar(stat="identity") + geom_text(
aes(label = paste(Total, "(", sprintf("%.1f%%",
")", sep = "")),
Percentage), position = position_stack(vjust = 0.5),
size = 2 # Adjust text size
+ coord_flip() )
12.3.2 Diagramas de caja
El diagrama de caja es una forma de visualizar la distribución de un conjunto de datos. Muestra la mediana, los cuartiles, los valores atípicos y la dispersión de los datos. En el siguiente gráfico de caja, se muestra la distribución de la variable F0_Media
agrupada por la variable Cortes_Descortes
.
ggplot(fonocortesia, aes(y=F0_Media,fill=Cortes_Descortes)) +
geom_boxplot()
12.3.3 Gráfico de correlaciones
El gráfico de correlaciones es una forma de visualizar la relación entre dos o más variables. Muestra la fuerza y la dirección de la relación entre las variables. En el siguiente gráfico de correlaciones, se muestra la matriz de correlaciones de las variables numéricas de la base de datos Fonocortesía.
library(corrplot)
<- fonocortesia%>%select_if(is.numeric)
datosnum <- cor(datosnum,use = "complete.obs")
correlaciones corrplot(correlaciones, method = "color",tl.col = "black",tl.cex = 0.7)
12.3.4 Gráficos de líneas
Los gráficos de líneas son una forma de visualizar la evolución de una variable a lo largo del tiempo o de otra variable continua. En el siguiente gráfico de líneas, se muestra la evolución de la variable F0_Media
a lo largo de las observaciones de la base de datos Fonocortesía.
ggplot(fonocortesia%>%mutate(id=row_number()),
aes(x=id,y=F0_Media,
fill=Cortes_Descortes,
color = Cortes_Descortes)) + geom_line() + geom_point()
12.3.5 Gráficos de dispersión
Un gráfico de dispersión es una forma de visualizar la relación entre dos variables continuas. Muestra cómo una variable depende de otra. En el siguiente gráfico de dispersión, se muestra la relación entre las variables F0_Media
e Intensidad_Media
.
ggplot(fonocortesia%>%filter(between(Intensidad_Media,60,90),
<300), aes(x=F0_Media, y=Intensidad_Media)) +
F0_Mediageom_point() + geom_smooth(method = "lm", se = FALSE, color = "blue")
12.3.6 Gráficos de burbujas
Un gráfico de burbujas es una forma de visualizar la relación entre tres variables: dos variables continuas y una variable categórica. Muestra cómo una variable depende de dos variables continuas y de una variable categórica. En el siguiente gráfico de burbujas, se muestra la relación entre las variables F0_Media
, Intensidad_Media
y Cortes_Descortes
.
ggplot(fonocortesia, aes(x=Duracion, y=Intensidad_Media,
size=F0_Media, fill = Cortes_Descortes, color=Cortes_Descortes)) +
geom_point()
12.3.7 Gráficos de áreas
Las áreas sirven para visualizar la distribución de una variable a lo largo de un eje. En el siguiente gráfico de áreas, se muestra la distribución de la variable F0_Media
a lo largo de las observaciones de la base de datos Fonocortesía, agrupada por la variable Cortes_Descortes
.
ggplot(fonocortesia%>%mutate(id=row_number())%>%
filter(Cortes_Descortes!="desconocido"),
aes(x=id, y=F0_Media, fill=Cortes_Descortes)) +
geom_area() + facet_wrap(~Cortes_Descortes)
12.3.8 Gráficos de violín
El gráfico de violín es una combinación de un diagrama de caja y un gráfico de densidad. Muestra la distribución de los datos en función de una variable categórica.
ggplot(fonocortesia, aes(x=Cortes_Descortes, y=F0_Media,
color=Cortes_Descortes, fill=Cortes_Descortes)) +
geom_violin() + coord_flip()
12.3.9 Gráficos de densidad
La densidad de un conjunto de datos es una estimación de la distribución de probabilidad subyacente de los datos. Los gráficos de densidad muestran la distribución de los datos en forma de una curva suave.
ggplot(fonocortesia, aes(x=F0_Media)) +
geom_density()
12.3.10 Gráficos de lolipop
El gráfico de lolipop es una forma de visualizar la distribución de una variable categórica. Muestra la media de una variable continua para cada categoría de la variable categórica.
<- fonocortesia%>%group_by(Cortes_Descortes)%>%
lolipop summarise(f0_mean=mean(F0_Media,na.rm = T))
ggplot(lolipop, aes(x=Cortes_Descortes, y=f0_mean,
fill = Cortes_Descortes, color =Cortes_Descortes)) +
geom_point(aes(size = f0_mean), alpha = 0.6) +
geom_segment(aes(x=Cortes_Descortes, xend=Cortes_Descortes,
y=0, yend=f0_mean)) +coord_flip()
12.3.11 Gráficos de donut
A diferencia de lo que puede pensarse, el gráfico circular (o donut) es quizá uno de los que conlleva más secuencias de código. En este caso, se muestra la frecuencia de la variable Cortes_Descortes
en un gráfico circular.
<- fonocortesia%>%group_by(Cortes_Descortes)%>%
data summarise(count=n())%>%na.omit()%>%
rename(category=Cortes_Descortes, count=count)
$fraction <- data$count / sum(data$count)
data
$ymax <- cumsum(data$fraction)
data
$ymin <- c(0, head(data$ymax, n=-1))
data
$labelPosition <- (data$ymax + data$ymin) / 2
data
$label <- paste0(data$category, "\n value: ", data$count)
data
ggplot(data, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=category)) +
geom_rect() +
geom_label( x=3.5, aes(y=labelPosition, label=label), size=3) +
scale_fill_brewer(palette=3) +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme_void() +
theme(legend.position = "none")
12.3.12 Gráficos de mapa de calor 🔥
En este caso, el mapa de calor que utilizamos para ejemplificar esta función no procede de la librería ggplot2, sino de gplots. En este caso, se muestra la media de las variables F0_Media
, Duracion
e Intensidad_Media
agrupadas por la variable Cortes_Descortes
. Para el mapa de calor es imprescindible disponer de valores numéricos que puedan proyectarse; en este caso, hemos utilizado la media de las variables, pero podrían haberse usado otras medidas de tendencia central. También es importante que no haya valores NA en las variables y que se aplique el procedimiento scale=“column” para normalizar los datos. En caso contrario, los resultados no se visualizarán de la manera más adecuado. Por ejemplo, para este mapa de calor se escalan los valores de intensidad, que se miden en decibelios, y los valores de F0, medidos en hercios.
library(gplots)
png(filename='heatmap.png', width=2400, height=1550, res=300)
<- fonocortesia %>%
p group_by(Cortes_Descortes) %>%
summarise_all(mean, na.rm = TRUE) %>%
column_to_rownames(var="Cortes_Descortes") %>%
select_if(is.numeric) %>%
select(F0_Media, Duracion, Intensidad_Media)
heatmap.2(as.matrix(p), na.rm = TRUE,
scale="column", cexCol = 0.8, cexRow = 0.8)
En el mapa de calor anterior, se observa que los enunciados descorteses duran más y tienen un F0 más alta, mientras que los enunciados corteses, a diferencia de lo anterior, presentan intensidades más altas. Debe recordarse que los valoro están relativizados en valores entre -1 y 1.
12.3.13 Nube de palabras
Las nubes de palabras son una forma visual de representar la frecuencia de las palabras en un texto. En este caso, se muestra una nube de palabras con las palabras más frecuentes en la variable Elemento_Analizado
de la base de datos Fonocortesía. Para ello, se ha utilizado la librería ggwordcloud
.
library(ggwordcloud)
<- fonocortesia %>%select(Cortes_Descortes,
df_words %>%
Elemento_Analizado)mutate(word = str_split(Elemento_Analizado, " "),
cortesia=Cortes_Descortes) %>% # Dividir el texto en palabras
unnest(word) %>% group_by(cortesia,word) %>%
summarise(frecuencia = n())%>%
mutate(word2 = gsub("[^a-zA-Z]","",word))%>%filter(frecuencia>2)
ggplot(df_words%>%filter(!word%in%c("A:","B:","C:","L:","M:","(...)")),
aes(label = word2, size = frecuencia,color=cortesia)) +
geom_text_wordcloud(area_corr = TRUE) +
scale_size_area(max_size = 20) +
theme_minimal()
13 Ejercicios
13.1 Enunciados
- Importa los datos del archivo
idiolectal.xlsx
y explora su estructura. - Haz dos dataframes según la variable genre. Cada uno de ellos debe contener los datos solo de un género.
- Crea un dataframe llamado “piquito_relocado” y ubica la variable tonemes delante de genre
- Visualiza en un gráfico de líneas en el dataframe “idiolectal” la evolución de los tonemas solo en el archivo 5pangelreal.
- Crea un dataframe llamado “piquito_filtrado” en el que filtre todos los datos que no sean NA en la variable tonemeMAS.
- Crea un diagrama de caja de la variable dur en el dataframe “idiolectal”. ¿Sabrías crearlos por hablante en un mismo gráfico? Hay varias maneras de hacerlo.
- ¿Cuántos tonemas hay en el dataframe “idiolectal”? Visualízalo en una tabla y en un gráfico de barras usando la base de datos “piquito_filtrado”.
- Correlaciona en el dataframe “idiolectal” las variables numéricas de este estudio.
- Haz una tabla de frecuencias de cada hablante en el dataframe “idiolectal” y saca la media de tonemeMAS, de dur y de body.
- Visualiza la información anterior en un mapa de calor.
13.2 Soluciones
- Importa los datos del archivo
idiolectal.xlsx
y explora su estructura.
library(readxl)
<- read_excel("databases/idiolectal.xlsx")
idiolectal str(idiolectal)
tibble [1,218 × 27] (S3: tbl_df/tbl/data.frame)
$ ...1 : chr [1:1218] "1" "2" "3" "4" ...
$ filename : chr [1:1218] "5pangelreal" "5pangelreal" "5pangelreal" "5pangelreal" ...
$ spk : chr [1:1218] "angelreal" "angelreal" "angelreal" "angelreal" ...
$ phon : chr [1:1218] "i*" "e*" "e*" "e*" ...
$ word : chr [1:1218] "intrusismo" "momento" "ser" "ser" ...
$ ip : chr [1:1218] "claro a lo mejor ahí sí que se podría considerar intrusismo" "en aquel momento" "puede ser" "puede ser" ...
$ ip_dur : num [1:1218] 2441 716 456 378 1567 ...
$ tmin : num [1:1218] 1982616 1983404 1984151 1985149 1986698 ...
$ tmax : num [1:1218] 1982703 1983443 1984254 1985221 1986789 ...
$ words : num [1:1218] 11 3 2 2 8 1 3 3 9 8 ...
$ dur : num [1:1218] 87 39 103 72 91 35 130 118 57 71 ...
$ toneme : chr [1:1218] "yes" "yes" "yes" "yes" ...
$ desplazamiento : chr [1:1218] "no" "no" "no" "no" ...
$ dur_first : num [1:1218] 31 84 26 20 27 60 130 118 168 37 ...
$ word_first : chr [1:1218] "claro" "aquel" "puede" "puede" ...
$ desplazamiento_first: chr [1:1218] NA NA NA NA ...
$ phon_preanac : chr [1:1218] NA "e" NA NA ...
$ word_preanac : chr [1:1218] NA "en" NA NA ...
$ dur_preanac : num [1:1218] NA 34 NA NA 69 NA NA 174 152 51 ...
$ tonemeMAS : num [1:1218] NA -1.31 NA NA 4.11 ...
$ circunflejo : chr [1:1218] "no" "no" "no" NA ...
$ MAStag : chr [1:1218] NA "PV" NA NA ...
$ body : num [1:1218] NA 26.4 NA NA NA ...
$ spk2 : chr [1:1218] "5pangelreal" "5pangelreal" "5pangelreal" "5pangelreal" ...
$ spk3 : chr [1:1218] "5pangelrealangelreal" "5pangelrealangelreal" "5pangelrealangelreal" "5pangelrealangelreal" ...
$ genre : chr [1:1218] "5p" "5p" "5p" "5p" ...
$ tonemes : chr [1:1218] NA "suspendido" NA NA ...
- Haz dos dataframes según la variable genre. Cada uno de ellos debe contener los datos solo de un género.
table(idiolectal$genre)
5p pod
609 609
<- idiolectal%>%filter(genre=="5p")
idiolectal_5p <- idiolectal%>%filter(genre=="pod") idiolectal_pod
- Crea un dataframe llamado “piquito_relocado” y ubica la variable tonemes delante de genre
<- idiolectal%>%relocate(tonemes, .before = genre) piquito_relocado
- Visualiza en un gráfico de líneas en el dataframe “idiolectal” la evolución de los tonemas solo en el archivo 5pangelreal.
library(tidyverse)
%>%filter(filename=="5pangelreal")%>%
idiolectalggplot(aes(x=tmin,y=tonemeMAS, color=spk, fill=spk)) +
geom_line() + geom_point()
- Crea un dataframe llamado “piquito_filtrado” en el que filtre todos los datos que no sean NA en la variable tonemeMAS.
<- idiolectal%>%filter(!is.na(tonemeMAS)) piquito_filtrado
- Crea un diagrama de caja de la variable dur en el dataframe “idiolectal”. ¿Sabrías crearlos por hablante en un mismo gráfico? Hay varias maneras de hacerlo.
ggplot(idiolectal, aes(x=spk, y=dur, fill=spk)) + geom_boxplot()
ggplot(idiolectal, aes(x=spk, y=dur, fill=spk)) +
scale_x_discrete(guide = guide_axis(n.dodge=5))+
geom_boxplot() + facet_wrap(~spk,ncol = 5)
- ¿Cuántos tonemas hay en el dataframe “idiolectal”? Visualízalo en una tabla y en un gráfico de barras usando la base de datos “piquito_filtrado”
table(piquito_filtrado$MAStag)
other PI PII PIII PIX PV PVIa PVIb PVII PVIII PXa PXI PXIIa
289 234 8 3 9 151 35 13 3 29 1 5 64
ggplot(piquito_filtrado, aes(x=MAStag)) + geom_bar()
- Correlaciona en el dataframe “idiolectal” las variables numéricas de este estudio.
library(corrplot)
<- cor(idiolectal%>%
correlaciones select_if(is.numeric),use = "complete.obs")
corrplot(correlaciones, method = "color",
tl.col = "black",tl.cex = 0.7)
- Haz una tabla de frecuencias de cada hablante en el dataframe “idiolectal” y saca la media de tonemeMAS, de dur y de body
%>%group_by(spk)%>%summarise(
idiolectaltonemeMAS_mean = mean(tonemeMAS,na.rm = T),
dur_mean = mean(dur,na.rm = T),
body_mean = mean(body,na.rm = T))
# A tibble: 5 × 4
spk tonemeMAS_mean dur_mean body_mean
<chr> <dbl> <dbl> <dbl>
1 angelreal 1.02 93.7 5.88
2 dufort 2.75 106. 4.38
3 estepa 0.240 130. -4.50
4 pzorro 11.0 99.8 7.28
5 rcastellano 1.10 87.0 15.4
- Visualiza la información anterior en un mapa de calor.
library(gplots)
<- idiolectal%>%group_by(spk)%>%summarise(
mapacalor tonemeMAS_mean = mean(tonemeMAS,na.rm = T),
dur_mean = mean(dur,na.rm = T),
body_mean = mean(body,na.rm = T))%>%
column_to_rownames(var="spk")
heatmap.2(as.matrix(mapacalor), na.rm = TRUE,
scale="column", cexRow = 0.5, cexCol = 0.5)
14 Estadística descriptiva
Cuando hablamos de estadística descriptiva normalmente nos estamos refiriendo a un conjunto de operaciones básicas como la media, la mediana, la moda, la desviación típica, etc. También entraría dentro de la estadística descriptiva el estudio de las distribuciones de las variables de nuestras bases de datos.
14.1 Precaución
Los cómputos estadísticos solo relacionan números; el valor explicativo que otorgamos a esas relaciones es una cuestión de interpretación. Por ejemplo, la correlación entre el número de personas que se ahogan en una piscina y el número de películas en las que aparece Nicolas Cage es del 66%. Esto no significa que una cosa cause la otra, sino que ambas variables están relacionadas con el tiempo. Pueden verse más de estas relaciones aquí:
https://www.tylervigen.com/spurious-correlations
14.2 Tratamiento previo
Antes de empezar este apartado sobre estadística descriptiva crearemos una modificación de la base de datos fonocortesía que hemos utilizado en el tema anterior. En esta nueva base de datos, que llamaremos corpusren, hemos renombrado las variables para que sean más accesibles en gráficos y tablas y hemos eliminado los casos en los que la variable Cortes_Descortes tiene el valor desconocido. También hemos eliminado los casos en los que la variable Tonema tiene el valor desconocido. La base de datos corpusren es la que utilizaremos en este tema.
library(kableExtra)
library(tidyverse)
library(corrplot)
library(psych)
library(flextable)
library(FactoMineR)
library(factoextra)
library(partykit)
library(readxl)
library(randomForest)
library(DataExplorer)
library(gplots)
library(ggwordcloud)
<- read_excel("databases/corpus.xlsx")
corpus <- corpus %>% rename(
corpusren
conv = Conversacion, cort = Cortes_Descortes,
Llam = Llama_Atencion, med = Mediodeexpresion,
F0I = F0_Inicial, F0F = F0_Final,
F0M = F0_Media, F0X = F0_Maxima, F0N = F0_Minima,
IU = Intensidad_Ultima, IM = Intensidad_Media,
IN = Intensidad_Minima, IX = Intensidad_Maxima,
IP = Intensidad_Primera, Sil = Silabas,
dur = Duracion, DPA = Duracion_Pausa_Anterior,
DPP = Duracion_Pausa_Posterior, CP = Continuacion_Pausa,
Cur = Curva_Melodica, OCur = Otro_Curva_Melodica,
ILI = Inflexion_Local_Interna, To = Tonema,
Disc = Unidad_Del_Discurso, Vmod = Valormodal,
OVmod = Otro_Valor_Modal, Fton = Fenomeno_Tonal,
Fdur = Fenomeno_Duracion, Fpau = Fenomeno_Pausas,
Fve = Fenomeno_Velocidad, Fam = Fenomeno_Amplitud,
UF = Unidad_Fonica, EPra = Estrategia_Pragmatica,
Efec = Efecto_Pragmatico_Asociado, EA = Elemento_Analizado,
Fr = Fragmento)%>%filter(cort!="desconocido", To != "desconocido")
options(scipen = 1, digits = 2)
14.3 Tablas simples o tablas de contingencia
En R, el método table sirve para crear tablas de frecuencia. Si usamos, por ejemplo, table(corpusren$cort), obtendremos una tabla con las frecuencias de la variable cort. Por su parte, una tabla de contingencia es una tabla que muestra la distribución conjunta de dos o más variables categóricas. En R, podemos crear tablas de contingencia con la función table, que nos permite cruzar dos o más variables categóricas, pero también con otras librerías, como flextable.
- Procedimiento table
- Procedimiento flextable de la librería flextable.
table(corpusren$cort)
cortés descortés
131 145
Ejemplo con table
set_flextable_defaults(
font.family = "Times",
font.size = 11,
padding = 0,
font.color = "black",
table.layout = "autofit",
digits = 1,
theme_fun = "theme_box"
)
<- as.data.frame(table(corpusren$cort))
p flextable(p)
Var1 | Freq |
---|---|
cortés | 131 |
descortés | 145 |
Ejemplo con la librería flextable.
Con la variable tonema:
flextable(corpusren%>%group_by(To)%>%
summarise(cantidad=n())%>%arrange(cantidad))
To | cantidad |
---|---|
circunflejo | 27 |
suspendido | 67 |
ascendente | 84 |
descendente | 98 |
Tabla resumen de las frecuencias de la variable Tonema
Procedimiento prop.table de la librería base. Sirve para calcular las proporciones de las tablas de contingencia.
Proporción por fila:
prop.table(table(corpusren$To,corpusren$cort),margin = 1)
cortés descortés
ascendente 0.27 0.73
circunflejo 0.44 0.56
descendente 0.51 0.49
suspendido 0.69 0.31
Proporción por columna:
prop.table(table(corpusren$To,corpusren$cort),margin = 2)
cortés descortés
ascendente 0.176 0.421
circunflejo 0.092 0.103
descendente 0.382 0.331
suspendido 0.351 0.145
Propoción del total:
prop.table(table(corpusren$To,corpusren$cort))
cortés descortés
ascendente 0.083 0.221
circunflejo 0.043 0.054
descendente 0.181 0.174
suspendido 0.167 0.076
Debemos recordar, no obstante, que nos encontramos en este caso en una fase de descripción y que, por tanto, sin la aplicación de pruebas estadísticas inferenciales no podemos controlar de manera precisa la repercusión de estos datos, que pertenecen a nuestra muestra, en relación con la población general de potenciales enunciados corteses o descorteses del español hablado.
La librería flextable permite realizar las mismas dos operaciones que hemos realizado anteriormente, la de observar las proporciones por columnas y por filas, en una misma tabla.
proc_freq(corpusren, "cort","To",)%>%fontsize(size = 10,part="all")
cort | To | |||||
---|---|---|---|---|---|---|
ascendente | circunflejo | descendente | suspendido | Total | ||
cortés | Count | 23 (8.3%) | 12 (4.3%) | 50 (18.1%) | 46 (16.7%) | 131 (47.5%) |
Mar. pct (1) | 27.4% ; 17.6% | 44.4% ; 9.2% | 51.0% ; 38.2% | 68.7% ; 35.1% | ||
descortés | Count | 61 (22.1%) | 15 (5.4%) | 48 (17.4%) | 21 (7.6%) | 145 (52.5%) |
Mar. pct | 72.6% ; 42.1% | 55.6% ; 10.3% | 49.0% ; 33.1% | 31.3% ; 14.5% | ||
Total | Count | 84 (30.4%) | 27 (9.8%) | 98 (35.5%) | 67 (24.3%) | 276 (100.0%) |
(1) Columns and rows percentages |
14.4 Resumen estadístico
Los resúmenes estadísticos permiten explorar de manera inicial una base de datos. Por defecto, el comando general para efectuar esa operación de resumen es summary. Con este comando, R ofrecerá una pantalla con una muestra de las frecuencias más pobladas de las variables categóricas y datos de estadística descriptiva como la media, la mediana, los valores mínimos y máximos, los valores vacíos, el primer y el tercer cuartil.
Con finalidad de ejemplificación, podemos observar valores de algunas variables de la base de datos Fonocortesía:
kable(summary(corpusren[,c(2,23,5:7)]))
cort | To | F0I | F0F | F0M | |
---|---|---|---|---|---|
Length:276 | Length:276 | Min. : 0 | Min. : 0 | Min. : 0 | |
Class :character | Class :character | 1st Qu.:166 | 1st Qu.:146 | 1st Qu.:180 | |
Mode :character | Mode :character | Median :220 | Median :211 | Median :221 | |
NA | NA | Mean :214 | Mean :212 | Mean :216 | |
NA | NA | 3rd Qu.:252 | 3rd Qu.:267 | 3rd Qu.:251 | |
NA | NA | Max. :490 | Max. :519 | Max. :420 | |
NA | NA | NA’s :41 | NA’s :41 | NA |
¿Para qué pueden servir entonces las tablas para analizar nuestras bases de datos? Por ejemplo, nos sirven para observar equilibrio en los datos. En Fonocortesía, ¿se han recogido un número similar de casos de cada conversación? Si quisiéramos conocer, en ese sentido, el total de recuento por conversación podríamos ejecutar el comando table. En el siguiente ejemplo, se combina table, con la propiedad arrange de la librería dplyr que permite ordenar los datos:
flextable(table(corpusren$conv) %>%
as.data.frame() %>% arrange(desc(Freq)))
Var1 | Freq |
---|---|
VALESCO 025A | 45 |
VALESCO 130A | 39 |
VALESCO 171A | 24 |
VALESCO 114A | 23 |
VALESCO 183A | 22 |
VALESCO 37B | 21 |
VALESCO 84A | 20 |
VALESCO 140A | 19 |
VALESCO 80A | 11 |
VALESCO 129B | 10 |
VALESCO 69A | 10 |
VALESCO 162A | 9 |
VALESCO 194A | 8 |
VALESCO 126A | 7 |
VALESCO 165A | 3 |
VALESCO 179B | 3 |
VALESCO 193A | 1 |
VALESCO 279b | 1 |
En general, hay una distribución más o menos constante por conversación, de 10 a 20 casos de media, aunque la 25A y la 130A, como decíamos anteriormente, recogen el mayor número de enunciados corteses o descorteses recogidos.
14.4.1 Valores estadísticos generales de una variable
También puede darse la situación de que estemos interesados en una variable en particular. Por ejemplo, si queremos recoger valores estadísticos para la variable F0_Media (F0M), podemos usar el comando describe de la librería psych. Los valores concretos que se recogerán serán los siguientes:
describe(corpusren$F0M)
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 276 216 61 221 217 52 0 420 420 -0.3 1 3.7
Podemos describir cada uno de estos valores estadísticos:
- Vars. Número de variables analizadas. En este caso hemos tomado los valores únicamente de la variable F0_media.
- n. Cantidad de elementos: 276
- Mean. Media de la variable, que serían 216 Hz.
- Sd. Desviación típica, es decir, los datos se desvían 61 Hz de media por encima o por debajo, precisamente, de la media de 216 Hz que se indicaba previamente.
- Median. Valor central de la variable, por encima y por debajo del cual se sitúan la mitad superior e inferior de los datos. Es un valor robusto que no se ve afectado por la presencia de datos extremos positivos o negativos. En este caso, sería algo superior a la media: 221 Hz.
- Trimmed. Se trata de la media con valores extremos eliminados. Serían 216.6 Hz
- mad. Desviación típica de la mediana. 52 Hz.
- min Valor mínimo recogido para esta variable. En el caso de la F0_media, se recoge 0 porque hay algún dato vacío.
- max. Valor máximo de la variable. Esta opción sirve para detectar casos extremos. Para la F0_media sería 420 Hz, que seguramente sea un error de alguna muestra de audio o, también, puede tratarse de un enunciado afectado por fenómenos paralingüísticos como las risas o por algún ruido medioambiental (golpes, por ejemplo).
- range. Se trata del rango de valores entre el valor mínimo y el valor máximo.
- skew. Es el grado de asimetría. Si se acerca a 0, como es el caso, significa que la distribución de la variable está ciertamente normalizada y que los valores se distribuyen de manera equilibrada alrededor de la media y la mediana y se distribuyen en forma positiva o negativa a los lados siguiendo la regla expuesta anteriormente del 68 %, 95 % y 99.8 %.
- kurtosis. La kurtosis es la forma de la curva de la distribución. Un valor de 1.01 indica que la curva refleja una concentración de valores algo más elevada de lo normal en el centro, es decir, hay más valores cercanos a la media, aunque no es un valor desproporcionado. De hecho, asimetría y kurtosis están relacionados.
- se. Es el error estándar de la media. En el caso de F0_Media indica que la media de nuestra muestra, 216 Hz, se encuentra seguramente a una distancia máxima de 3.7 desviaciones típica de la presunta media de toda la población. En general, valores pequeños de este valor indican que nuestra muestra es bastante adecuada. Al mismo tiempo, si obtuviéramos más datos, el valor se iría reduciendo de manera exponencial.
14.4.2 Valores estadísticos por grupos
Todos los valores que hemos tomado para la variable en conjunto pueden especificarse por una variable de grupo; por ejemplo, podemos observar los valores de estadística descriptiva para F0_Media según los grupos establecidos en la variable Cortes_Descortes; en la librería psych puede realizarse mediante el comando describeBy:
<- describeBy(x=corpusren$F0M,group = corpusren$cort)
p p
Descriptive statistics by group
group: cortés
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 131 198 66 200 200 71 0 333 333 -0.4 0.27 5.8
------------------------------------------------------------
group: descortés
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 145 232 52 228 230 41 92 420 327 0.43 0.94 4.3
14.5 Valores del resumen estadístico
En caso de querer acceder a un valor concreto del resumen estadístico, podemos obtenerlos mediante los siguientes comandos:
mean(x = corpus$F0_Media)
median(x = corpus$F0_Media)
max(x = corpus$F0_Media)
min(x = corpus$F0_Media)
range(x = corpus$F0_Media)
quantile(x = corpus$F0_Media)
IQR(x = corpus$F0_Media)
var(x = corpus$F0_Media)
sd(x = corpus$F0_Media)
skew(x = corpus$F0_Media)
skew(x = corpus$Duracion)
kurtosi(x = corpus$F0_Media)
15 Relaciones de estadística inferencial
Son muchas las pruebas estadísticas o técnicas de visualización que pueden realizarse mediante R. Sin embargo, en esta sección vamos a centrarnos específicamente en las siguientes: la prueba de chi cuadrado, la prueba T Test (o ANOVA, para más de dos categorías), el análisis múltiple de correspondencias, el árbol de decisiones y la prueba de Random Forest.
15.1 Chi cuadrado
En palabras de Moore (2005: 620): “el estadístico Ji cuadrado es una medida de la diferencia entre los recuentos observados y los recuentos esperados en una tabla de contingencia”.
La prueba de chi cuadrado puede emplearse de dos formas distintas en el análisis de datos. En la primera, se busca determinar si alguna frecuencia categórica difiere de lo esperado bajo ciertas condiciones de proporcionalidad, que pueden ser de equilibrio (igual proporción esperada para cada categoría) o de un desajuste conocido (por ejemplo, sabemos que en la conversación espontánea habrá proporcionalmente más casos de cortesía que de descortesía, con una proporción conocida de 70% de cortesía y 30% de descortesía). Esta aplicación de la chi cuadrado, conocida como prueba de bondad de ajuste, contrapone las frecuencias de las categorías de una única variable.
En la segunda aplicación de la chi cuadrado, que es la más común, se analizan dos variables categóricas cruzándolas en una tabla de contingencia. El objetivo es observar si existe una relación de dependencia entre las dos variables; es decir, si una categoría de una variable específica (por ejemplo, hombre de la variable sexo) está relacionada con una categoría o categorías de otra variable (por ejemplo, descortesía de la variable Cortes_Descortes). Si esta relación es significativa, encontraremos una cantidad considerable de casos en este cruce de variables.
Según Moore (2013: 621):
Interpreta el estadístico Ji cuadrado, X2, como una medida de la distancia entre los recuentos observados y los recuentos esperados. Como cualquier distancia, su valor siempre es cero o positivo. Es cero sólo cuando los recuentos observados son exactamente iguales a los recuentos esperados. Los valores de X2 grandes constituyen una evidencia en contra de H0, ya que indican que los recuentos observados están lejos de lo que esperaríamos si H0 fuera cierta. Aunque la hipótesis alternativa Ha es de muchas colas, la prueba Ji cuadrado es de una cola, ya que cualquier violación de H0 tiende a producir un valor de X2 grande. Los valores pequeños de X2 no constituyen ninguna evidencia en contra de H0.
La prueba de chi cuadrado determina la posible relación entre variables, pero no identifica inicialmente qué categorías están significativamente relacionadas. Para ello, se utiliza el residuo estandarizado, un valor calculado por la prueba. Residuales mayores o menores a 1.96 indican que las categorías están excesivamente representadas o subrepresentadas en los datos, sugiriendo una relación significativa entre las variables si no existiera relación entre ellas.
Dado que es improbable que no haya relación alguna, un residuo significativo sugiere una alta probabilidad de que la hipótesis nula (H0) sea falsa, indicando una relación entre las variables. Además, la fuerza de esta relación no se mide por el valor de la prueba ni por el valor p, sino por otros indicadores como la V de Cramer, donde valores superiores al 60-70 % indican una relación fuerte.
La prueba de chi cuadrado proporciona varios resultados clave:
Datos observados: recuento por categoría o cruces de categorías.
Datos esperados: frecuencia esperada bajo la hipótesis de no relación entre las variables.
Grados de libertad: parámetros técnicos que ayudan a interpretar las relaciones inferenciales. Se calculan como (número de filas - 1) x (número de columnas - 1). Por ejemplo, una tabla 2x2 tiene un grado de libertad, mientras que una 2x3 tiene dos.
Valor del estadístico: un valor alto sugiere rechazar H0, mientras que un valor bajo sugiere lo contrario.
Valor p: si es inferior a 0.05, indica una relación significativa entre las variables al nivel de significación del 95 %, común en estudios científicos.
Residuos: los residuos estandarizados de Pearson comparan la diferencia entre los datos observados y esperados, proyectándolos en una estandarización normalizada. Un valor superior o inferior a 1.96 sugiere que el cruce de categorías está significativamente por encima o por debajo de lo esperado bajo la hipótesis de no relación.
15.1.1 Bondad de ajuste
La bondad de ajuste es una prueba de chi cuadrado que se utiliza para comparar un modelo nulo con un modelo alternativo. En este caso, el modelo nulo es que no hay relación entre las variables y el modelo alternativo es que sí la hay. En el caso de la bondad de ajuste, se compara una variable categórica con una distribución de probabilidad conocida. En el caso de la fonocortesía, por ejemplo, podríamos comparar la variable Cortes_Descortes con una distribución de probabilidad conocida, como la proporción 1/2, 1/2. En este caso, la prueba de chi cuadrado nos dirá si la distribución de la variable Cortes_Descortes se ajusta a la distribución 1/2, 1/2.
%>%group_by(cort)%>%summarise(cantidad=n())%>%
corpusren arrange(desc(cantidad))%>%flextable()
cort | cantidad |
---|---|
descortés | 145 |
cortés | 131 |
Tabla de frecuencias absolutas de la variable combinación fonética
Valores de la prueba chi cuadrado
<- table(corpusren%>%select(cort))
table <- chisq.test(table,p = c(1/2,1/2))
chi chi
Chi-squared test for given probabilities
data: table
X-squared = 0.7, df = 1, p-value = 0.4
Valores de los residuos estandarizados
$residuals chi
cort
cortés descortés
-0.6 0.6
La interpretación de los datos señala que hay un equilibro entre los valores corteses y descorteses y que, por tanto, no se han recogido datos desajustados o con pesos distintos.
15.1.2 Chi cuadrado entre dos variables
La prueba de chi-cuadrado es una de las más conocidas en disciplina humanística para observar la relación entre dos variables categóricas. En esta sección vamos a analizar relaciones de variables de las dos bases de datos de este estudio. En primer lugar, observaremos la relación entre el tipo de combinación fonética y género para transmitir atenuación; en segundo lugar, analizaremos la relación entre la variable Cortes_Descortes y los tonemas.
15.1.2.1 Relación entre cortesía y tonemas
En este ejemplo, se analiza la relación entre dos variables de la base de datos Fonocortesía: Cortes_Descortes y tonema. El objetivo es determinar si la parte final de los enunciados presenta un comportamiento melódico diferente según la categoría cortés o descortés.
Primero, se guarda el resultado de la prueba de chi cuadrado en una variable llamada pruebachi
. Aunque no es esencial, esta práctica facilita el acceso a valores observados, esperados y residuos. Además, se utiliza el comando assocstats
de la librería vcd
, que proporciona datos relevantes como la V de Cramer, útil para medir la fuerza de la relación entre dos variables.
El siguiente código permite acceder al valor de la prueba de chi cuadrado y a los datos generados con assocstats
:
library(broom)
<- chisq.test(table(corpusren$cort,corpusren$To))
pruebachi pruebachi
Pearson's Chi-squared test
data: table(corpusren$cort, corpusren$To)
X-squared = 26, df = 3, p-value = 8e-06
assocstats(table(corpusren$cort,corpusren$To))
X^2 df P(> X^2)
Likelihood Ratio 27.053 3 5.7384e-06
Pearson 26.250 3 8.4528e-06
Phi-Coefficient : NA
Contingency Coeff.: 0.29
Cramer's V : 0.31
Likelihood ratio test y Pearson’s Chi-squared test son una pruebas de bondad de ajuste que se utiliza para comparar un modelo nulo con un modelo alternativo.
Phi-coefficient, Contingency coefficient y Cramer’s V son medidas de la fuerza de la relación entre dos variables categóricas. Sus valores se sitúan entre 0 y 1, siendo 0 la ausencia de relación y 1 la relación perfecta. La relación entre cortesía y tonemas es de 0.29 o 0.31, lo que indica que no todas las categorías están igualmente emparentadas.
En este caso Phi_Coefficient es NA porque solo se puede calcular para variables que tengan solo dos categorías.
Para acceder a los valores observados, esperados y residuos, el código es el que sigue:
15.1.2.2 Valores observados
$observed pruebachi
ascendente circunflejo descendente suspendido
cortés 23 12 50 46
descortés 61 15 48 21
15.1.2.3 Valores esperados
$expected pruebachi
ascendente circunflejo descendente suspendido
cortés 40 13 47 32
descortés 44 14 51 35
15.1.2.4 Valores de los residuos
$residuals pruebachi
ascendente circunflejo descendente suspendido
cortés -2.67 -0.23 0.51 2.52
descortés 2.54 0.22 -0.49 -2.39
Los residuos estandarizados muestran una relación significativa entre el tonema suspendido y la categoría cortés, así como entre la categoría descortés y el tonema ascendente. Desde un punto de vista epistemológico, estos datos son relevantes porque sugieren un comportamiento diferente al comúnmente aceptado en la comunidad científica. Según el conocimiento compartido, los valores de cortesía suelen estar asociados a subidas tonales; sin embargo, en nuestra muestra, se observa lo contrario.
Para una mayor claridad, los datos de los residuos pueden representarse en un gráfico llamado mosaicplot, como se muestra a continuación:
mosaicplot(table(corpusren$cort,corpusren$To),
main =" Mosaicplot cortesía vs Tonema", shade = TRUE,cex.axis = 0.5,las = 1)
15.1.3 Ejercicios
15.1.3.1 Enunciados
- En la base de datos Idiolectal, realizar una prueba de bondad de ajuste para la variable tonemes. ¿Hay alguna categoría que se desvíe de la proporción esperada (igualdad de proporción)?
- En la base de datos Idiolectal, realizar una prueba de chi cuadrado para la relación entre la variable tonemes y la variable genre. ¿Hay alguna relación significativa entre ambas variables?
- Realiza un mosaicplot para la relación entre la variable tonemes y la variable genre en la base de datos Idiolectal.
15.1.3.2 Soluciones
- En la base de datos Idiolectal, realizar una prueba de bondad de ajuste para la variable tonemes. ¿Hay alguna categoría que se desvíe de la proporción esperada (igualdad de proporción)?
<- table(idiolectal%>%select(tonemes)%>%na.omit())
table <- chisq.test(table,p = c(1/4,1/4,1/4,1/4))
chi chi
Chi-squared test for given probabilities
data: table
X-squared = 222, df = 3, p-value <2e-16
- En la base de datos Idiolectal, realizar una prueba de chi cuadrado para la relación entre la variable tonemes y la variable genre. ¿Hay alguna relación significativa entre ambas variables?
<- table(idiolectal%>%select(tonemes,genre)%>%na.omit())
table <- chisq.test(table)
chi chi
Pearson's Chi-squared test
data: table
X-squared = 7, df = 3, p-value = 0.08
- Realiza un mosaicplot para la relación entre la variable tonemes y la variable genre en la base de datos Idiolectal.
mosaicplot(table(idiolectal%>%select(tonemes,genre)%>%
na.omit()),shade=T,main="Mosaicplot de tonemes y género")
15.2 T test y ANOVA
Las pruebas T test (o t de Student) y ANOVA (analysis of variance) son pruebas usadas para observar la diferencia entre grupos ya creados a partir de una variable numérica. En el caso de la prueba T test se trata de un máximo de dos grupos, mientras que para la ANOVA se parte de más de dos. Un ejemplo concreto sería observar si en la base de datos Fonocortesía hay diferencia entre los registros de cortesía y los de descortesía en función de cualquiera de las variables numéricas de las base de datos: duración, F0_Media, Intensidad_Media…
15.2.1 Ejemplo de T. Test: F0 Media según (des)cortesía
En este caso analizamos como variable independiente la variables Cortes_Descortes y, por tanto, intentamos averiguar si existe una diferencia notable entre los valores medios de la F0 para los enunciados corteses y para los enunciados descorteses.
t.test(corpusren$F0M~corpusren$cort)
Welch Two Sample t-test
data: corpusren$F0M by corpusren$cort
t = -5, df = 245, p-value = 6e-06
alternative hypothesis: true difference in means between group cortés and group descortés is not equal to 0
95 percent confidence interval:
-47 -19
sample estimates:
mean in group cortés mean in group descortés
198 232
Las medias de los enunciados corteses son significativamente inferiores, con 198 Hz, frente a los 232 Hz de los enunciados descorteses. La prueba T de Student con un valor de -5, 245 grados de libertad y un valor p de 6e-06 indica que la diferencia es por tanto significativa y que, en esta situación, nos permite contemplar la presencia de dos grupos distintos. En otras palabras, los enunciados descorteses destacan por una F0 superior a los enunciados corteses.
Las pruebas estadísticas relacionadas con medias suelen acompañarse de algún tipo de gráfico para la visualización de estas. En concreto, podemos acompañar esta prueba de un diagrama de caja que, aunque permite visualizar el valor de la mediana y no la media, es un dato de tendencia central de los datos y, a no ser que haya outliers muy marcados, permite fácilmente detectar la diferencia entre grupos:
ggplot(corpusren, aes(x=cort, y=F0M, fill = cort)) +
geom_boxplot() + theme_minimal() +
labs(title="Diagrama de caja de la relación
entre F0 Media y Cortes_Descortes",
x="Cortes_Descortes", y="F0 Media")
15.2.2 Ejemplos ANOVA: Variables fónicas según medio de expresión
Esta sección nos servirá para introducir la prueba ANOVA (analysis of variance), que es una extensión de la prueba T de Student para más de dos grupos. Se usa para comparar las medias de dos o más grupos y determinar si al menos uno de los grupos es significativamente diferente de los demás. Para ello, se completa con una prueba post hoc, como la de Tukey (HSDTukey), que permite comparar los grupos dos a dos. Como la variable Medio de expresión tiene muchas categorías, vamos a simplificarla en tres: Atenuación, Intensificación y Otro valor. Para ello, usaremos el siguiente código:
<- corpusren%>%mutate(med2 = ifelse(
corpusren
== "Atenuación", "Atenuación",
med ifelse(
== "Intensificación", "Intensificación",
med "Otro_valor"
)
)
)
Para aplicar la prueba ANOVA y la de diferenciación de grupos (Tukey), vamos a analizar si hay diferencias significativas entre los tres categorías de la variable Medio de expresión en relación con las variables F0M, dur e IM.
15.2.2.1 F0 Media
En primer lugar, observamos la variable F0M:
TukeyHSD(aov(F0M~med2, data= corpusren))
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = F0M ~ med2, data = corpusren)
$med2
diff lwr upr p adj
Intensificación-Atenuación 32 11 53 0.00
Otro_valor-Atenuación -4 -30 22 0.93
Otro_valor-Intensificación -36 -57 -14 0.00
Los datos que se observan indican que hay diferencias significativas entre dos grupos, con valores inferiores a 0.05. En concreto, Intensificación y Atenuación se diferencian entre sí, al igual que Otro valor de Intensificación, pero no Atenuación de Otro valor. El diagrama de caja que se presenta a continuación muestra la diferencia entre los tres grupos:
15.2.2.1.1 Diagrama de caja
ggplot(corpusren, aes(x=med2, y=F0M, fill = med2)) +
geom_boxplot() + theme_minimal() +
labs(title="Diagrama de caja de la variable F0M
por género discursivo",
x="Género discursivo", y="F0 Media")
15.2.2.1.2 Descripción por grupos
library(psych)
describeBy(x= corpusren$F0M, group = corpusren$med2)
Descriptive statistics by group
group: Atenuación
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 61 199 53 200 197 49 91 315 224 0.18 -0.66 6.8
------------------------------------------------------------
group: Intensificación
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 157 230 58 231 231 46 0 420 420 -0.28 1.6 4.6
------------------------------------------------------------
group: Otro_valor
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 58 195 67 200 197 65 0 333 333 -0.52 0.69 8.8
15.2.2.2 Duración
En cuanto a la duración, los valores de la prueba ANOVA y el contraste post HOC Tukey son los siguientes:
TukeyHSD(aov(dur~med2, data= corpusren))
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = dur ~ med2, data = corpusren)
$med2
diff lwr upr p adj
Intensificación-Atenuación -0.11 -0.95 0.72 0.95
Otro_valor-Atenuación 0.29 -0.73 1.30 0.79
Otro_valor-Intensificación 0.40 -0.45 1.25 0.51
En el caso de la velocidad de habla no hay diferencias significativas entre los tres grupos. El diagrama de caja señala esa falta de diferencia:
ggplot(corpusren%>%filter(dur<20), aes(x=med2,
y=dur, fill = med2)) + geom_boxplot() +
theme_minimal() + labs(title="Diagrama de caja de
la variable duración por género discursivo",
x="Género discursivo", y="Duración")
15.2.2.3 Intensidad media
Finalmente, la variable de intensidad media tampoco presenta diferencias significativas entre grupos:
TukeyHSD(aov(IM~med2, data= corpusren))
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = IM ~ med2, data = corpusren)
$med2
diff lwr upr p adj
Intensificación-Atenuación -1.7 -7.4 4.0 0.76
Otro_valor-Atenuación -3.8 -10.8 3.1 0.40
Otro_valor-Intensificación -2.1 -8.0 3.7 0.67
15.2.2.3.1 Descripción por grupos
describeBy(x= corpusren$IM, group = corpusren$med2)
Descriptive statistics by group
group: Atenuación
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 61 79 15 83 81 5.9 0 90 90 -3 12 1.9
------------------------------------------------------------
group: Intensificación
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 157 77 13 82 78 8.9 50 143 93 0.21 3.1 1
------------------------------------------------------------
group: Otro_valor
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 58 75 24 76 73 17 48 222 174 3.9 22 3.1
15.2.2.3.2 Diagrama de caja
ggplot(corpusren, aes(x=med2, y=IM, fill = med2)) +
geom_boxplot() + theme_minimal() +
labs(title="Diagrama de caja de la variable
intensidad por género discursivo",
x="Género discursivo", y="Intensidad Media")
15.2.3 Ejercicios
15.2.3.1 Enunciados
- En la base de datos Idiolectal, realizar una prueba ANOVA para la variable tonemeMAS según la variable genre. ¿Hay alguna diferencia significativa entre los grupos?
- En la base de datos Idiolectal, realizar una prueba T.Test para la variable dur según la variable genre. ¿Hay alguna diferencia significativa entre los grupos?
- En la base de datos Idiolectal, realiza un boxplot con los datos anteriores.
15.2.3.2 Soluciones
- En la base de datos Idiolectal, realizar una prueba ANOVA para la variable tonemeMAS según la variable genre. ¿Hay alguna diferencia significativa entre los grupos?
TukeyHSD(aov(tonemeMAS~genre, data= idiolectal))
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = tonemeMAS ~ genre, data = idiolectal)
$genre
diff lwr upr p adj
pod-5p 0.022 -5.8 5.9 0.99
- En la base de datos Idiolectal, realizar una prueba T.Test para la variable dur según la variable genre. ¿Hay alguna diferencia significativa entre los grupos?
t.test(idiolectal$dur~idiolectal$genre)
Welch Two Sample t-test
data: idiolectal$dur by idiolectal$genre
t = -2, df = 1215, p-value = 0.01
alternative hypothesis: true difference in means between group 5p and group pod is not equal to 0
95 percent confidence interval:
-15.6 -1.7
sample estimates:
mean in group 5p mean in group pod
98 107
- En la base de datos Idiolectal, realiza un boxplot con los datos anteriores.
ggplot(idiolectal, aes(x=genre, y=dur, fill = genre)) +
geom_boxplot() + theme_minimal() +
labs(title="Diagrama de caja de la variable duración por género",
x="Género", y="Duración")
15.3 Análisis múltiple de correspondencias
El análisis múltiple de correspondencia (AMC) es una técnica exploratoria utilizada para visualizar la relación entre más de dos variables categóricas, aunque con solo dos variables se denomina análisis de correspondencias. En R, la librería recomendada para realizar AMC es FactoMineR, complementada por FactoInvestigate, que genera informes automáticos con gráficos y tendencias, y FactoShiny, que permite un análisis interactivo. El AMC es útil para identificar coocurrencias entre categorías sin necesidad de una variable independiente y puede complementarse con el análisis de clúster para agrupar elementos derivados del análisis.
15.3.1 Condiciones de la prueba
El análisis múltiple de correspondencias (AMC) requiere que las variables categóricas sean factores en R, y aunque no tiene restricciones severas, el uso de muchas variables y categorías puede dificultar la visualización gráfica con FactoMineR. Para interpretar el papel de cada categoría en las dimensiones generadas, se recomienda usar el proceso dimdesc
, que proporciona datos sobre las tres primeras dimensiones. Es común que las dos primeras dimensiones expliquen solo un 15-20% de la variabilidad, lo cual es aceptable ya que AMC es una herramienta de visualización. Validaciones posteriores, como la chi-cuadrado, determinarán relaciones significativas entre variables.
En palabras de Greenacre (2007:88):
CA is performed with the objective of accounting for a maximum amount of inertia along the first axis. The second axis accounts for a maximum of the remaining inertia, and so on. Thus the total inertia is also decomposed into components along principal axes, i.e., the principal inertias.
Un 20 % o menos de inercia explicada en las dos primeras dimensiones del AMC debe interpretarse como un núcleo de agrupación, indicando que los elementos en estas dimensiones comparten características definidas de variación. Además, FactoMineR permite crear un dendograma del análisis de clúster basado en el AMC, lo que mejora la visualización de los clústeres formados en las primeras dimensiones del análisis.
15.3.2 Ejemplo de AMC
Para el análisis múltiple de correspondencias (AMC) de la base de datos Fonocortesía, podemos utilizar cualquier variable categórica, excluyendo las columnas referenciales o de ejemplo, como Elemento_analizado o Fragmento. En este ejemplo, utilizaremos cuatro variables para evitar sobresaturar el gráfico resultante: Cortes_Descortes, Llama_Atencion, Tonema y Mediodeexpresion.
Primero, se computa el mapa de dimensiones que proyectará las cercanías entre las categorías estudiadas. Hay varios gráficos que se pueden generar, pero inicialmente nos centraremos en dos: el gráfico de relación entre los individuos y el gráfico de relación entre las variantes. El primero se observa en el siguiente gráfico:
library(FactoMineR)
<- MCA(corpusren[c(2,3,4,23)],
mcacortesia graph =FALSE,level.ventil = 0.05)
fviz_mca_biplot(mcacortesia, invisible=c("var"))
En el gráfico anterior, las dos primeras dimensiones, que suelen ser las más importantes para explicar la variación (Greenacre 2007), explican un 35% de la variación en la base de datos. Este porcentaje es significativo dado que las bases de datos lingüísticas suelen contener muchas variables y categorías.
Es crucial entender el concepto de dimensión en este contexto. Una dimensión busca reducir el espacio de variación entre los datos, similar al análisis de componentes principales (PCA), que también reduce la variación en un conjunto de datos. Las dimensiones del AMC crean un espacio virtual donde las proximidades y distancias se traducen en puntuaciones en un gráfico de ejes.
Las categorías y registros reciben puntuaciones en estas coordenadas según su cercanía o lejanía. Para interpretar estas dimensiones, se utiliza el comando dimdesc
, que muestra qué variables y categorías puntúan más alto en cada una de las dos principales dimensiones generadas, permitiendo etiquetar cada dimensión (por ejemplo, dimensión de la cortesía, dimensión de la prosodia).
En los gráficos resultantes, la proximidad entre categorías indica que comparten características comunes. Cada categoría representa un grupo de individuos que comparten características específicas de agrupación.
fviz_mca_biplot(mcacortesia, invisible=c("ind"))
En el gráfico anterior, se observan fenómenos interesantes que una prueba chi cuadrado podrá confirmar o refutar. Inicialmente, vemos que en la primera dimensión, la categoría cortés tiene una puntuación alta, acompañada por la categoría Atenuación, que también tiene una puntuación alta en la segunda dimensión y aún más en la primera. Además, la categoría entonativa suspendido muestra una puntuación alta en la primera dimensión, indicando un grupo de enunciados caracterizados por ser corteses, mayoritariamente con atenuación pragmática y entonación suspendida.
Por otro lado, la categoría descortés se encuentra en el extremo opuesto de la primera dimensión, que podría denominarse “dimensión de cortesía”. Esta categoría se asocia con intensificación y tonema ascendente, formando un grupo caracterizado por enunciados descorteses, intensificados y con entonación ascendente.
Las demás categorías proyectadas en el gráfico se relacionan principalmente con cuestiones entonativas en la segunda dimensión, especialmente con la variable Llama la atención, que indica los fenómenos fónicos que en un momento particular despertaron el interés de los investigadores y condicionaron la catalogación de un enunciado como cortés o descortés.
Para profundizar y observar la importancia de cada categoría en cada una de las tres primeras dimensiones, se puede utilizar el siguiente código:
dimdesc(mcacortesia,axes = c(1:2))
Representación de los eigenvalues. Los eigenvalues son una medida de la importancia de cada dimensión en el análisis. En general, se considera que una dimensión es importante si su eigenvalue es superior a 1. En este caso, las dos primeras dimensiones son las más importantes, con valores de 0.25 y 0.15, respectivamente.
fviz_eig(mcacortesia, )
Gráfico sobre la importancia de las categorías en las primeras dos dimensiones:
fviz_contrib(mcacortesia, choice = "var", axes = 1:2, top = 10)
El resultado del comando dimdesc
confirma muchas de las observaciones previas. Primero, se proporciona la puntuación de las variables en las dimensiones, acompañada de un valor p que indica significatividad. Luego, para cada dimensión, se puntúan también las categorías, igualmente acompañadas de un valor p.
En la primera dimensión, puntúan muy alto los valores previamente mencionados: enunciados corteses y atenuados, con una notable entonación suspendida. En el extremo opuesto, encontramos enunciados descorteses e intensificados, con un acento y entonación prominentes y vinculados a un tonema ascendente. La segunda dimensión, en cambio, destaca factores más fonéticos y un medio de expresión específico, como la atenuación, que se relaciona más con el tonema circunflejo y otros aspectos fónicos (acento, duración, etc.).
15.3.2.1 Análisis de clúster derivado
El análisis múltiple de correspondencias puede completarse con la librería FactoMiner mediante el uso del análisis de clúster que, al mismo tiempo, generará un conjunto de grupos que integran además características identitarias. La exploración de los resultados del análisis múltiple de correspondencias hace suponer que realmente hay dos grandes grupos; para no forzar completamente esta agrupación, hemos optado por indicar la creación de 3 grupos, aunque podríamos haber sugerido la creación de más grupos. Esta última opción no tendría demasiado sentido si tomamos en consideración todo lo visto anteriormente.
<- HCPC(mcacortesia, nb.clust = 3, graph = FALSE)
cluster fviz_cluster(cluster, geom = "point", palette =
c("#00AFBB", "#E7B800", "#FC4E07"), ggtheme = theme_minimal())
Los grupos generados se han coloreado con tres colores distintos. De todos modos, con el siguiente código podemos ver cuántos registros constituyen cada grupo y, además, cuáles son las características de cada uno de ellos.
table(cluster$data.clust$clust)
$desc.var cluster
15.4 Descripción de categorías con FactoMineR
La librería Factominer permite realizar una exploración de los datos relacionada parcialmente con el análisis múltiple de correspondencias . El procedimiento se llama catdes y permite observar en qué medida las variantes de una variable se correlacionan de modo significativo con categorías o medias numéricas de otras variables. De esta manera, las asociaciones generadas se utilizan para explicar cada una de las categorías de la variable de entrada.
Los elementos que hay que conocer para poder entender la prueba son los siguientes:
- Cla/mod. Se trata del porcentaje de casos de la categoría analizada dentro de la variable que aparece en el resultado.
- Mod/Cla. Se trata del porcentaje de casos de la variable del resultado dentro de la variable de entrada.
- Global. Se trata del porcentaje de casos que representa el cruce de categorías sobre el total.
- p.value. Valor de significación estadística.
- V.test. Si es superior a 0 indica que el valor es superior a la media o frecuencia general esperada; si es inferior a 0 indica que el valor es inferior.
Para entender algo mejor conceptos de esta prueba, como v.test, puede acudirse a Le, Josse y Husson (2008).
15.4.1 Desviaciones fónicas y atenuación
<- corpusren%>%select(cort, To, med2)
corpusselect
<- catdes(corpusselect,num.var = 1,proba = 0.01)
catedes catedes
Link between the cluster variable and the categorical variables (chi-square test)
=================================================================================
p.value df
med2 1.6e-16 2
To 8.5e-06 3
Description of each cluster by the categories
=============================================
$cortés
Cla/Mod Mod/Cla Global p.value v.test
med2=Atenuación 92 43 22 2.2e-16 8.2
To=suspendido 69 35 24 6.9e-05 4.0
To=ascendente 27 18 30 8.8e-06 -4.4
med2=Intensificación 28 34 57 6.4e-14 -7.5
$descortés
Cla/Mod Mod/Cla Global p.value v.test
med2=Intensificación 72.0 77.9 57 6.4e-14 7.5
To=ascendente 72.6 42.1 30 8.8e-06 4.4
To=suspendido 31.3 14.5 24 6.9e-05 -4.0
med2=Atenuación 8.2 3.4 22 2.2e-16 -8.2
plot.catdes(catedes, show= "quali", cex.names = 1.2,
col.upper = "blue",col.lower = "red")
En el anterior gráfico, el color azul señala los casos de sobrepoblación, mientras que el color rojo indica casos de categorías poco pobladas. No es, por tanto, un mapa de calor convencional, ya que en este gráfico solo se representan las categorías o valores que han resultado ser significativamente distintos.
15.4.2 Ejercicios
15.4.2.1 Enunciados
- En la base de datos Idiolectal, realiza una descripción de categorías para la variable genre en función de las variables tonemes, spk, spk2, MAStag y circunflejo.
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos.
- En la base de datos Idiolectal, realiza un análisis múltiple de correspondencias con las variables genre, tonemes, spk, spk2, MAStag y circunflejo.
- En la base de datos Idiolectal, realiza un análisis de clúster con los resultados obtenidos.
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos en el análisis múltiple de correspondencias.
15.4.2.2 Soluciones
- En la base de datos Idiolectal, realiza una descripción de categorías para la variable genre en función de las variables tonemes, spk, spk2, MAStag y circunflejo.
<- idiolectal%>%select(genre,tonemes,spk,spk2,MAStag,circunflejo)
idiolectalselect
<- catdes(idiolectalselect,num.var = 1,proba = 0.01)
catedes2
catedes2
Link between the cluster variable and the categorical variables (chi-square test)
=================================================================================
p.value df
spk2 1.6e-256 9
spk 4.6e-15 4
Description of each cluster by the categories
=============================================
$`5p`
Cla/Mod Mod/Cla Global p.value v.test
spk2=5ppzorro 100 46.6 23.3 3.4e-105 21.8
spk2=5pangelreal 100 16.9 8.5 8.8e-34 12.1
spk2=5prcastellano 100 15.9 8.0 9.9e-32 11.7
spk2=5pestepa 100 13.6 6.8 5.2e-27 10.8
spk2=5pdufort 100 6.9 3.4 1.1e-13 7.4
spk=angelreal 71 16.9 12.0 9.3e-08 5.3
spk=rcastellano 63 15.9 12.6 5.6e-04 3.5
spk=dufort 26 6.9 13.3 2.5e-11 -6.7
spk2=podangelreal 0 0.0 3.5 5.3e-14 -7.5
spk2=podrcastellano 0 0.0 4.7 1.8e-18 -8.8
spk2=podestepa 0 0.0 7.1 5.1e-28 -11.0
spk2=poddufort 0 0.0 9.9 1.1e-39 -13.2
spk2=podpzorro 0 0.0 24.9 4.7e-114 -22.7
$pod
Cla/Mod Mod/Cla Global p.value v.test
spk2=podpzorro 100 49.8 24.9 4.7e-114 22.7
spk2=poddufort 100 19.7 9.9 1.1e-39 13.2
spk2=podestepa 100 14.1 7.1 5.1e-28 11.0
spk2=podrcastellano 100 9.4 4.7 1.8e-18 8.8
spk2=podangelreal 100 7.1 3.5 5.3e-14 7.5
spk=dufort 74 19.7 13.3 2.5e-11 6.7
spk=rcastellano 37 9.4 12.6 5.6e-04 -3.5
spk=angelreal 29 7.1 12.0 9.3e-08 -5.3
spk2=5pdufort 0 0.0 3.4 1.1e-13 -7.4
spk2=5pestepa 0 0.0 6.8 5.2e-27 -10.8
spk2=5prcastellano 0 0.0 8.0 9.9e-32 -11.7
spk2=5pangelreal 0 0.0 8.5 8.8e-34 -12.1
spk2=5ppzorro 0 0.0 23.3 3.4e-105 -21.8
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos.
plot.catdes(catedes2, show= "quali", cex.names = 1.2,
col.upper = "blue",col.lower = "red")
- En la base de datos Idiolectal, realiza una análisis múltiple de correspondencias con las variables genre, tonemes, spk, spk2, MAStag y circunflejo.
library(FactoMineR)
library(factoextra)
<- idiolectal%>%select(genre,tonemes,spk,spk2,MAStag,circunflejo)
idiolectalselect2
<- MCA(idiolectalselect2,
mcaidiolectal graph =FALSE,level.ventil = 0.05)
fviz_mca_biplot(mcaidiolectal, invisible=c("var"))
- En la base de datos Idiolectal, realiza un análisis de clúster con los resultados obtenidos.
<- HCPC(mcaidiolectal, nb.clust = 3, graph = FALSE)
clusteridiolectal
fviz_cluster(clusteridiolectal, geom = "point", palette =
c("#00AFBB", "#E7B800", "#FC4E07"), ggtheme = theme_minimal())
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos en el análisis múltiple de correspondencias.
fviz_contrib(mcaidiolectal, choice = "var", axes = 1:2, top = 10)
fviz_mca_biplot(mcaidiolectal, invisible=c("ind"))
15.5 Árbol de decisiones y Random Forest
El árbol de decisiones es una técnica de visualización y reducción de variabilidad ampliamente utilizada para clasificar las categorías de una variable independiente utilizando un conjunto de variables explicativas, que pueden ser cuantitativas o nominales. La técnica Random Forest, derivada del árbol de decisiones, simula datos generando múltiples árboles para mejorar la clasificación. Un procedimiento común en estudios estadísticos es dividir la base de datos en dos partes para calcular la clasificación en una parte y validarla en la otra. Sin embargo, con bases de datos pequeñas, se puede usar toda la base para identificar reglas de clasificación y las variables más relevantes. Estas técnicas son robustas y dependen de cómo se configura la base de datos, evitando variables redundantes que puedan solapar información. Por ejemplo, variables como duración y número de sílabas pueden ser redundantes en el árbol de decisiones. Las clasificaciones no serán perfectas, siempre habrá variabilidad. Los árboles de decisiones, como el análisis de clúster, proponen secuencias de clasificación según la influencia de varias variables, pero existirán intersecciones entre categorías. Ejemplos detallados se presentarán en las secciones siguientes.
15.5.1 Condiciones de la prueba
Tanto el árbol de decisiones como RandomForest solo necesitan una variable independiente, numérica o nominal, y un conjunto de variables independientes, numéricas o nominales. Las variables nominales deben ser variables de factor. Hay que intentar que las variables numéricas no incluyan valores vacíos, comúnmente llamados NA en R.
15.5.2 Árbol con variable independiente numérica
En Levinson y Torreira (2015) se aplican tanto la técnica del árbol de decisiones como la de Random Forest para caracterizar los valores temporales de FTO (Floor Transfer Offset), una variable independiente numérica que mide el intervalo temporal entre la finalización de un enunciado por un hablante y el comienzo de otro enunciado por otro interlocutor. En su caracterización, se consideran tanto valores fónicos (descenso tonal, duración del grupo entonativo) como categóricos (acto de habla).
Tomando como referencia este ejemplo, analizaremos en esta sección la variable FM0, que mide la media de tono en un enunciado. Aquí, la variable independiente es numérica, por lo que se trata de un árbol de decisiones clásico.
Primero, utilizaremos solo los casos de la variable independiente que no tengan valores perdidos o iguales a 0. Los árboles de decisiones no permiten valores ausentes y no es conveniente incluir valores iguales a 0, ya que estos indican la imposibilidad de registrar valores tonales para ese enunciado, lo que impide calcular el rango tonal. Utilizaremos la librería partykit
, que ofrece configuraciones útiles para la representación gráfica, evitando solapamientos en las categorías.
Aquí está el código en R para realizar el análisis:
<- corpusren%>%filter(F0M>0)
corpusarbol sapply(corpusarbol, is.character)] <-
corpusarbol[lapply(corpusarbol[sapply(corpusarbol, is.character)],as.factor)
library(partykit)
A continuación, realizamos el primer árbol de decisiones y lo convertimos en gráfico. Si se desea, puede accederse a los datos numéricos y a las clasificaciones que la librería produce. Para ello, únicamente hay que almacenar el cómputo del árbol de decisiones en una variables y, posteriormente, invocarlo desde el terminal. Por ejemplo, en nuestro caso práctico vamos a almacenar el análisis en una variable/objeto que se llama corpustree y que podemos introducir directamente en el terminal.
Posteriormente, podemos usar la función plot para convertir el árbol de decisiones en un gráfico interpretable. En esta comando, se adjunta una especificación ep_args = list(justmin = 15) que se utiliza para que si hay nodos con muchas categorías no se solapen unas con otras.
library(dplyr)
<- partykit::ctree(F0M~cort+IM+To+med2+Vmod,
corpustree data= corpusarbol, control = ctree_control(maxdepth = 3))
plot(corpustree, ep_args = list(justmin = 15),
gp = gpar(fontsize = 8))
15.5.3 Árbol con variable independiente categórica
En análisis que combinan fonética y pragmática, es común utilizar una variable independiente compuesta por grupos predefinidos. En investigaciones sobre género discursivo y atenuación, se pueden utilizar variables categóricas como el género discursivo, la combinatoria fónica, la atenuación pragmática y el hablante como variables independientes. En esta sección, ejemplificaremos la clasificación basada en el género discursivo y la atenuación pragmática.
Primero, filtraremos la base de datos para eliminar casos desviados fónicamente que no indiquen atenuación pragmática. Estos casos pueden estar marcados como “sí” (transmiten atenuación pragmática) o “no” (no transmiten atenuación pragmática). Luego, ejecutaremos el gráfico del árbol de decisiones correspondiente.
Aquí está el código en R para realizar el análisis:
library(dplyr)
<- partykit::ctree(cort~F0M+IM+To+med2+Vmod,
corpustree data= corpusarbol, control = ctree_control(maxdepth = 3))
plot(corpustree, ep_args = list(justmin = 15),
gp = gpar(fontsize = 8))
El nodo inicial se basa en el medio de expresión (med2); cuando el enunciado presenta atenuación, se clasifica como cortés.
Si se utiliza intensificación u otros valores, se analiza el tonema (To).
Un tonema ascendente y circunflejo se clasifica aún más como descortés si la media de F0 es alta.
Un tonema descendente y suspendido se clasifica tanto como cortés como descortés.
15.5.4 Random Forest
La técnica de Random Forest genera múltiples árboles de decisiones para determinar con qué variables se clasifican mejor los datos de una variable independiente, ya sea numérica o categórica. Esta técnica ayuda a reducir las variables explicativas para optimizar la explicación de la variable de entrada.
Para ejemplificar el uso de Random Forest, utilizaremos la base de datos Fonocortesía, tomando como variable independiente la variable Cortes_Descortes. Utilizaremos todas las variables explicativas que no tengan más de 20 niveles y las variables numéricas más relevantes. Podemos usar el comando str
para conocer la tipología de las variables y la cantidad de factores.
Aquí está el código en R para realizar un análisis con Random Forest:
$cort <- gsub("cortés","cor",corpusren$cort)
corpusren$cort <- gsub("descor","des",corpusren$cort)
corpusren$cort <- as.factor(corpusren$cort)
corpusren<- randomForest(cort~Llam+med+
cortesia_cforest+IM+Sil+dur+DPA+DPP+CP+Cur+ILI+To+Vmod, data=corpusren%>%
F0Mmutate_if(is.character,as.factor), na.action = na.roughfix)
print(cortesia_cforest)
Call:
randomForest(formula = cort ~ Llam + med + F0M + IM + Sil + dur + DPA + DPP + CP + Cur + ILI + To + Vmod, data = corpusren %>% mutate_if(is.character, as.factor), na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 3
OOB estimate of error rate: 18%
Confusion matrix:
cor des class.error
cor 101 30 0.23
des 20 125 0.14
Inicialmente y sin más información, RandomForest genera un grupo de 500 árboles simulados, en los que cambia cada vez un dato de algunas de las variables empleadas. Porsteriormente, en el resultado principal de la prueba, observamos un porcentaje de clasificación adecuada de los grupos de la variable independiente. En general, hay un porcentaje de error del 19 %; los casos descorteses se clasifican bien en un 85 % (20 casos se han incluido como corteses), mientras que los de cortesía se clasifican algo peor, con un 76 % (32 casos se han considerado descorteses). Por tanto, la clasificación es en cierto modo interesante.
Podemos acceder a la contribución de cada variable en el proceso de clasificación. Se utiliza en este caso el código importance:
importance(cortesia_cforest)
MeanDecreaseGini
Llam 12.4
med 30.6
F0M 16.2
IM 13.2
Sil 8.3
dur 9.3
DPA 5.3
DPP 5.6
CP 5.9
Cur 7.7
ILI 5.4
To 6.5
Vmod 10.1
Además, RandomForest permite visualizar las contribuciones de las variables en forma de gráfico, como el que se incluye a continuación:
varImpPlot(cortesia_cforest)
En el gráfico anterior, se observa que hay una variable mucho más importante que el resto; se trata de med, que es el medio de expresión de la cortesía o descortesía. En general, como hemos visto en secciones anteriores, se trata generalmente de valores como atenuación o intensificación. Después, las otras cuatros variables que puntúan de manera alta serían la F0 y la intensidad medias, la variable llama la atención y la variable Valor modal.
RandomForest es complejo de interpretar en muchas ocasiones porque no produce un gráfico de clasificación como sucede con la prueba del árbol de decisiones tradicional. No obstante, podemos acceder a los valores de la base de datos con la predicción sugerido por el análisis de la prueba. En los siguientes ejemplos, vemos una muestra de los primeros ocho casos de la base de datos y la predicción que se ha generado basada en el resultado de la prueba:
head(cortesia_cforest$predicted, n= 8)
1 2 3 4 5 6 7 8
des cor des des des des cor des
Levels: cor des
Podemos acceder a la puntuación que ha recibido cada uno de esos registros. De esta manera, podemos comparar las predicciones realizadas con el valor real.
head(margin(cortesia_cforest), n=8)
des des des des des cor cor des
0.53 -0.66 0.56 0.85 0.82 -0.48 0.81 0.84
Podemos observar que los registros que no se han clasificado bien porque han puntuado de manera negativa han sido el 2 y el 6. El resto se ha clasificaco adecuadamente, aunque con porcentajes de seguridad medio altos.
15.5.5 Ejercicios
15.5.5.1 Enunciados
- En la base de datos Idiolectal, realiza un análisis de Random Forest con la variable genre como variable independiente y las variables tonemes, tonemeMAS, dur, spk, spk2, MAStag y circunflejo como variables explicativas.
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos.
- En la base de datos Idiolectal, realiza un árbol de decisiones con la variable genre como variable independiente y las variables tonemes, tonemeMAS, dur, spk, MAStag y circunflejo como variables explicativas. Excluye a “pzorro” de la variable spk.
- Si eliminamos genre y lo cambiamos por spk2, ¿cómo cambian los resultados?
- En la base de datos Idiolectal, realiza un árbol de decisiones con la variable spk2 como variable independiente y las variables tonemes, tonemeMAS, dur, MAStag y circunflejo como variables explicativas.
15.5.5.2 Soluciones
- En la base de datos Idiolectal, realiza un análisis de Random Forest con la variable genre como variable independiente y las variables tonemes, tonemeMAS, dur, spk, spk2, MAStag y circunflejo como variables explicativas.
library(randomForest)
<- idiolectal%>%select(genre,tonemes,
idiolectal %>%
tonemeMAS,dur,spk,spk2,MAStag,circunflejo)mutate_if(is.character,as.factor)
<-
idiolectal_cforestrandomForest(genre~tonemes+tonemeMAS+dur+spk+spk2+MAStag+circunflejo,
data=idiolectal, na.action = na.roughfix)
print(idiolectal_cforest)
Call:
randomForest(formula = genre ~ tonemes + tonemeMAS + dur + spk + spk2 + MAStag + circunflejo, data = idiolectal, na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 0%
Confusion matrix:
5p pod class.error
5p 609 0 0
pod 0 609 0
- En la base de datos Idiolectal, realiza un gráfico con los resultados obtenidos.
varImpPlot(idiolectal_cforest)
- Realiza un árbol de decisiones con la variable genre como variable independiente y las variables tonemes, tonemeMAS, dur, spk, MAStag y circunflejo como variables explicativas. Excluye a “pzorro” de la variable spk.
library(partykit)
<- partykit::ctree(genre~tonemes+
idiolectal_tree+dur+spk+MAStag+circunflejo,
tonemeMASdata= idiolectal%>%filter(spk!="pzorro")%>%select(genre,tonemes,tonemeMAS,dur,spk,MAStag,circunflejo)%>%mutate_if(is.character,as.factor), control = ctree_control(maxdepth = 3))
plot(idiolectal_tree, ep_args = list(justmin = 15))
- Si eliminamos genre y lo cambiamos por spk2, ¿cómo cambian los resultados?
<-
idiolectal_cforest2randomForest(spk2~tonemes+tonemeMAS+dur+MAStag+circunflejo,
data=idiolectal, na.action = na.roughfix)
print(idiolectal_cforest2)
Call:
randomForest(formula = spk2 ~ tonemes + tonemeMAS + dur + MAStag + circunflejo, data = idiolectal, na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 74%
Confusion matrix:
5pangelreal 5pdufort 5pestepa 5ppzorro 5prcastellano
5pangelreal 0 0 1 50 1
5pdufort 0 0 2 25 0
5pestepa 1 0 2 34 0
5ppzorro 1 1 7 105 3
5prcastellano 0 0 0 40 12
podangelreal 0 0 1 16 0
poddufort 0 0 2 55 2
podestepa 0 0 3 31 2
podpzorro 0 2 6 107 4
podrcastellano 0 0 0 20 0
podangelreal poddufort podestepa podpzorro podrcastellano
5pangelreal 1 2 1 47 0
5pdufort 0 1 2 12 0
5pestepa 0 5 4 37 0
5ppzorro 2 10 4 151 0
5prcastellano 1 2 3 39 0
podangelreal 2 1 0 23 0
poddufort 1 9 2 49 0
podestepa 2 4 4 40 0
podpzorro 1 1 4 178 0
podrcastellano 0 1 0 36 0
class.error
5pangelreal 1.00
5pdufort 1.00
5pestepa 0.98
5ppzorro 0.63
5prcastellano 0.88
podangelreal 0.95
poddufort 0.93
podestepa 0.95
podpzorro 0.41
podrcastellano 1.00
- Realiza un árbol de decisiones con la variable spk2 como variable independiente y las variables tonemes, tonemeMAS, dur, MAStag y circunflejo como variables explicativas.
<- partykit::ctree(spk2~tonemes+tonemeMAS+dur+
idiolectal_tree2+circunflejo,
MAStagdata= idiolectal, control = ctree_control(maxdepth = 3))
plot(idiolectal_tree2, ep_args = list(justmin = 15),
gp = gpar(fontsize = 8))
16 Ejercicios finales sobre el curso (usando la base de datos Idiolectal)
16.1 Enunciados
- Renombra la variable ip y llámala intonational_phrase.
- Crea una variable llamada id2 en la que se recoja el número de fila para cada grupo de la variable filename.
- Crea un dataframe llamado idiolectal_pod que recoja solo las variables spk, phon, tonemes, words de la categoría “pod” en genre. Este dataframe no debe tener valores vacíos en ninguna variable.
- Crea un diagrama de caja con la variable dur según las categorías de la variable genre.
- Construye un gráfico de líneas para el filename “poddufort” en el que tmin sea la línea de tiempo, tonemeMAS sea el eje de las ordenadas y spk sea el color de las líneas.
- Haz un mapa de calor de los hablantes en el genre “pod” con todas las variables numéricas que no sean tmin o tmax.
- Realiza un análisis de correspondencias múltiples con las variables tonemes, spk2,phon, MAStag y circunflejo. Visualiza un mapa con las categorías más relacionadas.
- Computa una variable que recoja la velocidad de habla. Recomendación: fíjate en la variable dur y en la variable words.
- Realiza un Wordcloud con la variable word, pero usa solo las 50 palabras más frecuentes.
- Transforma la variable genre en una variable de factor y realiza un análisis randomForest con las variables tonemes, tonemeMAS, dur, spk, MAStag y circunflejo (las variables de carácter también debes transformarlas a factor). La variable independiente será genre.
16.2 Soluciones
- Renombra la variable ip y llámala intonational_phrase.
library(tidyverse)
library(readxl)
<- read_xlsx("databases/idiolectal.xlsx",sheet = 1)
idiolectal <- idiolectal%>%dplyr::rename(intonational_phrase = ip) idiolectal
- Crea una variable llamada id2 en la que se recoja el número de fila para cada grupo de la variable filename.
<- idiolectal%>%group_by(filename)%>%
idiolectal mutate(id2 = row_number())
- Crea un dataframe llamado idiolectal_pod que recoja solo las variables spk, phon, tonemes, words de la categoría “pod” en genre. Este dataframe no debe tener valores vacíos en ninguna variable.
<- idiolectal%>%filter(genre == "pod")%>%
idiolectal_pod select(spk,phon,tonemes,words)%>%
na.omit()
- Crea un diagrama de caja con la variable dur según las categorías de la variable genre.
library(ggplot2)
ggplot(idiolectal, aes(x = genre, y = dur)) +
geom_boxplot()
- Construye un gráfico de líneas para el filename “poddufort” en el que tmin sea la línea de tiempo, tonemeMAS sea el eje de las ordenadas y spk sea el color de las líneas.
%>%filter(filename == "poddufort")%>%
idiolectalggplot(aes(x = tmin, y = tonemeMAS, color = spk)) +
geom_line()
- Haz un mapa de calor de los hablantes en el genre “pod” con todas las variables numéricas que no sean tmin o tmax.
library(gplots)
<- idiolectal%>%filter(genre == "pod")%>%
idiolectal_pod2 select(-tmin,-tmax)%>%na.omit()%>%
group_by(spk)%>%
summarise_all(mean,na.rm=T)%>%column_to_rownames(var="spk")%>%
select(ip_dur,dur,words,dur_first,dur_preanac,tonemeMAS,body)
heatmap.2(as.matrix(idiolectal_pod2), scale = "column",
cexRow = 0.8, cexCol = 0.8)
- Realiza un análisis de correspondencias múltiples con las variables tonemes, spk2,phon, MAStag y circunflejo. Visualiza un mapa con las categorías más relacionadas.
library(FactoMineR)
library(factoextra)
<- MCA(idiolectal%>%select(tonemes,spk2,
idiolectal_mca
phon,MAStag,circunflejo), graph =FALSE,level.ventil = 0.05)
fviz_mca_biplot(idiolectal_mca, invisible=c("ind"))
- Computa una variable que recoja la velocidad de habla. Recomendación: fíjate en la variable dur y en la variable words.
<- idiolectal%>%mutate(velocidad = words/dur) idiolectal
- Realiza un Wordcloud con la variable word, pero usa solo las 50 palabras más frecuentes.
library(ggwordcloud)
library(dplyr)
%>%count(word)%>%top_n(50)%>%
idiolectalggplot(aes(label = word, size = n)) +
geom_text_wordcloud()
- Transforma la variable genre en una variable de factor y realiza un análisis randomForest con las variables tonemes, tonemeMAS, dur, spk, MAStag y circunflejo (las variables de carácter también debes transformarlas a factor). La variable independiente será genre.
<- idiolectal%>%
idiolectal2 mutate(genre = as.factor(genre),tonemes = as.factor(tonemes),
spk = as.factor(spk),MAStag = as.factor(MAStag),
circunflejo = as.factor(circunflejo))
<-
idiolectal_cforest3randomForest(genre~tonemes+tonemeMAS+dur+spk+MAStag+circunflejo,
data=idiolectal2, na.action = na.roughfix)
print(idiolectal_cforest3)
Call:
randomForest(formula = genre ~ tonemes + tonemeMAS + dur + spk + MAStag + circunflejo, data = idiolectal2, na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 42%
Confusion matrix:
5p pod class.error
5p 338 271 0.44
pod 244 365 0.40
- Realiza un análisis de clúster con las variables genre, tonemes, spk2, MAStag y circunflejo.
library(FactoMineR)
library(factoextra)
<- MCA(idiolectal%>%select(genre,tonemes,spk2,
idiolectal_mca
MAStag,circunflejo), graph =FALSE,level.ventil = 0.05)
<- HCPC(idiolectal_mca, nb.clust = 3, graph = FALSE)
idiolectal_cluster
fviz_cluster(idiolectal_cluster, geom = "point", palette =
c("#00AFBB", "#E7B800", "#FC4E07"),
ggtheme = theme_minimal())
- Haz un árbol de decisiones con la variable spk como variable independiente y las variables tonemes, tonemeMAS, dur, MAStag y circunflejo como variables explicativas. Debes filtrar previamente la categoría “pzorro” de la variable spk.
library(stringr)
<- idiolectal%>%filter(spk != "pzorro")
idiolectal3
<- partykit::ctree(spk~tonemes+tonemeMAS+dur
idiolectal_tree3+MAStag+circunflejo,
data= idiolectal3%>%mutate(spk = str_trunc(spk, 4,ellipsis = ""))%>%
mutate_if(is.character,as.factor),
control = ctree_control(maxdepth = 3))
plot(idiolectal_tree3)
- Haz un árbol de decisiones con la variable dur como variable independiente y las variables tonemes, tonemeMAS, genre,spk, MAStag y circunflejo como variables explicativas.
<- partykit::ctree(dur~tonemeMAS+tonemes
idiolectal_tree4 +genre+spk+circunflejo,
data= idiolectal%>%mutate_if(is.character,as.factor),
control = ctree_control(maxdepth = 3))
plot(idiolectal_tree4)
- Haz una prueba ANOVA para la variable spk como independiente y la variable dur como dependiente.
<- TukeyHSD(aov(dur~spk, data = idiolectal%>%
Tuk mutate(spk = as.factor(spk))))
Tuk
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = dur ~ spk, data = idiolectal %>% mutate(spk = as.factor(spk)))
$spk
diff lwr upr p adj
pzorro-angelreal 6.1 -9.32 21.5 0.82
rcastellano-angelreal -6.7 -25.95 12.6 0.88
dufort-angelreal 12.5 -6.58 31.5 0.38
estepa-angelreal 36.1 17.28 55.0 0.00
rcastellano-pzorro -12.8 -27.88 2.3 0.14
dufort-pzorro 6.4 -8.46 21.2 0.77
estepa-pzorro 30.0 15.47 44.6 0.00
dufort-rcastellano 19.1 0.35 37.9 0.04
estepa-rcastellano 42.8 24.22 61.4 0.00
estepa-dufort 23.7 5.33 42.0 0.00
- Realiza una prueba chi cuadrado (bondad de ajuste) con la hipótesis de igualdad de proporciones en la variable tonemes.
<- table(idiolectal%>%select(tonemes))
table <- chisq.test(table, p = c(1/4,1/4,1/4,1/4))
bondad $residuals bondad
tonemes
filename enfático enunciativo interrogativo suspendido
5pangelreal -0.537 1.209 -0.416 -0.829
5pcastellano 0.850 0.500 -0.103 -1.127
5pdufort 1.004 -0.305 -1.118 -0.126
5pestepa -0.222 0.051 -1.221 0.391
podangelreal -0.896 -0.078 -1.196 1.007
poddufort -0.270 0.151 2.838 -0.638
podestepa 1.885 -0.835 -1.262 -0.148
poscastellano -1.958 -0.736 2.747 1.553
- Realiza una prueba chi cuadrado que observe a relación entre spk y tonemes. Analiza los residuos estandarizados en un mosaicplot.
<- table(idiolectal$spk,idiolectal$tonemes)
table2
<- chisq.test(table2)
bondad2
$residuals bondad2
enfático enunciativo interrogativo suspendido
angelreal -1.731 1.330 -0.138 -0.170
dufort 0.426 0.696 1.163 -1.333
estepa 0.764 0.298 -1.454 -0.528
pzorro 0.035 -1.310 0.323 1.320
rcastellano 0.139 0.290 0.076 -0.431
mosaicplot(table2, shade = TRUE)
- Realiza una prueba de correlación de Pearson entre las variables tonemesMAS, dur_first,dur_preanac,body y dur y visualízalo en un gráfico.
<- cor(idiolectal%>%select(tonemeMAS,dur_first,
correlacion %>%na.omit(), method = "pearson")
dur_preanac,body,dur)
library(corrplot)
corrplot(correlacion,addCoef.col = 'black',cl.pos = "n",
tl.pos = 'd', col = COL2('PiYG'),tl.cex = 0.8)
17 Referencias
17.1 Librerías utilizadas
- library(tidyverse)
- library(readxl)
- library(gridExtra)
- library(tidyverse)
- library(corrplot)
- library(FactoMineR)
- library(factoextra)
- library(partykit)
- library(randomForest)
- library(gplots)
- library(ggwordcloud)
17.2 Bibliografía
François Husson, canal de Youtube: https://www.youtube.com/channel/UCyz4M1pwJBNfjMFaUCHCNUQ
Breiman, L., Cutler, A., Liaw, A., & Wiener, M. (2022). randomForest: Breiman and Cutler’s Random Forests for Classification and Regression. https://www.stat.berkeley.edu/~breiman/RandomForests/
Cui, B. (2024). DataExplorer: Automate Data Exploration and Treatment. http://boxuancui.github.io/DataExplorer/
Gohel, D., & Skintzos, P. (2024). flextable: Functions for Tabular Reporting. https://ardata-fr.github.io/flextable-book/
Greenacre, M.J.. (2007). Correspondence analysis in practice. Chapman & Hall/CRC.
Greenacre, M.J. and Blasius, J. (2006). Multiple correspondence analysis and related methods. Chapman & Hall/CRC.
Hothorn, T., Hornik, K., & Zeileis, A. (2006). Unbiased Recursive Partitioning: A Conditional Inference Framework. Journal of Computational and Graphical Statistics, 15(3), 651-674. https://doi.org/10.1198/106186006X133933
Hothorn, T., & Zeileis, A. (2015). partykit: A Modular Toolkit for Recursive Partytioning in R. Journal of Machine Learning Research, 16, 3905-3909.
Hothorn, T., & Zeileis, A. (2023). partykit: A Toolkit for Recursive Partytioning. http://partykit.r-forge.r-project.org/partykit/
Husson, F., Josse, J., Le, S., & Mazet, J. (2024). FactoMineR: Multivariate Exploratory Data Analysis and Data Mining. http://factominer.free.fr
Husson F., Lê S., Pagès J. (2017). Exploratory Multivariate Analysis by Example Using R. 2nd edition. Chapman & Hall/CRC.
Kassambara, A., & Mundt, F. (2020). factoextra: Extract and Visualize the Results of Multivariate Data Analyses. http://www.sthda.com/english/rpkgs/factoextra
Lê, S., Josse, J., & Husson, F. (2008). FactoMineR: A Package for Multivariate Analysis. Journal of Statistical Software, 25(1), 1-18. https://doi.org/10.18637/jss.v025.i01
Levinson, S.C., Torreira, F., 2015. Timing in turn-taking and its implications for processing models of language. Front. Psychol. 6. https://doi.org/10.3389/fpsyg.2015.00731
Levshina, N., 2015. How to do Linguistics with R: Data exploration and statistical analysis. John Benjamins Publishing Company, Amsterdam / Philadelphia.
Liaw, A., & Wiener, M. (2002). Classification and Regression by randomForest. R News, 2(3), 18-22.
Pennec, E. L., & Slowikowski, K. (2023). ggwordcloud: A Word Cloud Geom for ggplot2. https://github.com/lepennec/ggwordcloud
R Core Team (2024). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. https://www.R-project.org/.
Revelle, W. (2024). psych: Procedures for Psychological, Psychometric, and Personality Research. https://personality-project.org/r/psych/ https://personality-project.org/r/psych-manual.pdf
Warnes, G. R., Bolker, B., Bonebakker, L., Gentleman, R., Huber, W., Liaw, A., Lumley, T., Maechler, M., Magnusson, A., Moeller, S., Schwartz, M., & Venables, B. (2024). gplots: Various R Programming Tools for Plotting Data. https://github.com/talgalili/gplots
Wei, T., & Simko, V. (2021a). corrplot: Visualization of a Correlation Matrix. https://github.com/taiyun/corrplot
Wei, T., & Simko, V. (2021b). R package «corrplot»: Visualization of a Correlation Matrix. https://github.com/taiyun/corrplot
Wickham, H. (2023). tidyverse: Easily Install and Load the Tidyverse. https://tidyverse.tidyverse.org
Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L. D., François, R., Grolemund, G., Hayes, A., Henry, L., Hester, J., Kuhn, M., Pedersen, T. L., Miller, E., Bache, S. M., Müller, K., Ooms, J., Robinson, D., Seidel, D. P., Spinu, V., … Yutani, H. (2019). Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686
Wickham, H., & Bryan, J. (2023). readxl: Read Excel Files. https://readxl.tidyverse.org
Zeileis, A., Hothorn, T., & Hornik, K. (2008). Model-Based Recursive Partitioning. Journal of Computational and Graphical Statistics, 17(2), 492-514. https://doi.org/10.1198/106186008X319331
Zhu, H. (2024). kableExtra: Construct Complex Table with kable and Pipe Syntax. http://haozhu233.github.io/kableExtra/