1 R base

Si esta es la primera vez que lees este apunte, te instamos a comenzar por los capítulos 2 y 3, y luego continuar con este capítulo. El texto está redactado para ser leído de esta manera. Después de leer los capítulos 2 y 3, este capítulo tendrá mucho más sentido.

En este capítulo cubre algunos aspectos básicos de R base, es decir sin el uso de paquetes adicionales.

1.1 Operaciones aritméticas

El lenguaje de programación R se puede utilizar para realizar aritmética básica entre números reales y enteros, como por ejemplo la suma, multiplicación, resta y división. Estos los puedes utilizar en el programa introduciendo los siguientes códigos en la consola tal como se ve en el siguiente ejemplo:

3+5
## [1] 8
3-4
## [1] -1
2*3
## [1] 6
4/3
## [1] 1.333333

Existen siete tipos básicos de operaciones aritméticas, las cuales se resumen a continuación.

Operador Nombre Ejemplo
+ Suma 17 + 3 = 20
- Resta 15.3 - 5.1 = 10.2
* Multiplicación 1.2 * 10 = 12
/ División 27 / 2 = 13.5
%/% División Entera 27 %/% 2 = 13
^ Potencia 2^4 = 16
%% Módulo 27 %% 2 = 1  

El orden en el que se aplican estas está definido por el uso de paréntesis y, en caso de no haberlos, el orden habitual de operaciones aritméticas.

(2 + 3) * (4 - 2)
## [1] 10
2 + 3 * 4 - 2
## [1] 12

1.2 Funciones

En R también se pueden calcular expresiones matemáticas que se necesitan a menudo, estas son:

Raices, las cuales se calculan mediante el comando sqrt(), este también se puede utilizar mediante elevar el número a una fracción como se ve en el siguiente ejemplo:

sqrt(4)
## [1] 2

Exponenciales, en R se puede obtener los valores de la función exponencial \(f(x) = e^x\). Para ello se útiliza la función exp(), como se ve en el siguiente ejemplo:

exp(1)
## [1] 2.718282

Logaritmos, en R se pueden obtener los valores de la función \(f(x) = \ln(x)\), donde \(\ln(x) = \log_{e}x\) y \(e=\)exp(1)\(\approx 2.71828\) el número de euler. Para ello se utiliza la función log(), como se ve en el siguiente ejemplo:

log(23)
## [1] 3.135494

Si deseamos calcular el logaritmo en otra base se debe hacer de la siguiente manera:

log(4,2)
## [1] 2

Donde la segunda entrada separada por una coma indica la base del logaritmo.

Otros También se pueden calcular los valores de funciones trigonométricas, y otros.

Un listado de funciones que ofrece R se puede encontrar aqúi (AGREGAR LINK).

En caso de que necesites utilizar mucho una función en tu programa es mejor dejarla programada para su posterior uso. Si por ejemplo deseas utilzar la función \(f(x) = x^5 + 2\) repetidas veces, entonces la puedes dejar programada al inicio de tu código mediante la seguiente secuencia:

elevar_a_5_y_sumar_2 = function(x){x^2 + 2}

Entonces luego en cualquier momento la puedes aplicar de la siguiente manera:

elevar_a_5_y_sumar_2(2)
## [1] 6

Es importante mencionar que el nombre que se le da a la función no debe ser un nombre de las funciones que vienen por defecto en el R.

1.3 Operadores lógicos

Una parte muy importante dentro de cualquier lenguaje de programación es el hecho de poder preguntar cuando una relación sera verdadera o falsa. Para hacerlo se utilizan los siguientes comandos:

1.3.1 Operadores de comparación

<,>, estos te permiten preguntar si un numero es mayor (o menor) a otro, como se ve en el siguiente ejemplo:

5<3
## [1] FALSE

Nota que lo que entrega el programa es FALSE, esto nos dice que la relación presentada es falsa; es decir el 5 no es menor que el 3. Nota también que:

4>4
## [1] FALSE

Es decir que el 4 no es mayor al 4.

<=,>=, estos nos permiten preguntar si dos valores son menores o iguales (mayores o iguales), como se ve en el siguiente ejemplo:

