6 Comparar léxicos

6.1 Introducción

En los capítulos anteriores has visto el corpus de los mensajes navideños en su conjunto. Ahora vas a realizar un análisis comparativo. Vas a comparar el léxico de los discursos de ambos reyes. Pero antes, debes regenerar todos los objetos que necesitas, es decir, cargar los textos y dividirlos en palabras. Si, como se te recomendaba en el capítulo anterior, guardarte en codigo el script que fuiste creando, es el momento de volver a cargarlo y ejecutarlo. Pero si lo prefieres, corta y pega todo el código que hay a continuación y ejecútalo.

Sabes que entre 1975 y 2013 reinó Juan Carlos I y que desde 2014 lo hace Felipe VI. Podrías usar estos datos para agrupar la información, pero también puedes crear una nueva variable con el nombre del rey y así manejar tan solo dos variables categóricas: Juan Carlos I y Felipe VI, en vez de las length(list.files("datos/mensajes")) que supone cada año y agruparlas por rey. Copia estas líneas de código en el editor de RStudio:

Con la función mutate() se creará la columna rey duplicando la columna anno, después cambiará los años (1975-2018) por los nombres de los reyes, con lo que ahora mensajes_vaciado tiene cuatro variables. Échale una ojeada a la pestaña Environment.

En las dos líneas siguientes lo que haces es reemplazar con la función str_replace() el contenido de las celdas de la nueva columna rey. Esta función requiere saber qué columna es la que se ha de reemplazar, qué es lo que ha de buscar y qué lo sustituirá. Lo que ha de buscar lo haremos por medio de una regla de expresión regular. Hay que buscar secuencias de cuatro dígitos. Puede ser sencillo, con \\d+ se buscaría cualquier secuencia de uno o más dígitos, pero sería errónea ya que serviría para cualquiera en el rango 1975-2018, y Juan Carlos I solo ha leído los mensajes de Navidad hasta 2013, por lo que hay que diseñar otra regla un poco más complicada para que los años 2014-2018 los sustituya por Felipe VI.

Podrías crear una primera regla para abarcar todo el siglo XX: 19\\d+, es decir, busca cualquier secuencia de números que empiece por 19 y que le sigan otros números, los que sean. Abarcaría 1900 a 1999, lo cual es perfecto ya que el margen 1975-1999 es correcto. Ahora queda el período 2000-2013. Una posibilidad es considerar primero el rango 2000-2009 que se podría expresar con 200\\d, es decir, busca cualquier secuencia de números que comience con 200 y que le siga cualquier otro número. Aún queda un tercer período: 2010-2013; para este caso necesitarías la regla 201[0123], la cual quiere decir: busca cualquier secuencia que tenga 201 y que le siga cualquiera de los cuatro números que hay entre los corchetes. De esta manera necesitas tres pasos para un único rey. Sin embargo, si consideras primero el reinado de Felipe VI, 2014-2018, puedes crear una primera regla 201[45678] que sirve para sustituir cualquiera de esos años por su nombre. Una vez hecho eso, ya puedes convertir todos los años del rey Juan Carlos I con la más simple de las fórmulas: \\d+, [0-9]+, \\d{4} o [0-9]{4}.

En esta ocasión has usado la función str_replace() que procede de la librería stringr, uno de los componentes de tidyverse, pero también podrías haber usado la función gsub() que ya has visto en otra ocasión (cf. Leer los mensajes en el capítulo Avance en el análisis textual).

Ya has añadido la columna con los reyes, con lo que ahora podrás comparar el uso léxico en cada uno de los reinados. Vas a extraer las diez palabras más comunes de cada uno de los dos reyes. Toda la información la tienes en mensajes_vaciado, tan solo tienes que agrupar los mensajes por rey, contar las palabras y extraer las diez más frecuentes. Lo puedes conseguir con

Cuando ejecutes la orden anterior aparecerá en la consola

