5 Palabras vacías

5.1 Introducción

Cuando cargaste y dividiste en palabras-token y palabras-tipo el capítulo Primer análisis de texto, y cuando en la segunda parte del capítulo Avance en el análisis textual leíste todos los mensajes y los dividiste, pudiste comprobar que la mayoría de las palabras que constituyen los mensajes de Navidad, en realidad cualquier otro texto, son muy poco informativas porque son preposiciones, artículos, conjunciones… como puedes observar en la gráfica 5.1.

Las treinta palabras más frecuentes en los mensajes de Navidad

Figura 5.1: Las treinta palabras más frecuentes en los mensajes de Navidad

Es más, entre las 30 palabras más frecuentes de los mensajes de Navidad, que suponen el 43.38 % de las palabras-token, aunque apenas son el 0.47 % de las palabras-tipo de este corpus, tan solo son de interés semántico: España (en la posición 23 con 331 ocurrencias) y españoles (en la posición 30 con 211 apariciones), y son esperables puesto que son un mensaje que dirige el rey de España a todos los españoles la tarde de Nochebuena.

A este tipo de palabras de altísima frecuencia, pero nulo valor semántico, que suelen coincidir con las llamadas palabras gramaticales, en el ámbito de la informática se las considera palabras vacías o huecas (ellos usan el término inglés stopwords). Por lo general las eliminan porque no les son útiles. Puesto que lo que te interesa en este momento es procesar las palabras con significado léxico hay borrarlas. Más adelante verás que las palabras vacías, las palabras gramaticales son la clave para resolver algunos problemas textuales (cf. Análisis de atribución de autoría).

5.2 Preparar el entorno

Quizá hayas estado cacharreando con RStudio y es posible que el Environment esté un poco desordenado e, incluso, es posible que hayas cargado alguna librería que no recuerdas y que te puede dar problemas. Mi recomendación, ya lo hice al principio del capítulo anterior, es que cierres RStudio y lo arranques de nuevo. Así te aseguras de que está todo en orden.

Ahora tienes que cargar los ficheros y regenerar los objetos que creaste en el capítulo anterior. Corta y pega en el editor de RStudio el bloque de código que hay a continuación.

He introducido comentarios, las líneas precedidas por # para recordarte qué hace cada bloque de código. Las explicaciones están en los capítulos precedentes.

Guárdalo en el directorio codigo y, por último, ejecútalo. La mejor manera es que sitúes el cursor en la línea en que se cargará tidyverse y vayas haciendo clic en el botón →Run del editor de RStudio, o selecciona todo con control A y ejecútalo con control intro (cmd en MacOS).

La última línea, la que dice rm() ( = remove = ‘borra’) lo que hace es borrar los objetos temporal, discurso y la variable de control i. No las necesitarás más y, aunque tu ordenador tendrá mucha memoria, es mejor tener el Environment algo aseado. Sé cuidadoso cuando utilices esta función porque una vez borrado un objeto ya no puede recuperarse, tendrías que regenerarlo.

Comprueba que todo ha ido bien revisando la pestaña Environment. Tienen que estar las tablas mensajes, mensajes_frecuencias y mensajes_palabras en la caja titulada Data. En la de Values tienen que estar los objetos annoy ficheros. Si es así, todo ha ido bien y tienes todo el material que necesitas para continuar.

5.3 Palabras vacías

En la red hay muchas listas de palabras vacías. No hay una válida para todo, por lo que cada analista ha de utilizar la que mejor le vaya para cada análisis. Por ejemplo, si quisieras analizar novelas publicadas en el siglo XIX te encontrarías con la sorpresa de que las que existen nunca borrarían las preposiciones y conjunciones que solían llevar tilde (á, ó, é, ú), algunas palabras que durante mucho tiempo han llevado tilde sin necesitarla (fué, fuí) y alguna otra. Pero no es el caso, por lo que, por el momento, puedes trabajar con la que trae de serie el paquete tidytext.

Para hacer más clara las cosas, vas a extraer la lista de palabras vacías que tiene tidytext y la vas a guardar en un objeto que llamarás vacias. Para hacerlo usarás la función get_stopwords() y como argumento le dirás que quieres las del español "es". La expresión es

Revisa ahora el contendido ejecutando en la consola esta orden

