0% encontró este documento útil (0 votos)
17 vistas87 páginas

Introducción A R (T)

El documento es una introducción al lenguaje de programación R, diseñado para principiantes sin conocimientos previos en estadística o programación. Se abordan temas como la instalación, ejecución, uso básico, y funciones de R, así como conceptos fundamentales de programación y análisis de datos. Se enfatiza la importancia de la práctica y la exploración activa para un aprendizaje efectivo.

Cargado por

lgomezr03
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
17 vistas87 páginas

Introducción A R (T)

El documento es una introducción al lenguaje de programación R, diseñado para principiantes sin conocimientos previos en estadística o programación. Se abordan temas como la instalación, ejecución, uso básico, y funciones de R, así como conceptos fundamentales de programación y análisis de datos. Se enfatiza la importancia de la práctica y la exploración activa para un aprendizaje efectivo.

Cargado por

lgomezr03
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

INTRODUCCIÓN A R

Guillermo Correa Londoño

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.

Con el segundo objetivo en mente, se ha elegido cuidadosamente el orden de presentación


de los temas, buscando que las instrucciones o los conceptos que se usen para ejemplificar
los aspectos centrales de cada apartado hayan sido detallados anteriormente.
Consecuentemente, la recomendación para quien no tenga conocimientos previos de R es
la de realizar un cubrimiento total de todo el texto, en el orden en que aparece. Quien ya
tenga algún conocimiento sobre R o retome el texto después del cubrimiento inicial, podrá
dirigirse al apartado específico que contenga los aspectos de su interés, a manera de
referencia. En tales casos, si el usuario se encontrara con algún concepto que surge
aparentemente de la nada, podría revisar los apartados anteriores, en los que muy
probablemente encontrará la explicación requerida.

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

R es un ambiente y un lenguaje de programación de fuente abierta, con grandes


capacidades estadísticas y gráficas.

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.

El mejor punto de partida para todo lo relacionado con R (instalación, aprendizaje,


actualizaciones, etc.) es la página del proyecto R ([Link] Allí puede
accederse a información básica y documentación, así como a la Red Exhaustiva de Archivos
de R (CRAN: The Comprehensive R Archive Network), desde donde pueden bajarse tanto los
instaladores del programa, como las extensiones del mismo (paquetes). Al hacer clic en el
vínculo CRAN, se direcciona a una página desde donde puede elegirse el servidor (mirror)
más conveniente. Cada servidor cuenta con una copia de todos los archivos. Uno de los
servidores de nuestro País se encuentra en la Universidad Nacional de Colombia
([Link]
Guillermo Correa Londoño – Introducción a R 4 de 87

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.

Seguidamente, el instalador ofrece la posibilidad de usar opciones de configuración. Se


recomienda elegir “Sí”. En tal caso, aparece una ventana en la que se ofrecen dos opciones
en relación con la interfaz: MDI (Multiple Document Interface), que da lugar a una interfaz
con una ventana madre en la que se alojan todas las demás ventanas (consola, scripts,
figuras, etc.), y SDI (Single Document Interface) que da lugar a una interfaz en la que todas
las ventanas son independientes. La elección de la interfaz dependerá de las preferencias
del usuario.

Para la forma en que se presenta la ayuda, se recomienda el formato HTML.


Guillermo Correa Londoño – Introducción a R 5 de 87

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.

Existen diversas formas de ejecutar el programa.

[Link]: Abre la interfaz más básica de R, consistente en una ventana sin ningún tipo
de menú.

[Link]: Ejecuta el programa en un sistema de ventanas en ambiente Windows, con una


barra de menús en la parte superior.

Otras Interfaces Gráficas: Existen muchas otras formas de ejecutar R a través de


programas de terceros que ofrecen interfaces más amigable, las cuales se denominan
genéricamente GUI (Grafical User Interface). Las hay de muy diversa índole; desde las que
incorporan las principales funciones en un sistema de menús y cajas de diálogo, sin que el
usuario necesite enterarse del código ejecutado; una de tales GUI es R Commander
([Link] la cual puede resultar muy útil para el usuario que lo
único que desea es obtener un resultado, sin involucrarse necesariamente en el
aprendizaje del código. Obviamente, no es este el enfoque que se pretende estimular. Por
otro lado, hay interfaces que hacen más cómodo el trabajo del programador, sin restarle
autonomía; una de las más populares con este enfoque, y que se constituye en nuestra
recomendada, es RStudio ([Link] Esta es la interfaz por defecto de
muchos desarrolladores serios, así como de usuarios finales.

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

4.1 Como calculadora

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.

4.2 Funciones básicas

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.

4.3 Separador decimal

R siempre usa el punto como separador decimal, independientemente de la configuración


local del equipo. Podría pensarse que si un equipo está configurado con la coma como
separador decimal, la función log(2,71) arrojaría el logaritmo natural de 2.71; no
obstante, el resultado obtenido es el logaritmo de 2 en base 71.

4.4 Argumentos de las funciones

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.

Considérese la función [Link], la cual realiza inferencia sobre el parámetro p de la


distribución binomial. Esta función tiene 5 argumentos, los cuales aparecen definidos en
el siguiente orden:
Guillermo Correa Londoño – Introducción a R 7 de 87

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.

[Link](x=185, n=200, p=0.9, alternative="greater",


[Link]=0.95)
[Link](185, 200, 0.9, "greater", 0.95)
[Link](185, 200, 0.9, "greater")
[Link](alternative="greater", p=0.9, n=200, x=185)
[Link](185, 200, alternative="greater", p=0.9)

4.5 Mayúsculas y minúsculas

R diferencia entre mayúsculas y minúsculas; consecuentemente, a y A representarán


distintos objetos. Asimismo, las funciones tienen una manera particular de escribirse, la
cual debe respetarse. Por tanto, si se escribe Log(2.71), se obtiene un mensaje de error,
en lugar del logaritmo natural de 2.71. La mayoría de funciones en R se escriben con
minúscula; no obstante, esta no es una regla, habiendo funciones, como View, que se
escriben con mayúscula. En otras ocasiones, la función pude combinar mayúsculas y
minúsculas, como en TukeyHSD.

4.6 Resultados en consola

Cuando el contenido de un vector es desplegado en la consola, aparecen indicadores de la


posición de los elementos. Tales indicadores están ubicados en la parte izquierda y van
entre corchetes.
Guillermo Correa Londoño – Introducción a R 8 de 87

Considérese la generación de 100 números aleatorios de la distribución Poisson, con


lambda igual a 130.

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

El contenido del vector resultante se ajusta al ancho de la consola. En la presente


ilustración, la consola despliega 17 elementos a lo ancho. El valor entre corchetes que
aparece encabezando la primera fila indica que 127 es el primer valor del vector. El valor
entre corchetes que aparece en las filas subsiguientes indica la posición que el elemento
inicial de cada fila ocupa en el vector. Así, 109 ocupa la posición 18; 121, la posición 35, y
147 ocupa la posición 86. Si todos los elementos del vector cupieran en una sola fila,
únicamente aparecería el indicador [1]; esto es lo usual para resultados que constan de un
único valor.

4.7 Secuencias

La función seq permite generar secuencias numéricas. El primer argumento (from)


indica el primer número de la serie. El segundo argumento (to) indica el final de la serie.
Por defecto, se utilizan intervalos de 1 (by=1).

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

Mediante el argumento [Link] es posible generar una secuencia especificando el


número de valores de la serie, dejando que la longitud del intervalo se calcule
automáticamente.

seq(0, 100, [Link]=5)


[1] 0 25 50 75 100

4.8 Repeticiones

La función rep permite repetir el primer argumento de la función. El segundo argumento


(times) especifica el número de repeticiones.

rep(5, 3)
[1] 5 5 5

También puede repetirse una secuencia.

rep(2:5, times=3)
[1] 2 3 4 5 2 3 4 5 2 3 4 5

La instrucción anterior da lugar a la repetición de la secuencia completa tres veces. En


contraste, el argumento each permite repetir cada uno de los elementos de la secuencia
un número determinado de veces.

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).

rep(c("a", "b", "c"), times=2, each=3)


[1] "a" "a" "a" "b" "b" "b" "c" "c" "c" "a" "a" "a" "b" "b" "b" "c" "c" "c"
Guillermo Correa Londoño – Introducción a R 10 de 87

4.9 Comandos o instrucciones

Se le denomina genéricamente comando o instrucción a la cadena de caracteres que al ser


ejecutada da lugar a un proceso o un resultado. Las asignaciones y las funciones son los
comandos más comunes. Al escribir un comando es imprescindible respetar la escritura
exacta, en lo concerniente al uso de las mayúsculas y las minúsculas; no obstante, no hay
ninguna restricción en lo que a espacios en blanco se refiere, siendo posible insertar
cuantos espacios en blanco se desee (o ninguno), sin que esto afecte la instrucción.

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.

4.9.1 Particiones correctas de comandos

peso.160=
predict(modelo, newdata=[Link](edad=160),
interval="confidence", level=0.99)

plot(
peso~edad, data=reg, main="Modelo ajustado")

4.9.2 Particiones incorrectas de comandos

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

ejemplo), una sesión de trabajo implica la ejecución de múltiples instrucciones. En tales


casos, es mucho más práctico organizar los comandos necesarios en un archivo que
digitarlos uno a uno en la consola. Al conjunto de comandos utilizado para la realización
de una tarea se le denomina script. Los scripts en R se guardan en archivos de texto con
extensión R. La interfaz gráfica de RStudio facilita la creación, carga y edición de scripts.
Estos aparecen por defecto en el panel superior izquierdo.

4.11 Ejecución de comandos

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).

Al abrir RStudio se establece el directorio de trabajo correspondiente a la ubicación del


script desde el que se haya llamado o el directorio de trabajo por defecto (si no se llamó
desde ningún script). Si luego de tener la interfaz abierta se cargan nuevos scripts, estos se
abren en nuevas pestañas, manteniéndose el directorio de trabajo establecido
previamente. Para cambiar de manera rápida el directorio de trabajo, haciéndolo
corresponder con la ubicación de un script abierto en una pestaña dada, se activa la
pestaña deseada y, en el menú “Session”, se eligen las opciones “Set Working Directory” y
“To Source File Location”. Esto equivale a aplicar la función setwd sobre la ruta del script
deseado.
Guillermo Correa Londoño – Introducción a R 14 de 87

6. PAQUETES

R es un ambiente de trabajo extensible por módulos. Hay miles de módulos disponibles,


cada uno de los cuales se especializa en realizar diferentes tareas. A estos módulos se les
denomina paquetes (packages) y pueden obtenerse desde cualquiera de los sitios de la
CRAN (v. gr. [Link]

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.

6.1 Instalación de Paquetes

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.

1) A través de la CRAN. Se ingresa por la página principal del proyecto R


([Link] y se elige un servidor o mirror. Una vez seleccionado
el servidor, se sigue el vínculo contributed extension packages. Puede buscarse el
paquete a través de una tabla organizada por fecha de publicación o a través de una
tabla organizada en orden alfabético. A no ser que se estén buscando los paquetes
más recientemente publicados, será más fácil encontrar un paquete a través de la
tabla organizada en orden alfabético. Cuando se usa esta vía se elige el
correspondiente archivo r-release. Una vez se haya bajado el archivo zip
comprimido, se procede a la instalación, usando la opción “Instalar paquete(s) a
partir de archivos zip locales”, ubicada en el menú “Paquetes”, si se está trabajando
desde la interfaz por defecto; o si se está trabajando en RStudio, se ingresa por el
menú “Tools”, se elige “Install packages” y, en el campo “Install from”, se elige
“Package Archive File”. Esta forma de instalación tiene la desventaja de exigirle al
usuario la instalación individual de cada uno de los paquetes de los que dependa el
paquete principal que vaya a instalarse. Ingresando a través de
[Link] búsquese, por ejemplo, el paquete homals. Obsérvese que
este paquete depende de los paquetes rgl, ape y scatterplot3d. Luego, si un
usuario desea usar el paquete homals, con todas sus funcionalidades, deberá
instalar adicionalmente los otros tres paquetes.
Guillermo Correa Londoño – Introducción a R 15 de 87

2) Desde RStudio. Es posible instalar los paquetes directamente desde la interfaz de


RStudio, sin necesidad de realizar ninguna descarga previa. Para este tipo de
instalación, se requiere conexión a Internet. Esta modalidad tiene la ventaja de
instalar el paquete principal junto con todos los otros paquetes de los cuales
dependa. Así, por ejemplo, si se realiza la instalación del paquete homals, por esta
vía, también se instalarán los paquetes rgl, ape y scatterplot3d, sin
necesidad de intervención por parte del usuario. Si se está trabajando en la interfaz
por defecto de R, se ingresa al menú “Paquetes”; allí se procede a “Seleccionar
espejo CRAN”; seguidamente se elige la opción “Instalar paquete(s)” y se selecciona
el paquete principal que se desee instalar. Si se está trabajando desde la interfaz de
RStudio (recomendada), se ingresa por el menú “Tools”, se elige la opción “Install
packages” y en la ventana que aparece se escribe el nombre del paquete que se
desea instalar, manteniendo activa la casilla de verificación “Install dependencies”,
para que se instalen los paquetes secundarios de los que dependa el paquete
principal. Seguidamente se procede con la instalación. En este caso, no se requiere
seleccionar un servidor; por defecto, toda la información se busca en el servidor de
RStudio (Global (CDN) – RStudio).

6.2 Carga de Paquetes

El hecho de haber instalado un paquete no significa que el mismo se encuentre siempre


cargado en memoria, listo para ser usado. Aunque a primera vista esto podría parecer una
desventaja, constituye en realidad una gran ventaja, por cuanto permite que el programa
se mantenga liviano al cargar en memoria únicamente lo que va a ser usado en un
momento determinado. Tal y como se indicaba anteriormente, hay siete paquetes básicos
que se cargan cada vez que se inicia el programa: base, stats, graphics, grDevices,
methods, utils y datasets. Estos vienen preinstalados con el programa y no
requieren ningún tipo de carga o intervención por parte del usuario. El uso de cualquier
otro paquete requerirá que este se cargue en memoria, para una sesión de trabajo
específica. Para cargar un paquete es necesario que este haya sido instalado previamente.
La instalación se realiza una sola vez (otro asunto son las actualizaciones); la carga debe
realizarse en cada sesión de trabajo en la que vaya a usarse el paquete.

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

require(paquete). Si el paquete que se pretende cargar está instalado, es indiferente


usar cualquiera de las dos funciones, pues ambas realizan exactamente la misma labor:
cargan el paquete en memoria, dejándolo disponible para su uso. Así, para cargar, por
ejemplo, el paquete homals, junto con sus paquetes anexos, puede usarse función
library(homals) o require(homals).

En caso de que el paquete no hubiera sido instalado previamente, el comportamiento de


ambas funciones diferiría: la función library(paquete) generaría un error, mientras
que la función require(paquete) generaría una advertencia y un marcador lógico
invisible falso, lo que facilitaría resolver dicha contingencia en un script, a través de la
función [Link] (cf. 19.4 Condicional).

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}.

