Feb 4 / Sebastián Garrido de Sierra

?R | #3 - Adiós, \xf3, ó & Co. 👋

Buen día colega.

Es martes de ?R 🤓.

La semana pasada me clave duro en el locale: ese conjunto de reglas que permiten que nuestras computadoras y programas se ajusten a las convenciones del idioma, país y cultura que queramos (dentro de ciertos límites).

En el camino, expliqué cómo resolver los primeros dos "problemas" que aparecen en este👇 gif:
Y dejé los dos últimos para esta semana porque su origen y solución es similar: dependen de la codificación de caracteres o encoding que se use al importar un archivo y/o abrir un script de R en RStudio.

De eso trata el número de hoy.

A darle.

💡 Tips

1) 🤌 ¿QUÉ ES EL ENCODING?

La codificación de caracteres o encoding es un método para representar, almacenar y transmitir caracteres a través de secuencias de símbolos físicos o digitales.

Durante décadas, las tarjetas y cintas de papel perforadas fueron los principales medios para realizar este tipo de codificación en el mundo de la computación y las telecomunicaciones.

La siguiente foto muestra una de estas cintas...

Fuente: Wikipedia

... y en este video puedes ver cómo se creaban y utilizaban.

Nota bene

Por fa nota cómo la persona que aparece en el video, primero usa el comando punch (perforar) para almacenar una instrucción en la cinta de papel, y después ejecuta el comando load (cargar) para que la computadora lea y ejecute la instrucción guardada en la cinta 🤯.


La tecnología para codificar caracteres comenzó a cambiar a mediados del siglo XX, gracias a la invención de los sistemas de almacenamiento magnético.

A partir de ese momento, el guardado y procesamiento de caracteres se trasladó progresivamente a medios digitales, utilizando bits y bytes para almacenar cualquier letra o símbolo mediante una combinación única de 0s y 1s.

Éste es el método que perdura hasta hoy.

A pesar del enorme brinco tecnológico que significó esta innovación, las primeras codificaciones digitales fueron diseñadas para representar, almacenar y transmitir los caracteres de lenguajes naturales específicos, (p. ej., coreano, hebreo, inglés), y los símbolos técnicos y científicos de ciertos países (p. ej., Estados Unidos, China).

Diagrama de ASCII | Fuente: Wikipedia

Como resultado, muchos de estos esquemas de codificación eran incompatibles entre sí, provocando que las computadoras de una región/país interpretaran incorrectamente uno o más de los caracteres registrados por los equipos en otra región/país.

Estos problemas se han reducido considerablemente gracias a la creación de formatos de codificación que incluyen los caracteres de un enorme conjunto de lenguajes naturales y miles de símbolos.

Uno de ellos es el 8-bit Unicode Transformation Format, o UTF-8, un formato de codificación de caracteres que nos permite representar cualquiera de los casi 155 mil caracteres y símbolos definidos por el estándar Unicode, mismo que abarca 168 sistemas de escritura, e incluye miles de jeroglíficos egipcios como estos:

Fuente: Unicode

2) 💔 "NO ERES TÚ... SOY YO"

Si bien la creación de UTF-8 y otros ambiciosos formatos de codificación de caracteres ha permitido que las computadoras se "entiendan" cada vez mejor, en la práctica, cada tanto ocurre algo como lo que ilustran los dos problemas que dejé pendientes la semana pasada:
En ambos casos, la aparición de esos caracteres extraños (p. ej., \xf3 o Ã³) se debe a que la configuración de una partecita del locale de la computadora o el programa que generó el archivo (aquella que define el encoding), es diferente a la del equipo o aplicación que intenta leerlo e interpretarlo.

Tomemos como ejemplo el "problema" 3.

Éste surgió después de que usé la función read_csv() del paquete {readr} para importar esta base de datos, misma que fue almacenada por el INEGI en un archivo de formato .csv, y que contiene la lista de posibles causas de mortalidad definidas por la Organización Mundial de la Salud (OMS).

Por default, la función read_csv() asume que los caracteres y símbolos guardados en el archivo que vas a importar fueron codificados con el formato UTF-8. Si esto no es así, como en este caso, R no podrá interpretar correctamente ciertos caracteres especiales (p. ej., letras con acento o diéresis).

3) 🛠️ ¿CÓMO RESOLVER ESTOS PROBLEMAS?

En términos generales, la solución consiste en modificar el encoding del programa que estás usando para que sea compatible con la codificación de caracteres utilizada por la persona o institución que generó el archivo en primera instancia.

Cómo llevar esto a la práctica, dependerá del programa que estés usando y/o la tarea que estés realizando.

Si la incompatibilidad de encodings surgió al importar archivos de texto plano a R con una de las funciones de {readr}, como en el "problema" 3, la solución consiste en modificar el valor que tiene por default el argumento locale en la respectiva función.

A continuación verás dos opciones de código:
Mientras que en la primera se usa el valor por default del locale (que implica, entre otras cosas, usar UTF-8 como encoding), en la segunda le indicamos a R que debe usar el formato latin1 con el código locale = locale(encoding = "latin1").