4>=4
## [1] TRUE

Nota que con este comando se admite la igualdad entre los valores.

==, con este comando se nos permite preguntar si dos variables son exactamente iguales, tal como se ve en el siguiente ejemplo:

1==1
## [1] TRUE

!=, con este comando se nos permite preguntar si dos variables son distintas, tal como se ve en el siguiente ejemplo:

1!=0
## [1] TRUE

En general, los operadores de comparación pueden usarse para comparar cualquier par objetos, siempre que sean de un mismo tipo. Por ejemplo, si uno compara frases o palabras (entre comillas), hace una comparación lexicográfica (de diccionario). Por ejemplo, bajo este criterio se tiene que “abc” es menor que “xyz”. Las comparaciones entre condiciones lógicas se definen tal que FALSE < TRUE.

A continuación se muestran todos los operadores de orden con ejemplos.

Operador Nombre Ejemplo Ejemplo
< Menor (17 < 20) == TRUE ("abc" < "ccc") == TRUE
> Mayor (17 > 20) == FALSE (TRUE > FALSE) == TRUE
<= Menor o igual (17 <= 20) == TRUE ("Zebro" <= "Zebra") == FALSE
>= Mayor o igual (20 >= 20) == TRUE ("1t4" >= "1t4") == TRUE
== Igual (5 == 4) == FALSE ("Marcos" == "marcos") == FALSE
!= Distinto (no Igual) (5 != 4) == TRUE (FALSE != TRUE) == TRUE .

1.3.2 Conectores lógicos y negación

En lógica se suele utilizar mucho los conectores lógicos o e y (OR o AND), generalmente para realizar mas de una pregunta al mismo tiempo. En R también existen estos conectores lógicos donde | representa el conector lógico o e & representa el conector lógico y, tal como se muestra en el siguiente ejemplo:

1<5 & 5!=0
## [1] TRUE
2>4 | 2==3
## [1] FALSE

También es necesario preguntar por lo opuesto a una pregunta, lo cual se puede hacer a través del operador de negación lógica, !. Por ejemplo:

!(1 < 5)
## [1] FALSE
!(5 != 0)
## [1] FALSE

A continuación presentamos un listado resumen de estos conectores y la negación:

Operador Nombre
! Negación
| OR lógico
& AND lógico
xor OR exclusivo lógico  

La siguiente tabla muestra todas los posibles formas en que pueden usarse estos conectores.

a b a | b a & b !a xor(a,b)
TRUE TRUE TRUE TRUE FALSE FALSE
TRUE FALSE TRUE FALSE FALSE TRUE
FALSE TRUE TRUE FALSE TRUE TRUE
FALSE FALSE FALSE FALSE TRUE FALSE 

1.4 Variables

En R, almacenamos valores en variables. Podemos asignarle valores a una variable a través del operador <-, o en su defecto, =. El nombre de una variable puede estar compuesto por letras y números, pero debe empezar con una letra. Es importante tener en cuenta que R distingue las mayúsculas de las minúsculas.

Las variables pueden usarse para almancenar valores de distinto tipo.

En el siguiente ejemplo asignaremos valores numéricos a las variables x e y:

x <- 2.14   # Asignamos a x el valor 2.14

w = 3.01    # Podemos también usar = en vez de <-

y <- 1.2    # Al asignar un valor a una variable, R no imprime nada en pantalla
y           # Al escribir el nombre de una variable, y presionar enter, R genera como salida el valor de ésta
## [1] 1.2

Copiemos el valor de la variable x en la variable z:

z <- x  
z
## [1] 2.14

Podemos modificar el valor de una variable:

x <- x+1    # Aquí estamos redefiniendo el valor de x a partir del valor anterior
x
## [1] 3.14

Observemos que el haber modificado x no afecta el valor de z:

z           # z porque era solo una copia de x
## [1] 2.14

En el siguiente ejemplo podemos ver que hay que tener cuidado con los nombres de las variables.

