Repaso

Crear proyecto nuevo

Crear un nuevo proyecto en nuevo directorio: “repaso-importacion”

Crear documento R Markdown

  1. Crear un nuevo archivo R Markdown:
    • Documento HTML
    • Título: “Repaso de importación de datos”
    • Contenido: Según el escenario presentado

Escenario

Trabajas en un medio de comunicación y te encargan revisar datos de Netflix. Para ello, te comparten el conjunto de datos “netflix.xlsx”. Necesitas importar el conjunto de datos y contestar algunas preguntas.

  1. ¿Cuántas filas tiene el conjunto de datos?
  2. ¿Cuántas columnas tiene el conjunto de datos?
  3. ¿Cuál es la unidad de observación del conjunto de datos?
  4. ¿Qué tipo de relaciones entre variables podrían obtenerse con este conjunto de datos?

Publicar en Rpubs.com el resultado de hacerle Knit al documento.

Elementos básicos de R

Crear nuevo proyecto

Para que mantengas un buen orden en tu aprendizaje, es momento de crear un nuevo proyecto en el que irás anotando todo lo que aprendas en esta sesión. Cabe mencionar que todo lo que anotes deberás publicarlo al final en tu perfil de Rpubs.com

  • Crear un nuevo proyecto en nuevo directorio: “rbasico”

Crear documento R Markdown

  • Crear un nuevo archivo R Markdown:
    • Documento HTML
    • Título: “Elementos básicos de R”
    • Contenido: Según las notas que tomes en la sesión

Operadores elementales

Aritméticos

Los operadores, como dice su nombre, nos permiten realizar operaciones entre ciertos valores de manera similar a como lo haríamos con una calculadora. Los siguientes nos permiten realizar operaciones aritméticas básicas:

Operador Operación
+ Adición
- Sustracción
* Multiplicación
/ División real
** o ^ Potencia
() Para priorizar operaciones al interior de los paréntesis

1994 + 27
## [1] 2021
28 / 365 * 100
## [1] 7.671233
2 ** 3
## [1] 8
(((1+2)*3)**2)/3
## [1] 27

Operador de asignación

Antes de explotar al máximo las capacidades de R, es necesario conocer otro operador fundamental: el de asignamiento. Está compuesto por el signo “menor que” (<) y el signo de resta (-), que al juntarse lucen como una flecha que apunta hacia la izquierda (<-).

Este operador sirve para asignar un nombre a cualquier objeto o valor, de tal modo podamos acceder a él con mayor facilidad. Por ejemplo, podemos asignarle el nombre “resultado” al resultado de la operación que realizamos anteriormente.

resultado <- (((1+2)*3)**2)/3

A simple vista, nada ha cambiado, pero cuando accedemos al objeto resultado ahora obtenemos inmediatamente la respuesta de nuestra operación.

resultado
## [1] 27

Si te diriges al panel Environment en RStudio, puedes ver que el objeto resultado está almacenado allí.

Actualizar valor asignado

Si por algún motivo necesitamos actualizar el valor asignado a nuestro objeto, basta con volver a asignar el mismo nombre a otro valor. Incluso se puede hacer referencia al valor anterior para modificarlo. No hay un límite de veces que el valor de un objeto puede ser modificado. En el siguiente ejemplo, sumaremos 3 a resultado para obtener 30.

resultado <- resultado + 3

Nuevamente, podemos ver el cambio al inspeccionar el elemento.

resultado
## [1] 30

Vectores

Identificando los vectores

Los siguientes objetos fundamentales para el manejo de R son los vectores. Estos pueden ser de dos tipos: atómicos y listas. La diferencia entre ellos radica en el tipo de información que pueden contener. Para efectos de estos tutoriales, consideraremos las listas como vectores “especiales” junto a otros que explicaremos más adelante.

Vectores atómicos

Los cuatro principales tipos de vectores atómicos son: logical, double, integer y character.

Los vectores de tipo logical pueden asumir dos valores: TRUE o FALSE(o en su forma abreviada T o F).

Los de tipo double e integer asumen valores numéricos, los double pueden asumir valores racionales y los integer sólo valores enteros.

Los vectores de tipo character asumen cualquier cadena de texto.

En el siguiente recuadro de código podemos ver un ejemplo de cada uno:

