Octava sesión con Rcmdr. Datos cualitativos. Matrices y dataframes.

Manejando variables cualitativas en R.

En la anterior sesión con Rcmdr aprendimos a utilizar (de forma básica) las matrices de R. Para refrescar la memoria puedes empezar ejecutando este código, en el que la única novedad es la última fila.

library("gtools") #recuerda que has debido instalar este paquete (ver septima sesion del blog)
combinaciones=combinations(4,3)
combinaciones
# de que tipo es el objeto combinaciones que hemos creado?
class(combinaciones)

Cuando lo ejecutes obtendrás como última linea de la salida:

> class(combinaciones)
[1] "matrix"

Es decir, que el objeto combinaciones es de tipo matrix. Puedes utilizar la función class de R para averiguar el tipo de cualquiera de los objetos que aparecen en una sesión de trabajo con R. Por ejemplo, prueba a usarla con un vector de números:

datos=c(2,5,17,21,9,7)
class(datos)

y observa el resultado. Verás que el vector datos es de tipo numeric.

Todo nuestro trabajo, en las anteriores sesiones del blog se ha centrado en números, en valores de variables cuantitativas. Pero sabemos que a veces es necesario trabajar con variables cualitativas.Recuerda que una variable cualitativa se usa para establecer clasificaciones nominales en los datos. Por ejemplo, la clasificación en hombre o mujer entre los pacientes que siguen un cierto tratamiento. O la clasificación taxonómica por especies.

Es cierto que siempre podríamos codificarlas mediante números.  Pero no es menos cierto que lo más cómodo es poder utilizar nombres como valores de las variables. Para hacer esto posible, R nos permite crear un cierto tipo de valores, que  son simplemente palabras o frases entrecomilladas (en general las llamamos cadenas de texto).  Por ejemplo, este vector podría representar el género de los diez pacientes que se han sometido a un cierto tratamiento:

pacientesPorGenero=c("mujer","mujer","hombre","mujer","hombre","hombre","hombre","mujer","mujer","mujer")
class(pacientesPorGenero)

Cuando ejecutes este código,obtendrás como último resultado

> class(pacientesPorGenero)
[1] "character"

Es decir, que los elementos del vector pacientesPorGenero son, para R, de tipo character. Ese es el tipo de dato que se utiliza en R para representar los valores de una variable cualitativa. Naturalmente, sin intentas  realizar operaciones numéricas con ese vector, como estas,

pacientesPorGenero^2
mean(pacientesPorGenero)

R te obsequiará con un surtido de insultos más o menos ofensivos en la ventana de mensajes de Rcmdr. En el segundo caso (el intento fallido de calcular la media), el valor que devuelve R es interesante: se obtiene NA, que es el valor que R devuelve cuando un resultado numérico es imposible de calcular, o no está disponible (Not Available, de ahí el nombre).

Una última observación: los vectores de tipo character se pueden ordenar, alfabéticamente, pero es muy posible que esa ordenación no tenga sentido en nuestro problema. Volveremos sobre esto en otra entrada, cuando tratemos el tema de los factores en R, que nos permitirán una gestión mucho más eficiente de la información que contienen las variables cualitativas.

Matrices a partir de un vector

En la sétima sesión obtuvimos varias matrices como resultado de las operaciones combinatorias que hacíamos. Pero ¿y si yo quiero rellenar una matriz con mis datos, escribiéndolos directamente?

Podemos hacer esto usando la función matrix de R. Como argumentos de esta función escribiremos los elementos de la matriz como un vector, y el número de filas mediante la opción nrow. Por ejemplo:

unaMatriz=matrix(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),nrow=3)
unaMatriz
class(unaMatriz)

producirá este (seguramente sorprendente) resultado:

> unaMatriz=matrix(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),nrow=3)
> unaMatriz
[,1] [,2] [,3] [,4] [,5]
[1,]    1    4    7   10   13
[2,]    2    5    8   11   14
[3,]    3    6    9   12   15
> class(unaMatriz)
[1] "matrix"

Obsérvese que R ha ido colocando los elementos por columnas, hasta formar una matriz de tres filas y cinco columnas (de acuerdo con el argumento nrow=3 que hemos usado).

Naturalmente también podríamos haber fabricado el vector usando cualquiera de los métodos que vimos en la sexta sesión, escribiendo por ejemplo:

unaMatriz=matrix(1:15,nrow=3)

y el resultado sería el mismo. Asimismo podemos emplear un vector guardado previamente mediante su nombre (y de esa manera puedes, por ejemplo, con lo que ya sabes de anteriores sesiones, fabricar una matriz a partir de los datos de un fichero csv).

¿.Y si quiero rellenar por filas (porque me resulta más natural, probablemente)? Pues basta con añadir una opción byrow=T a la  función matrix:

unaMatriz=matrix(1:15,nrow=3,byrow=T)
unaMatriz

Y ahora se obtiene