que imprimirá el comienzo de la tabla que contine la lista de las palabras vacías que tiene tidytext de serie.

## # A tibble: 308 x 2
##    word  lexicon 
##    <chr> <chr>   
##  1 de    snowball
##  2 la    snowball
##  3 que   snowball
##  4 el    snowball
##  5 en    snowball
##  6 y     snowball
##  7 a     snowball
##  8 los   snowball
##  9 del   snowball
## 10 se    snowball
## # … with 298 more rows

Tienes una tabla de 308 líneas y dos columnas. Cada línea tiene dos datos: una palabra española de muy alta frecuencia y la palabra snowball que indica la procedencia de la lista de palabras vacías: el proyecto Snowball. Es una información que no te interesa. El problemilla para nosotros es el nombre de la columna word.

5.3.1 La función rename()

Todos los lenguajes de programación, incluido R, están escritos en inglés, es decir, todas las funciones, órdenes, comandos, etc. están en esa lengua y no se pueden cambiar. Sin embargo, podemos nombrar las variables y los objetos como queramos.

En R, ya lo he dicho antes, solo hay dos restricciones serias a la hora de dar nombre a los objetos y las variables: nunca pueden empezar por un número. 1992_palabras no es válida, pero sí lo es palabras_1992. La otra es que no puede usar los signos matemáticos +, -, *, /) ni algunos otros símbolos como $ o #.

Ya lo has podido comprobar en los capítulos anteriores. Para hacerlo más claro, utilizo el español para dar nombre a las variables y objetos, pero sin letras con tildes, por lo que a veces las escribo en latín.

Cuando has dividido los textos de los mensajes en palabras, has identificado la columna que las almacena con el nombre palabra, pero las funciones del paquete tidytext emplea word. Podríamos haber identificado las columnas (variables) con los términos ingleses, pero ofuscaría un poco la explicación porque habría que dedicar algo de tiempo a dilucidar si es una función (siempre en inglés) o un objeto o una variable que has creado tú. Como vienen en inglés, y queremos mantener algo de orden, tenemos que cambiarlos al español. Es sencillo. Copia en el editor estas líneas.

Lo que acabas de pedirle a R es que cambie el nombre de la columna word a palabra. Para hacerlo, siempre se pone primero el nuevo nombre y después el término que se quiere cambiar. Una vez ejecutes lo anterior puedes comprobar que todo ha ido bien si ejecutas en la consola

Deberá imprimirse el comienzo de la tabla vacias.

## # A tibble: 308 x 2
##    palabra lexicon 
##    <chr>   <chr>   
##  1 de      snowball
##  2 la      snowball
##  3 que     snowball
##  4 el      snowball
##  5 en      snowball
##  6 y       snowball
##  7 a       snowball
##  8 los     snowball
##  9 del     snowball
## 10 se      snowball
## # … with 298 more rows

Fíjate que ahora la segunda línea dice palabra y lexicon, mientras que hace un momento decía word y lexicon. Un problema tonto resuelto en un segundo.

5.3.2 La función anti_join()

Una vez resuelto el asunto de los nombres de las columnas, es hora de borrar del corpus todas las palabras vacías, pero, para no eliminarlas del todo, pues puede que te venga bien tener una tabla con todas las palabras, guardarás la lista vaciada en mensajes_vaciado. Para borrar los términos no deseados se usa la función anti_join() cuyo argumento es el nombre de la tabla que contiene la lista de palabras que se han de borrar.

La forma de actuar de anti_join() es mirar en la columna palabra de la tabla mensajes_palabras y comprobar si alguna de las palabras se encuentra recogida en vacias. Si lo está, la borra. Ejecuta la orden. La respuesta de R habrá sido

## Joining, by = "palabra"

Esto quiere decir que tanto vacias como mensajes_palabras tienen una variable en común palabras que es la que ha permitido que funcione. De no haber cambiado el nombre de la variable, R habría respondido con un mensaje de error.

Error: `by` required, because the data sources have no common variables
Call `rlang::last_error()` to see a backtrace

Comprueba si en Environment ha aparecido el nuevo objeto mensajes_vaciado. Compara la cantidad de observaciones que tiene mensajes_palabras y las que tiene el nuevo objeto mensajes_vaciado. El primero tiene 57750 mientras que el segundo se ha reducido a 27687. Te has quitado de un plumazo 30063 palabras-token, más de la mitad de las que constituyen el corpus. Examina la tabla. La forma más sencilla es escribiendo en la consola View(mensajes_vaciado). Tan pronto como pulses intro se abre en la parte del editor una nueva pestaña con el contenido de mensajes_vaciado.

