Introducción

Para la elaboración de los ficheros de datos una herramienta muy utilizada es la hoja de cálculo, sin embargo, en numerosas situaciones la introducción o mecanización de los datos se convierte en un proceso tedioso y lleno de posibilidades de error. Estos casos son aquellos en los que se dispone de un gran número de variables y sólo algunas tienen valor, siendo 0 todos los demás. Por ejemplo:

  1. Inventarios de objetos de estudio

    Cada objeto está descrito por la presencia de uno o varios elementos de una lista. En la localidad A se han encontrado las esepcies 21, 57, 109 y 136; la localidad B se han encontrado las especies 39, 63, 81, 96, 137 y 154. En este caso necesitamos una hoja de cálculo con al menos 154 columnas. Las especies se identifican con un código facil de recordar basado en el nombre científico, por ejemplo: Salsola genistoides se identifica con Salgen o Asparagus albus por Aspalb.

  2. Descripción de sintomas o patologías

    Para cada paciente utiliza una variable se describe una patología o síntoma, el conjunto esto puede ser muy grande para el conjunto de pacientes pero relativamente breve para cada uno de ellos. El paciente A ha sufrido la patologias 4, 52, 62, 104, 132 y 358. Resultará muy conveniente disponner de una codificación para las patologías, como en el caso anterior.

Condensando

Para evitarlo, en algunas ocasiones es posible recurrir a una forma condensada en el proceso de edición de los datos. Veremos que esta estrategia presenta como ventajas tanto la disminución del tiempo de manipulación de los datos como la reducicción de los errores; además, facilita la revisión y edición de la información mecanizada.

Formato para presencia

Tal como hemos visto antes una situación se dá cuando simplemente a cada objeto o individuo se le asigna una lista de “características presentes”. Para este caso basta con un código identificador del objeto descrito y los elementos presentes.

caso01 d e g j q t
caso02 e g h o p q r s z
caso03 b j l o s w
caso04 f g h

El identificador de cada caso/observación nos permitirá conectar los valores con otros datos dispuestos en otros data.frames.

Definición de funciones

Para la lectura de los datos y la obtención de un data.frame definiremos una función, creaTabla, que realiza todo el procedimiento.

creaTabla <- function( fichero ){
    
    transforma <- function( x ){
       v <- unlist( strsplit( x, " " ) )
       l <- length( v )
       rep( v[ 1 ], l - 1 )
       v[ 2:l ]
       return ( cbind ( rep( v[ 1 ], l - 1 ),
                             v[ 2:l ] ) )
    }
    
    datos <- readLines( fichero )
    
    m <- as.data.frame( do.call( "rbind", lapply( datos, transforma ) ) )
    
    names( m ) <- c( "Objetos", "Variables" )
    m$Freq <- 1
    x <- xtabs( Freq ~ Objetos + Variables, m )
    
    return( as.data.frame.matrix( x ) )
}

Lectura de los datos

Usar la función para un fichero compacto es tan sencillo como:

tabla <- creaTabla( "./preguntas/datosCompactosPresencia.csv" )

# para aligerar la visualización de la tabla
# los ceros se cambian por puntos
tabla <- knitr::kable( tabla, format = "markdown"  )
gsub(0, '.', tabla)
b d e f g h j l o p q r s t w z
caso.1 . 1 1 . 1 . 1 . . . 1 . . 1 . .
caso.2 . . 1 . 1 1 . . 1 1 1 1 1 . . 1
caso.3 1 . . . . . 1 1 1 . . . 1 . 1 .
caso.4 . . . 1 1 1 . . . . . . . . . .

Como vemos no es necesario definir a priori el número de variables, depende de las observaciones incluidas en el fichero de trabajo. Tampoco es necesario que se dispongan los datos de entrada para cada observación en un orden determinado; son equivalentes las tres alternativas siguientes:

caso04 f g h
caso04 f h g
caso04 h f g

Si necesitamos crear una tabla con variables que no aparecen (por ejemplo, a fin de comparar con otras tablas), añadimos un caso (caso00) con la lista completa de variables posibles, luego lo eliminaremos del data.frame resultante. Obviamente habrá columnas con el valor cero para todos los casos.

Formato para frecuencia

En el caso de que existan valores asociados a las variables podemos recurrir también a formatos comprimidos. Un situación habitual es, por ejemplo, cuando ademas de la lista necesitamos considerar la frecuencia con que aparece, numero de ejemplares.

En estos casos, para simplificar la edición, recurriremos al formato como el que se ejemplifica.

caso01 
d 4
e 2
g 3
j 6
q 1
t 1
caso02 
e 1
g 2
h 1
o 5
p 2
q 1
r 7
s 1
z 1
caso03 
b 2
j 1
l 1
o 1
s 2
w 4
caso04 
f 5
g 1
h 3

Sin embargo, el formato ideal es el siguiente:

caso01 d 4
caso01 e 2
caso01 g 3
caso01 j 6
caso01 q 1
caso01 t 1
caso02 e 1
caso02 g 2
caso02 h 1
caso02 o 5
caso02 p 2
caso02 q 1
caso02 r 7
caso02 s 1
caso02 z 1
caso03 b 2
caso03 j 1
caso03 l 1
caso03 o 1
caso03 s 2
caso03 w 4
caso04 f 5
caso04 g 1
caso04 h 3

Preparación de los datos

Para realizar fácilmente en intercambio del primero, más fácil de escribir, al segundo, recurrimos a la terminal y usamos el siguiente comando:

awk 'NF==1 {eti=$1} NF==2{print eti, $0}' compactosCorto.csv > compactosLargo.csv

Definición de funciones

Ahora con la siguiente función permite desplegar la tabla comleta.

creaTablaFreq <- function( fichero ){
    m <- read.table( fichero )
    m <- read.table( "./preguntas/compactosLargo.csv" )
    names( m ) <- c( "Objetos", "Variables", "Freq" )
    x <- xtabs( Freq ~ Objetos + Variables, m )
    
    return( as.data.frame.matrix( x ) )
}

Lectura de los datos

Para nuestro fichero con formato “largo” bastará el siguiente código, análogo al caso anterior:

tabla <- creaTablaFreq( "./preguntas/compactosLargo.csv" )

tabla <- knitr::kable( tabla, format = "markdown"  )

# para aligerar la visualización de la tabla
# los ceros se cambian por puntos
gsub(0, '.', tabla) 
b d e f g h j l o p q r s t w z
caso.1 . 4 2 . 3 . 6 . . . 1 . . 1 . .
caso.2 . . 1 . 2 1 . . 5 2 1 7 1 . . 1
caso.3 2 . . . . . 1 1 1 . . . 2 . 4 .
caso.4 . . . 5 1 3 . . . . . . . . . .

Problemas

  • No tengo awk en mi terminal de windows 10: consulta este enlace.