Introducción A R (T)
Introducción A R (T)
TABLA DE CONTENIDO
PRÓLOGO
1. INTRODUCCIÓN
2. INSTALACIÓN DE R
3. EJECUCIÓN DE R
4. USO DE R
5. DIRECTORIO DE TRABAJO
6. PAQUETES
7. ACTUALIZACIONES
8. LECTURA DE DATOS
9. AYUDAS
10. OBJETOS Y ESTRUCTURAS DE DATOS
11. TAMAÑO, DIMENSIONES Y RECICLAJE DE UN OBJETO
12. CLASES, MODOS Y TIPOS
13. NOMBRES
14. INDEXACIÓN, FILTRADO, ADICIÓN Y SUSTITUCIÓN DE ELEMENTOS
15. VISUALIZACIÓN Y EDICIÓN DE OBJETOS Y DE DATOS
16. GENERACIÓN DE SALIDAS EDITABLES
17. ESCRITURA DE DATOS EN UNA HOJA DE CÁLCULO
18. TRANSFORMACIONES Y CREACIÓN DE NUEVAS VARIABLES
19. CICLOS Y CONDICIONALES
20. FUNCIONES DE PROBABILIDAD
21. FUNCIONES PERSONALIZADAS
22. FUNCIONES POR GRUPOS
23. GRÁFICOS
PRÓLOGO
Este texto introductorio a R ha sido concebido con dos propósitos en mente. En primera
instancia, aportar los elementos necesarios, partiendo de un punto cero, para iniciarse en
este universo, sin que se requiera ningún conocimiento previo ni de estadística ni de
programación. En segunda instancia, mantener el carácter secuencial de la presentación,
lo que implica que los diferentes conceptos se van construyendo a partir de los elaborados
anteriormente.
Para contribuir a la satisfacción del primer objetivo, se ha evitado establecer paralelos con
otras aplicaciones estadísticas o lenguajes de programación. Estas comparaciones, aunque
eventualmente podrían resultar útiles para quien pretenda migrar desde otros ambientes,
pueden generar angustia y confusión en quienes no conozcan el referente al que se haga
mención. De igual manera, se parte desde lo más fundamental como es la instalación del
programa y de los paquetes, así como la lectura o importación de datos. Y aunque se
avanza en la presentación de temas con mayor complejidad, la cobertura se mantiene en
un nivel general, sin entrar a detallar métodos estadísticos particulares.
Finalmente, para obtener los mejores frutos de las sesiones de estudio, se recomienda
trascender la lectura, mediante el seguimiento práctico de los diferentes temas ilustrados.
Asimismo, se invita a modificar las instrucciones y analizar qué efecto tienen dichas
modificaciones. No debe temerse la aparición de errores; el impacto sicológico de los
mismos y la consiguiente búsqueda de sus causas y soluciones constituyen una de las
mejores herramientas nemotécnicas para el aprendizaje.
Guillermo Correa Londoño – Introducción a R 3 de 87
1. INTRODUCCIÓN
La primera versión de R fue escrita por Ross Ihaka y Robert Gentleman. Los desarrollos
actuales son coordinados por un grupo de personas que se denomina el Grupo Nuclear de
Desarrollo de R (The R Development Core Team), del cual forman parte sus creadores. En
adición a su potencia, la característica que ha hecho de R el software estadístico más
popular es la de haberse mantenido gratuito y encontrarse en constante crecimiento a
través de las aportaciones recibidas por personas entusiastas a lo ancho de todo el mundo.
2. INSTALACIÓN DE R
Para instalar R, se elige el archivo que corresponda al sistema operativo del equipo en el
que se va a trabajar. El instalador incluye tanto la versión de 32 bits como la de 64 bits. Se
recomienda instalar la versión acorde con el sistema operativo.
3. EJECUCIÓN DE R
La primera vez que se instala R en un equipo, se crea una carpeta llamada R, localizada en
el directorio que usa el sistema operativo para alojar los programas (en Windows, es usual
que los programas se instalen dentro de Program Files); dentro de esta carpeta, se crea
una subcarpeta para cada versión. Así, si en un equipo se instaló inicialmente la versión
3.0.2, se crea la carpeta R-3.0.2; si luego se instala la versión 3.1.1, se creará una nueva
carpeta llamada R-3.1.1. Para cada versión, los archivos ejecutables se encuentran dentro
de la subcarpeta bin.
[Link]: Abre la interfaz más básica de R, consistente en una ventana sin ningún tipo
de menú.
Una vez se carga el programa, bien sea directamente o a través de una GUI, se tiene acceso
a la consola, la cual constituye el medio estándar de entrada y salida de texto (información
no gráfica). Allí pueden escribirse diferentes comandos y allí mismo aparecen las salidas
de texto.
El símbolo mayor que (>), denominado prompt o invitación, que aparece en la línea de
comandos, indica que el sistema está preparado para recibir información.
Guillermo Correa Londoño – Introducción a R 6 de 87
4. USO DE R
Sin que se requiera ningún tipo de preparación, es posible empezar a usar R, a manera de
calculadora, utilizando los operadores aritméticos básicos (+, –, *, /, ^). En caso de que la
expresión escrita esté conformada por más de dos términos y/o factores, se mantienen las
prelaciones usuales, pudiendo, asimismo, usarse paréntesis.
En adición a los operadores básicos, R incorpora gran cantidad de funciones. Todas las
funciones en R tienen el formato función(argumentos). Así, por ejemplo, si se desea
obtener el logaritmo natural de 2.71, se escribe: log(2.71); al presionar la tecla ENTER,
se obtiene el resultado 0.9969486. Entre las funciones básicas más comunes, se destacan
abs, sqrt, log y exp.
R usa la coma para separar los argumentos de una función. Los argumentos pueden ser
obligatorios, en cuyo caso tienen que ser suministrados por el usuario, o implícitos, caso
en el que toman un valor por defecto, a no ser que el usuario especifique algún valor
diferente. La función logaritmo tiene dos argumentos: log(x, base=exp(1)), siendo
x un argumento obligatorio, correspondiente al número o vector al que se le aplicará la
función logaritmo, y base un argumento implícito, cuyo valor por defecto es la constante
de napier (2.718281…). Al escribir log(2.71), se toma 2.71 como argumento principal,
y se usa el valor por defecto (la base del logaritmo natural) para el segundo argumento. Al
escribir log(2,71), se toma 2 como argumento principal y 71 como la base.
Los argumentos de las funciones tienen un orden definido, el cual puede ser alterado por
el usuario, siempre que se especifique el nombre del argumento. Si se respeta el orden
predeterminado, podrá omitirse el nombre de los argumentos.
Argumento 1: x, que representa el número de éxitos y no trae ningún valor por defecto.
Argumento 2: n, que representa el número de ensayos Bernoulli y no tienen ningún valor
por defecto.
Argumento 3: p, que representa el valor hipotético del parámetro p para la prueba de
hipótesis. Por defecto es 0.5.
Argumento 4: alternative, que representa el tipo de prueba, pudiendo ser de dos colas
("[Link]", valor por defecto), de cola izquierda ("less") o de cola derecha
("greater").
Argumento 5: [Link], que representa el nivel de confianza para el correspondiente
intervalo. Por defecto es 0.95.
Se tiene, pues, que de los cinco argumentos de la función [Link], los dos primeros
son obligatorios y los tres restantes traen valores por defecto. Supóngase que se desea
utilizar dicha función para realizar inferencia sobre el parámetro p, con base en un ensayo
binomial de tamaño 200, en el que se obtuvieron 185 éxitos y que se desea contrastar una
prueba de cola derecha que postula que el parámetro p es mayor de 0.9, generando un
intervalo de confianza del 95%. Cualquiera de las siguientes instrucciones es válida y da
lugar al mismo resultado.
rpois(n=100, lambda=130)
[1] 127 125 145 147 140 133 123 123 128 125 140 145 121 131 124 127 128
[18] 109 113 135 133 129 126 133 118 118 154 119 117 127 118 130 124 116
[35] 121 145 148 120 117 126 130 120 125 125 121 125 125 162 126 115 128
[52] 138 131 130 126 105 132 127 156 130 135 129 132 131 143 142 130 155
[69] 133 135 136 134 128 148 131 133 125 115 115 134 117 126 146 119 121
[86] 147 135 119 131 140 149 129 104 105 126 134 108 110 123 124
4.7 Secuencias
seq(3, 8)
[1] 3 4 5 6 7 8
seq(15, 40, 5)
[1] 15 20 25 30 35 40
seq(0,1,0.2)
[1] 0.0 0.2 0.4 0.6 0.8 1.0
seq(10,2,-2)
[1] 10 8 6 4 2
seq(0.5,4)
[1] 0.5 1.5 2.5 3.5
Si se usa un único argumento para la función, dicho valor se toma como segundo
argumento (to); el primer argumento (from) toma el valor por defecto de 1.
Guillermo Correa Londoño – Introducción a R 9 de 87
seq(5)
[1] 1 2 3 4 5
El operador “dos puntos” (:) utilizado entre dos números equivale a la función seq, en su
forma básica, es decir, con el valor por defecto para los intervalos (by=1).
5:8
[1] 5 6 7 8
4.8 Repeticiones
rep(5, 3)
[1] 5 5 5
rep(2:5, times=3)
[1] 2 3 4 5 2 3 4 5 2 3 4 5
rep(2:5, each=3)
[1] 2 2 2 3 3 3 4 4 4 5 5 5
Es posible utilizar simultáneamente los argumentos each y times. En tal caso, sin
importar el orden en que se escriban tales argumentos, se realizarán primero las
repeticiones de los elementos y luego las de la secuencia (con los elementos repetidos).
Es común —aunque no necesario— que cada instrucción ocupe una línea. Cuando el
comando es muy extenso es posible partirlo en dos o más líneas. A pesar de que hay
bastante flexibilidad en cuanto al sitio por el que puede partirse un comando, es necesario
observar un par de restricciones. No puede partirse ninguna palabra, ni aun en el caso en
que se trate de dos o más palabras unidas por punto. La primera línea debe contener como
mínimo el nombre de la función y el paréntesis de apertura, en caso de tratarse de una
función, o el nombre del objeto y el operador de asignación, en caso de tratarse de una
asignación.
peso.160=
predict(modelo, newdata=[Link](edad=160),
interval="confidence", level=0.99)
plot(
peso~edad, data=reg, main="Modelo ajustado")
peso.
160=predict(modelo, newdata=[Link](edad=1
60), interval="confidence", level=0.99)
plot
(peso~edad, data=reg, main="Modelo
ajustado")
Aunque es posible escribir más de un comando por línea, separándolos con punto y coma
(;), se considera que la escritura de un único comando por línea brinda mayor legibilidad.
4.10 Scripts
A no ser que se use R para ejecutar una tarea muy puntual (una operación matemática, por
Guillermo Correa Londoño – Introducción a R 11 de 87
En general, en R las instrucciones se ejecutan línea por línea, lo que facilita la depuración
de los scripts, al permitir verificar las acciones realizadas por cada comando.
Si se está trabajando desde la consola, basta con escribir el comando y presionar la tecla
ENTER para que se ejecute la correspondiente acción. Si se presiona ENTER antes de haber
escrito el comando completo, aparecerá un símbolo de suma (+), que indica la necesidad
de completar el comando. En tales casos, la función de la tecla ENTER consiste en partir el
comando en dos o más líneas, siendo necesario tener en cuenta lo mencionado
anteriormente sobre particiones correctas e incorrectas.
Cuando se trabaja desde el editor de scripts de RStudio, puede ejecutarse una línea, una
región del script o todo el script. Para tal efecto se presiona la combinación de teclas CTRL–
ENTER o se pulsa el botón RUN ( ), con lo cual se ejecuta la región seleccionada, o el
comando en el que se encuentra el cursor, en caso de no haber ninguna selección activa.
Para ejecutar todo el script, basta con enviar la orden de ejecución tras seleccionarlo en su
totalidad, lo cual se realiza de manera rápida, usando la combinación de teclas CTRL–A.
Asimismo, es posible ejecutar todo el script –sin necesidad de haberlo seleccionado
previamente– presionando la combinación de teclas CTRL–SHIFT-ENTER, lo que equivale a
escribir el comando:
source("ruta/[Link]", echo=T)
4.12 Comentarios
Al igual que todos los lenguajes de programación, R admite comentarios, esto es, cadenas
de texto que se insertan a manera de guía, para referencia del usuario, sin que tengan
ningún efecto en los procesos realizados. Cualquier cadena de texto que inicie con el
símbolo numeral (#) constituye un comentario. Asimismo, puede usarse el símbolo # para
desactivar temporalmente alguna línea que no se desee ejecutar dentro de un script. Los
comentarios pueden ocupar una o más líneas completas, pero también pueden ir al final
de una línea que contenga código ejecutable. La inserción de comentarios genera orden y
facilita enormemente la comprensión los scripts, por lo que se recomienda ampliamente
su uso.
Asimismo, cuando se leen scripts desde RStudio, es posible adaptar los comentarios para
Guillermo Correa Londoño – Introducción a R 12 de 87
que sirvan como marcadores de sección, facilitando la navegación a través del script.
Cualquier cadena de caracteres que inicie con al menos un símbolo numeral (#) y que
finalice con al menos cuatro símbolos numeral (####) funcionará como tal.
Equivalentemente, podría finalizarse con cuatro o más guiones (----). Podrá accederse a
tales marcadores desde la parte inferior de la ventana.
#Predicciones####
Guillermo Correa Londoño – Introducción a R 13 de 87
5. DIRECTORIO DE TRABAJO
El directorio de trabajo es la ubicación física en la cual R busca por defecto los recursos
necesarios (bases de datos para importación, por ejemplo) y copia salidas, cuando la
corrida de un script dé lugar a ello. Para averiguar cuál es el directorio de trabajo (working
directory), se usa el comando getwd. En RStudio es directa la visualización del directorio
de trabajo, sin necesidad de usar el comando getwd, dado que este aparece en la barra de
título de la consola (panel inferior izquierdo). Para definir alguna ruta específica como
directorio de trabajo, se usa el comando setwd("ruta").
La ruta que define el directorio de trabajo debe escribirse entrecomillada (bien sean
comillas sencillas o dobles), usando la barra (/) como separador de las localizaciones en
lugar del backslash (\). También puede usarse doble backslash (\\) como separador, pero
este solo es compatible con Windows, mientras que el uso de la barra (/) es compatible
con cualquier sistema operativo, por lo que se recomienda este último.
Cuando se abre RStudio a través de un script (haciendo doble clic sobre el mismo, siendo
necesario que el sistema esté configurado para que RStudio sea el programa por defecto
para lectura de archivos con extensión R), la ubicación del script queda establecida como
directorio de trabajo. Esto facilita la importación de datos, siendo suficiente con escribir
el nombre del archivo, siempre que este se encuentre en la misma ubicación en la que está
el script. Si se abre RStudio de otra manera (no llamándolo a través de un script) habrá un
directorio de trabajo por defecto (que puede ser modificada por el usuario).
6. PAQUETES
Cuando se instala R por primera vez, se incluyen siete paquetes básicos: base, stats,
graphics, grDevices, methods, utils y datasets. El usuario puede instalar todos
los paquetes adicionales que requiera, acorde con sus necesidades. A pesar del gran
potencial de R para ejecutar una infinidad de procesos, el programa es muy liviano y
eficiente; esto se debe al hecho de que R no carga simultáneamente toda su artillería, sino
únicamente los paquetes requeridos para una aplicación determinada. Para usar un
paquete es necesario instalarlo y cargarlo. Estos dos pasos se diferencian y detallan a
continuación.
Hay varias formas de instalar un paquete. Las dos más usuales son desde la interfaz y
mediante el uso de un archivo comprimido, que se baja de algún repositorio. Esta última
opción resulta útil para bajar el paquete en un archivo comprimido que puede usarse para
la posterior instalación en cualquier equipo, sin necesidad de conexión a Internet. Por su
parte, la instalación directa desde la interfaz requiere conexión a Internet.
Para cargar un paquete desde la interfaz estándar, se ingresa por el menú “Paquetes” y se
selecciona “Cargar paquete”; allí se elige el paquete con el que se va a trabajar, con lo cual
se cargará ese paquete junto con todos los paquetes de los que este dependa. Si se está
trabajando con la interfaz de RStudio, se elige la pestaña “packages” de la ventana inferior
derecha (o se presiona CTRL-7). Allí se hace clic en el paquete que se desee cargar. Si se
selecciona, por ejemplo, homals, automáticamente quedarán seleccionados los paquetes
que dependan de este (rgl, ape y scatterplot3d). Alternativamente, cualquiera que
sea la interfaz que se esté utilizando, puede cagarse un paquete, junto con todos los
paquetes de los que dependa, usando las funciones library(paquete) o
Guillermo Correa Londoño – Introducción a R 16 de 87
Todas las funciones en R forman parte de algún paquete que debe estar cargado para
poder usarse en una sesión de trabajo. Si, por ejemplo, en un artículo se dijera que se
realizó un análisis de correspondencias múltiples, mediante el uso de la función mjca,
sería necesario averiguar de cuál paquete hace parte dicha función (normalmente cuando
se hace referencia a una función se dice a cuál paquete pertenece). En este caso, se trata
de una función que forma parte del paquete ca, el cual deberá cargarse (tras haber sido
instalado previamente) para poder ser usado. La forma usual de referenciar una función
con el paquete del cual forma parte es escribiendo el nombre de la función, sucedido por
el nombre del paquete, entre llaves. Así, para referenciar, por ejemplo, la función mjca,
que forma parte del paquete ca, se escribe mjca{ca}.
7. ACTUALIZACIONES
Con el fin de contar con las versiones más recientes de los programas, es necesario realizar
periodicamente las correspondientes actualizaciones. Para tal efecto, deben diferenciarse
las actualizaciones del programa principal (R), las actualizaciones de los paquetes y las
actualizaciones de la interfaz. En cualquier caso, se requiere conexión a Internet.
7.1 Actualización de R
Al iniciar una sesión de trabajo en R (ya sea usando una interfaz o no), aparece información
sobre la correspondiente versión. Cada versión de R está identificada por un código
numérico y por un apodo. Así, por ejemplo, la versión 3.3.2, liberada el 31 de octubre de
2016, se denomina Sincere Pumpkin Patch. Es posible acceder en cualquier momento a la
información de la versión que se está ejecutando, mediante el comando version.
La actualización de los paquetes puede llevarse a cabo fácilmente tanto desde la interfaz
básica de R como desde RStudio. Si se está trabajando desde la interfaz básica, se abre el
menú “Paquetes”, se elige “Actualizar paquetes…”, seguidamente se selecciona el servidor
(CRAN mirror) y se hace clic en “OK” para actualizar todos los paquetes que aparecen en
la ventana. Si se está trabajando en RStudio, se ingresa por el menú “Tools”, se elige “Check
for Package Updates…”, con lo cual aparece una ventana en la que se muestran los
paquetes para los cuales hay actualizaciones disponibles, detallando la versión instalada y
la versión disponible; se hace clic en el botón SELECT ALL, para seleccionar todos los
paquetes, y seguidamente se hace clic en el botón INSTALL UPDATES. Es posible acceder
Guillermo Correa Londoño – Introducción a R 18 de 87
8. LECTURA DE DATOS
Las funciones más comunes para importar datos son [Link], [Link] y
[Link]. La función [Link] lee datos en formato ASCII, la función [Link]
lee datos almacenados en formato CSV (comma separated values) y la función [Link]
importa desde un archivo de Excel (formato xls o xlsx).
Cualquiera de las anteriores funciones tiene como primer argumento el nombre del
archivo que se importará, incluyendo la ruta completa, la cual puede ser una ruta local o
un URL (uniform resource locator). Dicho nombre, con su ruta (cf. 5. Directorio de trabajo),
debe escribirse entre comillas, ya sean sencillas o dobles.
La instrucción para leer una base de datos en formato ASCII podría tener el siguiente
aspecto:
bd=[Link]("C:/BDR/[Link]")
Los elementos dentro de los archivos ASCII pueden estar separados por espacios (uno o
más), por tabuladores o por una combinación de ambos, sin que tenga que satisfacerse
ninguna condición de alineación. No obstante, el formato con separadores tabulares es
más general, puesto que permite incorporar cadenas de texto que incluyan espacios.
esté ubicado en una ruta particular, con valores separados por tabuladores y con los
nombres de las variables en la primera fila, tendrá el siguiente aspecto:
bd=[Link]("C:/BDR/[Link]")
Para leer información directamente desde un archivo Excel, se usa la función [Link].
Esta función forma parte del paquete gdata. Adicionalmente debe instalarse el software
“Perl”, el cual se baja desde la página [Link]
bd=[Link]("C:/BDR/[Link]", sheet=1)
Por defecto, se lee la primera hoja. Si se desea leer una hoja diferente a la primera, puede
usarse el correspondiente número o el nombre.
bd=[Link]([Link])
Obsérvese que más allá de la aparente diversidad de métodos para importación de datos
a partir de archivos externos, en esencia se tienen funciones para leer información desde
formatos ASCII y Excel (xls o xlsx), dado que los archivos CSV son en realidad archivos de
Guillermo Correa Londoño – Introducción a R 21 de 87
Con excepción de la función [Link], que forma parte del paquete gdata, las demás
funciones reseñadas forman parte del paquete utils, que es uno de los que se carga cada
vez que se inicia una sesión de trabajo en R, no siendo necesario, por tanto, invocar el
correspondiente paquete.
Las funciones de importación que forman parte del paquete utils difieren únicamente
en los valores que traen por defecto para sus argumentos, siendo posible usar cualquiera
de ellas con argumentos especificados por el usuario, que se adecúen a las características
del archivo que se va a leer. A continuación se resumen las funciones mencionadas, con los
valores por defecto para sus principales argumentos.
Es importante aclarar que el hecho de que la función [Link] no pueda usarse para
leer información desde el portapapeles, no impide que puedan importarse datos
contenidos en un archivo Excel, mediante esta estrategia. De hecho, La situación más
común surge cuando se copian datos desde Excel al portapapeles (usando Ctrl-C en
Windows). Los valores en el portapapeles quedan separados por tabuladores. Suponiendo
que en el área seleccionada y copiada se hubieran incluido los encabezados de cada
columna, podría importarse dicha información en R así:
bd=[Link]("clipboard")
Guillermo Correa Londoño – Introducción a R 22 de 87
bd=[Link]("clipboard", sep="\t")
bd=[Link]("clipboard", header=FALSE)
bd=read.delim2("clipboard")
La rapidez y eficiencia del proceso de importación depende del tamaño de las bases de
datos, pudiendo ser prácticamente instatáneo o tardar mucho tiempo. Cuando se trabaja
con bases de datos muy grandes, puede resultar más práctico tener la base de datos en
formato nativo que realizar la importación cada vez que se retome el script. Puesto que los
datos usualmente provienen de una fuente externa (v. gr. un archivo de Excel o de texto),
aun en este caso será inevitable realizar una importación inicial. No obstante, cuando
vuelva a ejecutarse el script, los datos podrán leerse directamente desde el formato nativo,
haciendo más rápido el proceso.
Para guardar una base de datos se usa la función save, usando el nombre del objeto
importado como primer argumento y el nombre del archivo de datos como segundo
argumento. Supóngase, por ejemplo, que usando la función [Link], se importa una
base de datos desde Excel, quedando temporalmente en memoria como bd:
bd=[Link]("C:/BDR/[Link]", sheet=1)
Si a futuro se quiere usar nuevamente los datos contenidos en bd, sin necesidad de
importarlos nuevamente desde Excel, se guardan físicamente como un archivo de datos
en formato nativo de R, usando la función save, así:
Guillermo Correa Londoño – Introducción a R 23 de 87
save(bd, file="[Link]")
load("[Link]")
Guillermo Correa Londoño – Introducción a R 24 de 87
9. AYUDAS
Muchos paquetes incluyen archivos pdf en los que se desarrollan ampliamente las
particularidades del paquete en cuestión. Aunque es posible ubicar manualmente tales
archivos en la carpeta “doc”, dentro de la carpeta cuyo nombre corresponde con el del
paquete y que se encuentra, a su vez, dentro de la carpeta library, tales archivos son más
fácilmente ubicables invocando las ayudas del paquete con doble signo de interrogación.
??agricolae
En este caso, el paquete agricolae incluye un tutorial en pdf, al que puede accederse
por esta vía.
Si se busca ayuda sobre símbolos especiales, tales como los operadores, o sobre comandos
reservados, estos deben escribirse entrecomillados.
?"+"
help("if")
apropos ("read")
[1] ".readRDS" ".[Link]" "[Link]" "read.csv2" "[Link]"
[6] "[Link]" "read.delim2" "[Link]" "[Link]" "[Link]"
[11] "[Link]" "[Link]" "[Link]" "readBin" "readChar"
[16] "readCitationFile" "readClipboard" "readline" "readLines" "readRDS"
[21] "readRegistry" "readRenviron" "[Link]"
En Internet existe gran cantidad de recursos sobre R. Para acceder a los mismos, basta con
realizar la correspondiente búsqueda, bien sea a través de un buscador genérico como
Google o mejor aun a través del buscador específico R Seek ([Link] Aunque
eventualmente podrían encontrarse algunas ayudas en español, la mayoría está en inglés,
por lo cual se recomienda usar este idioma en todas las búsquedas.
Guillermo Correa Londoño – Introducción a R 26 de 87
Los vectores, las matrices y los arreglos están restringidos a contener elementos de un
único tipo; a tales estructuras se les denomina atómicas. Los dataframes y las listas son
estructuras que admiten elementos de diferentes tipos; a tales estructuras se les denomina
recursivas.
10.1 Vectores
a=c(3, 5, 9)
Guillermo Correa Londoño – Introducción a R 27 de 87
a<-c(3, 5, 9)
c(3, 5, 9)->a
El siguiente comando crea un vector tipo carácter. Al definir este tipo de vectores, es
necesario entrecomillar cada uno de los elementos constituyentes, siendo posible usar
comillas dobles o comillas sencillas.
10.2 Matrices
Las matrices son estructuras bidimensionales (filas y columnas) que agrupan objetos del
mismo tipo. La manera usual de crear una matriz es mediante la función matrix.
2 0 5
-1 9 1
Además de la especificación del número de filas (nrow) y del número de columnas (ncol),
es importante anotar que el valor por defecto del argumento byrow es ‘FALSE’, con lo
cual, si dicho argumento fuera omitido, los elementos ingresados se ordenarían por
columnas y, en lugar de la matriz objetivo, se obtendría la siguiente matriz:
a=c(2, 0)
b=c(5, -1)
c=c(9, 1)
Podría pensarse en concatenar dichos vectores, así: c(a, b, c), para obtener la matriz
generada anteriormente. No obstante, la función c siempre da lugar a vectores, con lo cual
el resultado obtenido será un vector, con los valores 2, 0, 5, -1, 9 y 1.
Existen, sin embargo, un par de funciones de concatenación que dan lugar a matrices:
rbind, que permite combinar vectores por filas (rows), y cbind, que permite concatenar
vectores por columnas (columns).
B=cbind(a, b, c)
a b c
[1,] 2 5 9
[2,] 0 -1 1
Obsérvese que, mediante el uso de la función cbind, se han combinado los vectores a, b
y c, de manera que cada uno de ellos constituye una columna de la matriz B. Para verificar
si el objeto B es una matriz, se usa la función [Link](B).
crossprod(X)
crossprod(X, X)
t(X)%*%X
crossprod(X, y)
t(X)%*%y
tcrossprod(X)
tcrossprod(X, X)
(X)%*%t(X)
tcrossprod(X ,y)
(X)%*%t(y)
No está de más anotar que para obtener los productos cruzados de dos matrices o
cualquier otro producto entre dos matrices, estas deben ser conformables, esto es, que el
número de columnas de la primera matriz sea igual al número de filas de la segunda.
En adición a las funciones básicas presentadas anteriormente, que forman parte del
paquete base, el paquete Matrix contiene funciones adicionales para realizar
operaciones avanzadas de álgebra lineal.
a=c(3, 5, 9)
b=c(7, 2)
A=matrix(c(2, 0, 5, -1, 9, 1), nrow=2, ncol=3, byrow=TRUE)
10.3 Arreglos
Cuando se tienen más de dos dimensiones del mismo tipo, es posible estructurar la
información en arreglos. Considérese una situación hipotética en la que se evalúan tres
variables sobre cuatro unidades muestrales, en dos tiempos, pudiendo obtenerse como
resultado cualquiera de las letras del alfabeto.
tiempo1 tiempo2
v1 v2 v3 v1 v2 v3
unidad1 a x d unidad1 b h r
unidad2 c m b unidad2 j o s
unidad3 f j u unidad3 h w n
unidad4 d l y unidad4 i p q
Aunque podría usarse un único comando para construir el arreglo en cuestión, a fin de
hacer más claro el proceso, se ilustrará en dos pasos. Inicialmente, se construye un vector
de 24 elementos con toda la información.
vector=c('a', 'c', 'f', 'd', 'x', 'm', 'j', 'l', 'd', 'b', 'u',
'y', 'b', 'j', 'h', 'i', 'h', 'o', 'w', 'p', 'r', 's', 'n', 'q')
, , 1
Guillermo Correa Londoño – Introducción a R 31 de 87
, , 2
Obsérvese que la función array concatena los objetos contenidos en vector, por
columnas (no existe la opción para concatenar por filas). En el argumento dim debe
proporcionarse un vector de enteros, con la longitud de cada una de las dimensiones.
10.4 Dataframes
Las estructuras ilustradas anteriormente (vectores, matrices y arreglos) exigen que todos
los elementos sean del mismo tipo. Por tal motivo se les denomina objetos atómicos
(puede verificarse con la función [Link](objeto)). El dataframe es una estructura
rectangular (dos dimensiones) que puede estar conformada por objetos atómicos de
diferente tipo.
id v1 v2
1 a23 2.4 4+3.0i
Guillermo Correa Londoño – Introducción a R 32 de 87
Esta capacidad de combinar objetos de diferentes tipos hace del dataframe la estructura
ideal para alojar bases de datos, las cuales suelen organizarse con objetos o individuos en
filas y variables en columnas.
No es necesario que los objetos que se concatenan para conformar un dataframe sean
vectores; también pueden concatenarse matrices, arreglos u otros dataframes,
exigiéndose únicamente que todos tengan el mismo número de filas.
El dataframe está diseñado como el contenedor ideal para bases de datos; no obstante,
resulta insuficiente para otros fines, al no admitir cualquier tipo de objeto (no admite, por
ejemplo, objetos del tipo lenguaje).
10.5 Listas
La lista constituye la estructura más flexible, pudiendo estar conformada por objetos de
cualquier tipo y clase, incluso por otras listas. Dada la diversidad de objetos que pueden
conformar una lista, en estas no existe el concepto de filas, columnas ni de ninguna otra
dimensión. De hecho, las listas son objetos unidimensionales y a menudo se hace
referencia a las mismas como ‘vectores genéricos’, esto es, vectores que pueden contener
elementos de diferentes tipos, a diferencia de los vectores básicos definidos anteriormente
que están restringidos a contener objetos de un único tipo. A estos vectores básicos se les
denomina vectores atómicos cuando se desea diferenciarlos de las listas.
Guillermo Correa Londoño – Introducción a R 33 de 87
Es posible conocer la clase de la que forma parte cualquier objeto, mediante la función
class. Los posibles resultados son “matriz”, “arreglo”, “dataframe” y “lista”; no existe una
clase denominada “vector”; cuando se evalúa la función class sobre un vector, se
obtienen resultados como “entero”, “numérico”, “lógico”, “complejo” y “carácter”.
11.1 Tamaño
11.2 Dimensiones
Cuando se intenta realizar una operación entre vectores de diferente tamaño, los
elementos del vector de menor tamaño se repiten cíclicamente (se reciclan) hasta que
ambos vectores se igualen en tamaño.
a=c(1, 3)
b=c(1, 2, 3, 4, 5)
Para sumar los vectores a y b, se requeriría que estos fueran del mismo tamaño. Por tanto,
si se solicita la operación a+b, los dos elementos del vector a se repetirán cíclicamente
hasta dar lugar a un vector de tamaño 5, así:
areciclado=c(1, 3, 1, 3, 1)
[1] 2 5 4 7 6
Si el tamaño del vector mayor es múltiplo del tamaño del vector menor, el proceso se
Guillermo Correa Londoño – Introducción a R 35 de 87
lambda=5
b=c(1, 2, 3, 4, 5)
lambda*b
[1] 5 10 15 20 25
Otro caso de reciclaje surge cuando se usa un vector como argumento de una función. Si el
tamaño de dicho vector es menor que el requerido, los elementos suministrados se
reciclan para generar un vector del tamaño necesario.
Guillermo Correa Londoño – Introducción a R 36 de 87
Algunas funciones exigen que el argumento sea de una clase determinada. Para verificar
la clase de un objeto, se usa la función class. Es posible, con ciertas restricciones,
modificar la clase de un objeto, mediante el uso de funciones tales como [Link],
[Link] y [Link], que permiten guardar objetos como matrices, dataframes
y listas, respectivamente. El comando apropos("as") presenta una lista completa de
tales funciones.
El modo (se verifica con la función mode) y el tipo (se verifica con la función typeof)
hacen referencia a las particularidades del objeto o de sus componentes, acorde con su
estructura básica y con la forma en que son almacenados. Aunque en general tales
características se manejan de forma automática dentro de R, sin que deban constituir un
motivo de preocupación para el usuario, deben ser tenidas en cuenta cuando se importe o
exporte código desde o hacia otros lenguajes tales como S, C, C++ o Fortran. Las categorías
complejo, lógico y carácter son coincidentes en modo y tipo. El modo numérico puede ser
de dos tipos: entero o doble (doble precisión), lo cual tiene que ver con el tipo de
almacenamiento usado por R.
Mode Tipo
mode typeof
Numérico (numeric) Entero (integer)
Numérico (numeric) Doble (double)
Complejo (complex) Complejo (complex)
Lógico (logical) Lógico (logical)
Carácter (character) Carácter (character)
Guillermo Correa Londoño – Introducción a R 37 de 87
13. NOMBRES
1) Todos los nombres deben comenzar con un carácter no numérico, es decir, con una
letra (un nombre que comience por un punto genera un objeto oculto).
2) No se admiten espacios.
3) En adición a los números y las letras, los únicos caracteres especiales que se
admiten como parte de los nombres son el punto (.) y el guion bajo (_). Los usuario
de R usan con mucha mayor frecuencia el punto que el guion bajo para separar
palabas.
4) Se admiten caracteres del alfabeto latino, tales como la ñ y las vocales con tilde.
Las matrices admiten nombres para las filas y para las columnas, así como para cada uno
de los elementos individuales. Asimismo, los arreglos, admiten nombres tanto para los
componentes de sus diferentes dimensiones, como para cada uno de sus elementos. Los
vectores, al ser estructuras unidimensionales, únicamente admiten nombres para sus
diferentes elementos. De igual manera, las listas, que también son objetos
unidimensionales, únicamente permiten nombrar cada uno de sus elementos de mayor
jerarquía.
Guillermo Correa Londoño – Introducción a R 38 de 87
La función names se usa tanto para la asignación de nombres como para su recuperación.
Al evaluar esta función con un vector, una matriz o un arreglo como único argumento, se
obtiene por resultado el nombre de cada uno de los elementos individuales, en caso de que
les haya sido asignado un nombre a los mismos (situación poco usual). Cuando el
argumento es una lista, el resultado es el nombre de cada uno de los elementos de mayor
jerarquía, en caso de que a estos les haya sido asignado un nombre. Cuando el argumento
es un dataframe, el resultado es el nombre de las columnas.
a=c(1, 2, 3)
Para nombrar los diferentes elementos dimensionales de una matriz o un arreglo, esto es,
para ponerles encabezado a las filas, columnas u otras dimensiones, se utiliza el
argumento dimnames= en la definición de la estructura. El valor del argumento debe ser
una lista, cada uno de cuyos elementos de mayor jerarquía contenga los nombres de los
encabezados en cada dimensión.
tiempo1 tiempo2
v1 v2 v3 v1 v2 v3
unidad1 a x d unidad1 b h r
unidad2 c m b unidad2 j o s
unidad3 f j u unidad3 h w n
unidad4 d l y unidad4 i p q
, , tiempo1
v1 v2 v3
unidad1 "a" "x" "d"
unidad2 "c" "m" "b"
unidad3 "f" "j" "u"
unidad4 "d" "l" "y"
, , tiempo2
v1 v2 v3
unidad1 "b" "h" "r"
unidad2 "j" "o" "s"
unidad3 "h" "w" "n"
unidad4 "i" "p" "q"
Para asignar nombres a los ítems de un dataframe (a las filas) se usa el argumento
[Link], mediante el cual se alimenta un vector con los correspondientes nombres. Si
se realiza un proceso de importación en el que los nombres de los ítems estén en alguna
de las columnas de la base de datos (usualmente en la primera), se indica su número o
nombre como valor del argumento [Link]. Si al momento de crear o importar el
dataframe, se omite lo referente al nombre de las filas, estas quedan nombradas por
defecto con los enteros entre 1 y n, siendo n el número de observaciones.
Guillermo Correa Londoño – Introducción a R 40 de 87
14.1 Indexación
Cada una de las posiciones dentro de una estructura de datos se encuentra indexada. Esto
permite referenciar cualquier elemento, a través del correspondiente índice. Para tal
efecto, R cuenta con tres descriptores de acceso: los corchetes sencillos [], los corchetes
dobles [[]] y el símbolo $.
[1] 8
Puesto que las listas también son objetos unidimensionales (vectores genéricos), el índice
hace referencia en estos casos a la posición ocupada por los elementos de mayor jerarquía.
En la lista L2, definida en el apartado de estructuras de datos, la instrucción L2[1] hará
referencia al primer elemento de dicha lista, es decir, al vector nombre:
tiempo1 tiempo2
v1 v2 v3 v1 v2 v3
unidad1 a x d unidad1 b h r
unidad2 c m b unidad2 j o s
unidad3 f j u unidad3 h w n
unidad4 d l y unidad4 i p q
Guillermo Correa Londoño – Introducción a R 41 de 87
R[4, 1, 2]
[1] "i"
2 0 5
A
1 9 1
Para referenciar todos los elementos de la segunda fila, se omite el índice de las columnas
así: A[2,]. Nemotécnicamente, esto puede leerse como fila 2 con todas las columnas.
[1] -1 9 1
En el arreglo R, la referencia a todas las lecturas del tiempo1 se realiza con la instrucción
R[,,1] .
v1 v2 v3
unidad1 "a" "x" "d"
unidad2 "c" "m" "b"
unidad3 "f" "j" "u"
unidad4 "d" "l" "y"
También es posible referenciar cualquier elemento de una matriz o arreglo con base en un
único índice. En tales casos, el índice corresponde con la posición del elemento,
contabilizando de manera continua y ordenada a traves de las diferentes dimensiones,
empezando con la primera.
A[1, 3]
A[5]
[1] 5
Nótese que en este caso el conteo se realiza inicialmente a través de las filas (primera
dimensión) y luego a través de las columnas (segunda dimensión).
R[2, 1, 2]
R[14]
[1] "j"
En este caso el conteo se realiza inicialmente a través de las unidades (primera dimensión),
luego a través de las variables (segunda dimensión) y finalmente a través de los tiempos
(tercera dimensión).
Es importante anotar que aunque los cinco comandos anteriores hacen referencia a la
misma información (la primera columna del dataframe DF), no todos dan lugar a objetos
de la misma clase. Los tres primeros comandos generan objetos de la clase
correspondiente al vector atómico al que se hace referencia (en este caso, factor); los
dos últimos comandos generan objetos de la clase dataframe.
El descriptor de acceso $ también puede usarse para referenciar objetos que forman parte
de una lista, siempre que les haya sido asignado un nombre a los mismos. Supóngase que
a la lista L2 que se usó como ejemplo anteriormente se le asignan nombres.
Ahora puede invocarse el primer elemento de mayor jerarquía de dicha lista, mediante la
siguiente instrucción:
L2$nombre
En este caso, cuando los elementos de mayor jerarquía tienen nombre, existe la posibilidad
de acceder a subelementos dentro de cada uno de los elementos de mayor jerarquía. Así,
para recuperar el tercer nombre, se usa la siguiente instrucción.
L2$nombre[3]
[1] "Diana"
Para acceder a todos los elementos ubicados en la fila 1 de la matriz B que constituye el
cuarto elemento de la lista L2, se usa la siguiente siguiente instrucción.
L2$B[1,]
[1] 2 5 9
Cuando los subelementos de una lista también tienen nombre, pueden encadenarse varios
descriptores de acceso $ para referenciar subelementos en un nivel más interno.
Considérense los siguientes nombres para los elementos de la lista L1 que conforma el
quinto elemento de la lista L2.
Guillermo Correa Londoño – Introducción a R 44 de 87
Para referenciar el objeto de la fila 2, columna 2, de la matriz B1 que aparece como cuarto
elemento de la lista L1, se usa el siguiente comando.
L2$L1$B1[2, 2]
[1] -1
L2[[5]][[4]]
Para referenciar el elemento que está en la primera fila y tercera columna de la anterior
matriz, se usa la siguiente instrucción:
L2[[5]][[4]][[1,3]]
[1] 9
attach(dca)
anava=aov(y~ttos)
detach(dca)
anava=aov(y~ttos, data=dca)
Guillermo Correa Londoño – Introducción a R 45 de 87
3) Cuando se utiliza alguna función como with, within o transform, las cuales
crean un ambiente de trabajo dentro del cual pueden referenciarse directamente
las variables.
anava=with(dca, aov(y~ttos))
14.2 Filtrado
Considérese la matriz A:
A[,2:3]
[,1] [,2]
[1,] 0 5
[2,] 9 1
O alternativamente:
A[,-1]
[,1] [,2]
[1,] 0 5
[2,] 9 1
A[,c(1, 3)]
[,1] [,2]
[1,] 2 5
[2,] -1 1
Asimismo, podría filtrarse con base en los elementos que satisficieran cierta condición.
Supóngase que se desea seleccionar únicamente los elementos mayores que 4.
Guillermo Correa Londoño – Introducción a R 47 de 87
A[A>4]
[1] 9 5
class(A[2,])
[1] "numeric"
Puesto que el subconjunto resultante tiene una única dimensión, este pasa a ser un vector
de la clase numeric. Para evitar este comportamiento, se usa el argumento drop=FALSE.
class(A[2, , drop=F])
[1] "matrix"
Para sustituir un elemento dentro de un objeto, basta con asignar otro valor a la
correspondiente posición.
Considérese la matriz A:
A[2,3]=7
A
A[1,]=c(1,2,3)
A
Una asignación a una posición inexistente da lugar a la ampliación del objeto. Esta
estrategia puede usarse con vectores, dataframes y listas, mas no con matrices o arreglos.
a=c(2, 0, -7)
a[4]=-9
a
[1] 2 0 -7 -9
Para el caso de vectores o listas no se requiere que los nuevos elementos estén contiguos
a los existentes. Así, podría asignarse un nuevo elemento a la sexta posición del vector
definido anteriormente.
a[6]=4
a
[1] 2 0 -7 -9 NA 4
La función [Link] combina las funciones ls y str, listando la estructura de todos los
objetos en el ambiente de trabajo.
datos
print(datos)
Para visualizar los primeros o los últimos elementos de un objeto, se utilizan las funciones
Guillermo Correa Londoño – Introducción a R 50 de 87
Aunque existen múltiples utilidades que permiten formatear elegantemente las salidas
generadas por R para incorporarlas en un informe, muchas veces el interés del usuario es
más prosaico: llevar las salidas de texto, tal y como se generan por defecto, a un archivo
editable, es decir a un archivo de Word, sin que se desbaraten en dicho proceso. Esto puede
resultar útil para estudiar dichas salidas, para imprimirlas o para tomar y editar lo que de
allí se estime conveniente y llevarlo a un informe.
summary(iris)
Para visualizar las primeras observaciones de este conjunto de datos, así como las últimas,
se usan las funciones head y tail, respectivamente, así:
head(iris)
tail(iris)
anava=aov([Link]~Species, data=iris)
summary(anava)
La función sink es las más expedita, siendo la recomendada cuando se tienen muchas
salidas y/o se quiere enviar absolutamente todo al archivo, incluyendo instrucciones y
resultados. Dicha función, en su forma básica, tiene un único argumento obligatorio, que
es el nombre del archivo, el cual debe escribirse entrecomillado, incluyendo su
correspondiente extensión (admite “txt”, “rtf” y “doc”). Es importante aclarar, sin embargo,
que aunque el archivo de salida tenga extensión “rtf” o “doc”, se trata en realidad de un
archivo de texto sin formato; por tal razón, si se desea tomar dicho archivo como punto de
partida para construir un informe en el que se manejen las diferentes herramientas de
formato que proporciona Word y se incluyan gráficos, deberá usarse la opción “guardar
como” de Word para guardarlo como un verdadero archivo de Word. Asimismo, podrán
incorporarse trozos de dicho documento en cualquier documento Word, mediante el
recurso del copiado y pegado, respetando el formato.
Una vez se ejecuta la función sink con un nombre de archivo como argumento, todo lo
que se genera en adelante, tanto instrucciones como resultados, se envía a dicho archivo.
Al final del script, se recomienda usar la función sink sin ningún argumento para cerrar
la conexión con el archivo, permitiendo su manipulación.
sink("[Link]")
data(iris)
summary(iris)
head(iris)
tail(iris)
anava=aov([Link]~Species, data=iris)
summary(anava)
sink
Guillermo Correa Londoño – Introducción a R 53 de 87
sink("[Link]", append=T)
[Link](resid(anava))
sink
[Link](cat("\n","\n"), [Link](resid(anava)),
file="[Link]", append=T)
En ocasiones, la apariencia del archivo resultante puede hacer pensar que no se satisfizo
el objetivo de capturar el texto, sin que se desconfigurara el formato. Esto es debido a que
el contenido capturado es más amplio que el ancho de hoja, lo que hace que la(s) última(s)
columna(s) pase(n) a la siguiente línea. Esto se soluciona fácilmente, bien sea
disminuyendo el tamaño de la fuente o disminuyendo las márgenes.
La función WriteXLS, que forma parte del paquete con el mismo nombre, permite copiar
dataframes a una hoja de cálculo de Excel. Esta función, al igual que [Link], usa el
software externo “Perl”; mediante la función testPerl, incluida en el paquete
WriteXLS, puede chequearse si el software en cuestión ya ha sido instalado; de no ser así,
puede bajarse desde la página [Link]
dfiris=[Link](iris)
WriteXLS(dfiris, "[Link]")
La primera línea copia la base de datos iris en un dataframe llamado dfiris, el cual se toma
como primer argumento de la función WriteXLS para ser exportado a la hoja de cálculo
“[Link]”, ubicada en el directorio de trabajo. El uso de la extensión determina el tipo de
archivo Excel que se genere. Si se usa extensión xls, se genera un archivo Excel 2003; si se
usa extensión xlsx, se genera un archivo Excel 2007.
Guillermo Correa Londoño – Introducción a R 55 de 87
Para transformar una variable o crear una nueva, basta con asignarle la expresión deseada.
Considérese el siguiente código.
a=25
raiz.a=sqrt(a)
En este caso, en adición al objeto a, que vale 25, se crea un nuevo objeto llamado raiz.a,
cuyo valor es 5.
a=25
a=sqrt(a)
Asimismo, es posible crear un nuevo objeto, combinando dos o más objetos, tal y como se
ilustra a continuación para el cálculo del índice de masa corporal.
peso=65
talla=1.65
IMC=peso/talla^2
Las situaciones ilustradas anteriormente son bastante sencillas, dado que se está
operando sobre un único valor. Lo usual, sin embargo, es transformar un vector de datos.
Puesto que el objeto por excelencia para la organización de bases de datos es el dataframe,
se ilustrarán varios aspectos relacionados con la transformación de vectores dentro de
estas estructuras. En este caso, también pueden crearse nuevos vectores o sobreescribirse
los existentes, dependiendo de que la expresión se asigne a un elemento ya existente o que
se use otro nombre.
La primera línea crea un dataframe, con dos columnas o vectores: a, conformado por la
secuencia de números entre 1 y 21, con incrementos de 2, y un segundo vector, llamado b,
conformado por 11 números aleatorios de la distribución normal estándar. La segunda
línea crea un vector llamado c, resultante de combinar los vectores a y b, acorde con la
Guillermo Correa Londoño – Introducción a R 56 de 87
expresión. Un aspecto esencial es lograr que el objeto transformado, bien sea que se trate
de un nuevo elemento o de un elemento de remplazo para algún otro existente, no quede
aislado en el ambiente de trabajo, sino que se integre al dataframe. En el anterior ejemplo,
el objeto c, definido de esta manera, no forma parte del dataframe [Link], el cual
sigue estando conformado únicamente por a y b. Hay múltiples formas de evitar esta
situación indeseable, las cuales se ilustran en el marco del dataframe definido
anteriormente, detallando únicamente lo concerniente a la segunda línea. Cualquiera de
los siguientes comandos da lugar al mismo resultado.
[Link]$c=log([Link]$a)+([Link]$b)^2
[Link]$c=with([Link], log(a)+b^2)
[Link]=within([Link], c<-log(a)+b^2)
[Link]=transform([Link], c<-log(a)+b^2)
Las cuatro instrucciones anteriores tienen el mismo efecto: dentro del dataframe
[Link] se crea una columna llamada c, a partir de la expresión indicada.
La primera forma, no obstante ser la más directa, exige referenciar cada una de las
variables antecedida por el nombre del dataframe, lo cual puede recargar el código; en
especial, si se usa una expresión compleja. Las otras tres opciones funcionan de manera
similar, creando un ambiente de trabajo temporal que permite referenciar las variables
directamente por su nombre, sin necesidad de que este vaya precedido por el nombre del
dataframe y el símbolo $. Obsérvese que dentro de las funciones within y transform
se utiliza <- como operador de asignación; en estos caso no es posible utilizar el operador
=. El resultado de la función with es la evaluación de la expresión. El resultado de dicha
evaluación se asigna al vector [Link]$c, que al referenciarse de tal manera, entra
a formar parte del dataframe [Link]. Para este caso sencillo, las funciones within
y transform tienen exactamente la misma sintaxis y dan lugar al mismo resultado:
generan un dataframe temporal que es copia del dataframe original ([Link]),
incorporando además el vector c. Puesto que dicho dataframe es temporal, es necesario
fijarlo a un objeto en el ambiente de trabajo, mediante el operador de asignación. En este
caso, al usarse el mismo nombre del dataframe original ([Link]), este es
sobreescrito; también podría asignarse a un objeto con otro nombre.
En este caso, el vector d se calcula a partir del vector c, definido anteriormente dentro de
la misma función, no siendo posible hacer esto mediante la función transform, la cual
Guillermo Correa Londoño – Introducción a R 57 de 87
Es posible usar simultáneamente todos estos controladores de flujo, anidando unos dentro
de otros, ya sean de la misma categoría (p. e. varios ciclos for anidados unos dentro de
otros) o de categorías diferentes (p. e. condicionales if anidados dentro de ciclos while).
Para todos los casos que se detallan a continuación, se usa el descriptor genérico
instrucciones. Tales instrucciones pueden estar conformadas por un comando o
por un conjunto de comandos. Si se trata de un único comando, no es obligatorio escribirlo
dentro de llaves, como sí lo es cuando se trata de varios comandos (cf. 4.9 Comandos).
Los ciclos que usan el controlador de flujo for se caracterizan por incluir un índice que
forma parte de las instrucciones, cuyo valor cambia en cada repetición del ciclo. En la
sintaxis ejemplificada anteriormente, i es el índice en cuestión; para su definición, puede
usarse cualquier nombre sintácticamente válido en R (cf. 13. Nombres). En cada ciclo, el
índice irá tomando secuencialmente cada uno de los valores definidos en el vector de
valores.
Guillermo Correa Londoño – Introducción a R 59 de 87
Es frecuente que el índice tome valores numéricos, definidos a través de una secuencia de
enteros, tal y como se ilustra a continuación.
0
1
2
3
4
5
En este caso el índice llamado dígito toma cada uno de los valores enteros entre cero y cinco,
acorde con lo definido en la secuencia 0:5 (cf. 4.7 Secuencias). Para cada uno de tales valores
se ejecuta la instrucción de imprimir dicho dígito. Inicialmente, dígito toma el primer valor
de la serie (0); a continuación se imprime el valor de dígito (0). Ahí concluye el primer ciclo.
Antes de iniciar el segundo ciclo, dígito toma el segundo valor de la serie (1); a continuación
se imprime el valor de dígito (1). Se continúa de esta manera hasta que dígito toma el
último valor de la serie (5) y se ejecuta el último ciclo, esto es, se imprime el valor de dígito
(5). Producto de este bucle, se tiene una impresión secuencial de los enteros entre 0 y 5.
Los valores que toma el índice no tienen que ser enteros. Bien podría definirse el siguiente ciclo.
[1] 0
[1] 0.09531018
[1] 0.1823216
[1] 0.2623643
[1] 0.3364722
[1] 0.4054651
En este caso el índice, al que se le ha denominado ind toma los valores definidos en la
secuencia, esto es, 1, 1.1, 1.2, 1.3, 1.4 y 1.5 (cf. 4.7 Secuencias), cada uno de los cuales se toma
como argumento de la función logaritmo natural, cuyo resultado se muestra en la consola, acorde
con lo indicado en la instrucción.
También es posible asignar al índice una serie arbitraria de valores, sin que exista requerimiento
alguno de intervalo u orden, tal y como se ilustra a continuación.
[1] 54.59815
[1] 23.10387
[1] 0.1353353
[1] 304.9049
Guillermo Correa Londoño – Introducción a R 60 de 87
En este caso, el índice (x), toma secuencialmente cada uno de los cuatro valores definidos en el
vector. Cada uno de tales valores es tomado como argumento de la función exponencial;
seguidamente, se imprime el resultado por pantalla.
Para la definición de los diferentes valores que tome el índice, ni siquiera es necesario que estos
sean numéricos. Bien pueden definirse elementos alfanuméricos, como en el siguiente ciclo.
[1] 10
[1] 6
[1] 9
[1] 7
En este caso, el índice f toma cada uno de los valores del vector flores; para cada uno de
tales elementos, se contabiliza el número de caracteres y se imprime el resultado.
Los ciclos que usan el controlador de flujo while se ejecuta indefinidamente mientras se
satisfaga la condición, la cual corresponden a una expresión formulada con base en
operadores lógicos, los más comunes de los cuales se relacionan en la siguiente tabla.
Operador Descripción
< Menor que
<= Menor o igual que
> Mayor que
>= Mayor o igual que
== Igual
!= Diferente
! Negación
& Y
| O
Cuando se usa el controlador de flujo while, es necesario que el objeto sobre el cual se
verifica la satisfacción de la condición forme parte de las instrucciones, con la
posibilidad de que estas alteren su valor, constituyendo esta la ruta normal para terminar
el ciclo.
epsilon=1
while(epsilon>0.0001) {
epsilon<-epsilon/2
print(epsilon) }
[1] 0.5
[1] 0.25
[1] 0.125
[1] 0.0625
[1] 0.03125
[1] 0.015625
[1] 0.0078125
[1] 0.00390625
[1] 0.001953125
[1] 0.0009765625
[1] 0.0004882812
[1] 0.0002441406
[1] 0.0001220703
[1] 6.103516e-05
Puesto que el operador de flujo repeat no incorpora una condición para la terminación
del ciclo, este se repetiría infinitamente a no ser que se anidara un condicional if (cf. 19.4
Condicional) que incorpore un comando para fin forzado (cf. 19.5 Salto y fin forzado).
repeat {instrucciones}
La definición de un condicional anidado if que fuerce la terminación del ciclo es
equivalente a la definición de dicha condición en un ciclo while, siendo más natural y
popular la definición mediante el controlador while.
i=0
repeat {
Guillermo Correa Londoño – Introducción a R 62 de 87
i=i+1
print(i)
if (i==7) {break}}
i=0
while(i!=7) {
i=i+1
print(i)}
19.4 Condicional
if (condición) {instrucciones}
En el siguiente ejemplo se ilustra el uso básico del condicional if, consistente en ejecutar
las instrucciones si se satisface la condición y no hacer nada (saltar al siguiente
bloque de instrucciones del script) en caso contrario.
if (length(x)!=length(y)) {
cat("¡Error!", "\n")
cat("Los vectores no tienen el mismo tamaño")}
if(!require(package)) {
[Link]("package", dependencies=T)
library(package)}
llaves por tratarse de una instrucción simple, en la misma línea en la que finaliza la
instrucción.
if (length(x)!=length(y)) {
cat("¡Error!", "\n")
cat("Los vectores no tienen el mismo tamaño")
} else {
z<-(x*y)
print(z)}
if (x==1) {instrucciones1
} else
if (x==2) {instrucciones2
} else
.
.
.
if (x==k) {instruccionesk}
Supóngase, por ejemplo, que se desea calcular la tarifa para un evento, dependiendo del
tipo de asistente.
if (t=="estudiante") {tarifa<-80
} else
if (t=="egresado") { tarifa<-100
} else
if (t=="externo") { tarifa<-150}
cat ("El valor de su inscripción es: ", tarifa)
Los ciclos for y while tienen una manera de terminación normal. En el caso de los ciclos
for, cuando el índice haya tomado todos los valores definidos; en los ciclos while,
cuando deje de cumplirse la condición. En ambos casos es posible terminar los ciclos
de manera extraordinaria, usando break y next como instrucciones de un
condicional interno. Para los ciclos repeat, al no existir una forma de terminación
ordinaria, esta es la única forma de interrumpir el ciclo.
[1] 0
[1] 1
[1] 2
[1] 4
[1] 5
epsilon=1
while(epsilon>0.0001) {
epsilon<-epsilon/2
if (epsilon==0.03125) {break}
print(epsilon)}
[1] 0.5
[1] 0.25
[1] 0.125
[1] 0.0625
Guillermo Correa Londoño – Introducción a R 65 de 87
Dentro del paquete stats, R cuenta con múltiples funciones para el cálculo de
probabilidades, así como para la generación de números aleatorios, pudiendo calcularse
de manera directa probabilidades puntuales (adecuado para funciones masa de
probabilidad), probabilidades acumuladas, valores que acumulan una probabilidad
determinada (cuantiles) y valores aleatorios.
Los nombres de las funciones están conformados por una primera letra que indica su
especificidad, así: d para funciones que calculan probabilidades puntuales (density
function), p para funciones que calculan probabilidad acumulada, q para funciones que
calculan cuantiles (quantile) y r para funciones que calculan números aleatorios (random
numbers). Seguidamente aparece una cadena de caracteres que hace referencia a la
distribución probabilística: binom, para la binomial; pois para la Poisson; norm, para la
normal; chisq, para la Ji cuadrado; t, para la t de Student, y f, para la F de Snedecor, entre
las más comunes. La siguiente tabla resume las funciones más usadas en inferencia
estadística.
Para obtener, por ejemplo, el área a la derecha de 2.3, en una distribución F con 5 y 15
grados de libertad, se utiliza la siguiente instrucción.
Guillermo Correa Londoño – Introducción a R 66 de 87
[1] 0.0969766
Las funciones inversas de la las funciones de probabilidad acumulativa, esto es, las
funciones cuantil, tienen como primer argumento (obligatorio) el valor de la probabilidad
cuyo cuantil se desea obtener. Seguidamente, aparecen los parámetros de la distribución,
igual que en las funciones de distribución acumulativa. También está el argumento
[Link], con valor TRUE por defecto; si se modifica a FALSE, permite obtener los
valores que dejan una probabilidad determinada a su derecha, es decir, la función inversa
de la función de sobrevivencia.
Para averiguar, por ejemplo, cuál es el valor que acumula un área de 0.95 (cuantil 0.95) en
una distribución Ji cuadrado con 7 grados de libertad, se usa la siguiente instrucción.
qchisq(0.95, 7)
[1] 14.06714
qchisq(0.05, 7, [Link]=F)
[1] 14.06714
Todas las funciones que generan números aleatorios (en realidad se trata de números
seudoaleatorios) con base en una distribución probabilística determinada tienen como primer
argumento (obligatorio) la cantidad de tales valores; seguidamente, van los parámetros de la
función generadora.
Así, para generar un vector con 100 valores aleatorios basados en la distrubición normal
estándar, se usa la siguiente instrucción.
rnorm(100)
En general, cada vez que se generen valores aleatorios estos serán diferentes. Para que los
resultados de un proceso que involucre números aleatorios sean reproducibles, es
necesario fijar la semilla con base en la cual se generan tales valores. Para tal efecto se
utiliza la función [Link], la cual requiere como argumento un número entero. Al
establecer una semilla sí se generan siempre los mismos valores:
[Link](66)
rpois(5, lambda=3)
Guillermo Correa Londoño – Introducción a R 67 de 87
[1] 8 5 3 2 4
Guillermo Correa Londoño – Introducción a R 68 de 87
En adición a las funciones que R trae incorporadas en los paquetes que se cargan al inicio
o en cualquier otro paquete, el usuario puede crear sus propias funciones para realizar de
manera ágil y personalizada labores que ejecute consuetudinariamente.
Una vez cargada en memoria, la función podrá usarse, invocándola por su nombre,
haciendo uso de los argumentos necesarios, con lo cual se ejecutarán todas las acciones
que se especificaron entre llaves en la definición de la función.
Considérese una función que tome como argumento un vector numérico, le calcule una
serie de estadísticos básicos, los cuales reporte con cuatro cifras decimales y con su
correspondiente leyenda en español, además de generar un gráfico de caja y bigotes.
estadisticos=function(x) {
cat("Media =", round(mean(x), 4), "\n")
cat("Desviación estándar =", round(sd(x), 4), "\n")
q=quantile(x)
cat("Mínimo =", round(q[1], 4), "\n")
cat("Cuartil 1 (25%) =", round(q[2], 4), "\n")
cat("Cuartil 2 (50%) =", round(q[3], 4), "\n")
cat("Cuartil 3 (75%) =", round(q[4], 4), "\n")
cat("Máximo =", round(q[5], 4), "\n")
require(e1071) # Para cálculo de asimetría y curtosis
s=skewness(x, type=2)
k=kurtosis(x, type=2)
cat("Coeficiente de asimetría =", round(s, 4), "\n")
cat("Coeficiente de curtosis =", round(k, 4), "\n")
quantile(x, c(.025, .5, .75))
require(lattice) # Para el gráfico de caja y bigotes
bwplot(x) }
Supóngase que se quiere usar la función creada anteriormente sobre un vector de 100
observaciones aleatorias de la distribución normal estándar.
estadisticos (rnorm(100))
Guillermo Correa Londoño – Introducción a R 69 de 87
Media = -0.0305
Desviación estándar = 1.0372
Mínimo = -2.4626
Cuartil 1 (25%) = -0.6166
Cuartil 2 (50%) = -0.192
Cuartil 3 (75%) = 0.7186
Máximo = 2.4617
Coeficiente de asimetría = 0.0438
Coeficiente de curtosis = -0.2751
-2 -1 0 1 2
[Link](47)
estadisticos (rnorm(100))
Media = 0.0515
Desviación estándar = 0.9826
Mínimo = -2.3224
Cuartil 1 (25%) = -0.6958
Cuartil 2 (50%) = 0.039
Cuartil 3 (75%) = 0.8857
Máximo = 2.1879
Coeficiente de asimetría = -0.138
Coeficiente de curtosis = -0.4123
Guillermo Correa Londoño – Introducción a R 70 de 87
La familia de funciones apply, que forma parte del paquete stats, permite operar sobre
subconjuntos de datos. Las funciones más comunes de esta familia son apply y tapply.
La función apply se usa para aplicar una función sobre cada uno de los elementos
dimensionales de un arreglo. Si el arreglo en cuestión fuera bidimensional, es decir, una matriz,
esto significa aplicar una función dada a cada una de sus filas o columnas. El formato general
es el siguiente:
Para obtener los promedios por fila de la matriz A, se usa la siguiente instrucción:
apply(A, 1, mean)
Considérese, ahora, la obtención de la suma de los elementos en cada una de las columnas.
apply(A, 2, sum)
[1] 1 9 6
El resultado es un vector con la suma de los elementos de cada una de las tres columnas de A.
Aunque el resultado de los dos casos ilustrados anteriormente ha sido un vector, ello se debe a
la naturaleza de las funciones usadas (media y suma), pero no siempre será así. Supóngase que
se quiere obtener el rango de los elementos dentro de cada una de las filas.
Guillermo Correa Londoño – Introducción a R 71 de 87
apply(A, 1, rank)
[,1] [,2]
[1,] 2 1
[2,] 1 3
[3,] 3 2
Este resultado puede no ser fácilmente visualizable, pues si bien se han calculado los rangos
dentro de cada fila, los correspondientes resultados aparecen organizados por columnas: en la
primera columna de la matriz resultante están los rangos de los elementos de la primera fila de
A, mientras que en la segunda columna de la matriz resultante están los rangos de los elementos
de la segunda fila de A. Para tener una visualización más directa del resultado, basta con
trasponer la matriz resultante.
t(apply(A, 1, rank))
[,1] [,2] [,3]
[1,] 2 1 3
[2,] 1 3 2
apply(R, 4, mean)
También es posible consolidar información de dos o más dimensiones. Así, por ejemplo, pueden
obtenerse los promedios de las dimensiones 1 y 3, lo que equivale a promediar sobre las
dimensiones 2 y 4. El resultado será una matriz de 5 filas (número de elementos dimensionales
de la dimensión 1 de R) y 2 columnas (número de elementos dimensionales de la dimensión 3
de R).
[,1] [,2]
[1,] 48.5 68.5
[2,] 49.5 69.5
[3,] 50.5 70.5
[4,] 51.5 71.5
[5,] 52.5 72.5
Guillermo Correa Londoño – Introducción a R 72 de 87
La función tapply permite aplicar una función sobre grupos o subconjuntos de elementos
dentro de un arreglo, definidos con base en los niveles de uno o más factores.
Considérese el siguiente dataframe, conformado por dos factores (f1 y f2) y por un vector
numérico, y.
[Link](12)
df=[Link](f1=c("a", "b", "c"),
f2=c(rep("A",3),rep("B",3),rep("C",3),rep("D",3)),
y=rnorm(36))
La siguiente instrucción genera los promedios de y, para cada uno de los niveles del factor f1.
a b c
-0.2122834 0.1392543 -0.2819433
Análogamente, pueden obtenerse los promedios de y, para cada uno de los niveles de f2.
A B C D
-0.36354544 -0.19166989 0.17691388 -0.09499511
Asimismo, pueden obtenerse los promedios para cada una de las combinaciones de los niveles
de f1 con los niveles de f2.
A B C D
a -1.0951263 -0.4974490 0.2885335 0.45490803
b 0.4405788 -0.2209877 0.3834918 -0.04606573
c -0.4360888 0.1434270 -0.1412837 -0.69382763
Guillermo Correa Londoño – Introducción a R 73 de 87
23. GRÁFICOS
5 10 15 20 25 30
x
Asimismo, es posible usar como único argumento un objeto con las coordenadas de la
abscisa y de la ordenada. Dicho objeto puede ser de la clase matriz o dataframe.
También es común el uso de una fórmula como argumento, en particular la que expresa la
relación entre dos variables mediante la virgulilla. En las expresiones en las que se usa
esta notación, la variable que aparece a la izquierda de la virgulilla actúa como respuesta,
graficándose, por tanto, en la ordenada, mientras que la que aparece a la derecha actúa
como predictora, graficándose en la abscisa.
plot(y~x)
Guillermo Correa Londoño – Introducción a R 74 de 87
plot(x, y, pch=16)
plot(x, y, cex=1.5)
Hay muchas formas en que puede modificarse el color de los símbolos, mediante el uso del
argumento col (color). Los colores básicos de la paleta pueden generarse con un código
numérico entre 1 y 8 o usando sus correspondientes nombres entre comillas. Los nombres
de los ocho colores básicos de la paleta se obtienen mediante la función palette; para
obtener una lista más completa de colores, se usa la función colors, siendo válido usar
cualquiera de los 657 nombres de dicha lista. En el sitio web de Stowers Institue for Medical
Research se presentan gráficos en pdf con los nombres y el aspecto de tales colores,
organizados de diferentes maneras, los cuales pueden generarse ejecutando el comando:
source("[Link]
[Link]/efg/R/Color/Chart/ColorChart.R"). También es posible
identificar un color mediante su correspondiente código RGB (red, green, blue). Si se desea,
por ejemplo, usar un púrpura profundo, el cual tiene código 80 para el rojo, 32 para el
verde y 117 para azul, el argumento para el color queda así:
col=rgb(80,32,117,max=255). Nótese el uso del argumento max=255 dentro de la
función rgb, el cual es necesario si se desea referenciar los valores RGB en la escala usual,
que va de 0 a 255 para cada componente. Los símbolos identificados con los códigos
numéricos entre 21 y 25 admiten diferentes colores para el borde y para el fondo. En tales
casos, el argumento col se usa para definir el color del borde, mientras que el argumento
bg (background) define el color del fondo.
Para cambiar las etiquetas que identifican los ejes, se usan los argumentos xlab (x label)
Guillermo Correa Londoño – Introducción a R 75 de 87
expression(frac(1, sqrt(2*pi*sigma))~e**((x-mu)^2/2*sigma^2))
expression(X%~%Gamma(alpha,~beta)
Mediante los argumentos [Link] (character expansion for the labels) y [Link]
(character expansion for the main label), que actúan de igual manera que el argumento
cex, es posible modificar el tamaño de las etiquetas, ya sean de texto o expresiones
matemáticas.
plot(x, y, asp=1)
Para cambiar el tamaño de los números que definen las escalas de los ejes, se usa el
argumento [Link] (character expansion for the axis). El argumento font permite
Guillermo Correa Londoño – Introducción a R 76 de 87
definir la fuente, mediante un código numérico. El argumento las (labels style) se usa para
establecer la dirección en que se grafican los valores de los ejes, así: 0: siempre paralelo a
los ejes (valor por defecto), 1: siempre horizontal, 2: siempre perpendicular a los ejes, 3:
siempre vertical.
Para tener mayor control en la presentación de los ejes, puede usarse el argumento
axes=F, con lo cual estos no aparecen. Seguidamente, cada eje se dibuja por separado,
mediante la función axis. Esta función tiene como primer argumento side, mediante el
cual se especifica la ubicación del eje, así: 1 para la abscisa (eje inferior), 2 para la ordenada
(eje izquierdo), 3 para el eje superior y 4 para el eje derecho. Mediante el argumento at
se definen los límites inferior y superior del eje y, opcionalmente, los incrementos. Para
llenar los espacios que quedan entre los ejes y darle al diagrama el aspecto de los que se
construyen por defecto, se usa la función box.
En ocasiones se requiere identificar cada punto con una etiqueta. Esto puede hacerse
mediante la función text, bien sea manteniendo el punto y agregando la etiqueta o
Guillermo Correa Londoño – Introducción a R 77 de 87
Si se ha optado por adicionar la etiqueta, manteniendo también la impresión del punto, puede
resultar conveniente realizar un ajuste al sitio en el que se grafica la etiqueta, de manera que no
se sobreponga con el símbolo de identificación para el punto. Para tal efecto, se utiliza el
argumento pos, el cual puede tomar una de los siguientes valores numéricos: 1 (debajo de las
coordenadas especificadas), 2 (a la izquierda), 3 (encima), 4 (a la derecha).
23.2 Series
Una serie consiste en un conjunto ordenado de datos numéricos, cada uno de cuyos valores
usualmente corresponde a la lectura de una variable en un tiempo dado. Así, la siguiente tabla
representa una serie de datos de biomasa, evaluada a lo largo de seis semanas.
Semana Biomasa
1 2
2 5
3 15
4 35
5 89
6 115
Son usuales las representaciones gráficas con la variable índice (usualmente el tiempo) en el eje
horizontal y la variable principal en el eje vertical, uniendo cada punto de la serie mediante un
segmento de línea. Para tal efecto puede usarse la función plot, con el argumento type="b",
o type="o", en adición con cualquiera de los argumentos reseñados en el apartado
correspondiente a diagramas de dispersión (cf. 22.1). El argumento lty, que puede tomar
cualquier valor entre 0 y 6, define el tipo de línea, siendo 1 la línea continua (valor por defecto).
El argumento lwd, que puede tomar el valor de cualquier entero positivo (por defecto 1),
permite definir el ancho de la línea.
Guillermo Correa Londoño – Introducción a R 79 de 87
Es bastante frecuente que se requiera graficar varias series en un mismo gráfico. Aunque para
tal efecto también podría usarse, con ciertas adecuaciones, la función plot, resulta más práctico
el uso de la función matplot. Esta función reconoce los mismos argumentos que la función
plot (cf. 22.1 Diagramas de dispersión), lo que le confiere gran flexibilidad.
Para el presente caso se usaría como primer argumento la variable índice (el tiempo) y como
segundo argumento las diferentes series. Si se omite el argumento correspondiente a la variable
índice, este se genera de manera automática con los enteros entre 1 y n, siendo n el número de
observaciones.
Supóngase que usando cualquiera de las funciones reseñadas en el apartado 8 (lectura de datos),
se incorpora la anterior información en un dataframe llamado datos. A continuación podría
usarse la siguiente línea para graficar las tres series.
matplot(datos[,2:4], type="b")
Aunque se cumple el objetivo de graficar las tres series de manera simultánea, el resultado no
es muy llamativo. No obstante, usando algunas opciones de personalización, mediante los
argumentos adecuados, puede lograrse un mejor resultado.
h=c(5, 9, 4, 12, 7, 5, 2)
barplot(h)
Muchos de los argumentos usados en la función plot (cf. 22.1 Diagramas de dispersión)
Guillermo Correa Londoño – Introducción a R 82 de 87
funcionan de manera análoga en la función barplot. Así, col permite cambiar el color de las
barras; xlab y ylab se usan para asignar etiquetas a los ejes horizontal y vertical,
respectivamente y [Link] para modificar el tamaño de tales etiquetas; main se usa para
definir el título principal y [Link] para modificar su tamaño; [Link] permite
modificar el tamaño de los números que definen la escala del eje vertical; font se usa para
cambiar las fuentes de ambas escalas; ylim y xlim permite redefinir las escalas vertical y
horizontal, respectivamente; el argumento las se usa para establecer la dirección en que se
grafican los valores de los ejes. Asimismo, es posible usar el argumento axes=F en
conjunción con las funciones axis para definir cada uno de los ejes de manera personalizada,
tal y como se ilustró para la función plot, pudiendo usarse también la función box para
encerrar todo el diagrama en una caja.
En adición a los anteriores argumentos, se usa el argumento [Link] para definir un factor
de expansión para el tamaño de las etiquetas de las barras. El argumento [Link]=1 dibuja
el eje horizontal, el cual está suprimido por defecto ([Link]=0). El argumento border
permite cambiar el color por defecto (negro) del borde. El argumento density permite definir
la densidad del trazado usado para llenar las barras. Una densidad igual a cero dará lugar a una
barra vacía, sin ningún trazo interior; densidades entre uno y aproximadamente 100
(dependiendo del tamaño del diagrama) darán lugar a barras con trazos oblicuos con diferentes
niveles de separación, densidades por encima de 300 generan barras sólidas.
Para dibujar barras horizontales, en lugar de verticales (valor por defecto), se usa el argumento
horiz=T.
Los argumentos optativos col, border y density pueden definirse con un único valor, en
cuyo caso, todas las barras tendrán el mismo aspecto. También es posible definir un valor
diferente para cada barra. En caso de que la longitud del vector con los valores de cualquiera de
tales argumentos sea menor que el número de barras, tales valores se reciclan, es decir, que se
repiten cíclicamente (cf. 11.3 Reciclaje de elementos).
Cuando se usa una matriz numérica como argumento principal (height) de la función
barplot, se genera un diagrama de barras por grupos. Por defecto, cada una de las variables
se apila (beside=F); no obstante, si se usa el argumento beside=T, se generan grupos de
barras por categoría.
Para ilustrarlo, considérese el dataframe iris, que forma parte de los datasets de R, el cual
contiene información sobre la longitud y el ancho del sépalo y el pétalo de tres especies de flores
del género Iris (I. setosa, I. versicolor e I. viginica). Inicialmente se construirá una matriz con
los valores promedio de cada una de las cuatro variables por especie.
data("iris")
[Link]=with(iris, tapply([Link], Species, mean))
[Link]=with(iris, tapply([Link], Species, mean))
[Link]=with(iris, tapply([Link], Species, mean))
[Link]=with(iris, tapply([Link], Species, mean))
(datos=rbind([Link], [Link], [Link], [Link]))
El objeto datos es una matriz de 4 filas y 3 columnas. Las filas corresponden con cada una de
las medidas tomadas en las flores y cada una de ellas tiene un nombre, el cual puede verificarse
con la función rownames(datos); las columnas corresponden a cada una de las categorías
de agrupación (especies, en este caso).
Guillermo Correa Londoño – Introducción a R 84 de 87
barplot(datos, col=c("skyblue","orchid1","yellow3","wheat4"),
beside=T, ylim=c(0,10), legend=T, xlab="especie",
ylab="centímetros", [Link]=1.5, [Link]=1.5, las=1)
box()
Supóngase, ahora que se desea construir un diagrama de barras, agrupando las distintas especies
por variable. Para el efecto, basta con trabajar sobre la transpuesta de la matriz datos, realizando
las adecuaciones del caso en lo concerniente a colores.
23.4 Rectas
La función abline permite trazar líneas rectas sobre un gráfico. Para trazar líneas horizontales,
se usa el argumento h; para líneas verticales, el argumento v. En adición puede modificarse el
tipo de línea, su color y su ancho, mediante los argumentos lty, col y ldw, respectivamente
(cf. 22.1 Diagramas de dispersión y 22.2 Series).
Cuando se traza más de una línea, el uso de un único valor por argumento modificador da lugar
a una serie de líneas de igual aspecto. Si se usan diferentes valores, estos se asignan a cada una
de las líneas trazadas, reciclándose de ser necesario (Cf. 11.3 Reciclaje de elementos).
plot(0,xlim=c(0,20),ylim=c(0,10),type='n',xlab='',ylab='')
abline(v=seq(0,20,2),col=seq(1, 8), lty=seq(1,6), lwd=seq(1,11))
abline(h=seq(0,10,2), col=c('gold4','maroon'),lty=c(3,1), lwd=3)
Guillermo Correa Londoño – Introducción a R 86 de 87
En lugar de los argumentos h o v, es posible usar el intercepto (a) y la pendiente (b) de una
recta. Nótese que una pendiente cero es una recta horizontal; luego, el par de argumentos a=x,
b=0, equivale al argumento h=x, dando lugar a una recta con pendiente cero (horizontal) que
corta la ordenada en x.
abline(2,1, lwd=3)
abline(10,-1, lwd=3)
Los coeficientes a y b pueden formar presentarse en un vector de dos elementos. Así, las
anteriores instrucciones podrían escribirse equivalentemente de la siguiente forma:
abline(c(2,1), lwd=3)
abline(c(10,-1), lwd=3)
La función abline también admite como argumento de entrada un objeto con dos coeficientes,
tal y como los objetos de la clase lm, que se generan al ajustar un modelo de regresión rectilínea
simple.
Nótese que en todos los casos anteriores, la línea trazada cubre completamente el marco de
graficación. Para trazar una línea que una un par de puntos cualesquiera, se usa la función
lines.
Para trazar una línea que una el punto (5, 4) con el punto (20, 6), se usa el siguiente código.
lines(c(5,20), c(4,6))
Esta forma de definir los argumentos puede parecer un poco antiintuitiva; no obstante, cobra
Guillermo Correa Londoño – Introducción a R 87 de 87
sentido, si se considera que el primer argumento contiene las coordenadas x, mientras que el
segundo contiene las coordenadas y.