Conceptos básicos

R es un conjunto de programas para cálculo numérico, creación de gráficos, manipulación de datos, análisis estadísticos, aprendizaje automático, entre muchas otras más. Iniciaremos el curso indagando en los conceptos más fundamentales (como lenguaje de programación) del mismo para enfocarnos en temas de probabilidad y análisis estadístico.

Artimética

Comenzaremos viendo que R puede realizar de manera directa operaciones como si fuera una calculadora:

# Esto es un comentario, solo sirve para hacer anotaciones en nuestras celdas de codigo.
# ------
# SUMA
41 + 8
## [1] 49
# MULTIPLICACION
4 * 7
## [1] 28
# DIVISION
14 / 7
## [1] 2
# POTENCIA
2 ** 3
## [1] 8

Resaltamos que R ejecuta el código de arriba hacía abajo. Además, una alternativa para ** a la hora de la exponenciación es el símbolo ^

# POTENCIA (ALTERNATIVA)
2 ^ 3
## [1] 8

Para el operador de residuo utilizamos %%. Por ejemplo, el residuo de efectuar la división \(\frac{5}{2}\) es uno, por lo cual

5 %% 2
## [1] 1

Hasta ahora hemos trabajado con números, los cuales en R se conocen como constantes. Existen varios tipos de constantes, dos de ellos son:

  • numeric: básicamente hace alusión a los números decimales o flotantes. De manera automática R detecta a los números enteros, por ejemplo el 1 o el 2, como del tipo numeric.
  • integer: este tipo de dato corresponde a los números enteros, los cuales debemos declarar colocando una L después del número entero.

Podemos checar el tipo de dato de una constante utilizando la función typeof() como sigue

# Veamos el tipo de dato correspondiente a:
typeof(5)
## [1] "double"
typeof(3.1416)
## [1] "double"
# y para el caso de un numero explicitamente entero
typeof(3L)
## [1] "integer"

Luego, si queremos guardar información para utilizarla después en nuestro código, podemos utilizar el concepto de variable.

Variables

Podemos utilizar variables para almacenar información. Por ejemplo, en una celda de código anterior obtivimos el residuo de dividir 5 entre 2, pero puede ser que querramos almacenar dicho valor para utilizarla después. Para asignar un valor a una variable utilizamos el operador <-, o equivalentemente el operador =. Éstos significan exactamente lo mismo: asignación.

# Asignamos a la variable x el valor resultante de 5 %% 2
x <- 5 %% 2

Ahora podemos utilizar la variable x en celdas de código posteriores:

# Al residuo de dividir 5 entre 2, le sumamos un 10
x + 10
## [1] 11

Apesar de que a x le sumamos un 10, el valor de x sigue siendo el mismo

x
## [1] 1

Si queremos almacenar un resultado, deberemos asignarlo a una variable

# Definimos una nueva variable con la notacion alternativa de =
y = x + 10
# Veamos el valor de la variable y
y
## [1] 11

En ese caso, asignamos el resultado de x+10 a la variable y. No obstante, podemos redefinir variables, esto es, podemos actualizar o cambiar el valor de x, de ahí su nombre de variables. Por ejemplo, por el momento sabemos que x vale 1, pero puede ser de nuestro interés que ahora valga 11, lo cual hacemos simplemente escribiendo

# Cambiamos el valor almacenada de la x
x <- 11
# Veamos el valor actual de la x
x
## [1] 11

Podemos operar aritméticamente con las variables

# Potencia
y ^ x
## [1] 285311670611

Veamos ahora el tipo character (o cadenas de texto). Para definir una variable de este tipo requeriremos utilizar comillas dobles o simples. Por ejemplo

# Detinimos una variable de tipo character
msj <- "Esto es una cadena de texto"
msj
## [1] "Esto es una cadena de texto"
# tipo de dato de la variable anterio
typeof(msj)
## [1] "character"

Tendremos que R le da una mayor jerarquía a variables de tipo character que a los del tipo numérico.

Podemos unir dos cadenas de texto con la función paste()

paste("Hola", "Mundo")
## [1] "Hola Mundo"

no solo eso, con esa misma función podemos unir cadenas de texto con otras variables, por ejemplo

paste("Valor de la variable x:", x)
## [1] "Valor de la variable x: 11"

Veremos otros dos tipos de datos: los del tipo factor y los del tipo booleanos. Los cuales abordaremos más adelante.

Vectores