Fíjate que el nombre de la pestaña es el mismo que el del objeto que acabas de crear mensajes_vaciado y que tiene tres columna anno, parrafo, y palabra, y en el borde inferior informa de que está mostrando las líneas 1 a 16 de 27687 entradas (la cantidad de líneas mostradas varia de acuerdo con la altura de la ventana, por lo que la cantidad que te menciono y la que puede aparecer en tu pantalla depende de tu ordenador). Recorre la tabla. Verás que hay números (p. ej. 1976), y algunas palabras cuyo significado no es muy interesante (tantos, toda, frente –en otras circunstancias puede serlo–, casi, mera, sino, hacia, así, alguno, tan…). No ha quedado muy limpia, sigue habiendo palabras poco interesantes. Esto se debe a que la lista creada por Snowball, aunque es amplia no es muy completa, porque no tiene, por ejemplo, el mas adversativo ni el si condicional, tampoco los pronombres éste, ése, áquel, etc.). Por ese motivo, en el proyecto 7PartidasDigital hemos creado una lista de palabras vacías más extensa que incluye esas antiguallas ortográficas que he mencionado, alguna errata, demasiado usual, del tipo ––, algunas abreviaturas como sr., sra., d., dña., , sto., etc., y las letras del alfabeto. Su uso es tan sencillo como el de la lista que ofrece tidytext de serie.

La tienes en el repositorio del proyecto, por lo que que vas a descargarla y guardarla en tu ordenador con

Cuando ejecutes la orden, en la consola aparecerá el mensaje

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

Lo que te indica R es que ha leído el fichero y que hay una única columna llamada palabra cuyo contenido son caracteres.

Te explico la orden. Le has pedido que guarde en vacias un fichero que hay en un repositorio externo (pero bien podría ser tu ordenador, tan solo tienes que cambiar la url por la ruta dentro de tu máquina). Para resolver el problema que los ordenadores Windows tienen con las letras acentuadas, le indicas que debe leerlo con el sistema de codificación de tu ordenador locale = default_locale().

Si quieres guardar en tu ordenador la lista de palabras, para no tener que depender del repositorio, usa esta orden

Si has decidido guardar una copia de la lista en tu ordenador, en los próximos capítulos tendrás que indicar que la ruta es "datos/vacias.txt", que es algo más sencillo que toda la dirección del respositorio.

Si se ha cargado bien, tendrás en Environment un objeto llamado vacias con 466 obs. of 1 variable. Puedes inspeccionarlo con View(vacias). Ya tienes la lista de palabras vacías que te ayudará a limpiar el corpus de las palabras gramaticales que no aportan, en este momento, nada. Recopia la orden

y ejecútala. Te responderá con

## Joining, by = "palabra"

Fíjate que ahora que el objeto mensajes_vaciado (lo tienes en la ventana Environment) tiene 26431 observaciones, es decir, 26431 palabras; bastantes menos que cuando lo limpiaste con la lista que tiene tidytext de serie. Vamos a ver, ahora, cuáles son las palabras más frecuentes del corpus. Para hacer el recuento vale con

pero esto solo te permitirá ver las 10 primeras y te indicará que ahora solo hay 6052 palabras-tipo.

## # A tibble: 6,052 x 2
##    palabra         n
##    <chr>       <int>
##  1 españa        331
##  2 españoles     211
##  3 año           162
##  4 sociedad      150
##  5 debemos       142
##  6 paz           140
##  7 futuro        136
##  8 hoy           104
##  9 convivencia   102
## 10 vida           96
## # … with 6,042 more rows

Vamos a verlo de manera gráfica. Como lo que has visto al principio de este capítulo, en la figura 5.1, pero un poco más elegante. Copia el código que hay a continuación, pero no lo ejecutes hasta que hayas leído la explicación de qué es lo que hará.