> unaMatriz=matrix(1:15,nrow=3,byrow=T)
> unaMatriz
[,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15

como queríamos.

Otra opción es usar la función t (simplemente la letra t), que traspone una matriz. Prueba a ejecutar este código para ver como funciona:

unaMatriz=matrix(1:15,nrow=3)
unaMatriz
matrizTranspuesta=t(unaMatriz)
matrizTranspuesta

Una pregunta natural cuando se usa la función matrix es ¿y qué pasa si las dimensiones de la matriz no casan con la longitud del vector? Por ejemplo, si tratamos de meter 13 datos en una matriz de  3 filas:

unaMatriz=matrix(1:13,nrow=3)
unaMatriz

El resultado es que se obtiene:

> unaMatriz
[,1] [,2] [,3] [,4] [,5]
[1,]    1    4    7   10   13
[2,]    2    5    8   11    1
[3,]    3    6    9   12    2

y una advertencia en la ventana de mensajes. R nos avisa de que el vector no era suficiente para rellenar la matriz y por esa razón ha vuelto al principio del vector, utilizando 1 y 2 para rellenar la parte restante de la matriz. Esta forma de trabajar de R nos puede resultar más o menos conveniente o convincente, pero en cualquier caso hay que conocerla.

Matrices por filas y columnas: cbind y rbind.

Otra manera de fabricar matrices a partir de vectores es utilizar las funciones rbind y cbind (donde r y c proceden de row, fila y column, columna, respectivamente) para escribir las filas o columnas directamente como vectores. Por ejemplo, el código

vectorFila1=2:5
vectorFila2=1:4
vectorFila3=c(-2,1,4,7)
matrizPorFilas=rbind(vectorFila1,vectorFila2,vectorFila3)
matrizPorFilas

produce este resultado:

> matrizPorFilas
[,1] [,2] [,3] [,4]
vectorFila1    2    3    4    5
vectorFila2    1    2    3    4
vectorFila3   -2    1    4    7

Y para ilustrar la función cbind vamos a añadirle una columna más a esta matriz, escribiendo:

quintaColumna=c(11,17,-4)
matrizModificada=cbind(matrizPorFilas,quintaColumna)
matrizModificada

que produce:

> matrizModificada
                          quintaColumna
vectorFila1  2 3 4 5            11
vectorFila2  1 2 3 4            17
vectorFila3 -2 1 4 7            -4

Obsérvese que cuando construimos la matriz mediante cbind y rbind, R usa los nombres de los vectores como nombres de las filas y columnas correspondientes. Volveremos pronto sobre esto (en una próxima entrada).

Dataframes

Después de conocer la forma en que R maneja las variables cualitativas, y de aprender un poco más sobre matrices, podemos estar tentados de combinar ambas ideas. Por ejemplo, puede resultar útil disponer de una tabla en la que guardamos, para cada uno de los pacientes ingresados en una planta de un hospital, su género (hombre o mujer),  su edad y el número de días que llevan ingresados. Algo como el contenido de este fichero pacientes.csv .

Puesto que cada columna contiene unos datos, podemos introducir los datos mediante vectores por columnas (usando cbind). El código sería:

vectorColumna1=c("hombre","mujer","mujer","mujer","hombre","hombre","mujer","mujer","hombre")
vectorColumna2=c(53,67,31,56,25,43,41,76,17)
vectorColumna3=c(3,1,4,2,1,7,2,4,8)
matrizPorColumnas=cbind(vectorColumna1,vectorColumna2,vectorColumna3)
matrizPorColumnas

y el resultado es:

> matrizPorColumnas
vectorColumna1 vectorColumna2 vectorColumna3
[1,] "hombre"       "53"           "3"
[2,] "mujer"        "67"           "1"
[3,] "mujer"        "31"           "4"
[4,] "mujer"        "56"           "2"
[5,] "hombre"       "25"           "1"
[6,] "hombre"       "43"           "7"
[7,] "mujer"        "41"           "2"
[8,] "mujer"        "76"           "4"
[9,] "hombre"       "17"           "8"

¿Perfecto, verdad? Espera un momento, algo va mal; esas comillas en las columnas de números no deberían estar ahí…

Para comprobar que en efecto tenemos un problema, tratemos de calcular la media de esa columna. Primero vemos el contenido de la columna (con matrizPorColumnas[,2]):

matrizPorColumnas[,2]
mean(matrizPorColumnas[,2])

Y al tratar de calcular la media obtenemos NA y un mensaje de advertencia en la ventana de mensajes.:

[18] NOTA: Aviso en mean.default(matrizPorColumnas[, 2]) :
argument is not numeric or logical: returning NA

¿Qué ha sucedido? Pues que nos hemos topado con la principal limitación de las matrices de R (que afecta también a los vectores, aunque hasta ahora no se nos había planteado el problema). Una matriz está formada por elementos que son todos del mismo tipo. Todos numeric, o todos de tipo character, pero no se admiten mezclas. Por eso, cuando le hemos pedido a R que usara los tres vectores columna para hacer una matriz, ha hecho lo que ha podido: ha convertido las columnas de números a tipo character, y las ha usado como tales (la conversión contraria, convertir character a numeric casi nunca tiene sentido, por eso R ha hecho lo que ha hecho).

Vaya decepción. Entonces, ¿en R no puedo escribir una tabla en la que se mezclen números y nombres? ¡Los dataframes al rescate! Un dataframe está pensado exactamente para eso, para albergar una tabla con tipos mixtos de datos. Veamos como funcionaría en este ejemplo:

pacientes=data.frame(vectorColumna1,vectorColumna2,vectorColumna3)
pacientes

Como puede verse, ahora no hay problema, el resultado es:

> pacientes
vectorColumna1 vectorColumna2 vectorColumna3
1         hombre             53              3
2          mujer             67              1
3          mujer             31              4
4          mujer             56              2
5         hombre             25              1
6         hombre             43              7
7          mujer             41              2
8          mujer             76              4
9         hombre             17              8

y si queremos calcular la media de la segunda columna, podemos hacer:

mean(pacientes[,2])

y se obtiene el resultado deseado.

> mean(pacientes[,2])
[1] 45.44444

Puesto que la columna dos tiene nombre (vectorColumna2), podemos conseguir lo mismo con esta otra notación  con el símbolo $ (volveremos a encontrarla en futuras entradas):

mean(pacientes$vectorColumna2)

Y ya que estamos en ello, es el momento de darse cuenta de que los nombres de las columnas en nuestro flamante data.frame no son especialmente afortunados. Podríamos haber sido más cuidadosos al elegir los nombres de los vectores, pero incluso si no lo hemos sido, todavía tiene remedio. Podemos hacer:

colnames(pacientes)=c("genero","edad","diasHospital")
pacientes

Y ahora se obtiene:

> pacientes
genero edad diasHospital
1 hombre   53            3
2  mujer   67            1
3  mujer   31            4
4  mujer   56            2
5 hombre   25            1
6 hombre   43            7
7  mujer   41            2
8  mujer   76            4
9 hombre   17            8

como queríamos.

En estos primeros ejemplos ya hemos visto que los dataframes se pueden manejar de manera muy parecida a como se hace con las matrices. En próximas entradas iremos aprendiendo más sobre ellos, por el procedimiento de usarlos. De momento, si quieres ver más ejemplos, te conviene saber que R incorpora una buena cantidad de dataframes de ejemplo. Para ver la lista escribe el comando

data()

y aparecerá (en otra ventana). Uno de los ejemplos es el dataframe llamado crabs. Puedes ver su contenido tecleando en R simplemente

crabs

y verás aparecer una tabla de datos (de 200 filas), con datos morfológicos de cangrejos (crabs, en inglés) del género Leptograpsus. Naturalmente, sin más información se hace difícil interpretar esta tabla. Para averiguar más sobre el fichero (o sobre casi cualquier otra cosa en R) puedes escribir su nombre precedido de una interrogación y ejecutar esa línea:

?crabs

Cuando lo hagas se abrirá una ventana de tu navegador (no te preocupes, aunque se abra el navegador no se necesita estar conectado a internet para esto), con información sobre el fichero, como en esta figura:

Finalmente, dataframes y ficheros csv. Funciones write.table y read.table

De la misma forma que hemos aprendido a usar scan y cat para leer y escribir vectores en ficheros csv, podemos leer y escribir dataframes a esos ficheros. Por ejemplo, para escribir el dataframe crabs a un fichero crabs.csv (que puedes abrir en Calc, por ejemplo), usaríamos la función write.table así (acuérdate de fijar el directorio de trabajo primero):

write.table(crabs,"crabs.csv",sep=" ",dec=",")

Un par de comentarios para explicar las opciones:

  1. la opción dec=”,” sirve para pedirle a R que al escribir el fichero reemplace los puntos decimales que emplea por comas. Esto es necesario si vas a usar el fichero en una versión española de Calc, que usa comas para los decimales.
  2. la opción sep=” ” le dice  a R que use espacios para separar los valores dentro de una línea del fichero csv. En este caso es necesario usar espacios, y no comas,  porque ya hemos usado comas para los decimales.

Si lo que queremos es leer un fichero de datos como el fichero pacientes.csv que vimos antes en esta misma entrada, podemos utilizar la función read.table así (¡recuerda fijar el directorio de trabajo!)

datosPacientes=read.table("pacientes.csv")
datosPacientes

Estos comandos producen esta salida:

> datosPacientes=read.table("pacientes.csv")
> datosPacientes
V1    V2
1 hombre ,53,3
2  mujer ,67,1
3  mujer ,31,4
4  mujer ,56,2
5 hombre ,25,1
6 hombre ,43,7
7  mujer ,41,2
8  mujer ,76,4
9 hombre ,17,8

donde vemos que, en efecto, R ha creado un nuevo data.frame datosPacientes, y le ha asignado automáticamente nombres V1 y V2 a las variables columna. En futuros encuentros con la función read.table aprenderemos más detalles sobre su funcionamiento.

Muchas gracias por la atención, especialmente en esta entrada tan extensa.

Séptima sesión con Rcmdr: paquetes y combinatoria. Datos en tablas

En la anterior sesión dejamos pendiente el problema de simular los lanzamientos de un par de dados. Queremos obtener resultados como (1,3) , (5,2), (4,3), etc. Vamos a utilizar este problema para aprender algunas cosas más sobre R.

Instalando paquetes adicionales

Más adelante, cuando veamos las estructuras básicas de bucles e iteración en R, dispondremos de otras maneras de construir los resultados. Pero, por el momento, para generar los valores que queremos, es mejor que nos aprovechemos del trabajo que otros han hecho por nosotros.

Una de las ventajas que se desprenden del hecho de que R sea un programa de código abierto esla gran cantidad de paquetes de código R que se han escrito, para resolver los problemas más variados. Ya hemos visto cómo guardar nuestros propios fragmentos de código en R. Otros usuarios, a menudo expertos en R y en alguna de sus aplicaciones, escriben sus propios fragmentos de código, para resolver problemas (a veces muy sofisticados). Y después ponen esos fragmentos de código, llamados a veces paquetes o librerías,  a disposición de la comunidad de usuarios de R, de forma libre y gratuita. A fecha de hoy, R-cran, que es el mayor almacén de código R,  contiene más de 4000 de esos paquetes. Para que te hagas una idea de lo que aportan, y lo elaborados que pueden lleagr a ser, la interfaz R-Commander que estamos usando es uno de esos paquetes.

Cuando instalas  R en tu ordenador, normalmente sólo instalas una pequeña parte de esos paquetes, para no hacer la instalación innecesariamente larga y complicada.Si quieres ver la lista de paquetes instalados en tu máquina, en la ventana Rgui (no es Rcmdr) utiliza el menú PaquetesCargar paquete…, y verás esa lista. Si en algún momento necesitas uno de los paquetes  que no llegaste a instalar, puedes conectar con un almacén en Internet, descargarlo e instalarlo de forma casi automática. Veamos cómo.

Para la sesión de hoy quiero usar un paquete que se llama gtools, que contiene, entre otras cosas, código para hacer Combinatoria. Cuando R arranca, lo normal es que sólo algunos de los paquetes instalados en nuestra máquina están disponibles (de nuevo para ahorrar recursos).  Para saber si el paquete gtools es uno de los que están instalados puedo buscarlo en la lista que hemos visto antes, o puedo teclear este comando, con el que le digo a R que quiero usar ese paquete:

library("gtools")

En este caso, el color rojo de la ventana de mensajes nos indica que algo ha ido mal, porque el paquete gtools no está instalado en nuestra máquina. Para instalarlo (conectados a internet, claro) tenemos que dirigirnos a la ventana  titulada Rgui, y usar el menú Paquetes → Instalar paquete(s)… Se abrirá una ventana, titulada CRAN mirror, en la que elegimos un mirror o almacén de paquetes R  Es conveniente elegir uno cercano geográficamente, así que yo voy a elegir Spain (Madrid). Tras unos instantes, en los que R descarga la lista de todos los paquetes disponibles en ese almacén, aparece una larga lista alfabética de paquetes. Ya casi hemos acabado, basta con localizar en esta lista el paquete gtools y pulsar en Ok

Si es el primer paquete que instalamos aparecerá una pregunta, en la que nos piden permiso para crear un “almacén local” de paquetes descargados en nuestro ordenador. Aceptamos, y comienza la descarga e instalación del paquete.

Cuando la instalación acabe, vuelve a Rcmdr, limpia la ventana de mensajes, y ejecuta de nuevo el comando library(“gtools”).  La ventana de mensajes ahora debería aparecer en verde. Ya podemos empezar el trabajo.

Permutaciones y combinaciones.

Los problemas típicos de la  Combinatoria más sencilla consisten en formar las combinaciones o permutaciones de unos objetos dados. En España distinguimos también variaciones, pero la tradición anglosajona considera las variaciones como otro tipo de permutaciones. Recordemos que la diferencia entre unas y otras estriba en que, en las combinaciones, el orden en que se colocan los objetos no importa. En cambio en las permutaciones-variaciones, dos listas se consideran distintas si los objetos aparecen en ellas en un orden distinto.

El paquete gtools añade dos funciones nuevas a R, permutations y combinations, que nos van a servir precisamente para obtener esos resultados.  No se trata de saber cuántos hay, sino, de hecho, de construirlos y enumerarlos. Para verlas en acción vamos a utilizar estos comandos para fabricar todas las listas posibles de tres elementos, elegidos de entre cuatro posibles. Para empezar, no admitimos repeticiones de los elementos. Entonces, si el orden no importa, estamos formando las combinaciones de cuatro elementos tomados de tres en tres. Y si el orden importa, entonces se trata de las variaciones (un inglés diría permutaciones) de cuatro elementos tomados de tres en tres.

Los correspondientes comandos son (recuerda que has debido utilizar primero library(“gtools”)):

combinations(4,3)
permutations(4,3)

Y la salida que se obtiene es, para el primer comando (combinaciones):

> combinations(4,3)
[,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    4
[3,]    1    3    4
[4,]    2    3    4

mientras que para el segundo comando (permutaciones), la salida es

> permutations(4,3)
[,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    4
[3,]    1    3    2
[4,]    1    3    4
[5,]    1    4    2
[6,]    1    4    3
[7,]    2    1    3
[8,]    2    1    4
[9,]    2    3    1
[10,]    2    3    4
[11,]    2    4    1
[12,]    2    4    3
[13,]    3    1    2
[14,]    3    1    4
[15,]    3    2    1
[16,]    3    2    4
[17,]    3    4    1
[18,]    3    4    2
[19,]    4    1    2
[20,]    4    1    3
[21,]    4    2    1
[22,]    4    2    3
[23,]    4    3    1
[24,]    4    3    2

que, evidentemente es más larga, puesto que ahora tenemos en cuenta la ordenación.

¿Y para lanzar dos dados? Bueno, si queremos obtener resultados equiprobables, debemos distinguir el orden (como si cada dado fuera de un color), y además, a diferencia de los dos ejemplos anteriores, debemos permitir resultados repetidos. Con esas premisas, hacemos

dosDados=permutations(6,2,repeats.allowed=TRUE)
dosDados

y obtenemos  los 36 resultados esperados:

[,1] [,2]
[1,]    1    1
[2,]    1    2
[3,]    1    3
[4,]    1    4
[5,]    1    5
[6,]    1    6
[7,]    2    1
[8,]    2    2
[9,]    2    3
[10,]    2    4
[11,]    2    5
[12,]    2    6
[13,]    3    1
[14,]    3    2
[15,]    3    3
[16,]    3    4
[17,]    3    5
[18,]    3    6
[19,]    4    1
[20,]    4    2
[21,]    4    3
[22,]    4    4
[23,]    4    5
[24,]    4    6
[25,]    5    1
[26,]    5    2
[27,]    5    3
[28,]    5    4
[29,]    5    5
[30,]    5    6
[31,]    6    1
[32,]    6    2
[33,]    6    3
[34,]    6    4
[35,]    6    5
[36,]    6    6

Ahora que ya vemos que esto funciona, podemos pararnos un momento y preguntarnos: estas respuestas que estamos obteniendo, que evidentemente no son vectores, ¿qué són? Y la respuesta es que los objetos como este dosDados que acabamos de fabricar son matrces, una estructura adecuada para almacenar datos en tablas.

Tablas de datos en R, un primer contacto

Las matrices son una de las formas que utiliza R para almacenar y organizar la información. (A este tipo de objetos -vectores, matrices, tablas, etc.- se los conoce en Informática como Estructuras de Datos). Su manejo tiene muchos parecido con lo que ya hemos aprendido en el caso de los vectores. Si vuelves a mirar la anterior matriz (la de los dos dados), verás que R la ha adornado con corchetes, que son de hecho una forma de indicarnos cómo se accede a los distintos elementos de la matriz. Por ejemplo, si escribes:

dosDados[23,]

obtendrás  como respuesta

> dosDados[23,]
[1] 4 5

Es decir, la fila número 23 de la matriz. Si lo que quieres es obtener su segunda columna, escribe

dosDados[,2]

y la respuesta de R será un vector con los elementos de esa columna:

> dosDados[,2]
[1] 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6

Como puede verse, los números entre corchetes que rodean la matriz nos ayudan a recordar  todo esto.  Si queremos, por poner un ejemplo, calcular la suma de los dados en cada tirada, podemos hacer:

sumaTiradas=dosDados[,1]+dosDados[,2]

y veremos aparecer un vector con esas sumas. Y si necesitas saber las dimensiones de la matriz (cuántas filas y cuuántas columnas tiene), puedes usar la función dim:

dim(dosDados[,1])

para averiguar esas dimensiones.Por su parte, la función length te dirá cuántos elementos tiene la matriz (en este caso, 72).

También podemos usar la notación de corchetes para seleccionar los elementos de la matriz que cumplen alguna condición, como hacíamos con los vectores. Por ejemplo, las filas en las que el segundo dado (la segunda columna) es 4 o más, se seleccionan con:

dosDados[dosDados[,2]>=4,]

que produce como resultado una nueva matriz con los resultados que queremos. Atención: los números de fila de esta nueva matriz no se corresponden con los de la original. Antes de cerrar esta entrada, te propongo un pequeño ejercicio: trata de adivinar lo que se obtiene con este comando:

dosDados[(dosDados[,1]+dosDados[,2])>7,]

En esta entrada hemos avanzado bastante, y hemos conseguido nuestro objetivo de representar las 36 tiradas diferentes de dos dados. Todavía podemos ir un poco más allá, pero para eso necesitamos aprender sobre estructuras de control. Con eso estaremos en condiciones de escribir auténticos programas en R. Eso lo veremos en las próximas entradas.

Gracias por la atención.

Sexta sesión con Rcmdr: más sobre vectores y combinatoria.

Cualquier curso de introducción a la Estadística incluye, a su vez, una introducción a la Probabilidad. Y los ejemplos iniciales de cálculo de probabilidades recurren necesariamente (por simplicidad, y por razones históricas) a juegos de azar, como los dados, lanzamientos de monedas, loterías, ruletas, etc. Estas situaciones simplificadas, e idealizadas, sirven de modelo a muchas otras que encontramos después en aplicaciones “más serias”. Y en muchas de ellas juega un papel la Regla de Laplace, que en esencia dice que, en un experimento en el que hay una familia de sucesos elementales equiprobables (SEE), la probabilidad del suceso A es:

P(A)=\dfrac{\mbox{n\'umero de SEE en los que ocurre A}}{\mbox{n\'umero total de SEE posibles}}

Para utilizar esta regla efizcamente hay que contar los sucesos que cumplen una cierta condición. Y contar, por elemental que pueda parecer, es una actividad extremadamente complicada. La rama de las matemáticas que se encarga de este tipo de problemas es la Combinatoria. Y en esta entrada vamos a empezar a utilizar la combinatoria como excusa para aprender un poco más sobre cómo se fabrican vectores a medida con R, y a mejorar nuestras habilidades con esos vectores.

Fabricando vectores a medida

Ya sabemos que, en R, podemos crear un vector con la función c, simplemente  enumerando sus elementos, como en

unVector=c(2,7,2,3,1,5)

Esto está muy bien, pero si queremos fabricar así un vector que contenga los números del 1 al 1000, es muy probable que antes de acabar nos invada la melancolía (por no mencionar el hecho de que, casi con seguridad, cometeremos algún error). Afortunadamente, R dispone de mecanismos para simplificar este tipo de tareas repetitivas. En este ejemplo, basta con usar:

milNumeros=1:1000
milNumeros

La segunda líneas, ya lo sabemos, es para ver el resultado. Y se obtiene:

(Por cierto, el resultado puede servir para entender porque R no muestra ningún resultado a menos que se lo pidamos explícitamente).

Es un avance sin duda, pero aún no resuelve muchos problemas. ¿Y si queremos los números del 1 al 1000, pero saltando de tres en tres? El lector mañoso tal vez habrá pensado “hago un vector con los primeros 333, y lo multiplico por 3…”. Pero en R hay una manera mucho más sencilla, usando la función seq. Hacemos:

deTresEnTres=seq(1,1000,3)
deTresEnTres

Y ahora la salida es:exactamente lo que queríamos.

La función seq permite fabricar vectores cuyos elementos se diferencian en una cantidad fija; que puede ser cualquier número, entero, fraccionario, expresado con decimales, etc.  Hay otra función, la función rep, estrechamente emparentada con est, cuyo principal uso es fabricar vectores siguiendo un patrón. El nombre rep viene de repeat, repetir. Y eso ayuda a adivinar lo que sucede si escribimos estos comandos:

datos=c(1,2,3,4,5)
rep(datos,3)

La salida correspondiente es, como cabría esperar, el vector datos repetido tres veces:

> datos=c(1,2,3,4,5)
> rep(datos,3)
[1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5

Quizá no sea tan fácil adivinar lo que sucede con este otro comando:

datos=c(1,2,3,4,5)
rep(datos,c(2,9,1,4,3))

Si lo ejecutamos,  la salida es:

> datos=c(1,2,3,4,5)
> rep(datos,c(2,9,1,4,3))
[1] 1 1 2 2 2 2 2 2 2 2 2 3 4 4 4 4 5 5 5

Y ahora está más claro lo que sucede: el segundo argumento nos dice cuántas veces debemos repetir cada uno de los correspondientes elementos del vector datos (el primer argumento).

Este funcionamiento de rep es especialmente interesante cuando tenemos una tabla de frecuencias.  Todavía no hemos visto, en este blog, como crear tablas en R (aunque nos hemos encontrado con las primeras al hacer Estadística Descriptiva). Pero vamos a suponer que tenemos dos vectores:

valores=c(2,3,5,8,13)
frecuencias=c(5,7,12,2,14)

de manera que el primero contiene los valores (distintos) que aparecen en nuestros datos, y el segundo contiene las frecuencias de esos valores (por supuesto, los dos vectores tendrán la misma longitud). Entonces , para recuperar el conjunto inicial de datos (sin agrupar) partiendo de esta “tabla de frecuencias”, podemos usar así la función rep:

valores=c(2,3,5,8,13)
frecuencias=c(5,7,12,2,14)
datosSinAgrupar=rep(valores,frecuencias)
datosSinAgrupar

Y se obtiene este resultado:

> valores=c(2,3,5,8,13)
> frecuencias=c(5,7,12,2,14)
> datosSinAgrupar=rep(valores,frecuencias)
> datosSinAgrupar
[1]  2  2  2  2  2  3  3  3  3  3  3  3  5  5  5  5  5  5  5  5  5  5  5  5  8  8 13 13
[29] 13 13 13 13 13 13 13 13 13 13 13 13

(Recuerda que la colocación del vector salida depende de la anchura de tu ventana de Rcmdr. Aquí aparecen [1] y [29], pero en tu máquina aparecerán seguramente otros valores, o sólo uno de ellos.)

Finalmente, si lo que queremos es ordenar un vector de números, la función sort viene en nuestra ayuda. Por ejemplo, el resultado de estos comandos:

datos=c(12,13,93,4,42,77,24,15,79,49,20,70,46,33,10,15,62,48,56,88,74,68,8,83,94,48,95,61,15,32)
sort(datos)

es este, en el que aparece el vector ordenado:

> datos=c(12,13,93,4,42,77,24,15,79,49,20,70,46,33,10,15,62,48,56,88,74,68,8,83,94,48,95,61,15,32)
> sort(datos)
[1]  4  8 10 12 13 15 15 15 20 24 32 33 42 46 48 48 49 56 61 62 68 70 74 77 79 83 88 93 94 95

Una aclaración importante. Esta ordenación no afecta en absoluto al vector datos original. Si quieres ordenar el vector y guardar el vector ordenado con el mismo nombre, entonces puedes usar el comando

datos = sort(datos)

pero es importante entender que este es un viaje sin retorno: el vector datos original, sin ordenar, se habrá perdido, y sólo tendremos la versión ordenada. ¡Cuidado con la posible pérdida de información!

Lanzando los dados: la función sample

Disponer de ordenadores, que hacen el trabajo duro por nosotros,  nos permite realizar muchos experimentos en los que poner a prueba nuestras ideas . En los primeros pasos dentro del mundo de la probabilidad, pensamos a menudo en ejemplos que involucran el lanzamiento de un dado.¿Cómo podemos usar R para “lanzar un dado virtual”? La forma más sencilla de hacerlo es utilizar otra función que fabrica vectores, la función sample.El código que usa esta función para simular 100 lanzamientos de un dado es este:

sample(1:6,100,replace=TRUE)

Los tres argumentos de la función sample, en este ejemplo simple, son:

  • el rango de resultados deseados. Por ejemplo, para un dado, del 1 al 6.
  • el número de valores que queremos obtener. Es decir, cuántas veces tiramos el dado, que aquí son 100.
  • en principio, R no admite repeticiones de valores que ya han aparecido (son muestras sin remplazamiento). Si queremos valores repetidos (remplazamiento), debemos indicarlo con el argumento replace=TRUE.

Y el resultado es algo como esto:

> sample(1:6,100,replace=TRUE)
[1] 1 3 1 6 4 6 5 5 5 4 2 2 1 1 4 5 1 3 3 6 1 2 6 6 6 6 1 2 2 5 5 2 3 5 1 2 6 4 6 1 6 2 4 2 5 5 4 1
[49] 3 1 6 5 4 5 5 3 5 2 4 2 6 6 3 3 1 1 1 1 2 1 2 6 4 4 3 5 4 1 3 1 1 3 5 3 6 2 4 6 5 1 5 6 2 3 5 5
[97] 6 3 5 4

En tu máquina los números serán distintos, claro está, porque la función sample está eligiendo aleatoriamente los valores (y en este caso, todos son equiprobables).

Si quieres saber cuántas veces ha aparecido cada uno de los valores, puedes utilizar

unDadoCienVeces=sample(1:6,100,replace=TRUE)
table(unDadoCienVeces)

Le hemos dado un nombre al vector para facilitar las cosas, y para que puedas hacer un experimento: en lugar de 100, escribe 100000, y compara las frecuencias con las anteriores. Además, si no le pusiéramos nombre, al ejecutar el comando verías desfilar ante tus ojos 100000 números en la ventana de resultados…

La función sample permite hacer ajustes mucho más finos que los que hemos visto en este primer ejemplo. Volveremos sobre esto en próximas entradas, pero por el momento nos despedimos de ella con un ejemplo que pretende preparar el terreno y avivar la curiosidad. Ejecuta unas cuantas veces este comando, observa los resultados  y trata de adivinar lo que está pasando (como pista, prob viene de probabilidad):

sample(c(1,2,4,7),100,prob=c(0.2,0.1,0.1,0.6),replace=TRUE)

Seleccionando elementos de vectores

Hemos lanzado 100 veces un dado, y hemos hecho la tabla de frecuencias del vector unDadoCienVeces resultante de ese experimento. Eso nos permite saber cuántas veces ha aparecido, por ejemplo, el número 5. Pero no nos permite saber cuál fue el resultado precisamente en la tirada número 23.  Para averiguar esto, en R escribimos

unDadoCienVeces[23]

De esa forma, usando los corchetes, podemos acceder directamente a cualquier posición del vector. Por ejemplo, el primer y el último elemento del vector son:

unDadoCienVeces[1]
unDadoCienVeces[length(unDadoCienVeces)]

En este caso sabemos que el vector tiene 100 elementos, y para obtener el último elemento podríamos haber escrito

unDadoCienVeces[100]

pero la otra versión (usando length) tiene la ventaja de que seguirá funcionando aunque el vector cambie.

Este recurso de los corchetes es mucho más potente de lo que parece a primera vista. Podemos seleccionar varios elementos a la vez indicando sus posiciones. Para seleccionar los elementos de unDadoCienVeces en las posiciones de la 12 a la 27 hacemos:

unDadoCienVeces[12:27]

y obtenemos un vector con los números que ocupan exactamente esas posiciones. Y si las posiciones que queremos no son consecutivas, basta con indicarlas mediante un vector:

unDadoCienVeces[c(3,8,21,43,56)]

nos proporciona los elementos en esas posiciones del vector. Cuando se combina esto con otras ideas que estamos viendo en esta entrada del blog se pueden conseguir resultados muy útiles. Por ejemplo, ¿qué crees que sucede al hacer esto? (Haz el experimento).

datos=1:100
datos
datos[seq(1,length(datos),3)]

Pero aún podemos ir más lejos. Podemos utilizarlo para seleccionar los elementos del vector que cumplen cierta condición. Por ejemplo, queremos saber cuántos de los resultados en unDadoCienVeces son mayores que 3. En primer lugar, igual que aprendimos (en la segunda sesión con Rcmdr) a sumar una cantidad a un vector, o a elevar un vector al cuadrado, etc., podemos también aplicar una condición lógica, como una desigualdad, a un vector:

unDadoCienVeces > 3

(Añado espacios por claridad; no cambia nada, los añadas o no). La respuesta es un nuevo vector como este (te recuerdo que en tu caso los resultados concretos variarán):

> unDadoCienVeces > 3
[1] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
[39] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[77]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE

Cada posición de este vector nos indica si la condición (o suceso) “ser mayor que 3” se cumple en la correspondiente posición del vector unDadoCienVeces. Si lo que queremos es obtener los valores originales del vector, entonces combinamos esta idea con la selección por corchetes:

unDadoCienVeces[ unDadoCienVeces > 3 ]

Y obtendremos una salida parecida a esta

> unDadoCienVeces[ unDadoCienVeces > 3 ]
[1] 6 5 6 6 5 5 4 6 5 4 6 4 6 4 5 5 4 4 5 5 6 4 4 4 4 4 5 4 6 5 5 5 6 4 5 6 5 4 4 5 5 5 5 5 6

con un vector en el que se ha seleccionado todos los elementos (y sólo esos elementos) del vector unDadoCienVeces que cumplen la condición “ser mayor que 3”.

Resumen final

Digerir esta entrada, en la que hemos visto muchos conceptos nuevos, puede llevar algo de tiempo y requiere de un rato de práctica con R. Haz todos los experimentos que quieras: son gratis y no vas a romper nada, claro. Con las técnicas que hemos aprendido, podemos dar los primeros pasos en el mundo de la probabilidad. Pero todavía, si queremos hacer un experimento tan sencillo como lanzar dos dados a la vez, y repetirlo 1000 veces, no disponemos del lenguaje necesario para representar esto en R de la forma más eficaz. Trataremos ese tema en la próxima sesión, en la que conoceremos las tablas de R (ya las hemos intuido, al pedirle a R que haga tablas de frecuencias).

Gracias por la atención.

Quinta sesión con Rcmdr: estadística descriptica con un vector (variable cuantitativa, datos no agrupados)

En esta sesión (quizá un poco más larga que las anteriores), vamos a empezar por fin el trabajo propiamente estadístico. Vamos a comenzar con un objetivo bastante modesto, pero para eso sirven los comienzos. Nuestro objetivo es trabajar con una colección de datos, concretamente un vector de datos, almacenados en un fichero csv. Para fijar ideas, vamos a trabajar con el mismo fichero edades01.csv, que ya usamos en la anterior sesión.

Hacemos esto para que nuestro viaje hacia el mundo de R sea lo más cómodo posible, partiendo de una cierta experiencia trabajando con hojas de cálculo. En una próxima sesión, una vez que hayamos introducido la noción de dataframe en R, volveremos a hacer este estudio, aprovechando las facilidades que proporciona para ello Rcmdr. Pero creo que es mejor empezar por lo más elemental, para que después podamos ver con más claridad donde estamos.

Así, que si no lo recuerdas, este es un buen momento para volver a la anterior sesión con Rcmdr, y ver cómo allí se utilizaba la función scan para leer el fichero csv y almacenarlo en un vector llamado vectorEdades. (Presta especial atención al directorio de trabajo en el que está ubicado el fichero). Ese vector contiene una lista de valores de una variable cuantitativa (de tipo discreto),  no agrupados por intervalos.  El tipo de análisis que vamos a hacer aquí se aplica a este tipo de variables; en otras entradas del blog comentaremos las diferencias que aparecen cuando el análisis se lleva a cabo con otros tipos de variables, o cuando trabajamos con datos agrupados.

Una vez cargados los datos, vamos a utilizar R para ir obteniendo, paso a paso, la descripción estadística de este conjunto de datos. Esta lista es como la lista que uno utiliza para hacer la maleta cuando se va de viaje. Algunas personas prefieren viajar con más equipaje, otras prefieren viajar más ligeros, y en cualquier caso la decisión siempre depende del tipo de viaje. Pero, a medida que uno va viajando, es muy posible que la lista sea cada vez más completa (sin llegar a ser enciclopédica).  La lista que vamos a presentar aquí es, seguramente, un compromiso razonable, un buen punto de partida, que el lector podrá ir completando a medida que gane experiencia viajando por la Estadísitica.

Iremos presentando los valores uno por uno, y al final los resumiremos todos en un fichero de instrucciones R que el lector puede usar como plantilla para este tipo de análisis.

1) Número y rango de los datos

Lo más básico es saber con cuántos datos estamos trabajando. Y para definir el rango de los datos necesitamos el valor mínimo y el máximo. Las instrucciones en R son:

n=length(vectorEdades)
n
min(vectorEdades)
max(vectorEdades)

2) Valores centrales (“medias”)

El siguiente paso puede ser calcular los valores centrales. Los mas sencillos son la media aritmética y la mediana. Los calculamos así:

mean(vectorEdades)
median(vectorEdades)

3) Medidas de dispersión: varianza, desviación típica.
Como siempre, al hablar de medidas de dispersión y software estadístico, se hace necesario hacer una advertencia. Es fundamental que el usuario comprenda si la varianza que está obteniendo es la varianza poblacional, definida así:

S^2=\dfrac{\sum_{j=1}^n (x_j-\bar x)^2}{n}

con n en el denominador, o si se trata de la varianza muestral (o cuasivarianza), definida así:

s^2=\dfrac{\sum_{j=1}^n (x_j-\bar x)^2}{n-1}

con n-1 en el denominador. En el caso de R, la función varsiempre calcula la varianza muestral (la cuasivarianza). ¿Y la varianza poblacional? Bueno, el caso es que, sorprendentemente, R no tiene una función para calcular directamente la varianza poblacional. Pero si se recuerda que la relación entre ambas varianzas es:

S^2=\dfrac{n-1}{n}\, s^2

entonces es muy fácil recuperar la varianza poblacional a partir de la función var de R (y del valor de n, que ya hemos obtenido en el primer punto).

La desviación típica muestral (respectivamente poblacional) es la raíz cuadrada de la varianza muestral (resp. poblacional). Como en el caso de las varianzas, R incluye una función, concretamente la función sd (de standard deviation),  para calcular directamente la desviación típica muestral de los elementos de un vector. Si lo que queremos es calcular la desviación típica poblacional,  calcularemos la varianza poblacional y haremos su raíz cuadrada. Y para eso es necesario saber que la raíz cuadrada se calcula con la función sqrt (de square root).

Con estas ideas, el código adecuado para calcular (y mostrar) ambas varianzas y desviaciones típicas es:

varianzaMuestral=var(vectorEdades)
varianzaMuestral
desvTipicaMuestral=sd(vectorEdades)

varianzaPoblacional=((n-1)/n)*varianzaMuestral
varianzaPoblacional
desvTipicaPoblacional=sqrt(varianzaPoblacional)
desvTipicaPoblacional

4) Medidas de posición: cuartiles y percentiles.

El cálculo de los cuartiles (o percentiles) en R, como en cualquier otro programa estadístico, requiere una discusión más detallada que los  valores anteriores que hemos discutido. Por un lado, si lo único que se desea es obtener la información por defecto que proporciona R, dejándo que sea el programa el que decida la mejor forma de proceder, entonces las cosas son muy sencillas. Basta con escribir

summary(vectorEdades)

Y, para el ejemplo con el que estamos trabajando, obtenemos (en la ventana de resultados) una tabla como esta:

> summary(vectorEdades)
Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
3.00    6.00    7.00    6.75    8.00   10.00

En la que aparece la información que buscábamos. Por otra parte, en lugar de utilizar summary, si sólo queremos uno de los cuantiles, o si lo que queremos son percentiles, podemos conseguir un control más fino de la respuesta utilizando la función quantile. Esta función necesita dos argumentos: el vector de datos, y un segundo vector en el que aparecen los porcentajes (expresados como tantos por uno) de los percentiles que queremos calcular. Por ejemplo, para pedirle a R que calcule (con el método que más le gusta) los percentiles 5%, 15% y 75% de vectorEdades escribimos este comando:

quantile(vectorEdades,c(0.05,0.15,0.75))
Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
3.00    6.00    7.00    6.75    8.00   10.00

y obtenemos

> quantile(vectorEdades,c(0.05,0.15,0.75))
5%  15%  75%
4.95 5.00 8.00

Aquí, como queremos mantener la discusión lo más simple posible, no vamos a entrar en más detalles técnicos sobre las decisiones que R toma para calcular estos números, pero queremos prevenir al lector de que las cosas se complican enseguida: en R hay varias (concretamente, nueve) formas distintas de calcular los cuartiles. Para no entretenernos aquí, dejaremos la información más detallada para otra entrada del blog.

5) Medidas de forma: simetría y apuntamiento.

En muchos cursos de introducción a la Estadística, al presentar la Estadística Descriptiva (típicamente uno de los primeros, si no el primer tema del curso), se describen también las llamadas medidas de forma de un vector de datos. Concretamente, se describen a menudo la simetría y apuntamiento (skewness y kurtosis, en inglés), como formas de saber cuánto se alejan nuestros datos de una distribución normal. Yo prefiero dejar que la distribución normal aparezca de una manera más natural, y más adelante en el curso,  pero en cualquier caso, añado aquí los comandos necesarios para calcular los coeficientes de simetría y apuntamiento  con R. UNa observación, el comando kurtosis no forma parte del núcleo central de comandos de R, y por eso es necesario cargar una librería para aplicarlo (de ahí el comando library(e1071) ):

skewness(vectorEdades)
library(e1071)
kurtosis(vectorEdades)

6) Tablas de frecuencias (absolutas, acumuladas, relativas)