La función search muestra los paquetes cargados en memoria. La función library


muestra todos los paquetes instalados disponibles, estén cargados o no.

Aunque no es usual descargar un paquete de memoria una vez se ha cargado,


eventualmente podría estarse en una situación en la que los recursos de memoria son
críticos o en la que se desea descargar un paquete para evitar conflictos con algún otro.
Para tal efecto, se utiliza la función detach, usando como argumento
package:paquete. Así, por ejemplo, para descargar de memoria el paquete phia, se
escribe el siguiente comando: detach(package:phia). Es importante tener presente
que mediante este procedimiento únicamente se descarga de memoria el paquete
relacionado en el argumento, sin que se descarguen los demás paquetes que hayan podido
cargarse por depender del paquete principal. Así, al usar, por ejemplo, el comando
library(phia), además de cargarse phia, también se carga de manera automática el
paquete car; no obstante, al usar el comando: detach(package:phia) únicamente se
descarga el paquete phia, manteniéndose cargado el paquete car.
Guillermo Correa Londoño – Introducción a R 17 de 87

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.

En la página principal del proyecto R ([Link] hay una sección de


noticias en la que se indica cuál es la versión más reciente de R y si hay algún lanzamiento
próximo. Asimismo, los diferentes servidores de la CRAN (v. gr. [Link]
cuentan con una copia del instalador de la versión más reciente. Es posible verificar si la
versión de R que se está ejecutando corresponde a la más reciente o no, usando la función
updateR, que forma parte del paquete installr. En caso de que el usuario esté
corriendo una versión desactualizada del programa, la función updateR brinda la
posibilidad de realizar la correspondiente actualización. De ser así y en caso de estar
usando RStudio, aparece una ventana en la que se sugiere abortar la actualización, salir de
RStudio y realizar el proceso directamente desde la interfaz gráfica propia de R (RGui).

7.2 Actualización de RStudio

Si se eligió RStudio como interfaz gráfica para el trabajo en R, puede verificarse si la


versión que se está corriendo está actualizada, usado la opción “Check for Updates” del
menú “Help”.

7.3 Actualización de Paquetes

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

directamente a la ventana de actualizaciones presionando el botón UPDATE ( ), que


aparece en la pestaña “Packages”, la cual está ubicada por defecto en la ventana inferior
derecha de RStudio.
Guillermo Correa Londoño – Introducción a R 19 de 87

8. LECTURA DE DATOS

Existen muchas formas de leer datos en R: ingresándolos directamente a través de la


consola (o de un script), leyéndolos desde un archivo en formato nativo que haya sido
guardado previamente o importándolos desde otro formato.

La primera forma, es decir, ingresándolos directamente a través de la consola es muy poco


práctica para leer bases de datos, por lo que no suele usarse más que en casos sencillos,
donde se tengan pocos datos o se esté usando R a manera de calculadora. La segunda
manera implica haber creado la base de datos en formato nativo en una sesión previa. La
tercera forma, es decir, la que procede por importación, es la más usual y es la que se
detallará a continuación.

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]")

Mediante el comando anterior se lee la información contenida en el archivo ASCII llamado


[Link], ubicado en el directorio BDR, que está en la raíz del disco C, y se asigna a un
objeto llamado bd. La ruta del archivo podrá omitirse si el archivo está ubicado en el
directorio de trabajo (cf. 5. Directorio de trabajo).

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.

Si la primera fila no contiene los nombres de las variables, R las nombrará


automáticamente de manera genérica como V1, V2, …, VK, siendo K el número de variables.
Si la primera fila contiene el nombre de la variable, deberá indicarse explícitamente, con
el argumento header=TRUE. Si el nombre de la variable contiene espacios o caracteres
especiales, estos serán remplazados por puntos. La instrucción para leer un archivo que
Guillermo Correa Londoño – Introducción a R 20 de 87

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]", sep="\t", header=TRUE)