Los vectores representan conjuntos de datos ordenados, por ejemplo \((1,5)\) es un vector, o también \((0,1,5,4.2)\) es un vector, donde vemos que están ordenados pues, para \((1,5)\), tenemos que el número 1 está en la primera posición (o entrada) del vector y el 5 en la segunda posición, y dicho orden importa, esto es, \((1,5)\) es distinto de \((5,1)\). Definimos vectores en R utilizando la función c(). Por ejemplo

# Definimos dos vectores
vector1 <- c(1, 5)
vector2 <- c(0, 1, 5, 4.2)
vector3 <- c(2, -8)

# Veamos los vectores
vector1
## [1] 1 5
vector2
## [1] 0.0 1.0 5.0 4.2
vector3
## [1]  2 -8

Podemos operar aritméticamente con los vectores, donde las operaciones se harán entrada a entrada. Por ejemplo:

# Sumamos dos vectores
vector1 + vector3
## [1]  3 -3

donde la suma se realizó entrada a entrada. Asimismo

# Multiplicamos dos vectores
vector1 * vector3
## [1]   2 -40

Etcétera. Podemos obtener el número de elementos que tiene un vector utilizando la función length()

# Numero de elementos de cada vector
length(vector1)
## [1] 2
length(vector2)
## [1] 4
length(vector3)
## [1] 2

Ya vimos cómo sumar dos vectores, pero también podemos sumar todas las entradas de un solo vector utilizando la función sum(). Por ejemplo:

# Definimos un vector nuevo (digamos que representa las ganancias de algo)
ganancias <- c(100, 1500, 20)

# Suma de las ganancias
sum(ganancias)
## [1] 1620

O también podemos obtener el promedio de las entradas de un vector

# Promedio de las ganancias
mean(ganancias)
## [1] 540

Podemos ordenar el vector de menor a mayor con la función sort()

sort(ganancias)
## [1]   20  100 1500

o de mayor a menor

sort(ganancias, decreasing = TRUE)
## [1] 1500  100   20

Veamos que los vectores en R son muy vérsatiles, y de hecho serán de gran utilidad al utilizarlos como estructuras de datos. Podemos agregar elementos nuevos a un vector, utilizando la función append():

# Al vector de ganancias le agregamos una nueva entrada 
#                nueva entrada
#                al vector
append(ganancias, 70)
## [1]  100 1500   20   70

Ahora bien, podemos definir vectores con entradas de diferentes tipos

vect_mixto <- c("Luis", 14)
vect_mixto
## [1] "Luis" "14"

Como se dijo antes, los datos del tipo character tienen mayor jerarquía que los del tipo numérico, por lo cual el 14 del vector anterior ha sido convertido al tipo character. Entonces, el vector anterior NO es del tipo numérico, por lo que no podremos realizar operaciones aritméticas con él.

Por otro lado, podremos unir dos vectores:

  • De manera horizontal o por filas:
# Utilizaremos la funcion rbind():
# Definimos dos vectores, donde cada uno sera considerado como una fila
v1 <- c(1,2,3)
v2 <- c(4,5,6)
# Unimos los vectores
rbind(v1, v2)
##    [,1] [,2] [,3]
## v1    1    2    3
## v2    4    5    6
  • De manera vertical o por columnas:
# Utilizaremos la funcion cbind():
# Definimos dos vectores, donde cada uno sera considerado como una columna
v1 <- c(1,2,3)
v2 <- c(4,5,6)
# Unimos los vectores
cbind(v1, v2)
##      v1 v2
## [1,]  1  4
## [2,]  2  5
## [3,]  3  6

Con lo aprendido hasta ahora podemos ver el tipo de dato factor. Este tipo de datos nos sirve para casos en los que trabajamos con categorías. Por ejemplo, supongamos que en cierta encuesta se pregunta a las personas si fuman o no; si fuman se coloca un 1, y si no fuman un 0. Entonces tenemos la asociación:

  • 1 –> Fuma
  • 0 –> No fuma

Supongamos además que tenemos la siguiente información

info_fumadores <- c(1, 0, 0, 1, 1, 0) 
length(info_fumadores)
## [1] 6

que han respondido 6 personas. Definimos una variable del tipo factor utilizando la función factor():

factor(info_fumadores)
## [1] 1 0 0 1 1 0
## Levels: 0 1

donde notamos que en automático se han detectado dos categorías en nuestros datos. Adicionalmente, recordemos que queremos considerar la asociación

  • 1 –> Fuma
  • 0 –> No fuma

lo cual podemos hacer