## # A tibble: 20 x 3
## # Groups:   rey [2]
##    rey           palabra         n
##    <chr>         <chr>       <int>
##  1 Juan Carlos I españa        280
##  2 Juan Carlos I españoles     186
##  3 Juan Carlos I año           147
##  4 Juan Carlos I paz           136
##  5 Juan Carlos I sociedad      125
##  6 Juan Carlos I debemos       112
##  7 Juan Carlos I futuro        109
##  8 Juan Carlos I esfuerzo       87
##  9 Juan Carlos I familia        84
## 10 Juan Carlos I libertad       81
## 11 Felipe VI     españa         51
## 12 Felipe VI     debemos        30
## 13 Felipe VI     convivencia    28
## 14 Felipe VI     futuro         27
## 15 Felipe VI     hoy            26
## 16 Felipe VI     españoles      25
## 17 Felipe VI     sociedad       25
## 18 Felipe VI     historia       22
## 19 Felipe VI     vida           22
## 20 Felipe VI     tenemos        19

aunque antes de imprimir el resultado te habrá avisado de que la selección de los datos se ha hecho por medio de la columna n, que es la que contiene las frecuencias de aparición, que es lo que le has pedido que tenga en cuenta con la instrucción top_n(10).

## Selecting by n

El resultado que ha impreso arroja los datos de las diez palabras más frecuentes de cada rey, de ahí que la segunda línea de la tabla diga Groups: rey [2]. Si no hubieras introducido esta línea solo te habría ofrecido las diez primeras líneas para el rey Juan Carlos I. Puedes observar que España es la top de ambos monarcas, y que españoles ha bajado a la sexta posición en Felipe VI. En este han aparecido dos palabras, convivencia e historia, que no están entre las top de Juan Carlos I. Pero ver tablas es poco iluminador. Es más fácil hacer la comparación por medio de gráficos de barras paralelos como el de la figura 6.1.

Las 10 palabras más frecuentes en ambos monarcas

Figura 6.1: Las 10 palabras más frecuentes en ambos monarcas

Para conseguirlo has de añadir tras top_n(10) el bloque de código que hay en la siguiente caja, pero antes de hacerlo escribe en esta última línea %>% e introduce un intro.

La línea de labs() supongo que la habrás aprendido al hacer una de las prácticas del capítulo anterior, pero te recuerdo qué es lo que hace: se ocupa de cambiar las leyenda que aparecen en los ejes X e Y de la gráfica. Como en el eje X se imprimirán las palabras, no hace falta poner leyenda alguna, pero sí en el eje Y. La única novedad con respecto a los gráficos que has dibujado con anterioridad es facet_wrap(). Esta es muy interesante y útil cuando se quiere comparar gráficas con los datos de dos o más variables puesto que permite dibujarlas unas junto a otras. Lo único que necesita saber R es la fuente de los datos, ~rey. El argumento scales = "", tiene un valor por defecto, que es fixed, pero puede ser "free_y" como en el ejemplo anterior, "free_x" o "free".

Experimenta con ellas para ver cómo cambian los resultados gráficos. Algunos pueden ser muy interesantes, como el de siguiente figura 6.2, que he obtenido aumentado top_n() a 30 y con el valor por defecto para scales().
Las 30 palabras más frecuentes en ambos monarcas con el valor por defecto para `scales()`

Figura 6.2: Las 30 palabras más frecuentes en ambos monarcas con el valor por defecto para scales()

Las líneas en las que no hay barra, como puedes suponer, indica que son palabras que no existen en los discursos de uno u otro rey.

También puedes ver cuáles son las palabras más frecuentes en cada discurso del rey Felipe (figura 6.3).

Las palabras más frecuentes en los discursos de Felipe VI

Figura 6.3: Las palabras más frecuentes en los discursos de Felipe VI

La gráfica de la figura 6.3 se consigue con dos grupos de instrucciones. El primero crea la tabla con los datos y el segundo se ocupa de dibujar la gráfica.