Marcos <- 3.2
Marcos
## [1] 3.2
Pedro <- 1.0
Pedro
## [1] 1
MArcos <- 3.4   # Las variables Marcos y MArcos son distintas!
Marcos
## [1] 3.2

En el siguiente ejemplo asignamos valores lógicos a variables

sera_cierto <- (3 < 2)
sera_cierto
## [1] FALSE

También podemos usar variables para almacenar palabras o frases, si estas las ponemos entre comillas.

mi_nombre <- "Juan Perez"
mi_nombre
## [1] "Juan Perez"

1.5 Tipos de variables y objetos

En R los valores que puede tomar una variable pueden ser de varios tipos. Los tipos básicos son:

  • numeric (numérico): Estos corresponden a números enteros (Integer) o racionales (Double)

  • logical (lógico): Estos pueden tomar valor TRUE ó FALSE (Verdadero o Falso)

  • character (carácter): Estos son caracteres separados por comillas

  • complex (complejo): Estos son números complejos (no usaremos en este libro)

Podemos determinar el tipo de un objeto o de una variable con el método typeof.

Ejemplos:

typeof(3.5)             
## [1] "double"

Por defecto R asume que todos los números son de tipo double.

typeof(3)
## [1] "double"

Si uno quiere que R trate un número como entero, debe ser explícito. Eso se puede hacer agregando el sufijo L a un número entero.

typeof(3L)              
## [1] "integer"

Es importante notar que los valores de variables lógicas (TRUE y FALSE) deben escribirse en mayúsculas.

typeof(TRUE)            
## [1] "logical"
#typeof(True)         # R piensa que True es el nombre de una variable que no encuentra.

Los valores de variables tipo character deben expresarse entre comillas.

typeof("Hola mundo!")
## [1] "character"

Si uno mete un número o un valor lógico entre comillas, R piensa que es un character.

typeof("3.5")
## [1] "character"
typeof("FALSE")
## [1] "character"

Es buena idea usar nombres de variables intuitivos para recordar lo que almacenan.

edad_de_pedro <- 8L
typeof(edad_de_pedro)
## [1] "integer"
LargoDeLaMesa <- 3.2
typeof(LargoDeLaMesa)
## [1] "double"

Es posible operar un objeto de tipo Integer con otro de tipo Double, obteniendo como resultado un objeto de tipo Double.

x <- 2 + 3L
typeof(x)
## [1] "double"

1.6 Vectores, factores y matrices

1.6.1 Vectores

Cuando pensamos en datos, estos usualmente vienen de a más de a uno. Por ejemplo, las edades de todos los alumnos de un curso o los ingresos semanales de una empresa durante todo un año. Un vector es una manera natural de representar una serie de datos.

Un vector en R es una secuencia ordenada de objetos del mismo tipo. Un vector tiene 2 características principales:

  1. El tipo de sus elementos, el cual podemos obtener con la función typeof().
  2. Su largo, que obtenemos con la función length().

La forma en la que podemos construir vectores es a través de la función c(), como vemos en el siguiente ejemplo:

v <- c(2, 3, 8)
v
## [1] 2 3 8

Veamos las características del vector v:

typeof(v)
## [1] "double"
length(v)
## [1] 3

¿Qué pasa si construimos un vector con objetos de distintos tipos? Veamos:

u <- c(TRUE, 2L, 3.5)
u
## [1] 1.0 2.0 3.5
typeof(u)
## [1] "double"
w <- c(TRUE, "Hola", 1, 2.5)
w
## [1] "TRUE" "Hola" "1"    "2.5"
typeof(w)
## [1] "character"

En este caso R convierte a todos los elementos a numérico (si juntamos elementos de tipo lógico con numéricos), o los convierte a todos a caracter (si combinamos elementos de cualquier tipo con uno de tipo caracter).

Acceder a los elementos de un vector

Podemos acceder a los elementos de un vector usando corchetes ([]), junto con uno o más índices. Estos índices son números, que representan la posición del valor que se desea observar en el vector. Los índices están enumerados desde uno.

Ejemplo: Observemos el segundo valor contenido en un vector.

v <- c(6, 3, 8)
v[2]
## [1] 3