A veces necesitaremos analizar los datos de un vector en forma de tabla de frecuencias. La tabla de frecuencias puede definirse agrupando los valores por intervalos, o simplemente haciendo un recuento de frecuencias para cada uno de los valores diferentes que forman el vector. La decisión depende de la naturaleza de los datos que forman el vector. Para el caso de vectorEdades (el ejemplo que estamos usando), la tabla de frecuencias (absolutas) , sin agrupar por intervalos se obtiene con el sencillo comando:

table(vectorEdades)

Y la respuesta es:

> table(vectorEdades)
vectorEdades
3  4  5  6  7  8  9 10
1  4 16 21 25 23  9  1

Si lo que queremos es una tabla de frecuencias acumuladas, entonces debemos aplicar la función cumsum al resultado de table. Es decir:

cumsum(table(vectorEdades))

que produce el resultado deseado:

> cumsum(table(vectorEdades))
3   4   5   6   7   8   9  10
1   5  21  42  67  90  99 100

Antes de seguir, queremos detenernos en un punto que puede pasar inadvertido. Hasta ahora, en este blog, y desde que empezamos a aprender sobre R, sólo hemos usado variables y vectores. Pero ahora estamos empezando a obtener tablas como resultado de nuestras operaciones. Las tablas son otra forma de almacenar, mostrar  y manipular datos en R. Y aún nos quedan muchos otros objetos en el camino: matrices, listas, datasets, factores… La lista es larga. Pero iremos aprendiendo sobre todos estos recursos sólo a medida que los necesitemos, y sólo los más sencillos ser necesarios en un primer encuentro con la Estadística.