El código anterior crea una nueva tabla que se llamará mesnaje_anno con tres variables procedentes de mensajes_vaciado: rey, anno y palabra. Estas se seleccionan con la función select(). Hay, sin embargo, un pequeño problema: ha seleccionado todas las filas, incluidas las del rey Juan Carlos, por lo que tienes que eliminarlas. Esto se puede hacer con filter(). Como tan solo te interesan los discursos del rey Felipe, el primer argumento es el nombre de la columna que ha de usar; en este caso rey. Pero tan solo te interesa extraer aquellas cuyo valor sea Felipe VI. Para expresar la igualdad se usan dos iguales seguidos ==. Podrías expresarlo de otra manera: filter(rey != "Juan Carlos I"), es decir, selecciona todas aquellas filas en las que no aparezca Juan Carlos I, es decir, que sea distinto !=. Ya te dije que muchas cosas se pueden hacer en R de más de una manera.

El bloque de código mejorado para crear mensaje_anno es

Ya tienes en mensaje_anno toda la información sobre los discursos de Felipe VI. Pero aún no ha hecho las cuentas. Como quieres contar separadamente las palabras de cada uno de los años, se lo tienes que indicar a R con group_by(anno). A continuación, cuentas las palabras y, por último, deshaces la agrupación anual, que ya no sirve para nada.

El segundo bloque, como te he indicado, se ocupa de dibujar la gráfica. Cópialo y pégalo en el editor de RStudio, pero no lo ejecutes hasta que hayas leído la explicación que le sigue.

En la tabla mensaje_anno están todas las palabras, pero como no quieres representarlas todas en una gráfica, sería horrible, tienes que tomar una decisión: el número mínimo de ocurrencias e indicárselo a R. Esto lo consigues con la función filter(). Ahí puedes establecer el número de ocurrencias n que debe considerar. Yo he puesto > 5, es decir, imprime en cada gráfica todas aquellas palabras cuya frecuencia de aparición sea mayor de 5. Juega tú con varios valores y extrae tus conclusiones. Haz lo mismo con el literal de fill = "", que es el responsable de los colores de las barras.

Reescribe el código para que puedas extraer las palabras más frecuentes de los discursos del rey Juan Carlos I. Puede ser tan fácil como cambiar un solo símbolo. Para que puedas verlo con mayor facilidad, aumenta a 8 el número de palabras que debe representar la gráfica. ¿Qué conclusiones sacas?

6.2 Comparar la frecuencia del léxico

6.2.1 Introducción

Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

Figura 6.4: Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

El gráfico de la figura 6.4 representa la comparación de la frecuencia de las palabras usadas por Juan Carlos I frente a las de Felipe VI. Las que están por encima de la línea son palabras que tienen una frecuencia de ocurrencia mayor en los discursos del rey Juan Carlos, mientras que las que están en la parte inferior lo son más en los de Felipe VI. Cuanto más próximas estén a la línea más semejante es la frecuencia de aparición en ambos conjuntos. Así, por ejemplo, España, españoles y año son palabras de muy alta frecuencia en ambos reyes mientras que acuerdos y construir aparecen con la misma frecuencia en ambos, pero en el parte baja, es decir, con poca frecuencia. Por otra parte, cuanto más alejadas estén de la línea, son palabras más frecuentes en un conjunto que en el otro. Por ejemplo, actitudes es más abundante en los discursos de Felipe VI (2 ocurrencias en 2016 y 1 en 2018) que en los de su padre (1 sola vez en 2010), mientras que justicia abunda en los de Juan Carlos I (54 ocurrencias a lo largo de los años, frente a una sola en Felipe VI, en 2017).

No te dejes engañar por las frecuencias absolutas, es decir, el número de veces que aparecen. Aquí estás trabajando con porcentajes, así actitudes es tres veces más frecuente en Felipe VI que en Juan Carlos, eso quiere decir que es un 75 % más frecuente. En las navidades de 2018 los comentaristas destacaron que la palabra convivencia había desbancado a españoles en la alocución y que era el eje central del discurso. Sin embargo, convivencia la usó el mismo número de veces en el discurso de 2017 que en el de 2018: siete. Ten en cuenta estos detalles a la hora de valorar los datos.

6.2.2 Preparar el entorno

El código para dibujar la gráfica de la figura 6.4 te lo presento y explico a continuación. Gran parte de él ya te es conocido, con lo que solo explicaré lo nuevo. Arranca una nueva sesión de RStudio, así te aseguras de que no hay nada escondido de una ejecución anterior.