Los índices negativos se usan para excluir elementos de un vector al acceder a sus datos.

u <- c(TRUE, 2L, 3.5)
u[-1]   # Un índice negativo retorna todos lo elementos, menos aquel señalado por el índice
## [1] 2.0 3.5

Uno puede usar slices para acceder a intervalos contínuos de elementos de un vector. Un slice indica y el primer y último elemento del intervalo a acceder, separando éstos por un símbolo :.

Ejemplo: Accediendo a los elementos con índice entre 2 y 4 de un vector.

w <- c(TRUE, "Hola", 1, 2.5)
w[2:4]  # Esto entrega todos los elementos desde el índice 2 al 4
## [1] "Hola" "1"    "2.5"
w[c(1,2,4)] # Podemos usar un vector de índices
## [1] "TRUE" "Hola" "2.5"

Nombres

Un vector en R, además de tener tipo y largo, tiene atributos o meta-data, entre los cuales se encuentran los nombres de sus elementos1. Los nombres son obtenidos a través de la función names():

names(v)
## NULL

Notemos que al intentar obtener los nombres del vector, R retorna NULL. Esto quiere decir que los nombres de este vector no han sido inicializados. Podemos inicializar los nombres de los elementos de un vector simplemente asignando un vector con los nombres al atributo names del vector:

names(v) <- c("Primero", "Segundo", "Tercero")
names(v)
## [1] "Primero" "Segundo" "Tercero"

Podemos también usar los nombres de los elementos de un vector para acceder a ellos:

v["Segundo"]
## Segundo 
##       3
v[c("Primero", "Tercero")]
## Primero Tercero 
##       6       8

Operaciones entre vectores

Podemos realizar operaciones aritméticas con vectores.

Si sumamos o restamos dos vectores la operación se hace componente a componente.

c(1, 2, 3) + c(3, 2, 1)
## [1] 4 4 4

Si sumamos un número a un vector, esta operación se aplica a todos los componentes.

2 + c(3, 2, 1)
## [1] 5 4 3

Más generalmente, si sumamos dos vectores de largo distinto, se completa el vector más corto con copias de sí mismo hasta igualar los largos. Esta operación no es recomendable, por lo que R tira una advertencia.

c(1, 2, 3) + c(0, 0, 0, 0, 0)
## Warning in c(1, 2, 3) + c(0, 0, 0, 0, 0): longer object length is not a multiple
## of shorter object length
## [1] 1 2 3 1 2

Las reglas de multiplicación de vectores son iguales a las reglas de adición de vectores. Cuando uno multiplica dos vectores del mismo largo, R genera un tercer vector cuyos elementos se obtienen multiplicando componente por componente. Hay que tener cuidado con esto, pues esto es distinto a lo que sucede en algunos otros lenguajes.

c(1, 2, 3) * c(2, 1, 4)
## [1]  2  2 12

Si multiplicamos un vector por un número, la multiplicación se hace a todos los elementos.

3*c(3, 2, 1, 2)
## [1] 9 6 3 6

También odemos realizar operaciones lógicas con vectores. Las reglas de operación son las mismas que con números. Si son del mismo largo, las operaciones se aplican componente a componente.

c(TRUE, FALSE, TRUE) & c(TRUE, TRUE,FALSE)
## [1]  TRUE FALSE FALSE

Si se aplican entre vectores de largo distinto, completa el más corto.

c(TRUE, FALSE, TRUE) & TRUE
## [1]  TRUE FALSE  TRUE

En general, el comportamiento de vectores es predecible cuando uno conoce estas reglas. Observemos que si uno compara un vector con otro, se aplica la comparación componente a componente.

c(7, 2, 6) < c(1,10,8)
## [1] FALSE  TRUE  TRUE

Esto también aplica a strings.

c("gato", "wow", "aaa") < c("zorro","avion","aaa")
## [1]  TRUE FALSE FALSE

Y si aplicamos un comparador entre vectores de largo distinto, también se procede a completar.

c(7, 2, 6) > 5
## [1]  TRUE FALSE  TRUE

Aplicación de funciones a vectores