La función [Link] trae por defecto las opciones de separador tabular y


encabezado, por lo que la importación ilustrada podría realizarse así:

bd=[Link]("C:/BDR/[Link]")

La función [Link] realiza en esencia la misma labor que [Link] o que


[Link], pero sobre un archivo CSV, cambiando los valores por defecto. Al usar la
función [Link], la primera fila del archivo se toma como encabezado y la coma es el
separador de los elementos.

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]

Esta función tiene la siguiente sintaxis:

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.

En adición a las anteriores funciones, también pueden usarse read.delim2 y


read.csv2, las cuales difieren de sus funciones cuasihomónimas en reconocer por
defecto la coma (,) como carácter decimal. En tal caso, los archivos CSV usan el punto y
coma (;) como separador de valores.

Cualquiera de las funciones anteriores puede usarse conjuntamente con la función


[Link], para importar un archivo que se encuentre en una ubicación cualquiera,
sin necesidad de referenciarlo, sino ubicándolo mediante una ventana de navegación. Si se
desea leer, por ejemplo, un archivo ASCII con nombres de variables en la primera fila,
separador tabular para los elementos y punto como carácter decimal, pude usarse la
siguiente instrucción:

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

texto en los que se usa otro separador de valores.

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.

Nombres de variables Separador de


Carácter decimal
Función Formato en la primera fila elementos
(dec= )
(header= ) (sep= )
[Link] ASCII FALSE "" "."
[Link] ASCII TRUE "\t" "."

ASCII TRUE "\t" ","


read.delim2
[Link] CSV TRUE "," "."
read.csv2 CSV TRUE ";" ","
[Link] xls o xlsx TRUE El del sistema

En adición a la lectura desde un archivo en una localización específica o en una ubicación


cualquiera (mediante la función [Link]), es posible leer información
directamente desde el portapapeles (clipboard); basta con usar cualquiera de las
funciones expuestas anteriormente, excepto [Link], introduciendo "clipboard"
como primer argumento de la función y realizando las especificaciones del caso en los
demás argumentos, de ser necesario.

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

Si la región seleccionada y copiada no incluyó encabezados, podría usarse el siguiente


comando:

bd=[Link]("clipboard", sep="\t")

bd=[Link]("clipboard", header=FALSE)

Si la región seleccionada y copiada incluyó encabezados, pero el separador decimal del


sistema es la coma, podría usarse el siguiente comando:

bd=read.delim2("clipboard")

En resumen, para la importación de datos se utiliza alguna de las funciones descritas


anteriormente, bien sea indicando el nombre del archivo que contiene la información o
mediante la opción de búsqueda del archivo ([Link]) o de copiado desde el
portapapeles (clipboard). A no ser que la labor realizada vaya a realizarse una única
vez, sin que vuelva a requerirse nunca su ejecución, se desaconseja el uso de la opciones
[Link] y clipboard, por no facilitar el uso posterior del script. Con miras a la
trazabilidad y posibilidad de edición y reejecución de los scripts, se aconseja explicitar
siempre el nombre del archivo que contiene los datos que se importan.

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]")

La anterior instrucción genera el archivo [Link], el cual contiene la información en el


formato nativo de R y puede ser rápidamente leída a futuro, usando la instrucción load.

load("[Link]")
Guillermo Correa Londoño – Introducción a R 24 de 87

9. AYUDAS

Para acceder a la ayuda sobre cualquier función o paquete, se escribe ?función o


help(función). Así, para obtener ayuda, por ejemplo, para la función [Link], se
escribe ?[Link] o help([Link]). La función sobre la que se busque ayuda
por esta vía debe formar parte de un paquete instalado y cargado.

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")

Si no se recuerda el nombre exacto de la función o se desea buscar funciones con nombres


similares, puede usarse la función apropos, la cual da como resultado los un listado de
las funciones cuyo nombre incluye la cadena de caractéres en cuestión.
Guillermo Correa Londoño – Introducción a R 25 de 87

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

10. OBJETOS Y ESTRUCTURAS DE DATOS

R es un lenguaje con características compatibles con la programación orientada a objetos.


Un objeto está definido como una entidad sobre la cual puede operarse. Así, un número es
un objeto, también son objetos una cadena de caracteres, una fórmula o un resultado.
Aunque es evidente la posibilidad de operar sobre un número, no lo es tanto la posibilidad
de operar sobre una cadena de caracteres, sobre una fórmula o sobre un resultado. No
obstante, si se considera, por ejemplo, la función print, tomando tales objetos como
argumento para mostrarlos en la consola, la posibilidad de operar sobre los mismos se
hace clara.

Un grupo de objetos de gran interés es el de los que actúan como contenedores de


información, permitiendo agruparla o estructurarla. La estructura más básica es el vector,
el cual está definido como un conjunto unidimensional de elementos del mismo tipo (todos
enteros, todos reales, todos complejos, todos caracteres, todos lógicos o todos en bruto).
En orden de complejidad, sigue la matriz, definida como una estructura bidimensional de
elementos del mismo tipo. Está también el arreglo, que constituye la generalización de la
matriz, pudiendo tener más de dos dimensiones; la matriz sería un arreglo particular de
dos dimensiones. El dataframe, al igual que la matriz, es una estructura bidimensional,
pero es más general que la matriz, por cuanto admite elementos de diferente tipo. Esta es
la manera en la que suelen estructurarse datos de diferente tipo (entero, real, carácter,
complejo, lógico, bruto); el dataframe es la base de datos por excelencia en R. La lista es la
estructura más general, teniendo la posibilidad de contener no solo vectores de diferente
tipo, sino también cualquiera de las otras estructuras, incluyendo otras listas.

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.

En resumen, las estructuras básicas de datos en R, en orden de complejidad son: vector,


matriz, arreglo, dataframe y lista. Las tres primeras son estructuras atómicas; las dos
últimas, recursivas.

10.1 Vectores

La manera más común de crear un vector es mediante el uso de la función de


concatenación, c, y el operador de asignación (<- ó =). Si se desea crear, por ejemplo,
un vector llamado a, que contenga los elementos 3, 5 y 9, podrá usarse cualquiera de los
siguientes comandos, para crear un vector numérico (cada uno de los elementos que lo
conforman es un número).

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

Aunque menos común, también podría usarse la función assign.

assign("a", c(3, 5, 9))

Valga anotar que es la función c la que define el vector; el paso correspondiente al


almacenamiento de dicho objeto en memoria (la asignación) se requeriría únicamente si
en un paso posterior fuera a usarse dicho vector. Si no se realizara el paso de asignación,
se generaría un vector que a pesar de su existencia efímera (únicamente existiría en la
línea en la que hubiera sido creado) podría bastar para un propósito determinado, tal y
como servir de argumento en una función determinada. Así, por ejemplo, la instrucción
c(3, 5, 9) crearía un vector numérico con los elementos 3, 5 y 9 y lo mostrará en la
consola; no obstante, dicho vector no podría recuperarse en una instrucción posterior.

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.

b=c("Gabriela", 'Ana', "Luz", 'Marina')

Para verificar si un objeto es un vector se usa la función [Link](objeto), la cual


genera un resultado lógico (falso o verdadero).

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.

Supóngase que se quiere crear la siguiente matriz numérica:

2 0 5
-1 9 1

Para tal efecto, se usa la siguiente instrucción.