Las tablas, que acabamos de conocer, se comportan en algunos sentidos como los vectores de R. Por ejemplo, si queremos multiplicar por dos todos los elementos de la tabla de frecuencias de vectorEdades, basta con hacer:

2*table(vectorEdades)

Y la respuesta es:

> 2*table(vectorEdades)
vectorEdades
3  4  5  6  7  8  9 10
2  8 32 42 50 46 18  2

Es decir, que lo que aprendimos de aritmética vectorial se extiende a las tablas. Esto tiene una consecuencia inmediata: la tabla de frecuencias relativas se obtiene simplemente dividiendo la tabla de frecuencias absolutas por el número n (el total de datos, es decir length(vectorEdades)). Y para la tabla de frecuencias acumuladas relativas aplicamos cumsum y luego dividimos. Esto es:

table(vectorEdades)/n
cumsum(table(vectorEdades))/n

7) Gráficos (de columnas y boxplot)

En Estadística el tipo de representación gráfica adecuada depende de la naturaleza de los datos. Para los datos que forman el vectorEdades, un gráfico de barras (no confundir con un histograma) puede ser la opción más sencilla y razonable, al tratarse de una variable aleatoria discreta, que ya hemos decidido antes no agrupar en intervalos. El gráfico se obtiene muy fácilmente mediante la función barplot de R, pero aplicada a la tabla de frecuencias de vectorEdades. Es decir:

barplot(table(vectorEdades))

Y el gráfico que se obtiene es este (cuidado; al menos en Windows, el gráfico no aparece en la ventana de Rcmdr, sino en la ventana llamada Rgui, que puede haber quedado cubierta por la de Rcmdr. A primera vista, puede parecer que el comando barplot no ha tenido efecto):

Dos observaciones:

  1. En R disponemos de muchísimas opciones para cambiar los colores, forma, rótulos, etc. de los gráficos. Nos vamos a conformar por el momento con las opciones más simples, pero conviene que el lector sepa que esto no es ni mucho menos el final de la historia con los gráficos de R.
  2. Naturalmente se pueden obtener gráficos similares a partir de las frecuencias relativas, acumuladas, etc.

El gráfico de caja y bigotes es otro tipo habitual de gráficos para datos como los que estamos manejando en este ejemplo. Y obtenerlo con R es también inmediato:

boxplot(table(vectorEdades))

produce como resultado: 

Resumen final

Con esto hemos completado un conjunto de análisis descriptivos del vector de datos bastante completo. Como resumen, y para faciltar el trabajo, agrupamos en este fichero todos los comandos que hemos utilizado. Hemos remplazado vectorEdades por un vectorDatos más genérico, para que el lector no tenga dificultad en reuitlizar este fichero para sus propios datos. Y hemos intercalado comentarios en el listado de comandos para ayudar a recordar el tipo de análisis que se está efectuando. En próximas entradas veremos análisis similares para valores agrupados por intervalos, variables cualitativas, etc.

Gracias por la atención

Cuarta sesión con Rcmdr: manejo elemental de datos almacenados en ficheros de texto (tipo csv)

Leer un fichero de tipo csv que contiene un vector

Ya vimos, en la anterior sesión, cómo se pueden almacenar los comandos que hemos utilizado en nuestro trabajo dentro de Rcmdr. Pero tenemos pendiente la tarea de aprender a importar los datos con los que vamos  a trabajar; y por supuesto, también debemos aprender a guardar los datos que podamos generar como resultado de nuestro trabajo en R.

En este blog ya hemos hablado anteriormente de los ficheros separados por comas (csv). Este nombre genérico describe un tipo de ficheros de texto que se usan a menudo para intercambiar datos entre distintos programas. Nosotros los vamos a usar para adentrarnos en el manejo con Rcmdr de volúmenes de datos que hacen incómodo  o inviable el trabajo “manual” de teclearlos. Y de paso, aprenderemos algo más sobre algunas estructuras de datos que luego nos resultarán útiles al avanzar en R.

El fichero edades01.csv  contiene la edad en años de una serie de individuos. Descárgalo en tu ordenador, para ver el aspecto de los datos. Lo abriremos con un editor de texto (el Bloc de Notas en Windows). Al hacerlo vemos el comienzo de una larga lista de datos, cada uno en una fila:

Queremos utilizar esos datos en R, como si fueran los  elementos de un vector que nosotros hubiéramos creado tecleándolos directamente (ver la segunda sesión, sobre vectores en Rcmdr). Para ello vamos a tener que empezar por explicarle a Rcmdr donde está el fichero que contiene esos datos. Para ello, en el menú Fichero de Rcmdr abrimos la opción Cambiar directorio de trabajo, como en la figura: Ahora se abrirá el típico cuadro de diálogo en el que debemos seleccionar la carpeta que contiene el fichero edades01.csv. Antes de seguir: este directorio de trabajo es el directorio desde el que R va a leer y en el que va a escribir todos los ficheros de datos que usemos en esta sesión. Así que conviene haberlo elegido con algo de buen juicio, para que luego no nos cause ningún problema localizar nuestros ficheros.

Para ilustrar este punto, y en una máquina con Windows, yo he creado una carpeta en el escritorio (Desktop) con el nombre FicherosR (puedes ponerle el nombre que quieras; aunque en general es buena idea evitar espacios, acentos, etc.). Y cuando la he seleccionado, Rcmdr me muestra este mensaje en la ventana de instrucciones: Esto me sirve además para ver (en la ventana de resultados) que la instrucción ya se ha ejecutado. Ya estamos listos para leer el fichero de datos.

Para ello vamos a utilizar la función scan de R. Aunque esta función tiene muchas opciones disponibles, nuestro primer uso de ella no podría ser más sencillo. Copia y ejecuta el siguiente código en Rcmdr:

vectorEdades=scan("edades01.csv")
vectorEdades

La segunda instrucción, como ya habrás adivinado, es para ver el resultado de la primera, que es donde ocurre la acción. En esa primera instrucción le decimos a R que use la función scan para leer el contenido del fichero edades01.csv, y que almacene lo que ha leído en un vector, que hemos decidido llamar vectorEdades. La ventana de resultados muestra el contenido de ese vector, con los 100 números que lo forman: Una advertencia: los números [1], [38] y [75] son sólo ayudas para que podamos localizar los elementos del vector. En mi pantalla la primera fila muestra los primeros 37 números del vector. Pero en la tuya, si la ventana de Rcmdr es de distinta anchura, los números entre corchetes pueden ser distintos.

En cualquier caso, ahora el vector vectorEdades contiene la información del fichero csv con el que habíamos  empezado, y podemos usarlo para hacer cálculos. Por ejemplo, podemos necesitar un vector en el que todas las edades aumenten en 5. Simplemente hacemos:

edadesIncrementadas=vectorEdades+5
edadesIncrementadas

Y en la ventana de resultados veremos aparecer inmediatamente el nuevo vector que hemos calculado.

Otra variante del fichero de entrada

Si ya has tenido alguna experiencia con ficheros csv, es posible que te estés haciendo preguntas somo esta: ¿qué hacemos si los datos del vector están todos en una fila, y por ejemplo separados por comas?

Es decir, qué hacemos si tenemos un fichero como el fichero edades02.csv, cuyo aspecto -visto a través de un editor de texto- es este:

Desde luego, no nos podemos plantear transformar “a mano” este vector en uno como el anterior. Podríamos buscar soluciones pasando por la hoja de cálculo (por ejemplo: lo leeríamos en una fila de la hoja, y luego habría que trasponerlo -es decir, girarlo- para finalmente volver a guardarlo). Afortunadamente, hay una solución, sin salir de R, bastante menos embrollada. Las instrucciones R para leer este fichero son muy parecidas a las que ya hemos visto. De nuevo usaremos la función scan, pero ahora debemos añadir un poco más de información para explicarle a R que los elementos de ese fichero están separados por comas.

Para experimentar esto, descárgate el fichero, guárdalo en la misma carpeta de antes, selecciónala como directorio de trabajo en Rcmdr, y ejecuta estas instrucciones

vectorEdades2=scan("edades02.csv",sep=",")
vectorEdades2

La novedad, naturalmente, es la inclusión de sep=”,” como argumento de scan.  Con ese argumento, la lectura de nuevo nos conduce a un vector de R que podemos manipular igual que antes.

Y el camino contrario:  escribir un vector a un fichero de tipo csv.

En el primer apartado de esta entrada, después de hacer operaciones con el vector vectorEdades hemos fabricado un nuevo – e interesantísimo – vector edadesIncrementadas, que queremos guardar o utilizar en otro programa (por ejemplo una hoja de cálculo, etc.). Lo natural es guardar ese vector en un fichero de tipo csv, como el fichero con en el que empezamos.  Para ello, si antes usábamos la función scan, ahora vamos a usar la función cat de R.

Podemos utilizar esa función pasando como argumentos simplemente el nombre del vector que queremos guardar, y el nombre del fichero en el que lo guardamos, de esta manera:

cat(edadesIncrementadas,file="edadesInc.csv")

No obstante, si hacemos esto, R fabricará un fichero en el que los elementos del vector aparecen uno tras otro separados por espacios: Y si lo que queremos es, como el fichero con el que empezamos, un fichero con un elemento del vector en cada fila, podemos usar un argumento más en la función cat. Ya tendremos tiempo de aprender más sobre el funcionamiento de cat; los mecanismos de lectura/escritura de R admiten muchas posibilidades de configuración, y entenderlas todas es laborioso. Pero por el momento nos conformamos con una solución sencilla. Podemos conseguir lo que queremos con este comando:

cat(edadesIncrementadas,file="edadesInc.csv",fill=1)

Añadiendo fill=1 el fichero que obtenemos tiene la forma de columna deseada: Finalmente: ¿y si lo que queremos es que los elementos del vector aparezcan todos en la misma fila, pero separados por comas? Entonces usaremos otra variante del comando con cat, que es este (he cambiado el nombre del fichero de salida, para evitar que sobrescriba el anterior):

cat(edadesIncrementadas,file="edadesInc2.csv",sep=",")

Y ahora el fichero resultante tiene este aspecto
Como ya hemos dicho, hay mucho más que aprender sobre scan y cat, pero con lo que hemos visto, tenemos suficiente para el manejo elemental de vectores usando ficheros csv.

Finalmente, para facilitar tu trabajo futuro con estos comandos, aquí tienes recopilados todos los pasos de esta sesión (¡pero recuerda cambiar el directorio de trabajo!):

#Leemos (y mostramos) un fichero csv que contiene un vector de datos en columna.
vectorEdades=scan("edades01.csv")
vectorEdades
#Calculamos (y mostramos) un nuevo vector, incrementando cada dato del original en 5.
edadesIncrementadas=vectorEdades+5
edadesIncrementadas
#Leemos (y mostramos) un segundo fichero csv, con un vector de datos separados por comas.
vectorEdades2=scan("edades02.csv",sep=",")
vectorEdades2
#Escribimos el vector incrementado a un fichero csv, con los datos en columna.
cat(edadesIncrementadas,file="edadesInc.csv",fill=1)
#Escribimos el mismo vector incrementado a un fichero csv, pero con datos separados por comas.
cat(edadesIncrementadas,file="edadesInc2.csv",sep=",")

Gracias por la atención.

Tercera sesión con Rcmdr: ficheros de comandos y comentarios

(Actualizado el 2013-06-25)

Terminábamos nuestra anterior sesión de trabajo con Rcmdr con la promesa de que nos íbamos a ocupar de un par de asuntos de organización que iban a hacer más fácil nuestro trabajo: guardar ficheros de comandos y  usar comentarios.

Ficheros de comandos

En la primera parte de la anterior sesión estuvimos trabajando con un vector edades,  que nos sirvió para empezar a practicar la aritmética vectorial en R. La lsita de comandos que usamos en la primera parte de esa sesión fue esta:

edades = c(22, 21, 18, 19, 17, 21, 18, 20, 17, 18, 17, 22, 20, 19, 18, 19, 18, 22, 20, 19)
edades
edades2 = c(22, 18, 20, 21, 20)
edades = c( edades, edades2)
edades
mean(edades)
mediaEdades=mean(edades)
sumaEdades=sum(edades)
sumaEdades
cuantosAlumnos=length(edades)
cuantosAlumnos
sumaEdades/cuantosAlumnos
edades^2

Esta lista de comandos, como la de cualquier otra sesión de trabajo en Rcmdr, se puede almacenar en un fichero de texto, y conservarla de esa manera, por si en el futuro la volvemos a necesitar, o por si, por ejemplo,  no podemos terminar el trabajo en una sola sesión, y queremos retomarlo después. O incluso, más interesante, para poder compartirla con otros usuarios de R.

Hay varias formas de guardar esa lista de comandos de nuestra sesión en Rcmdr. ¡Al fin y al cabo se trata simplemente de unas líneas de texto! Podemos por ejemplo,

  1. Marcarlas en la ventana de instrucciones de Rcmdr; si situas el cursor en cualquier punto de esa ventana y pulsas Ctrl+a, seleccionarás todo el contenido de la ventana (es decir, todos los comandos de  tu sesión de trabajo).
  2. Copiarlas al portapapeles (botón derecho del ratón o Ctrl+c)
  3. Pegarlas en un editor de texto (otra vez botón derecho, o Ctrl+v). El editor de texto puede ser el Bloc de Notas en Windows,  Textwrangler en Mac, o cualquiera de los que ya conocerás si eres usuario de Linux (kate, o leafpad, o gedit, por poner algunos ejemplos).
  4. Guardar el fichero de texto resultante. Es muy aconsejable añadirle la extensión R (en lugar de, por ejemplo, txt). De esa forma identificaremos rápidamente los archivos que contienen comandos de R.

Una segunda forma de hacer esto es utilizar la opción “Guardar las instrucciones como…” del menú Fichero de Rcmdr.  Con esa opción, Rcmdr hace directamente por nosotros el trabajo de fabricar un archivo de texto con los comandos de esta sesión de trabajo. La mayor virtud del otro método es que es más flexible, porque podemos seleccionar para guardar sólo la parte de la sesión de trabajo que nos interese. El resultado, en cualquier caso, será un fichero como este AritmeticaVectorial.R