A un vector se le pueden aplicar diferentes funciones, dentro de las mas destacables estan length() que entrega la cantidad de elementos que hay en el vector (o en otras palabras el largo del vector), y typeof() para saber los tipos de elementos contenidos en el vector. Estas funciones se pueden ver en el siguiente ejemplo:

vector = c('casa','gato','perro')
length(vector)
## [1] 3
typeof(vector)
## [1] "character"

Además si un vector es númerico, entonces puedes encontrar el valor máximo y minimo almacenado dentro del vector mediante las funciones max() y min() respectivamente:

v
## Primero Segundo Tercero 
##       6       3       8
min(v)
## [1] 3
max(v)
## [1] 8

Hay muchas otras funciones que R ofrece para aplicar a funciones. Algunos ejemplos comunes son:

Operador Nombre Expresión Valor
min Menor min(c(7,3,2,5,3)) 2
max Mayor max(c(7,3,2,5,3)) 2
mean Promedio mean(c(7,3,2,5,3)) 4
length Largo del vector length(c(7,3,2,5,3)) 5
median Mediana median(c(7,3,2,5,3)) 3
sd Desviación estándar sd(c(7,3,2,5,3)) 2
first Primer elemento first(c(7,3,2,5,3)) 7
last Último elemento last(c(7,3,2,5,3)) 3
nth n-ésimo elemento nth(c(7,3,2,5,3),4) 5
any Si algún elemento es verdadero any(c(TRUE, FALSE, TRUE) ) TRUE
all Si todos los elementos son verdaderos all(c(TRUE, FALSE, TRUE)) FALSE
sum Suma de elementos sum(c(7,3,2,5,3)) 20 .

Explicar opción na.rm = TRUE de estos métodos.

Para saber si un elemento está en un vector, puede aplicar el método %in:

v <- c("Pablo", "Rodolfo", "Claudia", "Danielle", "Marcos")
"Danielle" %in% v
## [1] TRUE
"Rolando" %in% v
## [1] FALSE

¿Dónde explicar if_else?

library(tidyverse)
x <- c(7,3,2,5,3)
if_else(x > 4, "yes", "no")
## [1] "yes" "no"  "no"  "yes" "no"
if_else(x > 4, x-4, x)
## [1] 3 3 2 1 3

1.6.2 Factores

Factor es un vector de datos no numéricos, formado por datos procedentes de categorías, por ejemplo, datos obtenidos al anotar si un individuo es hombre o mujer. En el siguiente ejemplo se muestra como convertir un vector de datos en factores:

v = c('hombre','mujer','mujer','hombre')
v = as.factor(v)
v
## [1] hombre mujer  mujer  hombre
## Levels: hombre mujer

Los datos del tipo factor tomaran mas relevancia en futuros capítulos

1.6.3 Matrices

Una matriz es un arreglo bidimensional, dada por filas y columnas, que contiene valores de un mismo tipo. En el siguiente ejemplo vamos a crear una matriz de 2 columnas y 5 filas, mediante la función matrix() de la siguiente forma:

A = matrix(data = c(2, 1,3, 4,3, 5,2, 10,12, 34 ),nrow =5,ncol = 2)
A
##      [,1] [,2]
## [1,]    2    5
## [2,]    1    2
## [3,]    3   10
## [4,]    4   12
## [5,]    3   34

Nota que las entradas de la matriz de van llenando de forma vertical, y nrow corresponde al numero de filas y ncol corresponde al numero de columnas.

Algunas funciones interesantes que se le pueden aplicar a las matrices son:

Las funciones rbind y cbind permiten pegar un vector por abajo o por derecha a una matriz. Por ejemplo a la matriz A del ejemplo anterior le pegaremos el vector c(1.2,3.4) por debajo, para ello utilizaremos la función rbind() ya que pegaremos por debajo.

v = c(1.2,3.4)
nueva_matriz_A = rbind(A,v)
nueva_matriz_A
##   [,1] [,2]
##    2.0  5.0
##    1.0  2.0
##    3.0 10.0
##    4.0 12.0
##    3.0 34.0
## v  1.2  3.4