Guillermo Correa Londoño – Introducción a R 28 de 87

matrix(c(2, 0, 5, -1, 9, 1), nrow=2, ncol=3, byrow=TRUE)

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:

[,1] [,2] [,3]


[1,] 2 5 9
[2,] 0 -1 1

Considérense los vectores a, b y c:

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).

Las matrices en R comparten las características de las matrices como concepto


matemático, siendo posible realizar operaciones matriciales con base en estas; entre las
más comunes, se destacan la suma (operador +), el producto matricial (operador %*%), la
trasposición (t), la inversión (solve), la obtención de la diagonal (diag), la
descomposición espectral (eigen) y la descomposición en valores singulares (svd).

Asimismo, puede obtenerse la suma de productos cruzados o la suma de cuadrados,


mediante las funciones crossprod y tcrossprod.
Guillermo Correa Londoño – Introducción a R 29 de 87

Las siguientes instrucciones son equivalentes y dan lugar al producto X’X.

crossprod(X)
crossprod(X, X)
t(X)%*%X

También son equivalentes las siguientes instrucciones.

crossprod(X, y)
t(X)%*%y

Asimismo, se tienen la siguiente equivalencia.

tcrossprod(X)
tcrossprod(X, X)
(X)%*%t(X)

Y esta otra equivalencia.

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.

Aunque los vectores son simples contenedores unidimensionales que no guardan


correspondencia con el concepto del álgebra lineal, también admiten operaciones
matriciales, adaptándose a vectores fila o vectores columna según corresponda.

Considérense los siguientes objetos:

a=c(3, 5, 9)
b=c(7, 2)
A=matrix(c(2, 0, 5, -1, 9, 1), nrow=2, ncol=3, byrow=TRUE)

A es una matriz 2x3, mientras que a y b son vectores de tamaño 3 y 2, respectivamente.

Todas las siguientes operaciones están adecuadamente definidas:


Guillermo Correa Londoño – Introducción a R 30 de 87

b%*%A # El resultado es una matriz 1x3


A%*%a # El resultado es una matriz 2x1
t(a)%*%a # El resultado es una matriz 1x1
a%*%t(a) # El resultado es una matriz 3x3
t(b)%*%b # El resultado es una matriz 1x1
b%*%t(b) # El resultado es una matriz 2x2

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

La anterior información podría estructurase en un arreglo de tres dimensiones, con las


unidades en la primera dimensión, las variables en la segunda y el tiempo en la tercera.
Asimismo, si se tuviera otro factor, como localidad, por ejemplo, podría incorporarse en la
cuarta dimensión. De igual manera, podrían generarse dimensiones adicionales.

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')

A continuación se genera el arreglo:

R=array(vector, dim=c(4, 3, 2))

, , 1
Guillermo Correa Londoño – Introducción a R 31 de 87

[,1] [,2] [,3]


[1,] "a" "x" "d"
[2,] "c" "m" "b"
[3,] "f" "j" "u"
[4,] "d" "l" "y"

, , 2

[,1] [,2] [,3]


[1,] "b" "h" "r"
[2,] "j" "o" "s"
[3,] "h" "w" "n"
[4,] "i" "p" "q"

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.

Para verificar si el objeto R es un arreglo, se utiliza la función [Link](R). Todas las


matrices son arreglos; solo un arreglo de dos dimensiones es equivalente en estructura a
una matriz.

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.

Considérense los siguientes vectores: id es un vector de caracteres, v1 es numérico y v2


es complejo.

id=c("a23", "f31", "j33", "m54")


v1=c(2.4, 7.9, 1.1, 8.5)
v2=c(4+3i, 2-0.8i, 1+1.1i, 3-5i)

Una manera de generar un dataframe es a través de la agregación de vectores, sin importar


su tipo. La siguiente instrucción genera un dataframe concatenando por columnas los
vectores definidos anteriormente.

DF=[Link](id, v1, v2)

id v1 v2
1 a23 2.4 4+3.0i
Guillermo Correa Londoño – Introducción a R 32 de 87

2 f31 7.9 2-0.8i


3 j33 1.1 1+1.1i
4 m54 8.5 3-5.0i

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.

Puesto que el dataframe es una estructura bidimensional, al incluir un arreglo en la


definición de un dataframe, este se “aplanaría” a dos dimensiones. Si se toma el arreglo R,
generado anteriormente (ver ejemplo en el ítem de arreglos) y se escribe el comando:
DF2=[Link](R), se obtiene un arreglo rectangular de cuatro filas y seis columnas
en el que los tiempos están concatenados por columnas.

Cuando se usan las funciones [Link], [Link], read.delim2, [Link],


read.csv2 o [Link], los objetos que se generan son dataframes. Para evaluar si un
objeto es un dataframe, se usa la función [Link]. Este aspecto es de particular
relevancia, pues muchas funciones que trabajan sobre datos exigen que estos sean de una
clase particular. Se indicaba, por ejemplo, que las operaciones matriciales exigen objetos
de la clase matriz (eventualmente, también vectores). Si bien las matrices están
conformadas por vectores del mismo tipo, esta no es una condición suficiente para tener
una matriz. Así, cuando se importa, por ejemplo, un conjunto de vectores numéricos, se
obtiene un dataframe; no una matriz. Para llevar un objeto a la clase matriz, se utiliza la
función [Link].

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

Considérense los siguientes objetos:

nombre=c('Iván', 'Rosa', 'Diana') #Vector tipo carácter


edad=c(34, 43) #Vector tipo doble precisión
aprobado=c(TRUE, TRUE, FALSE) #Vector tipo lógico
B=matrix(c(2, 0, 5, -1, 9, 1), nrow=2, ncol=3) #matriz tipo
#doble precisión

Los anteriores objetos pueden concatenarse en una lista, así:

L1=list(nombre, edad, aprobado, B) #Lista

A partir de los anteriores objetos puede generarse una nueva lista:

L2=list(nombre, edad, aprobado, B, L1) #Lista, uno de cuyos


# objetos es otra lista

Para verificar si el objeto L2 es una lista, se utiliza la función [Link](L2). Mediante la


función [Link], es posible verificar que los objetos L1 y L2 definidos anteriormente
en adición a ser listas, también son vectores.

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”.

En resumen, el lenguaje R proporciona una variada gama de contenedores que resulta


suficiente para satisfacer las necesidades de organización de la información. El vector
constituye la forma más básica de agrupar datos; es el objeto más utilizado para la
definición de argumentos secundarios en las funciones de R; es la estructura que se
utilizaría siempre que los datos fueran del mismo tipo y no exigieran un arreglo
multidimensional. Cuando se requiera realizar operaciones matriciales, los objetos deben
ser matrices o vectores. El arreglo resulta útil para organizar datos del mismo tipo en más
de dos dimensiones. El dataframe es la estructura en la que se organizan las bases de datos
en R. La mayoría de procedimientos estadísticos implementados en R exigen que el objeto
de entrada sea un dataframe. Cuando se importan datos, se genera un dataframe. La lista
resulta útil cuando se requiere tener toda la información en un mismo contenedor. Este es
el objeto que suele usarse para alojar los resultados de las funciones.
Guillermo Correa Londoño – Introducción a R 34 de 87

11. TAMAÑO, DIMENSIONES Y RECICLAJE DE UN OBJETO

11.1 Tamaño

Se obtiene mediante la función length. Cuando el argumento es un objeto atómico


(vector, matriz o arreglo), da como resultado el número de elementos del objeto. Al usarla
con una lista como argumento, el resultado se refiere al número de objetos de mayor
jerarquía, sin contabilizar los objetos anidados dentro de cada uno de estos. Cuando se
utiliza con un dataframe como argumento, el resultado es el número de columnas.

Es importante aclarar que en R no existe el concepto de escalar o de carácter individual,


cualquier número, ya sea real o complejo, y también cualquier cadena de caracteres es un
vector de tamaño 1.

11.2 Dimensiones

Mediante la función dim se obtiene el número de elementos dimensionales de un


contenedor multidimensional, esto es de una matriz, un arreglo o un dataframe. Así, la
función dim aplicada a una matriz informará su número de filas y de columnas. Esta
función no es aplicable a objetos unidimensionales, es decir, vectores y listas.

11.3 Reciclaje de elementos

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.

Considérense los siguientes vectores

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)

Luego, cuando se solicita la operación a+b, se suman los vectores (1, 3, 1, 3, 1) y


(1, 2, 3, 4, 5), obteniéndose el siguiente resultado.