Como de costumbre, lo primero es cargar las librerías básicas.

A continuación, lee los nombres de los ficheros de cada uno de los mensajes

y creas el vector anno que contendrá las fechas

aunque también lo podrías hacer con

En esta ocasión necesitas los nombres de los reyes. Podrías hacerlo por las fechas, pero es un poco más complicado. Lo siguiente es crear un vector con los nombres de los reyes. Tiene que estar 39 veces Juan Carlos I y cinco Felipe VI. El primer paso es crear un vector para cada rey: JCI y FVI. Como lo que quieres es repetir varias veces el nombre en cada uno de ellos, lo único que tienes que hacer es usar la función rep() –repetir– que requiere dos argumentos: lo que quieres repetir y el número de veces que los quieres repetir. Como este será el contenido de una futura columna (variable) llamada rey que contendrá el nombre los dos, creas un nuevo vector uniendo los dos anteriores con la función c(). Aquí el orden es fundamental, primero JCI y después FVI.

aunque también lo puedes hacer con

con lo que te ahorras el crear dos vectores, JCI y FVI, que no va usar de nuevo.

El siguiente paso es generar la tabla en la que guardarás todos los mensajes y la lectura de los ficheros. La única novedad es que añades la variable (columna) rey. Como puedes suponer, el bucle for leerá secuencialmente el nombre de cada uno de ellos, como los años.

A continuación creas dos nuevas tablas, una por cada rey: FVI y JCI. Cada una de estas tablas solo va a contener el texto, no te interesan ni los años ni ningún otro dato. Quizá digas… el nombre del rey. No, no es necesario ya que lo tienes en el nombre del objeto en el que vas a guardar los textos JCI y FVI.

Si usaste el primer método para crear el contenido del vector rey, vas a reutilizar el nombre de dos objetos que ya no te serán necesarios: JCI y FVI. Si usaste el segundo método, los creas por primera vez.

Los datos los extraerás de mensajes con la función select(), pero de cada uno de los reyes con filter(). El orden de las funciones es vital: primero se filtra (filter) el rey, y después se selecciona (select) el texto.

Si quieres te puedes deshacer de los objetos que ya no vas a utilizar con

Carga ahora la lista de palabras vacías.

Si no lo tienes guardardada en el disco duro (te expliqué cómo hacerlo en el capítulo anterior), usa esta otra orden, que lo leerá desde el repositorio externo del proyecto.

En cualquiera de los dos casos te responderá

## Parsed with column specification:
## cols(
##   palabra = col_character()
## )

En el capítulo anterior usaste read_csv para cargar la lista de palabras vacías. Los ficheros csv son tablas en las que los diferentes valores están separados por comas, de ahí el csv (= comma separated values). En esta ocasión, aunque es el mismo fichero, he usado read_tsv, en este caso se trataría de una tabla cuyos valores están separados por tabuladores, de ahí el tsv (= tab separated values).