Luego a esta nueva matriz le pegaremos el vector c(2,2,2,2,2,2) por derecha. Para ello usaremos la función cbind().

v = c(2,2,2,2,2,2)
nueva_matriz_A2 = cbind(nueva_matriz_A,v)
nueva_matriz_A2
##            v
##   2.0  5.0 2
##   1.0  2.0 2
##   3.0 10.0 2
##   4.0 12.0 2
##   3.0 34.0 2
## v 1.2  3.4 2

Otra función importante es la función dimensión dim() que te permite obtener la cantidad de filas y columnas de una matriz

dim(A)
## [1] 5 2
A
##      [,1] [,2]
## [1,]    2    5
## [2,]    1    2
## [3,]    3   10
## [4,]    4   12
## [5,]    3   34

También se le pueden colocar nombres a las filas y columnas de una matriz tal como se muestra en el siguiente ejemplo:

A = matrix(c(1,2,3,4),2,2, dimnames=list(c('indiv 1','indiv 2'),c('edad','ingresos')))
A
##         edad ingresos
## indiv 1    1        3
## indiv 2    2        4

Basta agregar el argumento dimnames a la función matrix(). También se le pueden cambiar los nombres a una matriz ya creada, como se ve en el siguiente ejemplo:

nombres = list(c('persona 1', 'persona 2'),c('cantidad de pan','cantidad de trigo'))
dimnames(A)<- nombres
A
##           cantidad de pan cantidad de trigo
## persona 1               1                 3
## persona 2               2                 4

1.7 Manipulación básica de strings

str_detect("arbol", "ar")
## [1] TRUE
str_detect(c("arbol", "perro", "naruto", "bazaar", "gato"), "ar")
## [1]  TRUE FALSE  TRUE  TRUE FALSE
paste("Hola", "Mundo")
## [1] "Hola Mundo"
paste("Hola", "Mundo", sep=":")
## [1] "Hola:Mundo"
paste(c("Hola", "Adios", "Bienvenido"), c("Marcos","Pedro","Diego"))
## [1] "Hola Marcos"      "Adios Pedro"      "Bienvenido Diego"
str_replace("Adios mundo cruel!", "Adios", "Hola")
## [1] "Hola mundo cruel!"
str_replace(c("Adios mundo cruel!", "Chao", "adios", "Adiosnda"), "Adios", "Hola")
## [1] "Hola mundo cruel!" "Chao"              "adios"            
## [4] "Holanda"
toString(27.32)
## [1] "27.32"
toString(TRUE)
## [1] "TRUE"
toString(c(1,2,3))
## [1] "1, 2, 3"
startsWith("Hola","Ho")
## [1] TRUE
endsWith("Hola","os")
## [1] FALSE

1.8 Ejercicios

1.8.1 Comandos básicos

Indique cuál será la salida de los siguientes comandos:

  1. typeof(2L)
  2. typeof(3 == 5)
  3. typeof("3.5")
  4. (3 + 2) * 5
  5. 12 * 3 - 2
  6. (12 < 5) & (12 >= 5)
  7. (12 < 5) | (12 >= 5)
  8. xor(12 < 5, 12 >= 5)
  9. ("amor" > "odio") == TRUE
  10. c(0, 1, FALSE, TRUE)
  11. c(0, 1, c(1 , 0))
  12. typeof(c(1, 2.5, "3.5"))
  13. length(c("A", "B", "D"))
  14. v <- c(2, 5, 6, 7, 3, 2)
    v[1]
  15. v <- c(2, 5, 6, 7, 3, 2)
    v[-3]
  16. v <- c(2, 5, 6, 7, 3, 2)
    v[2:5]
  17. min(c(1, 2, 4))
  18. max(min(c(1, 2, 4)), min(c(2, 3, 5)))
  19. c(1, 0 , 1, 1) + c(-2, 1, 0, -2)
  20. mean(c(0, 1))
  21. sum(c(0.5, 0.3, 0.2) * c(0.5, 0.3, 0.2))

  1. Existen otros atributos posibles, que no cubriremos aquí↩︎