Elementos básicos del lenguaje R
Objetivo del manual
Familiarizarse con los bloques básicos usados en la programación en R
Conocer las fuentes principales de documentación estandarizada en R
1 ¿Qué es R?
- Un Lenguaje de Dominio Específico (DSL) libre para la estadística y el análisis de datos
- Una colección de más de 21145 paquetes (al 12 de agosto de 2024)
- Una comunidad grande y activa en la industria y el mundo académico
- Una forma de hablar “directamente” con su ordenador
Históricamente:
- Basado en el lenguaje de programación S
- Alrededor de 20 años de antigüedad (el linaje data de 1975 - hace casi 40 años)
2 Rstudio
Entorno de desarrollo integrado (IDE) para R. Incluye:
- Una consola
- Editor para resaltar la sintaxis que soporta la ejecución directa del código
- Herramientas para el trazado, el historial, la depuración y la gestión del espacio de trabajo
2.1
3 Elementos del lenguaje R
En R todo lo que existe es un objeto y los objetos se pueden clasificar a grosso modo en objetos que contienen datos y objetos que realizan tareas, mejor conocidos como funciones:
Para sentirse cómodo programando en R en necesario saber en todo momento con que tipo de objetos estamos trabajando. Las funciones class()
y str()
nos permiten evaluar la estrucutra de los objetos. Las estaremos usando repetidamente en este tutorial.
3.1 Objetos que contienen datos
La estructura de datos básica en R es el vector. Con este se contruyen todas las otras clases de objetos. Para entender las clases es útil pensar en el número de dimensiones (1, 2 o mas) y tipos de datos que pueden contener: homogéneos (un único tipo de elemento) o homogéneos (o múltiples tipos de elementos).
Homogéneo | Heterogéneo | |
---|---|---|
1d | Vector atómico | Lista |
2d | Matriz | Cuadro de datos (data frame) |
nd | arreglo (Array) |
3.1.1 Objetos de 1 dimensión
Hay dos tipos básicos de vectores: vectores atómicos y listas.
Tienen tres propiedades comunes:
- Tipo,
typeof()
(clase/modo ~) - Longitud,
length()
(número de elementos) - Attributes,
attributes()
(metadatos)
Se diferencian en los tipos de sus elementos: todos los elementos de un vector atómico deben ser del mismo tipo, mientras que los elementos de una lista pueden tener diferentes tipos.
3.1.1.1 Vectores atomicos
Tipos de vectores atómicos:
- Lógico (booleano)
- Entero
- Numérico (doble)
- Caracteres
- Factores
Los vectores se construyen con la función c()
, Pueden ser numérico:
Código
<- 1
x <- c(1)
x1
all.equal(x, x1)
[1] TRUE
Código
class(x)
[1] "numeric"
De caracteres:
Código
<- "algo"
y
class(y)
[1] "character"
Lógico:
Código
<- TRUE
z
class(z)
[1] "logical"
O factor:
Código
<- factor(1)
q
class(q)
[1] "factor"
Por tanto, los números o cadenas individuales son en realidad vectores de longitud uno:
Código
class(1)
[1] "numeric"
Código
class("a")
[1] "character"
Los vectores sólo pueden contener elementos del mismo tipo. Los tipos diferentes de elementos serán forzados al tipo más flexible:
Código
<- c(1, 2, "a")
x
x
[1] "1" "2" "a"
Código
class(x)
[1] "character"
Los valores que faltan se especifican con NA, que es un vector lógico de longitud 1. NA siempre será interpretado al tipo correcto si se utiliza dentro de c()
:
Código
<- c(10, 11, NA)
v
class(v)
[1] "numeric"
Código
<- c("a", "b", NA)
v
class(v)
[1] "character"
3.1.1.2 Factores
Los vectores con factores son muy simulares a los de caracteres. Sin embargo, un factor sólo puede contener valores predefinidos, conocidos como niveles. Los atributos se utilizan para definir los niveles del factor.
Los factores se construyen sobre vectores enteros utilizando dos atributos:
- clase “factor”: hace que se comporten de forma diferente a los vectores de caracteres normales
- niveles: define el conjunto de valores permitidos
Código
<- factor(c("a", "b", "b", "a"))
x x
[1] a b b a
Levels: a b
Código
levels(x)
[1] "a" "b"
Código
str(x)
Factor w/ 2 levels "a","b": 1 2 2 1
Los factores parecen vectores de caracteres, pero en realidad son números enteros:
Código
<- factor(c("a", "b", "b", "a"))
x
c(x)
[1] a b b a
Levels: a b
3.1.1.3 Listas
Puede contener objetos de diferentes clases y tamaños. Las listas se construyen con list():
Código
<- list("a", 1, FALSE)
l
l
[[1]]
[1] "a"
[[2]]
[1] 1
[[3]]
[1] FALSE
Código
class(l)
[1] "list"
Código
str(l)
List of 3
$ : chr "a"
$ : num 1
$ : logi FALSE
En realidad pueden ser vistas como cajones donde se pueden poner cualquier otro tipo de objeto:
Código
<- list(c("a", "b"), c(1, 2, 3, 4), c(FALSE, TRUE, FALSE))
l
l
[[1]]
[1] "a" "b"
[[2]]
[1] 1 2 3 4
[[3]]
[1] FALSE TRUE FALSE
Código
str(l)
List of 3
$ : chr [1:2] "a" "b"
$ : num [1:4] 1 2 3 4
$ : logi [1:3] FALSE TRUE FALSE
3.1.2 Objetos de 2 dimensiones
3.1.3 Matrices
Todas los elementos son del mismo tipo:
Código
<- matrix(c(1, 2, 3, 11, 12, 13), nrow = 2)
m
dim(m)
[1] 2 3
Código
m
[,1] [,2] [,3]
[1,] 1 3 12
[2,] 2 11 13
Código
class(m)
[1] "matrix" "array"
Código
<- matrix(c(1, 2, 3, 11, 12, "13"), nrow = 2)
m m
[,1] [,2] [,3]
[1,] "1" "3" "12"
[2,] "2" "11" "13"
3.1.4 Cuadros de datos (data frames)
Caso especial de las listas. Puede contener elementos de diferentes tipos:
Código
<-
m data.frame(
ID = c("a", "b", "c", "d", "e"),
size = c(1, 2, 3, 4, 5),
observed = c(FALSE, TRUE, FALSE, FALSE, FALSE)
)
dim(m)
[1] 5 3
Código
m
ID | size | observed |
---|---|---|
a | 1 | FALSE |
b | 2 | TRUE |
c | 3 | FALSE |
d | 4 | FALSE |
e | 5 | FALSE |
Código
class(m)
[1] "data.frame"
Código
is.data.frame(m)
[1] TRUE
Código
is.list(m)
[1] TRUE
Código
str(m)
'data.frame': 5 obs. of 3 variables:
$ ID : chr "a" "b" "c" "d" ...
$ size : num 1 2 3 4 5
$ observed: logi FALSE TRUE FALSE FALSE FALSE
Pero los vectores deben tener la misma longitud:
Código
<-
m data.frame(
ID = c("a", "b", "c", "d", "e"),
size = c(1, 2, 3, 4, 5, 6),
observed = c(FALSE, TRUE, FALSE, FALSE, FALSE)
)
Error in data.frame(ID = c("a", "b", "c", "d", "e"), size = c(1, 2, 3, : arguments imply differing number of rows: 5, 6
3.1.5 Ejercicio 1
Cree un vector numérico con 8 elementos que contenga números positivos y negativos
Cree un vector de caracteres con los nombres de las provincias de Costa Rica
Añada al vector de punto anterior un NA
Cree una matriz numérica con 3 columnas y 3 filas
Cree una matriz de caracteres con 4 columnas y 3 filas
¿Qué tipo de objeto es ‘iris’ y cuales son sus dimensiones? (pista:
iris
es un objeto disponible por omisión en su ambiente)Cree un cuadro de datos (data frame) con una columna numérica, una columna de caracteres y una columna con factores
3.2 Funciones: objetos que hacen tareas
Todas las funciones se crean con la función function()
y siguen la misma estructura:
* Modified from Grolemund 2014
3.2.1 Funciones integradas
3.2.1.1 Funciones básicas
R viene con muchas funciones que puedes usar para hacer tareas sofisticadas:
Código
# built in functions
<- builtins(internal = FALSE)
bi
length(bi)
[1] 1388
Algunas funciones vienen de forma predeterminada con R básico. Nuevas funciones pueden ser cargadas como parte de paquetes adicionales o incluso creadas por el usuario.
3.2.1.2 Operadores
Los operadores son funciones:
Código
1 + 1
[1] 2
Código
'+'(1, 1)
[1] 2
Código
2 * 3
[1] 6
Código
'*'(2, 3)
[1] 6
3.2.1.2.1 Operadores mas utilizados
Operadores aritméticos:
Operador | Descrición |
---|---|
+ | suma |
- | resta |
* | multiplicación |
/ | división |
^ or ** | exponente |
Código
1 - 2
[1] -1
Código
1 + 2
[1] 3
Código
2 ^ 2
[1] 4
Código
2 ** 2
[1] 4
Código
2:3 %in% 2:4
[1] TRUE TRUE
Operadores lógicos:
Operador | Descrición |
---|---|
< | menor que |
<= | menor o igual que |
> | mayor que |
>= | mayor o igual que |
== | exactamente igual que |
!= | diferente que |
!x | No es x |
x | y | x O y |
x & y | x Y y |
x %in% y | correspondencia |
Código
1 < 2
[1] TRUE
Código
1 > 2
[1] FALSE
Código
1 <= 2
[1] TRUE
Código
1 == 2
[1] FALSE
Código
1 != 2
[1] TRUE
Código
1 > 2
[1] FALSE
Código
5 %in% 1:6
[1] TRUE
Código
5 %in% 1:4
[1] FALSE
3.2.2 Vectorización
La mayoría de las funciones están vectorizadas:
Código
1:6 * 1:6
* Modified from Grolemund & Wickham 2017
[1] 1 4 9 16 25 36
Código
1:6 - 1:6
[1] 0 0 0 0 0 0
R recicla vectores de longitud desigual:
Código
1:6 * 1:5
* Modified from Grolemund & Wickham 2017
3.2.3 Funciones de paquetes adicionales
Estas son funciones que son incluidas en paquetes adicionales que se pueden instalar y cargar en R. Para ser utilizadas el paquete debe ser instalado y cargado.Por ejemplo para usar la función corTest
del paquete “psych” primero debemos instalar. Los paquetes son instalados del servidor de CRAN (Comprehensive R Archive Network) con la función install.packages()
:
Código
install.packages("psych")
.. y cargar el paquete:
Código
library(psych)
Una vez instalado y cargado ‘psych’, podemos llamar a la función corTest
:
Código
corTest(iris$Sepal.Length, iris$Sepal.Width)
Call:corTest(x = iris$Sepal.Length, y = iris$Sepal.Width)
Correlation matrix
[1] -0.12
Sample Size
[1] 150
These are the unadjusted probability values.
The probability values adjusted for multiple tests are in the p.adj object.
[1] 0.15
To see confidence intervals of the correlations, print with the short=FALSE option
El uso de paquetes externos es la caracteristica mas util de R ya que permite hacer uso de un número casi infinito de funciones especializadas en diferentes tareas así como de campos muy diversos de la ciencia y la industria.
Podemos explorar los paquetes disponibles para R en la página de CRAN (hacer click en el enlace “packages”).
3.2.4 Ejercicio 2
Busque un paquete que le interese en CRAN
Instale el paquete y carguelo
Corra el codigo de ejemplo de una de sus funciones
4 Manipulación de objetos
4.1 Extraer subconjuntos usando indexación (indexing)
Los elementos dentro de los objetos pueden ser llamados por medio de la indexación. Para sub-conjuntar un vector simplemente llame a la posición del objeto usando corchetes:
Código
<- c(1, 3, 4, 10, 15, 20, 50, 1, 6)
x
1] x[
[1] 1
Código
2] x[
[1] 3
Código
2:3] x[
[1] 3 4
Código
c(1,3)] x[
[1] 1 4
Los elementos se pueden eliminar de la misma manera:
Código
-1] x[
[1] 3 4 10 15 20 50 1 6
Código
-c(1,3)] x[
[1] 3 10 15 20 50 1 6
Las matrices y los marcos de datos requieren 2 índices [fila, columna]
:
Código
<- matrix(c(1, 2, 3, 11, 12, 13), nrow = 2)
m
1, ] m[
[1] 1 3 12
Código
1] m[,
[1] 1 2
Código
1, 1] m[
[1] 1
Código
-1, ] m[
[1] 2 11 13
Código
-1] m[,
[,1] [,2]
[1,] 3 12
[2,] 11 13
Código
-1, -1] m[
[1] 11 13
Código
<- data.frame(
df provincia = c("San José", "Guanacaste", "Guanacaste"),
canton = c("Montes de Oca", "Nicoya", "Liberia"),
distrito = c("San Rafael", "Nosara", "Nacascolo")
)
df
provincia | canton | distrito |
---|---|---|
San José | Montes de Oca | San Rafael |
Guanacaste | Nicoya | Nosara |
Guanacaste | Liberia | Nacascolo |
Código
1, ] df[
provincia | canton | distrito |
---|---|---|
San José | Montes de Oca | San Rafael |
Código
1] df[,
[1] "San José" "Guanacaste" "Guanacaste"
Código
1, 1] df[
[1] "San José"
Código
-1, ] df[
provincia | canton | distrito | |
---|---|---|---|
2 | Guanacaste | Nicoya | Nosara |
3 | Guanacaste | Liberia | Nacascolo |
Código
-1] df[,
canton | distrito |
---|---|
Montes de Oca | San Rafael |
Nicoya | Nosara |
Liberia | Nacascolo |
Código
-1, -1] df[
canton | distrito | |
---|---|---|
2 | Nicoya | Nosara |
3 | Liberia | Nacascolo |
Código
"provincia"] df[,
[1] "San José" "Guanacaste" "Guanacaste"
Código
c("provincia", "canton")] df[,
provincia | canton |
---|---|
San José | Montes de Oca |
Guanacaste | Nicoya |
Guanacaste | Liberia |
Las listas requieren 1 índice entre dobles corchetes [[índice]]
:
Código
<- list(c("a", "b"),
l c(1, 2, 3),
c(FALSE, TRUE, FALSE, FALSE))
1]] l[[
[1] "a" "b"
Código
3]] l[[
[1] FALSE TRUE FALSE FALSE
Los elementos dentro de las listas también pueden ser subconjuntos en la misma cadena de código:
Código
1]][1:2] l[[
[1] "a" "b"
Código
3]][2] l[[
[1] TRUE
4.2 Explorar objectos
Las siguientes funciones de R básico (predeterminadas) nos pueden ayudar a explorar la estructura de los objetos:
Código
str(df)
'data.frame': 3 obs. of 3 variables:
$ provincia: chr "San José" "Guanacaste" "Guanacaste"
$ canton : chr "Montes de Oca" "Nicoya" "Liberia"
$ distrito : chr "San Rafael" "Nosara" "Nacascolo"
Código
names(df)
[1] "provincia" "canton" "distrito"
Código
dim(df)
[1] 3 3
Código
nrow(df)
[1] 3
Código
ncol(df)
[1] 3
Código
head(df)
provincia | canton | distrito |
---|---|---|
San José | Montes de Oca | San Rafael |
Guanacaste | Nicoya | Nosara |
Guanacaste | Liberia | Nacascolo |
Código
tail(df)
provincia | canton | distrito |
---|---|---|
San José | Montes de Oca | San Rafael |
Guanacaste | Nicoya | Nosara |
Guanacaste | Liberia | Nacascolo |
Código
table(df$provincia)
Guanacaste San José
2 1
Código
class(df)
[1] "data.frame"
Código
View(df)
4.3 Ejercicio 3
Utilice los datos de ejemplo
iris
para crear un subconjunto de datos con sólo las observaciones de la especiesetosa
Ahora cree un subconjunto de datos que contenga las observaciones tanto de “setosa” como de “versicolor”
También con
iris
cree un subconjunto de datos con las observaciones para las queiris$Sepal.length
es mayor que 6¿Cuántas observaciones tienen una longitud de sépalo superior a 6?
4.4
5 El estilo importa
Based on google’s R Style Guide
5.1 Nombres de archivos
Los nombres de los archivos deben terminar en .R y, por supuesto, ser auto-explicatorios:
- Bien: graficar_probabilidad_posterior.R
- Mal: graf.R
5.2 Nombres de objetos
Variables y funciones:
- Minúsculas
- Utilice un guión bajo
- En general, nombres para las variables y verbos para las funciones
- Procure que los nombres sean concisos y significativos (no siempre es fácil)
- Avoid using names of existing functions of variables
Código
- Bien: dia_uno: dia_1, peso_promedio(),
- Mal: diauno, dia1, primer.dia_delmes
5.3 Syntaxis
5.3.1 Espacios
- Utilice espacios alrededor de los operadores y para los argumentos dentro de una función
- Ponga siempre un espacio después de una coma, y nunca antes (como en el inglés normal)
- Coloque un espacio antes del paréntesis izquierdo, excepto en una llamada a una función
Código
- Bien:
<- rnorm(n = 10, sd = 10, mean = 1)
a <- sum(x[1, ])
total
- Mal:
<-rnorm(n=10,sd=10,mean=1)
a<- sum(x[,1]) total
5.3.1.1 Corchetes
- La llave de apertura nunca debe ir en su propia línea
- La llave de cierre debe ir siempre en su propia línea
- Puede omitir las llaves cuando un bloque consiste en una sola declaración
Código
- Bien:
if (is.null(ylim)) {
<- c(0, 0.06)
ylim
}
if (is.null(ylim))
<- c(0, 0.06)
ylim
- Mal:
if (is.null(ylim)) ylim <- c(0, 0.06)
if (is.null(ylim)) {ylim <- c(0, 0.06)}
if (is.null(ylim)) {
<- c(0, 0.06)
ylim }
5.3.1.2 Crear objetos
- Use <-, no =
Código
- GOOD:
<- 5
x
- BAD:
= 5 x
5.3.1.3 Sugerencias para añadir comentarios
- Comente su código
- Las líneas enteras comentadas deben comenzar con # y un espacio
- Los comentarios cortos pueden colocarse después del código precedido por dos espacios, #, y luego un espacio
Código
# Create histogram of frequency of campaigns by pct budget spent.
hist(df$pct.spent,
breaks = "scott", # method for choosing number of buckets
main = "Histograma: individuos por unidad de tiempo",
xlab = "Número de individuos",
ylab = "Frecuencia")
5.3.1.4 Disposición general y ordenación (estilo de google)
- Comentario de la declaración de derechos de autor (?)
- Comentario del autor
- Comentario de la descripción del archivo, incluyendo el propósito del programa, las entradas y las salidas
- declaraciones source() y library()
- Definiciones de funciones
- Sentencias ejecutadas, si procede (por ejemplo, print, plot)
6 Documentación de R
La mayoría de los recursos de R están muy bien documentados. Así que la primera fuente de ayuda a la que debe acudir cuando escriba código R es la propia documentación de R. Todos los paquetes están documentados de la misma manera estándar. Familiarizarse con el formato puede simplificar mucho las cosas.
6.1 Package documentation
Reference manuals
Los manuales de referencia son colecciones de la documentación de todas las funciones de un paquete (sólo 1 por paquete):
6.2 Documentación de las funciones
Todas las funciones (por defecto o de paquetes cargados) deben tener una documentación que siga un formato estándar:
Código
?mean
help("mean")
Esta documentación también puede mostrarse en Rstudio pulsando F1
cuando el cursor está en el nombre de la función
Si no recuerda el nombre de la función pruebe con apropos()
:
Código
apropos("mean")
[1] ".colMeans" ".rowMeans" "circadian.mean" "circular.mean"
[5] "colMeans" "geometric.mean" "harmonic.mean" "kmeans"
[9] "mean" "mean.Date" "mean.default" "mean.difftime"
[13] "mean.POSIXct" "mean.POSIXlt" "rowMeans" "weighted.mean"
[17] "winsor.mean" "winsor.means"
6.3 Viñetas (vignettes)
Las viñetas son documentos ilustrativos o casos de estudio que detallan el uso de un paquete (opcional, pueden ser varios por paquete).
Las viñetas se pueden llamar directamente desde R:
Código
<- browseVignettes() vgn
Código
vignette()
También deberían aparecer en la página del paquete en CRAN.
6.4 Demonstraciones
Los paquetes también pueden incluir demostraciones de código extendidas (“demos”). Para listar las demos de un paquete ejecute demo("nombre del paquete")
:
Código
demo(package="stats")
# call demo directly
demo("nlm")
6.5 Ejercicio 4
¿Qué hace la función
cut()
?¿Para qué se utiliza el argumento
breaks
encut()
?Ejecuta las 4 primeras líneas de código de los ejemplos proporcionados en la documentación de
cut()
.¿Cuántas viñetas tiene el paquete warbleR?
6.6 Referencias
- Advanced R, H Wickham
- Google’s R Style Guide
- Hands-On Programming with R (Grolemund, 2014)
Información de la sesión
R version 4.3.2 (2023-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 22.04.2 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
time zone: America/Costa_Rica
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] psych_2.3.12
loaded via a namespace (and not attached):
[1] vctrs_0.6.5 nlme_3.1-155 svglite_2.1.3 cli_3.6.3
[5] knitr_1.48 rlang_1.1.4 xfun_0.47 stringi_1.8.4
[9] highr_0.11 jsonlite_1.8.9 glue_1.8.0 colorspace_2.1-1
[13] htmltools_0.5.8.1 scales_1.3.0 rmarkdown_2.28 grid_4.3.2
[17] evaluate_1.0.0 munsell_0.5.1 kableExtra_1.4.0 fastmap_1.2.0
[21] yaml_2.3.10 lifecycle_1.0.4 stringr_1.5.1 compiler_4.3.2
[25] htmlwidgets_1.6.4 rstudioapi_0.16.0 lattice_0.20-45 systemfonts_1.1.0
[29] digest_0.6.37 viridisLite_0.4.2 R6_2.5.1 parallel_4.3.2
[33] mnormt_2.1.1 magrittr_2.0.3 tools_4.3.2 xml2_1.3.6