v_logical <- TRUE
v_double <- 3.1416
v_integer <- 5L
v_character <- "Hola mundo"

Si estamos atentos, vemos que el integer va acompañado de una “L” al final. Esto es necesario porque R interpreta por defecto cualquier número como double. Tanto los double como los integer pertenecen a la categoría de vectores numéricos. Los character siempre estarán rodeados de comillas ("").

Comprobar tipo de vector con is.*()

Para comprobar si nuestro vector es de un tipo determinado utilizamos una función de forma is.*() reemplazando el * por el tipo que queremos comprobar.

is.logical(v_logical)
## [1] TRUE
is.numeric(v_double)
## [1] TRUE
is.integer(v_double)
## [1] FALSE

Podemos ver que por cada consulta obtenemos un valor logical TRUE cuando se cumple la condición y FALSE cuando no se cumple. Es decir, es cierto que v_logical es logical, es cierto que v_double es numérico y es falso que v_double es integer. El valor logical obtenido con cada consulta es un vector en sí mismo.

Comprobar tipo de vector con typeof()

Otra manera de verificar el tipo de vector que tenemos es con la función typeof(). Esta nos devuelve un character indicando el tipo de vector que tenemos.

typeof(v_character)
## [1] "character"
typeof(v_integer)
## [1] "integer"

Ejercicio

1. Identificar tipo de vector

En bloques de código, ejecuta el código necesario para identificar el tipo de los siguientes valores:

  1. "3.1415"
  2. FALSE
  3. 1 + 10
  4. 142365L

2. Descartar tipo de vector

¿Cuáles de los siguientes vectores son de tipo double?

  • 100
  • 7.9
  • "50.0 mm"
  • 1024L

Continuamos …

Vectores con más de un elemento

Hasta el momento hemos visto vectores que contienen un solo elemento. Sin embargo, es sumamente común encontrarse con vectores de mayor longitud. Por ejemplo, el vector letters contiene todas las letras minúsculas del alfabeto. Podemos consultar la longitud de un vector con la función length().

Esto es muy útil cuando sabemos que nuestro vector podría contener una gran cantidad de elementos y no queremos inspeccionarlos todos. El número que vemos rodeado entre corchetes ([]) en nuestro resultado nos indica el índice que el elemento siguiente tiene en el vector. Es por ello que hasta el momento en cada operación que realizábamos hemos obtenido un “[1]” antes de cada resultado.

length(v_logical)
## [1] 1
length(letters)
## [1] 26
letters
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"

Para formar vectores de longitud mayor a uno (1) se utiliza la función c() agregando como argumentos todos los elementos que queremos.

mi_vector_largo <- c("elemento1", 
                     "elemento2", 
                     "elemento3", 
                     "elemento4")

mi_vector_largo
## [1] "elemento1" "elemento2" "elemento3" "elemento4"

Operador de secuencia simple

Para vectores numéricos, también es posible utilizar el signo dos puntos (:) como operador para crear una secuencia, que avanza de uno en uno, desde un número a otro. El vector resultado incluirá a los dos números utilizados en la operación.

mi_vector_numerico1 <- 1:6

mi_vector_numerico1
## [1] 1 2 3 4 5 6

Concatenar vectores largos

Podemos hacer uso de c() nuevamente para seguir haciendo crecer nuestro vector. Incluso podemos usar una operación de secuencia como argumento.

mi_vector_numerico2 <- 11:16

mi_vector_muy_largo <- c(mi_vector_numerico1, 
                         mi_vector_numerico2, 
                         21:26)

mi_vector_muy_largo
##  [1]  1  2  3  4  5  6 11 12 13 14 15 16 21 22 23 24 25 26

Al consultar el tipo de vector que hemos creado, vemos que mantiene el mismo tipo que sus “ancestros”: integer.

typeof(mi_vector_muy_largo)
## [1] "integer"

Ejercicio

1. Crear secuencia

En bloques de código, ejecuta código para obtener lo siguiente:

  • Crea un secuencia que vaya del 100 al 200
  • ¿Qué tipo de vector se formó con esa secuencia?

2. Crear vector de nombres

En bloques de código, ejecuta código para obtener lo siguiente:

  • Crea un vector en el que cada elemento es una parte de tu nombre completo. Por ejemplo:
mi_nombre <- c("Barack", "Obama")
  • ¿Qué tipo de vector se formó con esta operación?

Descanso de 15 minutos

Operaciones con vectores

Es posible realizar operaciones entre vectores. Cuando los vectores tienen la misma longitud, la operación se hará elemento a elemento de acuerdo a su índice. Es decir, el primer elemento del vector 1 con el primer elemento del vector 2, el segundo elemento del vector 1 con el segundo elemento del vector 2, y así sucesivamente.

mi_secuencia1 <- 1:10
mi_secuencia2 <- 11:20

mi_secuencia1 + mi_secuencia2
##  [1] 12 14 16 18 20 22 24 26 28 30
mi_secuencia2 - mi_secuencia1
##  [1] 10 10 10 10 10 10 10 10 10 10
mi_secuencia1 * mi_secuencia2
##  [1]  11  24  39  56  75  96 119 144 171 200

Reciclaje de vectores

Cuando un vector tienen longitud de uno (1), su valor se reciclará.

mi_secuencia1 + 1
##  [1]  2  3  4  5  6  7  8  9 10 11
mi_secuencia1 * 5
##  [1]  5 10 15 20 25 30 35 40 45 50
mi_secuencia1 ** 2
##  [1]   1   4   9  16  25  36  49  64  81 100

Coerción y valores NA

Coerción de vectores

Crear vectores más largos puede tener efectos inesperados para el usuario que no está atento. Veamos el siguiente ejemplo:

vector_combinado <- c(mi_vector_muy_largo, "1")

typeof(vector_combinado)
## [1] "character"

Al agregar "1" a nuestro vector, su tipo ha cambiado a character. ¿Por qué sucede esto? En primer lugar, hay que tener claro que "1" no es lo mismo que 1. Recordemos que todo valor que está entre comillas es de tipo character, incluso si se trata de números.

En segundo lugar, tengamos en cuenta que los vectores atómicos sólo pueden tener un tipo. Esto quiere decir que cuando los tipos de los elementos que se combinan dentro del vector son diferentes, R debe decidir cuál de los tipos de vector mantener, eligiéndo sólo uno. Este procedimiento es llamado coerción.

Reglas de coerción implícita

Aunque suena complicado, las reglas de coerción son bastante sencillas. R le dará prioridad a mantener el tipo de vector según el siguiente orden:

  1. Character
  2. Double
  3. Integer
  4. Logical

Es decir, ante cualquier conflicto en el tipo de vectores a combinar se preservará el tipo que tenga más alta prioridad.

Si nos detenemos a analizar por qué sucede, es bastante evidente. Los valores logical son en realidad leídos por la computadora como 1 cuando son TRUE y como 0 cuando son FALSE. Es por ello que la siguiente operación no nos arroja un error.

1L + TRUE
## [1] 2

Del mismo modo, sabemos que cualquier número entero también puede ser expresado como número racional. Es por ello que los integer son coercionados a double cuando hay conflicto entre ellos.

typeof(1L + 3.1416)
## [1] "double"

¿Es posible convertir texto a números en R? No. Es por ello que cuando un vector tipo character se combina con cualquier otro tipo de vector, prevalece el tipo character, como en el ejemplo que vimos al inicio de esta sección.

Coerción explícita

En todos los casos de coerción que hemos mencionado hasta el momento R ha decidido mediante sus propias reglas qué tipo de vector debe prevalecer, aplicando coerción implícita. Este procedimiento puede ocasionar problemas cuando el usuario no tiene suficientemente claras las reglas de coerción.

La coerción explícita permite decidir de antemano qué tipo de vector queremos obtener. Para ello se hace uso de una función de la forma as.*() donde * representa el tipo deseado.

vector_true_integer <- as.integer(TRUE)

typeof(vector_true_integer)
## [1] "integer"

En este ejemplo, hemos usado as.integer() para cambiar el tipo de nuestro vector, de logical a integer. Es posible hacer lo mismo para otros tipos de vectores. Tomemos en cuenta que la transformación se realiza de manera directa, sin respetar el orden de prioridad.

as.character(TRUE)
## [1] "TRUE"

Es por ello que TRUE se convierte directamente en el character "TRUE" sin convertirse primero en el integer 1L, luego en el double 1 y luego en el character "1". De aquí viene el verdadero poder de la coerción explícita, porque nos permite incluso “revertir” el orden de prioridad que R usa en la coerción implícita. Es decir, podemos convertir cualquier tipo de vector a otro.