[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

realiza de manera silenciosa; de no ser así, aparece un mensaje de advertencia, indicando


que el tamaño del objeto mayor no es múltiplo del tamaño del objeto menor. Sin embargo,
la operación se realiza.

Un caso particular de reciclaje se da cuando se realiza una operación entre un escalar y un


vector. Tal y como se ha indicado anteriormente, en R no existe el concepto de escalar,
siendo tratados estos como vectores de tamaño 1. En estos casos el único elemento de
dicho vector se repite cuantas veces sea necesario para ajustarse al tamaño del mayor
vector.

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

12. CLASES, MODOS Y TIPOS

Como parte de la programación orientada a objetos, R maneja funciones genéricas, que


derivan a funciones particulares, tomando en consideración la clase del argumento
principal de la función. Las clases más comunes de los objetos que se usan como
contenedores de datos son matriz, arreglo, dataframe y lista. Las clases más comunes de
los componentes de las matrices, los arreglos, los dataframes, las listas, así como de los
vectores atómicos, son entero, numérico, lógico, complejo y carácter.

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.

La clase factor es de especial relevancia, por ser la clase requerida de algunos


componentes en ciertos procedimientos estadísticos tales como análisis de varianza. La
clase factor se aplica a variables categóricas, para las que se define un conjunto de niveles
(levels). Cualquier vector puede llevarse a esta clase, mediante la función [Link].

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

A continuación se enumera algunos aspectos que es necesario tener en cuenta al momento


de nombrar los objetos, así como sus elementos constitutivos.

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.

5) Se distingue entre mayúsculas y minúsculas.

Dependiendo de la forma en que estén estructurados los datos (vectores, matrices,


arreglos, dataframes o listas) es posible –y en ocasiones hasta obligatorio– nombrar los
elementos individuales y/o los componentes de cada una de las dimensiones.

La principal estructura de base de datos en R es el dataframe, siendo esta la que se usa


como argumento principal en la mayoría de procedimientos estadísticos. Se trata de una
estructura rectangular con individuos, observaciones o ítems en filas y con variables (que
pueden ser de diferentes tipos) en columnas. En los dataframe, cada columna tiene
obligatoriamente un nombre. Cuando se genera un dataframe por importación el nombre
de la columna puede leerse de la información contenida en la primera fila, o puede
definirse automáticamente como V1, V2, …, VK, siendo K el número de columnas. Este
comportamiento queda definido por la función usada para la importación y sus
argumentos. Las filas (individuos u observaciones) también tienen nombres; por defecto,
son los enteros desde 1 hasta n, siendo n el número de observaciones. Aunque mucho
menos común, podría asignarse también un nombre a cada uno de los elementos del
dataframe.

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.

13.1 Asignación de nombres

Para asignación de nombres se combina la función namescon el operador de asignación.

Considérese el siguiente vector:

a=c(1, 2, 3)

Es posible asignarle nombre a cada uno de los elementos, de la siguiente forma:

names(a)=c("uno", "dos", "tres")

Mediante el mismo procedimiento podrían nombrarse los elementos de una matriz o de


un arreglo, así como los objetos de mayor jerarquía de una lista. Al realizar un
procedimiento análogo sobre un dataframe, se modifican los nombres de las columnas.

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.

Considérese el arreglo tridimensional, R, definido anteriormente:

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

vector=c('a', 'c', 'f', 'd', 'x', 'm', 'j', 'l', 'd',


'b', 'u', 'y', 'b', 'j', 'h', 'i', 'h', 'o', 'w', 'p',
Guillermo Correa Londoño – Introducción a R 39 de 87

'r', 's', 'n', 'q')


ndim1=c("unidad1", "unidad2", "unidad3", "unidad4")
ndim2=c("v1", "v2", "v3")
ndim3=c("tiempo1", "tiempo2")
[Link]=list(ndim1, ndim2, ndim3)
R=array(vector, dim=c(4, 3, 2),
dimnames=[Link])

, , 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. INDEXACIÓN, FILTRADO, ADICIÓN Y SUSTITUCIÓN DE ELEMENTOS

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 $.

El descriptor de acceso [] permite referenciar el elemento que ocupa una posición


específica dentro de una estructura. Así, datos[7] se refiere al elemento que ocupa la
séptima posición dentro del objeto datos.

Para los objetos unidimensionales (vectores y listas), la indexación es directa,


asignándosele a cada elemento el índice correspondiente a su posición.

a=c(3, 8, 21, 7, 14)


a[2]

[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:

[1] "Iván" "Rosa" "Diana"

La referencia a un elemento particular dentro de un objeto multidimensional (matrices,


arreglos o dataframes) puede realizarse de varias formas, la más intuitiva de las cuales
consiste en separar con comas los correspondientes índices de posición en cada una de las
dimensiones.

Tómese como referencia el arreglo R generado anteriormente, el cual se esquematizaba


de la siguiente manera:

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

Para referenciar el elemento de la unidad4, v1, tiempo2, se escribe:

R[4, 1, 2]

[1] "i"

La designación de todos los elementos de un componente dimensional dado se realiza


omitiendo la referencia al índice de las demás dimensiones, manteniedo, sin embargo, la(s)
correspondiente(s) coma(s) de separación. Considérese la siguiente matriz:

 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

Análogamente, la referencia a todos los elementos de la tercera columna se realiza con la


instrucción A[,3] (Columna 3 con todas las filas).
[1] 5 1

En el arreglo R, la referencia a todas las lecturas del tiempo1 se realiza con la instrucción
R[,,1] .

[,1] [,2] [,3]


[1,] "a" "x" "d"
[2,] "c" "m" "b"
[3,] "f" "j" "u"
[4,] "d" "l" "y"

Nótese que la salida de la anterior instrucción es un arreglo bidimensional, en el cual cada


una de sus filas y columnas se encabeza con base en la nomenclatura expuesta. En caso de
que se hubieran asignado nombres a los diferentes componentes dimensionales, se
mostrarían estos en lugar de la nomenclatura descrita.

v1 v2 v3
unidad1 "a" "x" "d"
unidad2 "c" "m" "b"
unidad3 "f" "j" "u"
unidad4 "d" "l" "y"

En el mismo arreglo R, la referencia a todas las lecturas de la variable3, en el tiempo2 se


realiza con la instrucción R[,3,2].
Guillermo Correa Londoño – Introducción a R 42 de 87

unidad1 unidad2 unidad3 unidad4


"r" "s" "n" "q"

Cuando los componentes dimensionales tienen nombres, estos pueden usarse


entrecomillados en lugar de los índices numéricos. Así, el resultado anterior podría
obtenerse igualmente mediante la instrucción: R[,"v3","tiempo2"].

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.

Considérese nuevamente, la matriz A definida anteriormente:

[,1] [,2] [,3]


[1,] 2 0 5
[2,] -1 9 1

Las siguientes instrucciones son equivalentes:

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).

En el arreglo R, las siguientes instrucciones son equivalentes:

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).

Cuando se usa un único índice en un dataframe, este hace referencia a la correspondiente


columna. Así, DF[2] es equivalente a DF[,2]. En ambos casos se selecciona la segunda
columna.

La manera usual de referenciar las columnas de un dataframe es mediante el descriptor


de acceso $. El formato general es [Link]$[Link].
Guillermo Correa Londoño – Introducción a R 43 de 87

Considérese el dataframe DF, que se ejemplificó en el apartado de estructuras de datos.


Para hacer referencia a la primera columna del mismo, puede escribirse DF$id, DF[ ,1],
DF[ ,"id"], DF[1] o DF[ "id"].

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.

names(L2)=c("nombre", "edad", "aprobado", "B", "L1")

Ahora puede invocarse el primer elemento de mayor jerarquía de dicha lista, mediante la
siguiente instrucción:

L2$nombre

[1] "Iván" "Rosa" "Diana"

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

names(L2$L1)=c("nombre1", "edad1", "aprobado1", "B1")

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

Mediante el descriptor de acceso [[]]es posible referenciar subelementos dentro de una


lista, sin que se requiera que los elementos contenedores tengan nombre. Supóngase que
dentro de la lista L2 se quiere referenciar el cuarto elementos de la lista L1, objeto que a
su vez es el quinto elemento de L2.

L2[[5]][[4]]

[,1] [,2] [,3]


[1,] 2 5 9
[2,] 0 -1 1

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

El descriptor de acceso $ no funciona con estructuras atómicas (vectores, matrices y


arreglos); únicamente con estructuras recursivas (dataframes y listas).

En ocasiones es posible referenciar una variable directamente por su nombre, sin


necesidad de anteponer el nombre de la estructura contenedora y el símbolo $.

1) Cuando se liga un objeto a la ruta de búsqueda de R, mediante la función attach.

attach(dca)
anava=aov(y~ttos)
detach(dca)

2) Cuando la referencia a la variable se hace dentro de una función que incluya el


argumento data, mediante el cual se indique el nombre del correspondiente
dataframe.

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))

La primera alternativa, al modificar la ruta de búsqueda, puede generar confusión y