Ya hemos visto como guardar las sesiones de trabajo en ficheros de texto. El camino inverso, para recuperar esas sesiones de trabajo, es casi evidente. Y de nuevo se puede hacer de dos formas. Si abrimos el fichero de extensión R con un editor de texto (como el Bloc de Notas)  podemos usar Copiar-y-pegar para transferir todo o parte de ese fichero a la ventana de instrucciones de Rcmdr (de hecho, esta técnica de copiar y pegar fragmentos de código la venimos usando en este blog desde la primera sesión con Rcmdr; ahora sólo lo hacemos oficial). Este es el método más flexible, porque nos permite controlar,  como decimos,  no sólo que parte de la sesión recuperamos, sino en que punto de la ventana de instrucciones la pegamos. De esa forma podemos mezclar código nuevo con código viejo. También podemos usar la opción “Abrir fichero de instrucciones…”  del menú Fichero de Rcmdr. Pero en este caso ¡cuidado! los contenidos de la ventana de instrucciones son remplazados por los del fichero que abrimos (y se pueden perder).  En última instancia puedes recuperarlos con Ctrl+z  mientras no cierres Rcmdr, pero mejor andarse con cuidado.

Documentando las sesiones de R: comentarios

Aprender a guardar nuestros ficheros de comandos R es sin duda muy útil. Nos permite volver a abrirlos al cabo de un aña, o tal vez un mes… y comprobar que no recordamos absolutamente nada de lo que hicimos cuando creamos ese fichero. A medida que vayamos escribiendo ficheros de R cada vez más complejos, creeme, este problema se hará cada vez pero, salvo que aprendamos a documentar como es debido nuestro trabajo. Documentar significa, en este contexto, añadir a las sesiones de R información que no está pensada para dar instrucciones al ordenador, sino que ha sido  pensada para ayudarnos a entender lo que se está haciendo en esa sesión de trabajo  (nosotros mismos u otros usuarios de ese fichero).

Hacer esto es muy fácil, porque R incluye un mecanismo sencillo para insertar comentarios en los ficheros de instrucciones R (de los que hemos hablado en el anterior apartado). Vamos a verlo en un ejemplo. Empezamos una sesión nueva de Rcmdr, con estas sencillas instrucciones:

a=1
a
a=a+1
a

Cuando ejecutes esto verás la salida previsible:

> a=1
> a
[1] 1
> a=a+1
> a
[1] 2

Primero le hemos dado a la variable a el valor 1 y hemos pedido a R que nos muestre ese valor. Luego hemos incrementado el valor de a en 1, y de nuevo le hemos pedido a R que lo muestre, obteniendo 2. Ninguna sorpresa. Ahora vuelve a la ventana de instrucciones y modifica la tercera instrucción añadiendo el símbolo # justo al principio, así:

a=1
a
#a=a+1
a

Y vuelve a ejecutar todo el código. La salida ahora es:Como puedes ver, las dos veces que le preguntamos a R por el valor de a, la respuesta (en azul) es la misma: 1. ¿Por qué? Pues porque el símbolo #, insertado en una línea de instrucciones, hace que R ignore todo el resto de línea, simplemente como si no estuviera ahí.

Esto tiene dos ventajas:

  1. nos permite documentar el código. Podemos utilizar # para insertar líneas en el código en las que explicamos los pasos que vamos dando. Esas líneas de comentariono son para el ordenador, son para los usuarios (humanos) del código. Por ejemplo, aquí tenemos una lista de instrucciones muy parecida a la que hemos usado antes.  Tenemos un vector de edades de alumnos de una clase, se incorporan unos cuantos alumnos nuevos, y queremos ver como afecta eso a la edad media de la clase. Eso se lleva a cabo con este fichero
    edades = c(22, 21, 18, 19, 17, 21, 18, 20, 17, 18, 17, 22, 20, 19, 18, 19, 18, 22, 20, 19)
     edades
     mean(edades)
     edades2 = c(22, 18, 20, 21, 20)
     edades = c( edades, edades2)
     edades
     mean(edades)
    

    Pero las cosas resultan mucho más claras si utilizamos líneas de comentarios para explicar lo que estamos haciendo, como en esta nueva versión del mismo conjunto de instrucciones:

    #Tenemos un vector con las edades de los alumnos de clase
    edades = c(22, 21, 18, 19, 17, 21, 18, 20, 17, 18, 17, 22, 20, 19, 18, 19, 18, 22, 20, 19)
    #mostramos el vector
    edades
    #Calculamos la edad media
    mean(edades)
    # Este segundo vector contiene las edades de los nuevos alumnos
    edades2 = c(22, 18, 20, 21, 20)
    # Concatenamos los vectores para actualizar la lista de clase
    edades = c( edades, edades2)
    #Vemos el resultado
    edades
    #Y ahora calculamos la edad media de los alumnos, después de incorporar a los nuevos.
    mean(edades)
    

    La diferencia entre los dos listados son las líneas que (aquí, en el blog, no en Rcmdr) se muestran en otro color. Desde el punto de vista de R, los dos conjuntos de instrucciones son idénticos. Pero para nosotros el segundo resulta más fácil de entender, porque los comentarios aportan las explicaciones necesarias. No siempre será necesario ni útil comentar todas y cada una de las líneas; ¡eso puede resultar contraproducente! Pero más vale pecar de exceso de comentarios que lamentar después su falta cuando, al cabo de un tiempo, no seamos capaces de entender el código; ni siquiera nuestro propio código.

  2. La segunda ventaja, que al principio de tu trabajo con R tal vez no resultará tan evidente, es una generalización de lo que hemos hecho al empezar a hablar de comentarios. Cuando cambiábamos la línea 
    a=a+1
    

    por esta otra

    #a=a+1
    

    no estamos “explicando” nada, sino que estamos cambiando el comportamiento de R. Y cambiarlo sólo nos cuesta el trabajo de introducir un símbolo. Esto permite tener un conjunto de instrucciones que se puede comportar de distinta manera, jugando con los símbolos de comentario. Veremos ejemplos de esto en próximas sesiones, para entender mejor lo práctico que puede llegar a ser.
    Gracias por la atención.

Segunda sesión con R-Commander

Vectores: primer ejemplo

En esta sesión vamos a empezar a utilizar R-Commander (Rcmdr) para hacer estadística, empezando por lo más elemental. Tenemos una lista de números, que puede ser la lista de edades de los alumnos de una clase:

22 21 18 19 17 21 18 20 17 18 17 22 20 19 18 19 18 22 20 19

Y queremos calcular la edad media de esos alumnos. ¿Cómo lo hacemos, usando Rcmdr?  En R, las listas de números como esta se almacenan en vectores. El vector que corresponde a esas edades se construye en R mediante un comando como este:

edades = c(22, 21, 18, 19, 17, 21, 18, 20, 17, 18, 17, 22, 20, 19, 18, 19, 18, 22, 20, 19)

Hemos creado una variable, llamada edades, en la que se va a guardar el vector con los datos. Esos datos están separados por comas, y rodeados por paréntesis. Hasta aquí todo es bastante típico, pero fíjate especialmente en la letra c que precede al primer paréntesis. Esa letra c es la forma que tiene R de crear un vector.

Prueba a hacerlo: copia el comando anterior en tu ventana de instrucciones y ejecútalo; recuerda Ctrl+r. Y recuerda también que R no te muestra el resultado de las asignaciones salvo que se lo pidas (y educadamente, claro). Así que teclea el nombre de la variable edades en la siguiente línea de la ventana de instruccciones, y ejecútalo. Tu ventana de Rcmdr debería tener un aspecto similar a este:

Prueba también a ejecutar la sentencia sin la letra c delante de los datos para que veas un bonito mensaje de error de R en la última ventana de Rcmdr que nos queda por presentar: la ventana de mensajes, situada en la parte inferior de la interfaz.

Operaciones con vectores

Imagínate que, como sucede a menudo, después de haber creado nuestra lista de edades de alumnos, desde la Administración nos avisan de que hay cinco alumnos nuevos, recién matriculados, y debemos incorporar sus edades, que son

22 18 20 21 20

a nuestro vector de datos. Naturalmente, podemos emepzar de nuevo, pero preferimos reutilizar el vector edades que ya habíamos creado. Vamos a ver esto como primer ejemplo para empezar a aprender cómo se manipulan vectores en R.

Concatenando vectores

Una forma de añadr los datos es empezar creando un nuevo vector:

edades2 = c(22, 18, 20, 21, 20)

Y a continuación concatenamos los vectores, usando de nuevo la letra c, de una manera distinta:


edades = c( edades, edades2)

edades

Vamos a analizar paso a paso lo que ha ocurrido:

  1. La instrucción c( edades, edades 2) toma los datos contenidos en edades y edades2 y los usa, en ese orden, para fabricar un nuevo vector, que todavía no está guardado en ninguna variable.
  2. La asignación edades=c( edades, edades 2) toma ese vector y lo guarda en la propia variable edades. Al hacer esto, como era de esperar, el anterior vector edades es reemplazado con la nueva lista, y su contenido anterior se pierde (cuidado con esto; las reasignaciones son una de las formas habituales de cometer errores).

El resultado debería ser este

y como puede verse, el vector edades contiene ahora el resultado de concatenar ambas listas de edades.

Calculando la media

Ahora ya tenemos nuestro vector de edades completo, y podemos calcular la media. No podría ser más sencillo, Escribimos y ejecutamos el comando:

mean(edades)

El resultado aparece en la ventana inferior. Recuerda; cuando guardas algo, R no te muestra el resultado; pero si le pides que haga una operación, entonces sí verás el resultado. Para profundizar en esto, prueba a escribir esta instrucción en la siguiente línea, ejecútala y compara el resultado con el anterior.

mediaEdades=mean(edades)

Deberías obtener algo como esto

Naturalmente, esa media es el resultado de dividir la suma de los elementos que forman el vector por el número de elementos del vector (la longitud del vector). Esos dos ingredientes se pueden calcular por separado en R con sendas funciones, sum y length. Ejecuta estas líneas de código para ver en acción a ambas funciones, que nos proporcionan otra manera de calcular la media:

sumaEdades=sum(edades)
sumaEdades
cuantosAlumnos=length(edades)
cuantosAlumnos
sumaEdades/cuantosAlumnos

Después de ejecutar este grupo de comandos, asegúrate de mirar la ventana de resultados para comprobar que, de  nuevo, hemos calculado la media.

Pronto aprenderemos muchas otras funciones para realizar los cálculos estadísticos habituales.

Aritmética vectorial

Una de las características más utiles la gestión de vectores con R es la forma en la que se realizan las operaciones con vectores. Por ejemplo, para algunas operaciones estadísticas es necesario calcular el cuadrado de la edad de cada uno de nuestros alumnos. En lugar de hacer eso a mano, en R podemos simplemente ejecutar