Lo de la primera línea lo tienes claro, es de dónde va a extraer los datos, de mensajes_vaciado. En la segunda, count(), contará cuantas ocurrencias tiene cada palabra-tipo y las ordenará de mayor a menor. En la tercera solo tendrá en cuenta aquellas que aparezcan 65 o más veces (> 65), lo que se consigue con la función filter(). Puesto que se ha creado una nueva tabla interna, que no vas a ver, tienes que crear una nueva columna con mutate() que tendrá una columna llamada palabra para almacenar esta nueva información y, además, la vas a reordenar por las frecuencias, de mayor a menor, para que sea más sencilla la lectura.

Ahora vienen las instrucciones para dibujar la gráfica encabezadas por ggplot(). Ya te advertí que para hacerlas bonitas hay que escribir algunas líneas de código algo complicadillas. Recuerda que cada instrucción de ggplot() se une a la siguiente con un +, no con %>%.

El primer argumento de ggplot() es qué es lo que ha de dibujar, y se le indica con aes(). Y lo que quieres es que en el eje horizontal x represente las palabras, en el vertical y marque la cantidad de veces que aparece cada palabra. El argumento fill = palabra provocará que cada una de las barras tenga un color para cada palabra, para que no sea una serie de aburridas barras grises (que es el color por defecto). Dentro de un ratito verás el resultado.

La función geom_bar(), aunque ya lo sabes de capítulos anteriores, indica cuál será del tipo de gráfico que dibujará. En este caso, de barras. El argumento stat = "identity" lo que le dice a R es que la altura de las barras representa los valores de n.

Las cuatro líneas siguientes son las responsables de no imprimir una leyenda para explicar el gráfico theme(legend.position = "none"); qué leyenda debe haber en el eje y y lo haces con ylab("Número de veces que aparecen"); que no debe haber ninguna etiqueta identificaba en el eje x, para lo que usas xlab(NULL); y, por último, cuál será el título del gráfico con ggtitle("Mensajes de Navidad 1975-2018"). La última línea, coord_flip() fuerza a que el eje y se imprima en la parte horizontal, y que el eje x se sitúe en la vertical puesto que así será más fácil leerlo. Ya sabes qué es lo que va a hacer, así que ejecútalo. El resultado tiene que ser el bonito gráfico multicolor de la figura 5.2.

Las 30 palabras más frecuentes en los mensajes de Navidad con _embellecimientos_

Figura 5.2: Las 30 palabras más frecuentes en los mensajes de Navidad con embellecimientos

Juguetea con los valores de filter(); mira el resultado si borras fill = palabra.
Busca en la red como convertir el rango de años 1975-2018 en un subtítulo y añadir una noticia con tu firma, algo parecido a este gráfico de la figura 5.3.
Gráfico que has de obtener modificando el código que ya tienes

Figura 5.3: Gráfico que has de obtener modificando el código que ya tienes

5.4 Palabras vacías propias

Si te fijas, de las palabras que aparecen más de 65 veces varias son esperables: año, años, día, noche, país ya que se trata del mensaje en el que se recapitulan algunos de los hechos más importantes del año de un país; el mensaje se lee en el contexto de unas fiestas que se desarrollan en una serie de días, en una noche determinada y, por supuesto, el mensaje se dirige a todos los ciudadanos de España, es decir, a todos los españoles. Podrías borrar estas palabras. Aquí no son un gran estorbo, pero, pongamos por caso, en el análisis de una novela, o conjunto de novelas, abundarán los nombres propios, y eso podría ofuscar un tanto los resultados.

Considera el gráfico de la figura 5.4 que corresponde a las quince palabras más frecuentes en la novela Los Pazos de Ulloa de Emilia Pardo Bazán.

Las 15 palabras más frecuentes en _Los Pazos de Ulloa_

Figura 5.4: Las 15 palabras más frecuentes en Los Pazos de Ulloa

De ellas, siete son nombres propios: Gabriel, Julián, Nucha, Perucho, Pedro y Ulloa. Dos son sustantivos que indefectiblemente aparecen junto a un nombre propios: don y marqués. Señor queda en duda. Bien, mismo y la forma verbal tenía poco dicen. Por lo tanto, de las quince palabras más frecuentes solo nos quedan tres: casa, ojos y mano.

Puedes borrar todas esas palabras que poco dicen acerca del texto. Es decir, puedes crear tu propia lista de palabras vacías para cada análisis que hagas. Para lograrlo tienes que generar una tabla que contengan todas esas palabras que estimas que no sirven para nada. Para verlo más claro vamos a jugar un poco con Los Pazos de Ulloa.

