Códigos de caracteres en R

Esta entrada acompaña y remata para los usuarios de R la que escribí en general sobre los códigos de caracteres. Es un pequeño experimento en el que comparo lo que pasa al leer un fichero de texto codificado de dos maneras distintas en dos plataformas, Linux y Windows, que usan códigos de caracteres distintos.

Primero creo dos ficheros (en Linux) con el mismo contenido pero codificados de dos maneras distintas, utf-8 y latin1:

$ echo "hóla;adiós" > hola_utf8.txt 
$ file hola_utf8.txt 
hola_utf8.txt: UTF-8 Unicode text
$ iconv -f utf-8 -t latin1 hola_utf8.txt > hola_latin1.txt 
$ file hola_latin1.txt 
hola_latin1.txt: ISO-8859 text

Los ficheros pueden descargarse de este enlace.

La codificación interna de caracteres en Linux (al menos, en el mío) es utf-8. En Windows no lo tengo tan claro, pero parece que es algo similar a latin1.

Mi experimento consiste en ejecutar tanto en Linux como en Windows el siguiente código:

foo <- function( file, encoding ){
    a <- scan( file, what = "character", 
               fileEncoding = encoding )
    strsplit( a, ";" )
}
 
foo( "hola_latin1.txt", "latin1" )
foo( "hola_latin1.txt", "utf-8" )
foo( "hola_latin1.txt", "" )
 
foo( "hola_utf8.txt", "latin1" )
foo( "hola_utf8.txt", "utf-8" )
foo( "hola_utf8.txt", "" )

El motivo de usar strsplit es que es una función que puede fallar catastróficamente cuando encuentra caracteres codificados incorrectamente (desde el punto de vista de la codificación de la plataforma en la que se ejecuta).

La primera y la quinta llamada funcionan correctamente tanto en Linux como en Windows: a la función scan se le ha especificado la codificación correcta del fichero y lo ha transformado adecuadamente.

Las llamadas segunda y cuarta fallan en ambos sistemas: equivale a engañar a R y es natural que los resultados sean… subóptimos.

Las llamadas tercera y sexta son más interesantes: en Linux falla tercera y funciona la sexta; en Windows ocurre lo contrario. El motivo es que si no se especifica la codificación, R asume que es la natural del sistema (aunque supongo que se podrá configurar de alguna manera, algo en lo que no entro). Es decir, en Linux no especificar la codificación equivale a asumir utf-8 y en Windows, latin1.

Este es un detalle a tener en cuenta por quienes aspiran a desarrollar código portable, es decir, que puede ser usado por cualquiera y en cualquier plataforma para leer archivos de texto.

Nota: este experimento tiene que ver con el desarrollo del paquete pxR, que debería ser capaz de leer ficheros (y ejecutar strsplit sobre sus cadenas, entre otras funciones) en la plataforma de elección de sus usuarios (y sobre la que los autores no tenemos control). Aparentemente, los ficheros PC-Axis que queremos leer en R, según la documentación oficial, están en codificados en formato Windows.

Nuestra actual implementación está basada en ideas extraidas del experimento anterior. Si alguien ve un error en las conclusiones (o conoce una manera más adecuada para garantizar la portabilidad), le rogaría que se pusiese en contacto conmigo para trasladarla al código.

2 comentarios sobre “Códigos de caracteres en R

  1. Jose Luis 8 septiembre, 2011 11:37

    Muy interesante. Me pasa continuamente con archivos csv en linux y en windows, no me había parado a revisar la función scan.

    Una pregunta, con el formato de fin de línea en windows y en linux ¿os ha dado problema? A mi me pasa que un fichero con formato de fin de línea de windows si lo puedo leer en linux pero al revés no y tengo que cambiarlo , por ejemplo con gedit…

    Saludos

  2. datanalytics 8 septiembre, 2011 14:42

    @Jose Luis
    Bueno, supongo que con read.table se puede llegar a hacer algo parecido a lo que cuento con los códigos de caracteres llegado el caso.

    No hemos tenido problema con el fin de línea (de momento) pero estaremos atentos. La verdad es que hace mucho que no me he tropezado con ese problema.

Los comentarios están desabilitados.