edades^2

La respuesta de R (compruébalo en tu ventana de resultados) es:

> edades^2
[1] 484 441 324 361 289 441 324 400 289 324 289 484 400 361 324 361 324 484 400 361 484 324 400 441 400

Lo que R ha hecho es calcular un nuevo vector que contiene en cada posición el cuadrado del correspondiente elemento del vector edades.  También puedes probar a multiplicar el vector edades por 2, a sumarle 5, etc. Prueba estas operaciones ejecutando:

2*edades
edades+5

Y asegúrate antes de seguir de que entiendes las respuestas de R.
Ahora vamos a trabajar con dos vectores. Ejecuta estos comandos (yo he hecho un poco de limpieza en mis ventanas de Rcmdr antes de hacer esto):

vector1=c(2,4,-1,3)
vector2=c(1,0,2,-3)
vector1+vector2
vector1*vector2

Deberías obtener algo como esto:que muestra, otra vez, que en R las operaciones con vectores se hacen componente a componente, sumando o multiplicando cada pareja de elementos que ocupan la misma posición en cada uno de los dos vectores.

Pero…espera un momento, ¿qué pasa si los dos vectores no son de la misma longitud? Pues sucede algo interesante, y que en cualquier caso conviene conocer para evitar errores. Te invito a que lo descubras ejecutando este ejemplo:

vector3=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
vector4=c(0,1,2)
vector3+vector4

El resultado es:

¿Qué ha hecho R? Puedes entenderlo así: al principio empieza sumando normalmente, posición a posición. Pero tras sumar tres posiciones, R descubre que vector4 se ha agotado. Y lo que hace es simplemente volver al principio de vector4 y comenzar de nuevo a utilizar sus elementos desde el primero. Así pues, en el resultado,  se suma el vector 0,1,2 con 1,2,3 y luego se vuelve a sumar 0,1,2 con 4,5,6, (para dar 4,6,8 de resultado) y así, consecutivamente, vamos recorriendo la suma hasta que el vector más largo, vector3, se agota a su vez.

En este ejemplo hemos tecleado “a mano” un vector como el vector3, formado por los números del 1 al 20. Si se hubiera tratado de los números del 1 al 100 el trabajo habría sido mucho más pesado, e insufrible para 1000 números. En R existen mecanismos para fabricar vectores utilizando diversas recetas. Por ejemplo, si pruebas a ejecutar:

vector5=c(1:1000)
vector5

verás que fabricar un vector con los números del 1 al 1000 es muy sencillo en R. ¿Te animas a fabricar un vector con los cuadrados de los números del 500 al 800?

En próximas sesiones ampliaremos esta y otras formas de fabricar vectores en R. Pero antes, para hacer nuestra vida más cómoda, debemos aprender algunas características del programa que hacen nuestra vida más sencilla: guardar nuestro trabajo de una sesión a otra, añadir comentarios, conseguir ayuda, etcétera. Eso lo veremos en nuestra próxima sesión de trabajo con Rcmdr.

Gracias por la atención.

Primera sesión con R-Commander

Con esta entrada pretendo iniciar una serie de artículos que sirvan de introducción al uso del programa  R,  para cálculos estadísticos, y de la interfaz gráfica Rcmdr, que permite un uso más intuitivo de R. Los artículos incluirán ejemplos y fragmentos  de código R que puedes copiar y pegar directamente en Rcmdr para usarlos mientras practicas. De hecho, cuando veas uno de esos fragmentos sobre un fondo gris claro, puedes pulsar sobre él con el ratón y verás aparecer unos iconos como estos

que te permiten, entre otras cosas, copiar todo el fragmento de código directamente al portapapeles.

Para empezar nuestra primera sesión de trabajo, vamos a suponer que ya tenemos instalado el paquete R-Commander. Una de las formas más sencillas de hacerlo, para los usuarios de Windows, es utilizar el paquete R-UCA de la Universidad de Cádiz. En esa misma página encontrarás instrucciones para instalarlo en Ubuntu Linux (válidas para sistemas basados en Debian). Si eres usuario de Mac, en este enlace tienes unas instrucciones actualizadas (en inglés) sobre la instalación de Rcmdr (siempre te queda la opción de usar un buscador).

Cuando arrancamos el paquete R-Commander por primera vez nos encontraremos con esta pantalla.

En esta primera toma de contacto con R, a través de R-Commander, vamos a aprender a usar R como una calculadora. El objetivo principal es que empecemos a familiarizarnos con la sintaxis de R y con las peculiaridades de la interfaz de R-Commander (a partir de ahora Rcmdr).

Así que vamos a ello. Situate con el ratón en la ventana superior de Rcmdr (la ventana de instrucciones), y teclea:

a=2
a^2

La primera línea le dice a R que asigne el valor 4 a la variable a. Y la segunda le pide que calcule el cuadrado. El resultado, naturalmente, será 4, pero al teclear estas líneas R aún no ha hecho nada, no se da por aludido.

Para que suceda algo tenemos que pedirle a R que ejecute las líneas de código que hemos tecleado. Hay dos formas de hacer esto:

  1. si eres más amigo del ratón, puedes úsarlo para seleccionar las líneas de código, y pulsar el botón Ejecutar, situado donde te indica esta figura:
  2. También puedes utilizar el teclado para seleccionar esas dos líneas y pulsar Ctrl+r (las dos teclas a la vez).

El resultado, en cualquiera de los dos casos es que Rcmdr te devolverá este resultado, utilizando para ello la (adecuadamente llamada) ventana de resultados:Como ves Rcmdr repite, en la ventana de resultados, cada una de las instrucciones que hemos tecleado (en rojo), y añade debajo su respuesta (en azul). La primera instrucción

a=2

simplemente le dice a R que guarde el valor 2 en la variable R, y no produce ningún mensaje de salida.  La segunda instrucción,

a^2

le pide a R que haga una operación, elevar al cuadrado el valor de a, que sí produce un resultado. Por eso, en la ventana de resultados vemos aparecer el mensaje

> a^2
[1] 4

El valor 4 es la respuesta esperada, pero ¿qué es ese [1] que ha aparecido delante? Más adelante, al usar R para cálculos estadísticos, haremos operaciones mucho más complicadas que producirán resultados muy extensos, que ocupan varias líneas de la pantalla. Para ayudarnos a leer esas respuestas, R siempre numera las líneas de su respuesta. Así que ese [1] es la forma que tiene R de decirnos: “esta es la primera línea de la respuesta”.

La ventana de resultados guarda un registro de lo que vamos haciendo. De manera que si vuelves a pulsar Ctrl+r, aparecerá un segundo par de resultados, y si lo pulsas de nuevo un tercero, etcétera:Este comportamiento de la ventana de resultados puede ser muy útil cuando, al cabo de un rato, queremos volver sobre alguna operación que hemos hecho antes (basta buscarla más arriba, y se puede cortar y pegar desde esta ventana). Pero en ocasiones querremos hacer limpieza, empezar con una ventana de resultados limpia. Para ello, basta con hacer click en la ventana con el botón derecho del ratón, y seleccionar la opción Limpiar ventana ¿Acabas de hacerlo y ya te has arrepentido? No pasa nada: pulsa Ctrl+z y los resultados que has borrado volverán a aparecer.

El método de limpieza de la ventana y la misma opción de deshacer, una por una, las últimas operaciones con Ctrl+z están igualmente disponibles en la ventana de instrucciones. Y en ambas ventanas, tecleando Ctrl+y  vuelves a hacer lo que has deshecho, de modo que puedes ir adelante y atrás en tu historial de operaciones.

Las operaciones aritméticas en R se representan así

  • suma: +
  • resta: –
  • producto: *
  • cociente: /
  • potencia: ^   (por ejemplo 2^3=8)
  • cociente entero:  %/%   (por ejemplo   17%/%3=5, porque 17=3*5+2)
  • resto entero:  %%   (por ejemplo   17%%3=2, porque 17=3*5+2)

La raíz cuadrada es una función en R, la primera que vemos. Se representa con sqrt (de square root) y se usa poniendo el argumento entre paréntesis. Por ejemplo, si tecleas

sqrt(9)

en la ventana de instrucciones y lo ejecutas (recuerda, Ctrl+r)
obtendrás este resultado:Además de la raíz cuadrada, R dispone de una buena colección de funciones matemáticas:

  • trigonométricas: sin, cos, tan, asin, acos, atan
  • exponencial: exp
  • logaritmos: log (neperiano), log10 (base 10)

Y naturalmente, hay muchas otras funciones relacionadas con la Estadística que iremos viendo en sucesivas sesiones. Para practicar lo que acabamos de aprender sobre Rcmdr, y para introducir un par de ideas nuevas, puedes utilizar este código de ejemplo:

2+3
15-7
4*6
12/5
12%/%5
12%%5
1/3+1/5
sqrt(25)
sqrt(26)
sin(pi)
sin(3.14)

Trata de adivinar el resultado de cada operación antes de ejecutar el código. Después,  cópialo en la ventana de instrucciones para ejecutarlo. Puedes ejecutar todas las líneas de código de una vez, como hemos visto al principio de esta sesión. O puedes ir colocando el cursor en cada una de las líneas (con las flechas del teclado o con el ratón) e irlas ejecutando una por una (con el botón Ejecutar o con Ctrl+r).

Lo más importante que tienes que bservar en los resultados es que R trabaja con la representación mediante decimales de los números. Esto es evidente, por ejemplo, en la respuesta a la instrucción

1/3+1/5

que es 0.5333333, y no 8/15. El valor decimal es una aproximación a la fracción, pero no es un resultado exacto (la fracción sí es exacta). Por lo tanto, cuando hagamos operaciones con R tenemos que tener cuidado con la posible pérdida de precisión que llevan siempre aparejadas las operaciones con decimales.

Para acabar esta primera sesión, usa el menú Fichero, selecciona Salir, y dentro de esa opción, elige De Commander y R.  Después pulsa en Aceptar. A continuación vamos a responder No a las dos preguntas sobre Guardar el fichero de instrucciones y Guardar el fichero de salida. Veremos el significado y la utilidad de esas dos preguntas en próximas sesiones, pero por hoy es suficiente.

Gracias por llegar hasta aquí, y hasta la próxima sesión.