Todas las tablas que se utilizan en este libro están creadas como ficheros tsv porque su contenido son textos y como estos pueden contener comas se podrían provocar errores, aunque en el caso de tratarse de ficheros de texto separados por comas, entonces el contenido textual tendría que estar encerrado entre comillas. Esto último supone otro pequeño problema puesto que en los textos puede haber citas y expresiones entrecomilladas, con lo que habría que solucionar este nuevo problemilla (no lo es tanto en español si no utilizamos las comillas rectas " sino las tipográficas, tanto «» como “”. Todos estos problemas se pueden solucionar, pero cualquier solución es un poco más compleja que separar los valores con tabuladores.

A continuación, divide los discursos de ambos monarcas en palabras y borra las palabras vacías.

Una vez que hayas ejecutado ambas órdenes, en la consola se habrá impreso el mensaje

## Joining, by = "palabra"

Tan solo te informa de que la variable común por medio de la que has borrado las palabras vacías es palabra.

6.2.3 Calcular las frecuencias

Establecer cuáles son las palabras más frecuentes en uno y otro rey es cuestión de calcular las frecuencias, pero tienes que hacerlo por porcentajes, de otro modo no podrías comparar los discursos de ambos reyes, pues uno tiene 39 discursos y el otro tan solo cinco, por lo que para evitar este problema se usan las frecuencias relativas o porcentajes. Para hacerlo vas a crear una nueva tabla en la que solo tendrás las palabras, también borrarás los números ya que aparecen muchas veces, por lo general son los años (1975…2019), pero hay otros.

Para ello usarás la función mutate() y le dirás que conserve en palabra todo aquello que no sean dígitos. Para conservar solo las palabras usarás la función str_extract() que emplea las expresiones regulares. Esta función necesita saber el nombre de la variable que ha de manejar y el patrón que ha de utilizar. La variable va en primer lugar, la expresión regular en segundo. Como lo que quieres es conservar lo que no sean números, usarás el patrón \\D+ que lo que hace es tomar todo aquello que no sean números. Podrías indicarlo de otra manera, con [[:alpha:]]+ que solo tomaría las palabras. De nuevo, te recuerdo que con R las cosas se pueden hacer de más de una manera.

En el siguiente paso cuentas las palabras con count(). Y en el tercero conservas la variable palabra, creas la columna con la frecuencia, pero la llamarás por el nombre del rey correspondiente –JuanCarlos y Felipe– y por último creas una nueva variable –rey– con el nombre del rey. Pero como no quieres conservar la variable n, que es la que almacena las frecuencias absolutas, utilizas transmute() en vez de mutate() porque transmute() solo conserva las variables que se crean y aquellas que se le indican que debe conservar de la tabla de origen.

Solo queda un último paso antes de poder dibujar el gráfico: unir ambas tablas en una sola, en reyes_frecuencias, y lo consigues con esta orden

Primero guardas en reyes_frecuencias el contenido de FVI_porcentaje. Después le pides que incorpore JCI_porcentaje, pero de una manera especial en la que el elemento clave es la variable palabra. Puesto que en JCI_porcentaje habrá palabras que no estén en FVI_porcentaje y en este habrá palabras que no estén en aquel, R lo remediará incluyendo en esas casillas que no existe con NA (= not available ‛no disponible’), por eso usas la función left_join(). Échale una ojeada la tabla. Para hacerlo, ejecuta en la consola

La respuesta será

## # A tibble: 1,510 x 5
##    palabra      Felipe rey.x     JuanCarlos rey.y        
##    <chr>         <dbl> <chr>          <dbl> <chr>        
##  1 abdicación 0.000291 Felipe VI NA         <NA>         
##  2 abierta    0.000583 Felipe VI  0.000348  Juan Carlos I
##  3 abierto    0.000291 Felipe VI  0.000522  Juan Carlos I
##  4 abiertos   0.000583 Felipe VI NA         <NA>         
##  5 abnegación 0.000291 Felipe VI  0.000130  Juan Carlos I
##  6 abordar    0.000291 Felipe VI  0.0000870 Juan Carlos I
##  7 abra       0.000291 Felipe VI  0.0000435 Juan Carlos I
##  8 abre       0.000291 Felipe VI  0.000435  Juan Carlos I
##  9 abrirme    0.000291 Felipe VI NA         <NA>         
## 10 abrirnos   0.000291 Felipe VI NA         <NA>         
## # … with 1,500 more rows

Tan solo te muestra las diez primeras de las 1510 palabras. Fíjate que abdicación, abiertos, abrirme y abrirnos son palabras que utiliza Felipe VI, pero no Juan Carlos I, por eso en la casilla correspondiente de la columna JuanCarlos (y rey.y) aparece NA. Ya estás en disposición de dibujar la gráfica, pero necesitas una librería especial para poder dibujarla ya que si no los datos se perderían en la gráfica. La librería que necesitas es scales. Instálala en tu ordenador

e invócala.

6.2.4 Dibujar la gráfica comparativa

Ya estás en disposición de dibujarla; el resultado será la gráfica de la figura 6.5. Es una instrucción compleja. Te acuerdas que te lo dije, que podía ser complicado. Aquí tienes un buen ejemplo. Te explico qué hace en cada línea. Ten cuidado con los paréntesis, las comas y los mases cuando copies el código.

Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

Figura 6.5: Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

Como ya sabes, para trazar cualquier gráfico empleas la función ggplot(). Recuerda que las diferentes instrucciones de ggplot se encadenan con el signo +, así que cada vez que lo veas pulsa intro. También lo he hecho tras cada coma en los argumentos para que puedas leer el código con comodidad, pero no es necesario. Esta primera línea indica con data = de dónde tomarás los datos, en este caso de reyes_frecuencias; de ese objeto tomará tan solo los datos de las variables Felipe y JuanCarlos mientras que el argumento color = se ocupa del color de los puntos, pero aquí es una curiosa fórmula a base de restar los valores de Felipe a JuanCarlos y tomarlo como un valor absolutoabs–, sin tener en cuenta su signo.

La función geom_abline() dibujará la línea que separa ambos conjuntos de datos (ya usaste geom_hline() para dibujar la media y la mediana) capítulos atrás. Los argumentos indican el color y lty = el tipo de línea (figura 6.6). geom_jitter() es el responsable de que el color de los puntos sean más o menos oscuros, pues depende de los valores de x e y. alpha define la transparencia (1 = opaco), size es el tamaño, y width y height indican cómo se dispersarán los puntos en el gráfico. geom_text() se encarga de imprimir en el gráfico las etiquetas (label) pertinentes, en este caso se trata de los valores de palabra. El argumento check_overlap = T evita que las palabras muy próximas se sobreimpriman una sobre otras y conviertan el gráfico en ilegible (pruébalo; borra este argumento y vuelve a imprimir el gráfico. Ilegible, ¿verdad?). El último, vjust es la justificación vertical de la etiqueta. Es decir, pequeñeces para que la gráfica quede más bonita y legible.

Figura 6. Posibles valores de `lty`

Figura 6.6: Figura 6. Posibles valores de lty

Las dos líneas siguientes, cuyas funciones comienzan con scale_ y acaban con _log10, son un truco para que la gráfica sea comprensible al comparar valores que cubren una amplia gama. Lo que hace es pedirle que trate los ejes x e y en escala logarítmica.

scale_color_gradient() se ocupa de la escala de los colores de los puntos y de las etiquetas dentro del gráfico y oscila entre dos límites marcados por high y low, donde pones los colores entre los que variará (juguetea cambiando los colores).

El gráfico con las víctimas mortales del maremoto de 2004 en el océano Índico que hay en Wikipedia (Escala logorítmica) te permitirá entender con rapidez la cuestión. Si quieres ver realmente lo que pasa en el gráfico que estás dibujando, pon una almohadilla al comienzo de cada una de las líneas scale_, así no se ejecutarán. Ejecuta el código y comprueba la diferencia entre usar y no usar la escala logarítmica.

La dos últimas líneas, creo que ya te son conocidas. theme() es la responsable de que no se imprima una leyenda explicativa y labs() se ocupa de las etiquetas de los ejes, e incluso, recuerda, puede servirte para poner títulos, subtítulos y avisos.

Cuando ejecutes el código anterior, se habrá impreso en la consola un mensaje de aviso con dos líneas cuyo tenor es parecido a este

Warning messages:
1: Removed 391 rows containing missing values (geom_point). 
2: Removed 392 rows containing missing values (geom_text).

R te avisa de que hay un número de líneas en las que no hay valores. Son los NA de palabras como abdicación, abiertos, abrirme y abrirnos que viste al echarle una ojeada a reyes_frecuencias.

Pero fíjate que en la parte superior del gráfico (figura 6.5) hay una banda gris que dice Felipe VI. Es información redundante porque la tienes en el eje horizontal. Puedes eleminarla si añades en la penúltima línea strip.text.x = element_blank(). Esa línea debe ser idéntica a esta

Es algo meramente estético, pero si lo haces así, el grafico quedará mucho más elegante, como puedes ver en la figura 6.7.

Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

Figura 6.7: Las palabras más frecuentes en los discursos de ambos monarcas según las frecuencias

Ahora tiene un aspecto mejor.

Juguetea, como te he dicho a lo largo de las explicaciones, y cambia los colores, los tamaños, etc. Te permitirá observar cómo funcionan los gráficos.