Para cargar la novela de doña Emilia ejecuta esta orden (puedes copiarla en una sola línea, o bien dar un intro tras cada coma):

He condensado en una sola línea varias órdenes. Ya lo has visto antes. Le estás pidiendo a R que guarde en el objeto pazos el texto de la novela Los pazos de Ulloa que se encuentra en un repositorio externo. Ese objeto tiene que ser una tabla, lo que se consigue con tibble(), y ha de tener una columna llamada texto. Además, no ha de tener en cuenta las tres primeras líneas skip = 3 porque en ellas están los metadatos, mínimos, del fichero.

Emilia Pardo Bazán
Los Pazos de Ulloa
1886-1887

Si todo ha ido bien, en la pestaña Environment habrá aparecido un nuevo objeto llamado pazos con 2815 obs. of 1 variable. Puedes ver el comienzo del contenido si ejecturas en la consola

## # A tibble: 2,815 x 1
##    texto                                                                   
##    <chr>                                                                   
##  1 PRIMERA PARTE                                                           
##  2 Los Pazos de Ulloa                                                      
##  3 TOMO I                                                                  
##  4 I                                                                       
##  5 Por más que el jinete trataba de sofrenarlo agarrándose con todas sus f…
##  6 Iba el jinete colorado, no como un pimiento, sino como una fresa, encen…
##  7 Al acabarse el repecho, volvió el jaco a la sosegada andadura habitual,…
##  8 —¿Tendrá usted la bondad de decirme si falta mucho para la casa del señ…
##  9 —¿Para los Pazos de Ulloa? —contestó el peón repitiendo la pregunta.    
## 10 —Eso es.                                                                
## # … with 2,805 more rows

Ahora tienes que dividirlo en palabras-token y borrar las palabras vacías con

## Joining, by = "palabra"

Habrás obtenido un nuevo objeto llamado pazos_palabras con 82372 palabras-token. Además, en la consola se habrá impreso un mensaje recordándote que la eliminación de las palabras vacías se hizo por medio de la variable palabra.

¿Podrías averiguar cuántas palabras-tipo suponen esas 82300 palabras-token? La respuesta está tras este numerito5.

Ahora tienes que borrar las palabras que has visto que son poco informativas. Para hacerlo tienes que crear una tabla con todas ellas. Vas a llamar a esta tabla vacias_adhoc (puedes usar cualquier nombre). Como es una tabla, usarás la función tibble(), y como argumento le indicarás que el nombre de la columna será palabra (¡cabía alguna duda!). El contenido será la serie de palabras que has decidido que no te interesa tener en cuenta. Para crear esta lista de palabras R tiene la función c() (‛concatenar’) que sirve para crear vectores, ya lo has visto en varias ocasiones. Como son cadenas alfanuméricas, debes encerrar cada elemento (cada palabra) entre comillas "" y separarlas con comas. La orden completa es la que hay a continuación. (Puede ser en una única línea, pero para que lo veas mejor he introducido un intro tras la coma que separa cada uno de los elementos.)

Cuando ejecutes la línea anterior, se creará una tabla con 8 observaciones y una sola variable. Esas son las ocho palabras extra que has decidido borrar del texto de Los Pazos de Ulloa. Ahora solo tienes que borrarlas. Ya sabes la fórmula, solo que esta vez el argumento de anti_join() será vacias_adhoc.

## Joining, by = "palabra"

El número de observaciones, es decir, de palabras que hay ahora en pazos_palabras es de 80213. Compara ahora la gráfica de la figura 5.5 con la de la figura 5.4.

Las 15 palabras más frecuentes en _Los Pazos de Ulloa_ tras aplicar tu propia lista de palabras vacías

Figura 5.5: Las 15 palabras más frecuentes en Los Pazos de Ulloa tras aplicar tu propia lista de palabras vacías

La gráfica de la figura 5.5 se consigue con el bloque de código que hay a continuación.

No te lo explico porque lo tienes un poco más atrás. Volvemos a los Mensajes de Navidad, pero lo harás en el siguiente capítulo.


  1. Quedan 22621 palabras-tipo. Para averiguarlo se usa esta expresión pazos_palabras %>% count(palabra). Para regresar, pulsa