factor(info_fumadores, labels = c("No fuma", "Fuma"))
## [1] Fuma    No fuma No fuma Fuma    Fuma    No fuma
## Levels: No fuma Fuma

donde con el parámetro labels= cambiamos los unos y los ceros por los mensajes Fuma y No fuma. Por ahora solo estamos indagando en las herramientas más básica, no obstante, en clases posteriores veremos su uso práctico.

Generación de secuencias

Supongamos que definimos el vector

vect1 <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
vect1
## [1] 1 2 3 4 5 6 7 8 9

puede ser una labor tediosa definir un vector que contenga todos los números enteros del 1 al 100, así como lo definimos manualmente para el caso del 1 al 9. Para ello podemos generar secuencias de números:

# Secuencia de enteros del 1 al 9
1:9
## [1] 1 2 3 4 5 6 7 8 9

O también

# Secuencia de enteros del 1 al 100 almacenada en una variable
seq1 = 1:100
seq1
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
##  [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
##  [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
##  [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
##  [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
##  [91]  91  92  93  94  95  96  97  98  99 100

Donde en las secuencias anteriores el incremento es de uno en uno. Como alternativa para crear secuencias, podemos utilizar seq(). Así, 1:100 es totalmente equivalente a seq(1, 100). Con la función seq() podemos modificar el incremento:

# Secuencia del 1 al 9 modificando el incremento
seq2 <- seq(1, 9, by=0.5)
seq2
##  [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0

El resultado de las secuencias es siempre un vector. De hecho, dentro de la función c() podemos definir secuencias

# Forma 1
vector_seq <- c(1:10)
vector_seq
##  [1]  1  2  3  4  5  6  7  8  9 10
# Forma 2
vector_seq_2 <- c(seq(1,10))
vector_seq_2
##  [1]  1  2  3  4  5  6  7  8  9 10

Adicionalmente podemos generar vectores de números aleatorios utilizando la función sample()

# Colocamos primero un vector de numeros que representan las posibilidades de la seleccion aleatoria.
# Despues colocamos la cantidad de numeros aleatorios que queremos extraer del vector anterior.
sample(1:100, 10)
##  [1] 80 70 36 81 66 24 54 43 99 84

donde con lo anterior extraemos 10 número de manera aleatoria del vector de número enteros del 1 al 100. Si especificamos el parámetro replace=TRUE entonces la selección aleatoria se hará con reemplazo, es decir, podremos seleccionar más de una vez un número

sample(1:100, 20, replace = TRUE)
##  [1] 28 99 42 71 56 93 35 84 22 62 28 57  6 98  3 55 61 88 99 29

Tipo de datos booleanos

Los tipos de datos booleanos (logical): Son datos lógicos, los cuales solo pueden ser o TRUE (verdadero) o FALSE (falsos).

# Definiendo una variable booleana
esta_lloviendo <- FALSE
esta_lloviendo
## [1] FALSE

Notemos que escribimos esta_lloviendo uniendo las palabras mediante el guión bajo pues, no podemos definir variables dejando espacios en blanco:

# Obtendremos un error:

# Definiendo una variable booleana
esta lloviendo <- FALSE
esta lloviendo
## Error: <text>:4:6: unexpected symbol
## 3: # Definiendo una variable booleana
## 4: esta lloviendo
##         ^

Las variables booleanas son muy importantes, además de que podemos combinarlas con operadores booleanos:

  • Operador or (|): Considera dos variables booleanas y regresa una variable booleana, donde la regla es

    • TRUE | TRUE regresa TRUE
    • TRUE | FALSE regresa TRUE
    • FALSE | TRUE regresa TRUE
    • FALSE | FALSE regresa FALSE
# Veamos dos ejemplos aplicando el operador or (|)
TRUE | FALSE
## [1] TRUE
FALSE | FALSE
## [1] FALSE
  • Operador and (&): Considera dos variables booleanas y regresa una variable booleana, donde la regla es:
    • TRUE & TRUE regresa TRUE
    • TRUE & FALSE regresa FALSE
    • FALSE & TRUE regresa FALSE
    • FALSE & FALSE regresa FALSE
# Veamos dos ejemplos aplicando el operador and (&)
TRUE & TRUE
## [1] TRUE
FALSE & FALSE
## [1] FALSE
  • Operador de negación (!): Considera una variable booleana y regresa una variable booleana, donde:
    • !TRUE regresa FALSe
    • !FALSE regresa TRUE
# Veamos un ejemplo del operador de negacion
!TRUE
## [1] FALSE