typeof(as.logical("TRUE"))
## [1] "logical"
typeof(as.integer("10"))
## [1] "integer"
typeof(as.integer(5.0))
## [1] "integer"
typeof(as.double("6.108"))
## [1] "double"

Coerción puede perder información

De todos modos, esto se debe usar con precaución. Sabemos que todo logical puede convertirse a integer, estos a su vez pueden convertirse a double y estos a character sin perder ninguna información. No sucede lo mismo en el procedimiento reverso. Por ejemplo, esto sucede cuando queremos convertir un double con cifras decimales a integer.

as.integer(5.4234)
## [1] 5

El contenido decimal se pierde, porque R no lo necesita en el integer, y no es posible recuperarlo aún retransformando el valor a double en la misma línea de código.

as.double(as.integer(5.4234))
## [1] 5

Algo similar sucede cuando intentamos convertir a logical valores numéricos diferentes a 0.

as.logical(8)
## [1] TRUE
as.logical(-0.000000135)
## [1] TRUE

R interpreta como TRUE todo número diferente a 0. Es probable que no sea el resultado que esperábamos en esta transformación.

Ejercicio

Práctica de coerción

Intenta este ejercicio primero sin ejecutar código. Luego, verifica si tus suposiciones eran correctas.

¿Qué tipos de vector obtenemos en los siguientes bloques de código?

Una vez que compruebes de qué tipo son los vectores creados, agrega una explicación de esa coerción antes de cada bloque de código.

test1 <- c(10:15, TRUE)

test2 <- c(10:15, 16)

test3 <- c(10:15, "FALSE")

test4 <- c("10:15", 16L)

Valores NA

¿Qué sucederá si intentamos convertir una palabra a número?

as.integer("sustantivo")

R no es capaz de asignar un valor numérico a "sustantivo" y como resultado nos arroja un advertencia o warning: NAs introduced by coercion. El valor NA representa un valor perdido y no es posible transformarlo. Los valores perdidos pueden aparecer en nuestros datos por diferentes motivos, desde la recolección hasta la transformación de nuestra data.

as.integer("sustantivo")
## Warning: NAs introduced by coercion
## [1] NA

Suma con valor NA

Debemos ser extremadamente cuidadosos al trabajar con ellos, porque pueden generar algunos problemas indeseados. Por ejemplo, si queremos obtener la suma de todos los elementos de un vector, usando la función sum(), y resulta que uno de ellos es un NA.

vector_con_NA <- c(1, 2, 3, 4, NA, 6, 7)
sum(vector_con_NA)
## [1] NA

El resultado obtenido es simplemente NA. El mismo problema se extiende al querer obtener un promedio usando la función mean().

mean(vector_con_NA)
## [1] NA

Argumento na.rm

Felizmente, estas funciones permiten proporcionar el argumento na.rm = TRUE para ignorar los valores NA y trabajar sólo con valores válidos.

sum(vector_con_NA, na.rm = TRUE)
## [1] 23
mean(vector_con_NA, na.rm = TRUE)
## [1] 3.833333

Sin embargo, no necesariamente encontraremos esta herramienta en todas las funciones que trabajan con vectores. Por ello es indispensable estar atentos al trabajar nuestros datos y revisar la documentación de las funciones con las que estamos trabajando.

Ejercicio

Crear vectores

  1. Crea un vector de cualquier tipo con 10 elementos
  2. Crea un vector de cualquier tipo con 10 elementos, el último elemento debe ser un NA
  3. Crea un vector de cualquier tipo con 10 elementos, el sexto elemento debe ser un NA

Comprobar tipo de vector

Intenta este ejercicio primero sin ejecutar código. Luego, verifica si tus suposiciones eran correctas.

¿Qué tipos de vector obtenemos en los siguientes bloques de código?

Una vez que compruebes de qué tipo son los vectores creados, agrega una explicación de esa coerción antes de cada bloque de código.

test1 <- c(1:6, NA)
test2 <- test1 * 10
test3 <- test1 + NA
test4 <- c(test1, "7")
test5 <- c(test1, TRUE)
test6 <- NA * NA

Data.frames

Por completar …