errores de ejecución, máxime si se olvida desligar la base de datos después de haberla
usado. Aunque se desaconseja el uso de esta función, en caso de que el usuario decida
utilizarla bajo su responsabilidad, se recomienda un desligado posterior, mediante la
función detach.

El uso de la segunda alternativa, aunque es seguro, no siempre es viable. Únicamente


puede usarse con funciones que consideren el argumento data.

La tercera opción, además de ser segura, siempre es viable, pudiendo usarse


conjuntamente con cualquier función.
Guillermo Correa Londoño – Introducción a R 46 de 87

14.2 Filtrado

Con base en los descriptores de acceso presentados anteriormente, es posible aplicar


filtros a un conjunto de datos estructurados en un objeto, para seleccionar un subconjunto
de elementos que satisfagan ciertos requerimientos, bien sea de posición o de cualquier
otra índole. Los índices pueden estar constituidos por enteros positivos, en cuyo caso se
mantienen los correspondientes elementos o por enteros negativos, lo que equivale a
retirar los correspondientes elementos.

Considérese la matriz A:

[,1] [,2] [,3]


[1,] 2 0 5
[2,] -1 9 1

Para seleccionar las columnas 2 y 3, pude usarse el siguiente comando:

A[,2:3]

[,1] [,2]
[1,] 0 5
[2,] 9 1

O alternativamente:

A[,-1]
[,1] [,2]
[1,] 0 5
[2,] 9 1

En el comando trasanterior se usó el operador de secuencia “:”, aprovechando la vecindad de


las dos columnas seleccionadas. Si se deseara seleccionar las columnas 1 y 3, podría
utilizarse el siguiente comando.

A[,c(1, 3)]

[,1] [,2]
[1,] 2 5
[2,] -1 1

Equivalentemente, podría utilizarse un vector conformado por elementos lógicos.

A[,c(TRUE, FALSE, TRUE)]

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

Aunque los subconjuntos resultantes de los procesos de filtrado generalmente son de la


misma clase que el objeto de origen, esto puede no ser así cuando hay reducción de la
dimensionalidad. En caso de que se requiera, puede usarse el argumento drop=FALSE
para asegurar que el subconjunto resultante sea de la misma clase que el objeto de origen,
sin importar si hay o no reducción de la dimensionalidad. Considérese la extracción de la
segunda fila de la matriz A.

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"

Sin importar la reducción de la dimensionalidad, el objeto resultante sigue siendo una


matriz, de dimensiones 1x3.

14.3 Adición y Sustitución de Elementos

Para sustituir un elemento dentro de un objeto, basta con asignar otro valor a la
correspondiente posición.

Considérese la matriz A:

[,1] [,2] [,3]


[1,] 2 0 5
[2,] -1 9 1

Podría remplazarse el elemento de la segunda fila, tercera columna por 7, así:

A[2,3]=7
A

[,1] [,2] [,3]


[1,] 2 0 5
[2,] -1 9 7
Guillermo Correa Londoño – Introducción a R 48 de 87

Puede remplazarse la primera fila de la matriz A, así:

A[1,]=c(1,2,3)
A

[,1] [,2] [,3]


[1,] 1 2 3
[2,] -1 9 7

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

Mediante un proceso análogo al anterior, es posible agregar nuevas filas o columnas a un


dataframe. Las nuevas filas no necesariamente tienen que ser contiguas a las existentes;
las nuevas columnas sí tendrían que quedar a continuación de las existentes, no siendo
posible dejar columnas vacías.
Guillermo Correa Londoño – Introducción a R 49 de 87

15. VISUALIZACIÓN Y EDICIÓN DE OBJETOS Y DE DATOS

La función ls (o equivalentemente objects) lista todos los objetos presentes en el


ambiente de trabajo.

La función str presenta de manera compacta la estructura de cualquier objeto en R,


indicando el nombre (en caso de que este exista) de cada uno de sus componentes
atómicos, su clase, su tamaño y sus primeros valores.

La función [Link] combina las funciones ls y str, listando la estructura de todos los
objetos en el ambiente de trabajo.

Existen diversas formas de visualizar el contenido de un objeto en R; la más directa es


llamándolo a través de su nombre, lo que equivale a utilizar la función print. Para
desplegar, por ejemplo, el contenido del objeto datos, puede usarse cualquiera de las
siguientes instrucciones:

datos
print(datos)

Es posible combinar funciones en un solo comando para definir un objeto y generar su


visualización. Debe tenerse en cuenta, sin embargo, que en este caso, no es posible usar el
símbolo de igualdad (=) como operador de asignación.

print(datos<-c(7, 15, 23))

La función View permite visualizar el contenido de un objeto en una rejilla, al estilo de


una hoja de cálculo. Esta función no es aplicable a listas cuando los elementos de mayor
jerarquía tienen diferente número de filas.

Mediante la función [Link] es posible visualizar y/o modificar objetos en un editor


tipo hoja de cálculo. Esta función puede utilizarse con vectores o matrices, cuyo modo sea
numérico o carácter. También puede usarse con dataframes, cuyas columnas sean todas
numéricas o carácter, y con listas, cuyos elementos sean de cualquiera de tales modos.

La interfaz de RStudio facilita la visualización de los objetos presentes en el ambiente de


trabajo, mediante la pestaña Global Environment que por defecto está ubicada en el panel
superior derecho. Puede accederse directamente a dicha pestaña presionando Crtl+8. Los
objetos se organizan en dos grupos: Data, donde están las matrices y los dataframes, y
Values, donde aparecen los demás objetos. Hacer clic sobre algún objeto de la clase matriz
o dataframe equivale a invocar el comando View.

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

head y tail, respectivamente.


Guillermo Correa Londoño – Introducción a R 51 de 87

16. GENERACIÓN DE SALIDAS EDITABLES

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.

Considérese los siguientes comandos:

data(iris) # Carga la base de datos 'iris', que forma parte del


# paquete 'datasets', que viene preinstalado en R

Puede solicitarse un resumen de la base datos:

summary(iris)

[Link] [Link] [Link] [Link] Species


Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500

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)

[Link] [Link] [Link] [Link] Species


1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa

tail(iris)

[Link] [Link] [Link] [Link] Species


145 6.7 3.3 5.7 2.5 virginica
146 6.7 3.0 5.2 2.3 virginica
147 6.3 2.5 5.0 1.9 virginica
148 6.5 3.0 5.2 2.0 virginica
149 6.2 3.4 5.4 2.3 virginica
150 5.9 3.0 5.1 1.8 virginica
Guillermo Correa Londoño – Introducción a R 52 de 87

Considérese, ahora, la obtención de un análisis de varianza para la variable [Link],


en función del factor Species.

anava=aov([Link]~Species, data=iris)
summary(anava)

Df Sum Sq Mean Sq F value Pr(>F)


Species 2 80.41 40.21 960 <2e-16 ***
Residuals 147 6.16 0.04
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Finalmente, supóngase que se desea llevar toda la información obtenida a un archivo de


Word, sin que se desconfigure el formato. Para el efecto, pueden usarse las funciones sink
y [Link].

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.

El script para el presente ejemplo tendría la siguiente forma.

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

El anterior script genera un archivo llamado “[Link]”, en el directorio de trabajo, que


contiene tanto las instrucciones como los correspondientes resultados, desde
data(iris), hasta sink.

Para ejercer un mayor control sobre lo que se escribe en el archivo, seleccionando


exactamente lo que se quiera registrar, sin incluir las correspondientes instrucciones e
incorporando saltos de línea entre los diferentes resultados, se usa la función
[Link], así:

[Link](summary(iris), cat("\n","\n"), head(iris),


cat("\n","\n"), tail(iris), cat("\n","\n"), summary(anava),
file="[Link]")

El anterior comando genera un archivo de texto llamado “[Link]”, en el directorio de


trabajo, que contiene las cuatro salidas solicitadas. La instrucción cat("\n","\n")
introduce un par de saltos de línea entre salida y salida.

Es posible añadir información al archivo creado anteriormente, incluyendo el argumento


append=T en cualquiera de las dos funciones ilustradas. Supóngase que se desea
adicionar el resultado de una prueba de Shapiro-Wilk realizada sobre los residuales del
modelo. Para ello se ejecutan las siguientes instrucciones, asegurándose de que el archivo
“[Link]” esté cerrado.

sink("[Link]", append=T)
[Link](resid(anava))
sink

O, usando la función [Link]:

[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.

Es importante resaltar que el hecho de que las funciones anteriores (sink y


[Link]) estén dirigidas exclusivamente a la captura de texto no representa
un problema, dado que la exportación de contenido gráfico desde RStudio es una labor
trivial (revísese la funcionalidad del botón “export” en el panel “plots”).
Guillermo Correa Londoño – Introducción a R 54 de 87

17. ESCRITURA DE DATOS EN UNA HOJA DE CÁLCULO

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]

Para la exportación de un dataframe a un archivo Excel se usa la siguiente sintaxis:

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

