[Pxr-commits] cambios en read.px --- cleanDat

Carlos J. Gil Bellosta cgb at datanalytics.com
Sun Sep 4 23:26:34 CEST 2011


Hola, ¿qué tal?

Hacía días que estaba retirado de este asunto. Esencialmente, desde
que se me rompió el ordenador. Ahora escribo desde el nuevo.

Y respondo abajo.

El día 25 de agosto de 2011 12:38, Oscar Perpiñan Lamigueiro
<oscar.perpinan at upm.es> escribió:
> El Wed, 24 Aug 2011 15:04:52 +0200
> "Carlos J. Gil Bellosta " <cgb at datanalytics.com> escribió:
>> Hola, ¿qué tal?
>>
>> Es cierto que cleanDat es subóptima. Hace varias pasadas por encima de
>> la cadena. Incluso estoy seguro de que alguna de ellas es innecesaria.
>>
>> Pero permite hacer algunas cosas que no sé si scan puede. Por ejemplo,
>> NA puede codificarse de varias maneras:  no sólo como "." sino también
>> como ".." y otras. ¿Funcionaría scan en estos casos?
>
> Sí, funciona. El argumento na.strings de scan espera un vector, no un
> único elemento. He modificado read.px (después de probarlo) para que sea
> capaz de gestionar hasta cuatro "dots".

Vaya, no sabía eso. Estupendo.


>> Estuve trabajando un poco en maneras de leer partes DATA cuando vienen
>> especificadas las KEYS (una especie de formato "sparse"). En tal caso,
>> scan dejaría de funcionar pero cleanDat podría modificarse para
>> aceptar ese tipo de datos. (Aunque tengo tamibén dudas de si el
>> formato "sparse" se usa realmente: ni Francisco ni yo creemos haberlo
>> visto por ninguna parte fuera de las especificaciones del formato).
>>
> Ok. Pero creo que podríamos hacer que scan también lo leyese...en todo
> caso, busquemos algún fichero que nos sirva para trastear.

Yo creo que podríamos dejar esto sin implementar hasta que vamos un
fichero "de verdad" con dicho formato. Me da la impresión de que no se
usa. Ninguno de los ficheros que he revisado en los últimos tiempos
utiliza ese formato. ¡Para qué ponernos la venda antes que sufrir la
herida!

>> Existiría una alternativa híbrida más eficiente que la actual que es
>> cambiar cleanDat para que:
>>
>> 1) en una pasada sustituyese los caracteres equivalentes a NA por "NA"
>> usando expresiones regulares (en lugar de una sucesión de
>> sustituciones)
>> 2) usar textConnection + scan para leer los datos finalmente.
>>
>
>> Habría 2 pasadas por la cadena en lugar de la una actual, pero podría
>> resolverse el problema de los diversos tipos de NA. Pero habría muchas
>> menos pasadas por la cadena que en la versión original (en la que,
>> todo ha de decirse, no se tuvieron en cuenta cuestiones de eficiencia
>> porque el problema tampoco se había planteado).
>>
>
> Como digo, scan admite un vector, y por tanto creo que no es necesario
> este híbrido.

Estupendo de nuevo.

> Saludos.
>
> Oscar
>
>> Un saludo,
>>
>> Carlos J. Gil Bellosta
>> http://www.datanalytics.com
>>
>

Finalmente, uno de los motivos por los que también he estado apartado
es que he querido investigar algo más sobre los "encodings" y cómo
funcionan en R. La idea es poder conseguir que el paquete funcione
bajo distintas plataformas (que operan con distintos "encodings") de
manera predecible.

El _bug_ que tuvimos con strsplit tiene que ver con eso: strsplit
protestaba cuando le pasaban una cadena de texto con un "encoding"
inesperado.

Lo que he averiguado hasta la fecha es (¡aparentemente!) que:

1) Que R utiliza un "encoding" nativo heredado del sistema operativo
(getOptions("encoding")): es UTF-8 en casi todos los sistemas menos
sobre Windows, donde es quién sabe qué.

2) Las funciones que manipulan texto (p.e., strsplit) asumen dicho
"encoding" en las cadenas sobre las que operan.

La solución que propuse para strsplit, es decir, usar useBytes = T, es
un apaño. Lo que hace es forzarlo a considerar todos los caracteres
que se codifican como dos o más bytes como dos (o más) caracteres
distintos. El problema puede surgir si un determinado caracter (una d
con acento de un idioma raro, p.e.) se codifica (p.e., de nuevo) como
"f;". El resultado sería caos.

La solución que propongo es la siguiente:

1) Codificar todas las cadenas de entrada en el "encoding" nativo (sea
el que sea) de la plataforma cuanto antes (en el primer scan).

2) Operar siempre en el "encoding" nativo (de nuevo, sea cual sea
porque da igual realmente) de la plataforma, dado que es el que
esperan las funciones de manipulación de caracteres.

3) Sólo en las salidas (write.px) recodificar las cadenas al formato
que espere el usuario.

En las especificaciones del formato PC-Axis no son particularmente
precisos, pero parecen asumir que DOS/Windows son las únicas
plataformas que existen. Luego si asumen un "encoding" determinado,
sólo sabemos que no es UTF-8.

He subido una implementación alternativa de read.px (read.px.alt.R en
drafts) que:

1) Lee el fichero así:

a <- scan( filename, what = "character", sep = "\n", quiet = TRUE,
fileEncoding = encoding )

donde "encoding" es un parámetro con "default" "latin1". Por lo tanto,
el objeto a tiene el "encoding" nativo: será una cadena latin1 en
Windows y utf-8 en Linux.

2) Como consecuencia de lo anterior, la representación en pantalla de
las cadenas es la "esperada" (sin símbolos raros) en ambas
plataformas.

3) No es necesaria la llamada a iconv (que está comentada).

4) He quitado todos los useBytes. ¡No son necesarios! La función
strsplit funciona correctamente sin esa opción "peligrosa".

La he probado con el fichero problemático EPOB_es_6.px tanto en
Windows como en Linux y funciona correctamente. Pero no la he probado
con más ficheros.

Si no hay objeciones al respecto, ¿la damos por buena?

Un saludo,

Carlos J. Gil Bellosta
http://www.datanalytics.com


More information about the Pxr-commits mailing list