Cabe mencionar que hasta ahora para ver algún tipo de dato o una variable simplemente escribimos dicho dato o dicha variable en una línea nueva para poder verla en consola. Esto es

# Definimos una variable:
# (Podemos combinar operadores booleanos)
#               (TRUE)
bool1 <- TRUE & !FALSE
# Para ver el valor de dicha variable escribimos en una linea nueva sun nombre que le asignamos
bool1
## [1] TRUE

De manera alternativa podemos utilizar la función print() para ver los resultados en salida:

print(bool1)
## [1] TRUE

Recordemos que tenemos operaciones vectorizadas en R, por ejemplo

# A cada entrada del vector se le suma el 5
c(1, 2, 3) + 5
## [1] 6 7 8

Asimismo, podemos obtener vectores lógicos escribiendo algo como

c(1, 2, 3) < 2
## [1]  TRUE FALSE FALSE

donde se evalúa:

  • 1 < 2 lo cual es verdadero (TRUE)
  • 2 < 2 lo cual es verdadero (FALSE)
  • 3 < 2 lo cual es verdadero (FALSE)

regresándonos así el vector lógico TRUE FALSE FALSE. Podríamos aplicarle el operador de negación al vector anterior

!(c(1, 2, 3) < 2)
## [1] FALSE  TRUE  TRUE

que revierte los valores lógicos. También, podemos utilizar operadores lógicos entre dos vectorres lógicos

# T equivale a TRUE y F a FALSE
v1 <- c(T, T, F, F)
v2 <- c(T, F, T, F)

v1 & v2
## [1]  TRUE FALSE FALSE FALSE

donde obtivimos que

  • T & T regresa T
  • T & F regresa F
  • F & T regresa F
  • F & F regresa F

Finalmente, es preciso mencionar que el operador de menor que (<) o mayor que (>) se conocen como operadores relacionales, de hecho hay otros de ellos: <=, >=, ==. Con == el operador de igualdad. Recordemos que = representa la idea de asignación, más no de igualdad como tal.

# Ejemplo de uso de ==.
# Nos preguntamos si el 0 es igual al 1
0 == 1
## [1] FALSE

Ejercicios

  1. Considerando la regla del operador and
  • T & T regresa T
  • T & F regresa F
  • F & T regresa F
  • F & F regresa F

la cual obtuvimos utilizando los vectores v1 y v2, obtén los resultados correspondientes para la regla del operador or y el operador de negación not (!). A las reglas de los operadores booleanos se les conoce como tablas de verdad.

  1. Define dos variables denominadas pi y r que representan al número \(\pi\) y a un radio positivo cualquiera \(r\), respectivamente. Define otra variable denominada area que almecene el área del círculo resultante de aplicar la fórmula \(A=\pi \cdot r^{2}\), e imprime el resultado de tal manera que se muestre:
## [1] "Área del círculo: n"

donde en vez de verse la n deberá verse el área del círculo que calculaste en la variable area.

  1. Define un vector denominado pares con los números: 2, 4, 6, 8, 10, 12, 14, 16, 18, 20. Luego, define otro vector que almace los resultados de aplicar el operador residuo %% a cada una de las entradas del vector pares. ¿Qué observas?

  2. Haz lo mismo que en el punto anterior, pero ahora utiliza un vector denominado impares con los números: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19. ¿Qué observas? ¿Qué podríamos concluir a partir de este y el punto anterior?

  3. Une los vectores pares e impares de dos formas distintas: una, utilizando rbind, y la otra cbind.

  4. Crear un vector de longitud 20 cuyas entradas solo sean el número 0 y el número 1. La forma en que tenga dichos valores el vector deberá de ser aleatoria, por lo cual deberás utilizar la función sample(). Luego, definine una variable de tipo factor con dos niveles (M y F) utilizando el vector que creaste antes.

  5. Dada una variable booleanda con valor TRUE (o abreviadamente T), el valor cambiará a F si utilizamos el operador de negación !, esto es

!TRUE
## [1] FALSE

Ahora, utilizando las tablas de verdad que vimos en clase, calcula el resultado de:

a).

(FALSE) | (!FALSE)

b).

!(FALSE & TRUE) & (!FALSE)

Ojo: Para resolver lo anterior NO DEBES UTILIZAR R, más bien, debes calcular “a mano” los resultados, para ello utiliza las tablas de verdad que vimos.

  1. Una vez que has calculado los resultados del punto anterior, compruébalos utilizando R.