18. TRANSFORMACIONES Y CREACIÓN DE NUEVAS VARIABLES

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.

Si no se tiene interés en conservar el objeto original, podría asignarse la expresión a un


objeto con el mismo nombre del objeto transformado, así:

a=25
a=sqrt(a)

En este caso, al final habrá un único objeto, llamado a, cuyo valor es 5.

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.

Considérense los siguientes comandos:

[Link]=[Link](a=seq(1, 21, 2), b=rnorm(11))


c=log([Link]$a)+([Link]$b)^2

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.

Cuando se realizan transformaciones concatenadas, las funciones within y transform


pueden actuar de manera diferente. La función within actualiza el objeto temporal a
media que aparecen las evaluaciones, lo que permite ir generando nuevas variables a
partir de variables creadas anteriormente, dentro de la misma función.

[Link]=within([Link], {c<-a+b; d<-c^2})

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

evalúa de manera simultánea todas las expresiones incluidas en la función.


Guillermo Correa Londoño – Introducción a R 58 de 87

19. CICLOS Y CONDICIONALES

Cuando se requiere ejecutar un mismo conjunto de instrucciones varias veces, resulta


práctico establecer un ciclo, el cual podría repetirse un número predeterminado, un
número indefinido o incluso un número infinito de ocasiones. Para tal efecto, pueden
utilizarse los controladores de flujo for, while y repeat, respectivamente. En otras
situaciones se requiere que el conjunto de instrucciones se ejecute una sola vez si se
satisface alguna condición, para lo cual se usa el controlador de flujo if o las variantes
if...else e ifelse.

Se utiliza for para controlar el flujo de un ciclo que ha de ejecutarse un número


predeterminado de veces. Por su parte, while permite ejecutar el ciclo hasta que deje de
satisfacerse una condición. Cuando se usa repeat, el ciclo se ejecutará infinitamente,
siendo necesario utilizar algún recurso extraordinario para forzar la terminación del ciclo.

El controlador de flujo if permite establecer una condición bajo cuyo cumplimiento se


ejecutaría un conjunto de instrucciones. La variante if...else permite definir un
conjunto alternativo de instrucciones que habría de ejecutarse en caso de no satisfacerse
la condición. Se usa ifelse para evaluar la satisfacción de una condición en cada uno de
los elementos de un vector, devolviendo un resultado en caso de satisfacerse y algún otro,
en caso contrario.

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).

19.1 Número Predeterminado de Ciclos

La siguiente es la sintaxis básica del controlador de flujo for.

for (i in valores) {instrucciones}

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.

for (dígito in 0:5) {cat(dígito, "\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.

for (ind in seq(1, 1.5, 0.1)) {print(log(ind))}

[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.

for (x in c(4, 3.14, -2, 5.72)) {print(exp(x))}

[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.

flores=c('Amaranthus', 'Clavel', 'Hortensia', 'Gerbera')


for (f in flores) {print(nchar(f))}

[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.

19.2 Número Indeterminado de Ciclos

A continuación se presenta sintaxis básica del controlador de flujo while.

while (condición) {instrucciones}

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

Es importante destacar la diferencia existente entre el operador de igualdad (==) y el


operador de asignación (=). El operador de igualdad se utiliza para verificar la satisfacción
de una condición (que la expresión a la izquierda del operador tenga igual valor que la de
su derecha). El operador de asignación (equivalente al operador <-) se utiliza para asignar
Guillermo Correa Londoño – Introducción a R 61 de 87

el valor o la expresión de la derecha del operador al objeto localizado a su izquierda y no


puede usarse como operador lógico.

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

19.3 Número Infinito de Ciclos

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).

A continuación se presenta la sintaxis básica del operador de flujo repeat.

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}}

Un conjunto equivalente de instrucciones con el controlador while tiene la siguiente


forma:

i=0
while(i!=7) {
i=i+1
print(i)}

19.4 Condicional

El operador de flujo if permite establecer una condición, bajo cuyo cumplimiento se


ejecutarían las instrucciones, con base en el siguiente esquema.

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")}

Mediante el condicional if puede verificarse la existencia de un paquete que se requiera


en un script, programando su instalación, con sus correspondientes dependencias, en caso
de que no esté presente. Considérese un paquete cualquiera, llamado genéricamente
package.

if(!require(package)) {
[Link]("package", dependencies=T)
library(package)}

El operador de flujo if puede complementarse con el operador else, para especificar un


conjunto de instrucciones alternativas que se ejecutarían en caso de no
satisfacerse la condición, así:

if (condición) {instrucciones} else {instrucciones alternativas}

Al usar la anterior estructura, es necesario ubicar el operador else en la misma línea en


la que aparece la llave de cierre (}) de instrucciones o, en caso de no haberse usado
Guillermo Correa Londoño – Introducción a R 63 de 87

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)}

Es posible encadenar una serie de estructuras if...else para ofrecer cuantas


instrucciones alternativas se requieran.

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)

Una estructura equivalente a if...else, aplicable a los elementos de un vector o algún


otro contenedor de elementos (v. gr. matriz, arreglo, dataframe. Cf. 10. Objetos y
estructuras de datos) es ifelse. En este caso se evalúa la satisfacción de una condición
sobre cada uno de los elementos del contenedor y, para cada uno de ellos, se genera una
respuesta en caso de satisfacerse la condición y alguna otra ni no se satisface. El resultado
es un objeto del mismo tamaño y atributos que el objeto sobre cuyos elementos se evalúa
la condición.

ifelse (condición_elem.obj, [Link], [Link])

nota=c(3.2, 4.3, 5.0, 1.5, 2.9)


Guillermo Correa Londoño – Introducción a R 64 de 87

ifelse (nota>=3.0, "Aprobado ", "Reprobado")

[1] "Aprobado" "Aprobado" "Aprobado" "Reprobado" "Reprobado"

19.5 Salto y Fin Forzado

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.

Cuando se satisface la condición definida en un condicional if interno y se usa next como


instrucciones, se omite la realización del resto de instrucciones del correspondiente
ciclo, pasando al ciclo siguiente. Al usar break en condiciones análogas, se interrumpe no
solo el bucle presente, sino que se dan por terminados todos los ciclos.

for (dígito in 0:5) {


if(dígito==3) {next}
print(dígito)}