Nota bene

OJO: Aquí usé latin1, o ​ISO 8859-1 Western Europe​, porque junto con UTF-8latin2 y latin3, es uno de los formatos de encoding más usados al generar archivos en países hispanohablantes.

¿Pero qué pasa cuando no sabes qué
encoding fue utilizado al crear la base de datos que quieres importar a R? 😮


Sufrir no debes tú (Yoda dixit). En los recursos de esta semana 👇 te cuento cómo lidiar con esta incertidumbre.


Por otro lado, si la incompatibilidad de encodings se presenta al abrir un script de R en RStudio, como en el
"problema" 4, entonces debes seguir los pasos que ilustro en este gif:


En este ejemplo elijo UTF-8 como encoding porque sabía que esa era la codificación de caracteres que usó la persona que creó el script (yo merol).

En tu caso, es probable que no tengas ese pedazo de información, pero en la siguiente sección te explico cómo "adivinar" el encoding de cualquier archivo de texto plano.

¿Te gustaría recibir nuestro newsletter cada semana en tu correo?

Compártenos tu info y te lo mandamos 🤓.

Nos importa tu privacidad.
Averigua
aquí qué hacemos para protegerla.
Muchas gracias 🙂

En los próximos minutos recibirás un correo de Sebastián de Data Crunchers

Si no lo encuentras en la bandeja de entrada, por favor revisa las carpetas de Spam y Social (o equivalentes).

⚡️ Recursos

1) 🔮 "ADIVINA" EL ENCODING DE UN ARCHIVO

Arriba expliqué cómo modificar los valores del encoding de R y RStudio para que al importar una base de datos o abrir un archivo de R, estos programas interpreten adecuadamente todos los caracteres incluidos en el archivo.

En ambos casos, el éxito del proceso depende de que sepas qué encoding usó quien creó el archivo.

Y esto no es trivial. Existen decenas de formatos de codificación.

¿Cuál de todos estos debemos pedirle a R o RStudio que use?

Por suerte, el paquete {readr} incluye la función guess_encoding(), misma que nos permite responder esta pregunta probabilísticamente.

Como su nombre lo sugiere, esta función tratará de “adivinar” el formato de codificación que se utilizó al crear el archivo que almacena la base de datos que quieres importar a R.

Ejemplifico el uso de guess_encoding() con la base de datos que generó lo que en varias ocasiones he llamado el "problema" 3.

Supongamos que:
  • Importé la base de datos que contiene la lista de posibles causas de mortalidad definida por la OMS, usando la función readr::read_csv();
  • Que R no interpretó correctamente ciertos caracteres; y,
  • No tengo idea de cuál es el encoding que usó el INEGI al crear este archivo.
Si este fuera el caso, entonces podría ejecutar el siguiente código para pedirle a R que me ayude a adivinarlo:
Después de analizar el archivo, guess_encoding() imprimirá el siguiente resultado en la Consola:
En él, R propone dos opciones de formatos de codificación (ISO-8859-1 e ISO-8859-2), e indica el grado de confianza que tiene respecto a que sea uno y otro: 0.71 y 0.25, respectivamente.

Los valores en la columna confidence van de 0 a 1, donde 0 es nula confianza y 1 es confianza absoluta.

Partiendo de esta información, parece una buena apuesta utilizar el encoding ISO-8859-1 (equivalente a latin1 que usé en la sección anterior) para que R entienda correctamente todos los caracteres al importar la base de datos.

Nota bene

❗️También puedes usar la función guess_encoding() para "adivinar" el encoding de un script de R.


2) 💪🏻 EL PODER DE LOCALE

Arriba expliqué cómo puedes usar el argumento locale del paquete {readr} para cambiar el encoding al momento de importar una base datos usando una de sus funciones.

Ésta es la punta del iceberg.

Échale un ojo a esta página para aprender todo lo que puedes ajustar con este argumento.

3) ⬅️ SOBRE LA FLECHITA DE ASIGNACIÓN EN R

La computadora que aparece en el video que te compartí al comienzo de este correo es una Teletype, similar a la que usaron John Chambers, Rick Beker y colegas al desarrollar S, uno de los lenguajes en los que se inspiraron Ross Ihaka y Robert Gentleman para crear R.

Cuenta la leyenda que la flechita de asignación que usamos en R se deriva del teclado de esta computadora (en particular, de la tecla O).

Si alguna vez tenemos el gusto de coincidir en el curso R para mortales te cuento la historia completa.


Es todo por esta semana, colega.

Gracias por leerme. Espero que hayas encontrado uno que otro bite valioso.

Saludos,

~ Sebastián

Empty space, drag to resize
Postdata

Un último dato ñoño para quienes llegaron hasta aquí.

¿Sabes cuál es la relación entre los primeros telares mecánicos y el encoding?

Bueno, pues que las cintas de papel perforadas que durante décadas sirvieron para codificar caracteres, tienen como uno de sus antecedentes directos las cintas utilizadas en los siglos XVIII y XIX para controlar el comportamiento de telares mecánicos (p. ej. los inventados por Bouchon y Jacquard) y otras máquinas.