[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

20. FUNCIONES DE PROBABILIDAD

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.

Distribución Probabilidad Cuantiles Números


acumulada aleatorios
Binomial pbinom qbinom rbinom
Poisson ppois qpois rpois
Normal pnorm qnorm rnorm
Ji cuadrado pchisq qchisq rchisq
T pt qt rt
F pf qf rf

Todas las funciones de probabilidad acumulativa tienen como primer argumento


(obligatorio) el valor de la variable aleatoria para el cual se desea obtener el área
acumulada, esto es, el valor del cuantil. Seguidamente, aparecen los parámetros de la
distribución. Para el caso de la normal, se consideran por defecto los valores mean=0 y
sd=1 (normal estándar). Las demás distribuciones mencionadas no tienen valores por
defecto para sus parámetros, siendo necesario especificarlos: size (número de ensayos
Bernoulli) y prob (probabilidad de éxito) para la binomial; lambda para la Poisson, df
(grados de libertad) para la t y la Ji cuadrado; df1 y df2 (grados de libertad del
numerador y del denominador, respectivamente) para la F. Asimismo, podría modificarse
a FALSE el valor del argumento [Link], que está marcado por defecto como TRUE,
si se desea obtener probabilidad a la derecha (función de sobrevivencia).

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

pf(2.3, df1=5, df2=15, [Link]=F)

[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

Equivalentemente, podría haberse escrito:

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

21. FUNCIONES PERSONALIZADAS

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.

El formato general para crear una función personalizada es:

[Link]ón=function(arg1, arg2, …, argk) {acciones}

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.

[Link]ón (arg1, arg2, …, argk)

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

A fin de que los resultados presentados sean reproducibles, considérese, ahora, la


aplicación de la misma función sobre 100 valores aleatorios (seudoaleatorios) basados en
una distribución normal estándar, usando el valor 47 como semilla.

[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

22. FUNCIONES POR GRUPOS

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:

apply(arreglo, dimensión(es), función)

El primer argumento de la función corresponde al nombre del arreglo; el segundo indica el


número de la dimensión: 1 para las filas de una matriz, 2 para las columnas de una matriz, 3
para la tercera dimensión de un arreglo y así sucesivamente; el tercer argumento es el nombre
de la función, sin paréntesis; de ser necesario especificar argumentos para dicha función, estos
irán a continuación, separados por comas.

Considérese la matriz A, conformada por 2 filas y 3 columnas.

[,1] [,2] [,3]


[1,] 2 0 5
[2,] -1 9 1

Para obtener los promedios por fila de la matriz A, se usa la siguiente instrucción:

apply(A, 1, mean)

[1] 2.333333 3.000000

El resultado es un vector con dos elementos: el promedio de la primera fila y el promedio de la


segunda fila.

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

Definamos ahora, un arreglo tetradimensional, con 5 elementos en la primera dimensión, 4


elementos en la segunda, 2 elementos en la tercera y 3 elementos en la cuarta.

R=array(1:120, c(5, 4, 2, 3))

Para obtener los promedios de la cuarta dimensión, se usa la siguiente instrucción:

apply(R, 4, mean)

[1] 20.5 60.5 100.5

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).

apply(R, c(1, 3), mean, trim=0.1)

[,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.

(medias.f1=tapply(df$y, df$f1, mean))

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.

(medias.f2=tapply(df$y, df$f2, mean))

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.

(medias.f1f2=with(df, tapply(y, list(f1, f2), mean)))

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

23.1 Diagramas de dispersión

La función plot permite construir un diagrama de dispersión bidimensional. La manera


más básica de usar esta función es con dos argumentos: el primero para las coordenadas
de la abscisa (x) y el segundo para las de la ordenada (y).

x=c(3, 5, 9, 12, 15, 23, 30)


y=c(7, 9, 14, 12, 15, 16, 18)
plot(x, y)
18
16
14
y
12
10
8

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.

Cualquiera de los siguientes pares de instrucciones genera el mismo diagrama.

coor.m=cbind(x, y) # Matriz de coordenadas


plot(coor.m)

coor.d=[Link](x, y) # Dataframe de coordenadas


plot(coor.d)

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

Existen numerosos argumentos opcionales que le permiten al usuario personalizar las


características de la gráfica. A continuación, se presentan algunos de ellos.

El argumento pch (plotting character) permite especificar mediante un entero o un


carácter individual (que deberá escribirse entrecomillado) el símbolo que ha de usarse
para la identificación de los puntos en el diagrama. El valor por defecto de dicho
argumento es 1, que corresponde a un círculo sin relleno. Los códigos numéricos de 0 a 25
corresponden a los símbolos que se usan con mayor frecuencia.

plot(x, y, pch=16)

Mediante el argumento cex (character expansion) es posible controlar el tamaño del


símbolo usado para graficación. El valor por defecto es cex=1; si se define un valor
diferente, este actúa como factor multiplicativo del tamaño original; así, un valor de 3 da
lugar a símbolos cuyo tamaño es tres veces mayor que el tamaño original, mientras que
0.5 genera símbolos de la mitad del tamaño original.

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.

plot(x, y, pch=22, col="black", bg=rgb(255, 102, 0, max=255))

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

y ylab (y label), para la abscisa y la ordenada correspondientemente. Para agregarle un


título a la gráfica, se usa el argumento main (main label). El contenido de tales argumentos
se escribe entre comillas. Para incluir expresiones matemáticas en cualquiera de las
etiquetas se usa el comando expression, el cual puede tomar como argumento
cualquier expresión matemática. En tal caso no se usan las comillas. Así, por ejemplo, para
imprimir la distribución probabilística normal, se escribe:

expression(frac(1, sqrt(2*pi*sigma))~e**((x-mu)^2/2*sigma^2))

En la anterior expresión, la virgulilla representa un espacio; pueden usarse varias


virgulillas para generar varios espacios. Si se quisiera que la expresión contuviera la
virgulilla, esta se escribiría encerrada en símbolos de porcentaje.

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, xlab="Dimensión 1", ylab="Dimensión 2", main="ACP",


[Link]=1.5, [Link]=2)

Algunas técnicas dan lugar a la representación de puntos en un espacio bidimensional, en


el cual la distancia entre los puntos se interpreta como disimilitud entre los mismos. En
tales casos es muy importante construir los diagramas con un valor unitario para la razón
entre la escala de la ordenada y la de la abscisa, de manera que las distancias en cualquier
dirección sean equivalentes. Para tal efecto se usa el argumento asp=1.

plot(x, y, asp=1)

El escalamiento de los ejes se realiza de manera automática, adaptándose a los datos


graficados, lo que generalmente resulta adecuado. No obstante, en ocasiones el usuario
puede tener interés en realizar un escalamiento particular de los ejes. Esto puede lograrse
mediante los argumentos xlim (x limits) y ylim (y limits), que permiten establecer los
límites de la abscisa y la ordenada, respectivamente. Cada uno de tales argumentos se
define mediante un vector de dos valores, con los correspondientes límites inferior y
superior.

plot(x, y, xlim=c(0, 35), ylim=c(2, 20))

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.

plot(x, y, [Link]=1.8, font=5, las=1)

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.

plot(x, y, pch=22, cex=2, col=1, bg='orangered1', main='Diagrama


de dispersión', [Link]=2.5, xlab='dim 1', ylab='dim 2',
[Link]=1.5, xlim=c(0, 35), ylim=c(2, 24), axes=F)
axis(1, at=seq(0, 35, 5), [Link]=1.4)
axis(2, at=seq(2, 24, 2), [Link]=1.4,las=1)
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

eliminando la impresión del punto y dejando únicamente la etiqueta. Para eliminar la


impresión del punto, se incluye el argumento type='n', en la función plot. La función
text tiene como primer(os) argumento(s) las coordenadas, tal y como se describió para
la función plot; mediante el argumento labels, que debe estar conformado por un
vector de caracteres, se especifica el texto que se desea imprimir.

[Link]=c('a12', 'd31', 'f23', 'a34', 'g18', 'b52', 'g49')


plot(x, y, type='n')
text(x, y, labels=[Link], cex=0.7, col='blue')

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).

plot(x, y, pch=17, cex=0.8)


text(x, y, labels=[Link], cex=0.8, col='blue', pos=3)
Guillermo Correa Londoño – Introducción a R 78 de 87

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

biomasa=c(2, 5, 15, 35, 89, 115)


plot(1:6, biomasa, type="o" , xlab="semana", col=2)

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.

Considérese la siguiente información.

Mes Serie1 Serie2 Serie3


Enero 147 8 20
Febrero 146 14 50
Marzo 144 26 114
Abril 141 46 134
Mayo 138 76 150
Junio 132 100 158
Julio 115 114 162
Agosto 89 126 165
Septiembre 35 134 167
Octubre 15 138 169
Noviembre 5 140 170
Diciembre 2 141 170
Guillermo Correa Londoño – Introducción a R 80 de 87

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.

matplot(datos[,2:4], type="o", xlab=" ", ylab="Biomasa",


pch=c(2, 8, 15), col=c(2,3,4), axes=F, lty=1)
axis(1, at=seq(1, 12), labels=datos[,1], [Link]=0.9, las=2)
axis(2, at=seq(0,190,20), [Link]=0.9,las=1)
box()
legend(6,70, names(datos[,2:4]), col=c(2, 3, 4),
cex=0.9, pch=c(2, 8, 15), lty=1)
Guillermo Correa Londoño – Introducción a R 81 de 87

23.3 Diagramas de barras

La función barplot , con el argumento height permite construir un diagrama de


barras básico, siendo height un vector con las alturas de las barras.

h=c(5, 9, 4, 12, 7, 5, 2)
barplot(h)

Para etiquetar cada una de las barras, se usa el argumento [Link].

et=c('tto5', 'tto2', 'tto1', 'tto7', 'tto6', 'tto3', 'tto4')


barplot(height=h, [Link]=et)

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).

barplot(height=h, [Link]=et, xlab="Grupos",


ylab="Frecuencia", [Link]=1.5, [Link]=1.2,
[Link]=1.2, las=1, [Link]=1, col="salmon1",
density=c(0, 5, 30, 300), border=c(1, 'blue', 'red'),
ylim=c(0,15))
box()
Guillermo Correa Londoño – Introducción a R 83 de 87

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]))

setosa versicolor virginica


[Link] 5.006 5.936 6.588
[Link] 3.428 2.770 2.974
[Link] 1.462 4.260 5.552
[Link] 0.246 1.326 2.026

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

Al construir un diagrama de barras con un objeto como el presente, usando el argumento


legend=T, se genera una leyenda con base en los nombres de las filas, la cual ubica por defecto
en la esquina superior derecha.

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.

Para personalizar la leyenda, se omite el argumento legend=T y se genera aparte, con la


función legend, tal y como se ilustra a continuación.

barplot(t(datos), beside=T, col=c("blueviolet", "darkred",


"cadetblue1"), ylim=c(0,11), xlab="medida",
ylab="centímetros", [Link]=1.5,[Link]=1.3, las=1)
legend(1,10, c("I. setosa", "I. versicolor", "I. virginica"),
fill=c("blueviolet", "darkred", "cadetblue1"), cex=0.9)
box()
Guillermo Correa Londoño – Introducción a R 85 de 87

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.

También podría gustarte