<- 3 mi_escalar
Apuntes de R
Trabajando con variables en R
Estructuras de datos en R - Parte 1: Escalares y vectores
Un concepto clave para usar R en todas sus capacidades es el de estructuras de datos. Al usar R normalmente queremos trabajar no con uno o dos datos como en los ejemplos de sumas simples en la sección anterior, sino que queremos trabajar con decenas, centenas, miles y potencialmente millones de datos. R nos permite operar con datos, desde uno solo hasta millones de ellos, usando estructuras de datos.
Las estructuras de datos que vamos a utilizar en el curso son escalares, vectores, listas, matrices y data frames. En esta primera parte revisaremos las dos primeras estructuras de datos.
Escalares (y nombres de estructuras)
La estructura de datos más simple es un escalar, que es un nombre técnico para indicar que esta estructura almacena solo un dato. A toda estructura de datos se le asigna un nombre (que usaremos para referirnos a esta), y en el siguiente ejemplo vamos a crear un escalar llamado mi_escalar
en el que guardaremos un solo dato, el valor 3
.
Podemos ver que R no nos ha presentado ningún resultado. En este caso esto es una buena noticia ya que significa que R exitosamente creó la estructura de datos mi_escalar
y almacenó el valor 3
en ella. De forma general, comandos que crean o sobrescriben estructuras de datos no mostrarán ninguna retroalimentación en R.
Si quiero confirmar que la estructura fue creada puedo pedirle a R que me muestre las estructuras que tienen en memoria usando el comando ls
(una abreviación del inglés list, vale decir listar lo que está en memoria):
Si en R no han ejecutado otro código más allá del que hemos revisado hasta aquí, en los apuntes deberían ver solo la estructura que recién creamos. Si han creado o cargado otros objetos verán que la lista incluye otros elementos.
ls()
[1] "mi_escalar"
Si bien no es usualmente necesario, es posible borrar objetos que R tiene en memoria usando el comando rm
(piensen en remover). Usando rm(nombre_del_objeto_a_borrar)
podemos remover el objeto.
# Objeto que voy a querer borrar
<- 5
mi_esQalar
ls()
[1] "mi_escalar" "mi_esQalar"
rm(mi_esQalar)
ls()
[1] "mi_escalar"
Al volver a correr ls() podemos ver que el objeto mi_esQalar
efectivamente fue borrado y que mi_escalar
sigue en memoria.
Si queremos ver el contenido de una estructura de datos en R podemos usar el nombre de la estructura como un comando:
mi_escalar
[1] 3
Al ingresar el nombre de la estructura, R muestra sus contenidos, en este caso el dato 3
que habíamos guardado.
Es importante notar que los datos que guardamos pueden no solo ser numéricos sino también cadenas de caracteres (vale decir, textos):
<- "El niño que vivió"
harry_potter harry_potter
[1] "El niño que vivió"
Sin embargo, es importante tener cuidado de indicar exactamente el nombre:
Harry_Potter
Error: object 'Harry_Potter' not found
Como pueden ver, R es sensible a distinciones de mayúsculas y minúsculas!
<- "Escalar a minúscula"
a <- "Escalar a mayúscula" A
Sobre los nombres de estructuras de datos en R
Podrán notar que hay flexiblidad respecto al nombre que se le puede dar a las estructuras de datos. En general los nombres válidos que pueden usar en R pueden tener cualquier letra, cualquier número, puntos y guiones bajos, siempre y cuando el primer caracter sea una letra, por ejemplo:
<- "Letras y número"
ejemplo1
.2 <- "Letras, punto y número"
ejemplo
<- "Letras, guión bajo y números"
ejemplo_3
<- "No usen nombres así"
Este_es_un.pesimo.ejemplo._deNombre12423432
<- "Eviten también nombres poco descriptivos" var4325
Vectores (y tipos de datos)
La siguiente estructura de datos, una de las más comunes, nos permite agregar múltiples datos y referirnos a ellos en conjunto usando un solo nombre.
Para crear un vector debemos usar una estructura especial, declarando el vector con la letra c
antes de listar objetos separados por comas entre paréntesis. Usamos la letra c
porque combinamos elementos en un vector.
Si bien los vectores pueden contener múltiples datos, es posible crear un vector con un solo dato:
`un_solo_dato <- c(5)`
R creará el objeto `un_solo_dato` sin problemas y lo identificará como un vector, pero para efectos prácticos esto es equivalente a un escalar.
<- c(5.3, 5.8, 6.3)
mis_notas mis_notas
[1] 5.3 5.8 6.3
Los vectores pueden contener datos de texto también. Noten que los datos de texto en R tienen que estar entre comillas para que sean leídos correctamente.
<- c("Blade Runner","Cazadores del arca perdida","Star Wars")
peliculas peliculas
[1] "Blade Runner" "Cazadores del arca perdida"
[3] "Star Wars"
<- c('El padrino','Pulp Fiction','Perdidos en Tokio')
otras_peliculas otras_peliculas
[1] "El padrino" "Pulp Fiction" "Perdidos en Tokio"
Sobre el uso de comillas en R
Es importante que presenten atención al tipo de comillas, pueden usar comillas dobles o comillas simples, pero deben ser consistentes. Sin embargo, es importante que sean comillas rectas (comillas sin curvas) '
como estas'
o "
como estas"
.
Usar comillas 'así' o "así"
Algunos procesadores de texto (como Microsoft Word) cambian las comillas rectas por comillas tipográficas (suelen verse como comillas curvas) ‘como estas’ o “como estas”.
No usar comillas ‘así’ o “así”
Como pueden ver, los vectores pueden almacenar tanto datos numéricos como datos de texto. Cada estructura de datos en R tiene un tipo de datos asociado que nos permite saber cuál es el tipo de contenido que está guardado dentro de la estructura. Podemos usar el comando ‘mode’ para ver el tipo de datos de una estructura.
# Los datos de tipo textos en R son llamados "character"
mode(mis_notas)
[1] "numeric"
# Algunos de los datos numéricos en R son llamados "numeric"
mode(peliculas)
[1] "character"
Tipos de datos en vectores en R
En los dos ejemplos anteriores, todos los datos dentro de cada vector eran del mismo tipo, pero ¿qué ocurre cuando mezclamos datos de texto y datos numéricos?
<- c("Blade Runner", 1982, "Star Wars", 1977)
peliculas_y_años peliculas_y_años
[1] "Blade Runner" "1982" "Star Wars" "1977"
mode(peliculas_y_años)
[1] "character"
Podemos ver que, a pesar de que intentamos cargar texto y números, el vector fue creado como teniendo solo texto. Esto se debe a que un vector solo soporta elementos de un mismo tipo, si se intenta combinar números y texto el vector se creará como un vector de texto y los números serán tratados como caracteres.
Veamos algunos ejemplos de cómo referirnos a los datos contenidos dentro de un vector. Vamos a partir creando un vector con 10 notas de controles en un curso y luego vamos a pedir a R que nos indique el largo del vector, vale decir, cuántos datos están contenidos en él.
<- c(4.8,5.3,6.2,4.6,5.9,6.0,5.3,5.1,6.5,4.2)
notas_de_controles
# Ver el largo de un vector
length(notas_de_controles)
[1] 10
Lo primero que vamos a ver es que R permite referirnos a cada elemento dentro del vector en base a su posición en el vector, indicando dicha posición o posiciones entre corchetes cuadrados [
y ]
.
# Ver todos los datos
notas_de_controles
[1] 4.8 5.3 6.2 4.6 5.9 6.0 5.3 5.1 6.5 4.2
# Ver dato 1
1] notas_de_controles[
[1] 4.8
# Ver dato 5
5] notas_de_controles[
[1] 5.9
# Ver dato 10
10] notas_de_controles[
[1] 4.2
# Ver datos 3, 5 y 7
c(3,5,7)] notas_de_controles[
[1] 6.2 5.9 5.3
# Ver datos 2, 8 y 9
c(2,8,9)] notas_de_controles[
[1] 5.3 5.1 6.5
# Ver todos los datos menos los datos 1 y 10
-c(1,10)] notas_de_controles[
[1] 5.3 6.2 4.6 5.9 6.0 5.3 5.1 6.5
# Ver todos los datos menos los datos 4, 5 y 6
-c(4,5,6)] notas_de_controles[
[1] 4.8 5.3 6.2 5.3 5.1 6.5 4.2
Ahora que conocemos nuestra primera estructura de datos vamos a revisar cómo tomar ventaja del hecho que podemos operar simultáneamente sobre todos los datos dentro de esta, en particular, vamos a ver cómo R nos permite aplicar funciones a nuestros datos.
Estructuras de datos en R - Parte 2: Matrices y data frames
Matrices (con coordenadas y nombres)
Los vectores son estructuras útiles, pero en R existen otras estructuras que nos permiten operar sobre datos más complejos. Imaginemos el caso en el que tenemos datos no solo sobre una variable, sino que sobre 3 variables: las notas de las pruebas en un curso, las notas los controles y las notas del trabajo de ese mismo curso para 5 estudiantes.
Idealmente, queremos almacenar estos 15 datos (3 notas para cada uno de 5 estudiantes) en una estructura que nos permita ver con claridad a qué corresponde cada dato. Una forma natural de ordenar estos datos es una matriz como la siguiente:
-----------------------------------------------------------------|Estudiante | NotaPruebas | NotaControles | NotaTrabajo |
-----------------------------------------------------------------|Est01 | 4.5 | 4.9 | 5.5 |
|Est02 | 5.6 | 5.3 | 6.5 |
|Est03 | 6.5 | 6.9 | 6.5 |
|Est04 | 4.0 | 4.7 | 5.0 |
|Est05 | 4.2 | 4.4 | 4.5 |
-----------------------------------------------------------------
Este tipo de estructura debería ser conocida si han visto tablas de datos, por ejemplo, en Microsoft Excel. Podemos ver los datos de cada tipo de evaluación en columnas separadas y ver datos de cada estudiante en la fila correspondiente.
Podemos crear este tipo de estructura usando el comando matrix
(matriz en inglés). La función matrix
requiere dos argumentos al menos:
- Los datos que se pretende ingresar a la matriz
- Cuántas columnas o cuántas filas debe tener la matriz que se está creando, ingresando los valores uno tras otro partiendo en orden por los datos de la primera columna, siguiendo por los datos de la segunda y finalmente la tercera.
# Ingresamos los datos y le indicamos a la función que los divida en 3 columnas
<- matrix(c(4.5,5.6,6.5,4.0,4.2,4.9,5.3,6.9,4.7,4.4,5.5,6.5,6.5,5.0,4.5), ncol = 3)
matriz.de.notas.ej1
matriz.de.notas.ej1
[,1] [,2] [,3]
[1,] 4.5 4.9 5.5
[2,] 5.6 5.3 6.5
[3,] 6.5 6.9 6.5
[4,] 4.0 4.7 5.0
[5,] 4.2 4.4 4.5
# Ingresamos los datos y le indicamos a la función que los divida en 5 filas
<- matrix(c(4.5,5.6,6.5,4.0,4.2,4.9,5.3,6.9,4.7,4.4,5.5,6.5,6.5,5.0,4.5), nrow = 5)
matriz.de.notas.ej2
matriz.de.notas.ej2
[,1] [,2] [,3]
[1,] 4.5 4.9 5.5
[2,] 5.6 5.3 6.5
[3,] 6.5 6.9 6.5
[4,] 4.0 4.7 5.0
[5,] 4.2 4.4 4.5
# Estos dos métodos, indicar columnas o filas, genera resultados iguales
# Podemos comparar estas dos matrices con el operador `==`
== matriz.de.notas.ej2 matriz.de.notas.ej1
[,1] [,2] [,3]
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE
[4,] TRUE TRUE TRUE
[5,] TRUE TRUE TRUE
# El resultado muestra que todas las celdas son iguales
Hemos creado nuestra matriz, pero vemos que solo tenemos los datos y no se ve claramente qué representa cada columna o cada fila. Para resolver esto R permite la creación de nombres dentro de una estructura de datos. Los nombres los podemos crear con los comandos colnames
(de column names) y rownames
(de row names).
matriz.de.notas.ej1
[,1] [,2] [,3]
[1,] 4.5 4.9 5.5
[2,] 5.6 5.3 6.5
[3,] 6.5 6.9 6.5
[4,] 4.0 4.7 5.0
[5,] 4.2 4.4 4.5
# Indicamos que los nombres de las columnas están en el vector que declaramos
colnames(matriz.de.notas.ej1) <- c("NotaPruebas","NotaControles","NotaTrabajo")
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
[1,] 4.5 4.9 5.5
[2,] 5.6 5.3 6.5
[3,] 6.5 6.9 6.5
[4,] 4.0 4.7 5.0
[5,] 4.2 4.4 4.5
# Indicamos que los nombres de las filas están en el vector que declaramos
rownames(matriz.de.notas.ej1) <- c("Est01","Est02","Est03","Est04","Est05")
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
Ahora podemos ver que nuestra matriz tiene no solo los datos, sino también una clara identificación de cada columna y cada fila. Cuando ya tenemos una estructura así podemos, por ejemplo, calcular los promedios del curso (de cinco estudiantes) en la prueba, los controles, y el trabajo o los promedios de cada estudiante al considerar cada una de sus evaluaciones.
Para ver un primer ejemplo de como hacer esto tenemos que recordar que si tenemos un vector en R, yo puedo llamar un dato específico indicando su posición entre corchetes cuadrados ‘[]’:
Puede ser confuso al ver el resultado de este ejemplo que, si bien pedimos a R que nos mostrara el segundo elemento del vector, al imprimir el resultado R nos muestra un `[1]` al lado del elemento. Esto se debe a que los números en corchetes que R muestra al imprimir resultados indican solamente el número de elemento al que corresponde el resultado, en este caso, el resultado tiene un solo elemento y R nos indica que ese es el elemento [1].
peliculas
[1] "Blade Runner" "Cazadores del arca perdida"
[3] "Star Wars"
# Recuperamos el valor en la segunda posición en el vector
2] peliculas[
[1] "Cazadores del arca perdida"
Esta misma idea se aplica a las matrices, pero ahora no nos basta con un valor para identificar la posición de un dato: necesitamos dos datos, primero saber en qué fila se encuentra y luego en qué columna. R nos permite llamar datos dentro de una matriz indicando estos dos valores (filas y columna) indicándolos también entre corchetes cuadrados siguiendo este formato [fila, columna]
.
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
# Si quiero ver la nota que el estudiante 3 (tercera fila) obtuvo en sus controles (segunda columna)
3,2] matriz.de.notas.ej1[
[1] 6.9
# Si quiero ver la nota que el estudiante 5 (quinta fila) obtuvo en sus pruebas (primera columna)
5,1] matriz.de.notas.ej1[
[1] 4.2
Este sistema de coordenadas nos permite identificar cualquier dato en una matriz, pero no solo eso, podemos usarlo para referirnos a múltiples datos de la siguiente manera:
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
# Quiero ver todas las notas del segundo estudiante (segunda fila)
2,] matriz.de.notas.ej1[
NotaPruebas NotaControles NotaTrabajo
5.6 5.3 6.5
# Quiero ver todas las notas de los trabajos (tercera columna) en el curso
3] matriz.de.notas.ej1[,
Est01 Est02 Est03 Est04 Est05
5.5 6.5 6.5 5.0 4.5
# Quiero ver todas las notas del segundo y cuarto estudiante (segunda y cuarta fila)
c(2,4),] matriz.de.notas.ej1[
NotaPruebas NotaControles NotaTrabajo
Est02 5.6 5.3 6.5
Est04 4.0 4.7 5.0
# Quiero ver todas las notas de las pruebas y controles (primera y segunda columna) en el curso
c(1,2)] matriz.de.notas.ej1[,
NotaPruebas NotaControles
Est01 4.5 4.9
Est02 5.6 5.3
Est03 6.5 6.9
Est04 4.0 4.7
Est05 4.2 4.4
# Quiero ver las notas del cuarto y quinto estudiante en las pruebas y trabajos
c(4,5),c(1,3)] matriz.de.notas.ej1[
NotaPruebas NotaTrabajo
Est04 4.0 5.0
Est05 4.2 4.5
Podemos ver entonces que puedo referirme a los datos por filas o por columnas indicando solo aquellos valores que me interesan. Usemos esto entonces para calcular promedios:
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
# Promedio del curso en las pruebas
mean(matriz.de.notas.ej1[,1])
[1] 4.96
# Promedio del curso en los controles
mean(matriz.de.notas.ej1[,2])
[1] 5.24
# Promedio del curso en los trabajos
mean(matriz.de.notas.ej1[,3])
[1] 5.6
# Promedio de notas del estudiante 2
mean(matriz.de.notas.ej1[2,])
[1] 5.8
# Promedio de notas del estudiante 4
mean(matriz.de.notas.ej1[4,])
[1] 4.566667
Pero si recordamos que nuestra matriz tiene nombres, podemos incluso llamar datos usando los nombres respectivos. Para esto tenemos que combinar el uso de nombres con el “sistema de coordenadas” que acabamos de revisar. Recuerden, al indicar qué datos quiero entre corchetes en una matriz lo que está antes de la coma se refiere a las filas y lo que está después de la coma se refiere a las columnas:
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
# Promedio del curso en las pruebas
mean(matriz.de.notas.ej1[,"NotaPruebas"])
[1] 4.96
# Promedio del curso en los controles
mean(matriz.de.notas.ej1[,"NotaControles"])
[1] 5.24
# Promedio del curso en los trabajos
mean(matriz.de.notas.ej1[,"NotaTrabajo"])
[1] 5.6
# Promedio de notas del estudiante 2
mean(matriz.de.notas.ej1["Est02",])
[1] 5.8
# Promedio de notas del estudiante 4
mean(matriz.de.notas.ej1["Est04",])
[1] 4.566667
Supongamos ahora que sabemos que la nota final de cada estudiante se calcula en base a la ponderación de las pruebas en un 50%, los controles en un 20% y el trabajo en un 30%. Podemos hacer los cálculos de las notas finales directamente refiriendo a la matriz:
matriz.de.notas.ej1
NotaPruebas NotaControles NotaTrabajo
Est01 4.5 4.9 5.5
Est02 5.6 5.3 6.5
Est03 6.5 6.9 6.5
Est04 4.0 4.7 5.0
Est05 4.2 4.4 4.5
<- matriz.de.notas.ej1[,1] * .5 +
promedio.final 2] * .2 +
matriz.de.notas.ej1[,3] * .3
matriz.de.notas.ej1[,
promedio.final
Est01 Est02 Est03 Est04 Est05
4.88 5.81 6.58 4.44 4.33
Data frames
Supongamos ahora que queremos tener una estructura de datos que nos permita ver datos de distintos tipos, por ejemplo, nombres de películas, el año en que fueron exhibidas y cuánto dinero recaudaron.
--------------------------------------------------------------| Título | Recaudación | Año |
--------------------------------------------------------------| Avatar | $2,810,779,794 | 2009 |
| Avengers: Endgame | $2,797,501,328 | 2019 |
| Titanic | $2,194,439,542 | 1997 |
| Star Wars: The Force Awakens | $2,068,223,624 | 2015 |
| Avengers: Infinity War | $2,048,359,754 | 2018 |
| Jurassic World | $1,671,713,208 | 2015 |
--------------------------------------------------------------
Vamos a crear una matriz con nuestros datos:
<- matrix(c("Avatar","Avengers: Endgame","Titanic","Star Wars: The Force Awakens","Avengers: Infinity War","Jurassic World",2810779794,2797501328,2194439542,2068223624,2048359754,1671713208,2009,2019,1997,2015,2018,2015), ncol = 3)
datos.de.peliculas
colnames(datos.de.peliculas) <- c("titulo","recaudacion","año")
datos.de.peliculas
titulo recaudacion año
[1,] "Avatar" "2810779794" "2009"
[2,] "Avengers: Endgame" "2797501328" "2019"
[3,] "Titanic" "2194439542" "1997"
[4,] "Star Wars: The Force Awakens" "2068223624" "2015"
[5,] "Avengers: Infinity War" "2048359754" "2018"
[6,] "Jurassic World" "1671713208" "2015"
Hasta ahora todo se ve relativamente bien… pero… si tratamos de calcular el promedio de recaudación de estas películas:
mean(datos.de.peliculas[,"recaudacion"])
Warning in mean.default(datos.de.peliculas[, "recaudacion"]): argument is not
numeric or logical: returning NA
[1] NA
R nos presenta un error, indicando que el argumento que le entregamos (los valores que tienen que ser promediados) no son valores numéricos. Esto puede parecer extraño, ya que claramente ingresamos números a nuestra matriz, pero podemos ver qué nos dice R respecto al tipo de datos que hay en esta matriz:
mode(datos.de.peliculas)
[1] "character"
Y vemos entonces el problema… ¡R indica que la matriz es de caracteres! Esto se debe a que, al igual que los vectores, una matriz solo puede albergar datos del mismo tipo. Como intentamos guardar datos de texto (los nombres de las películas) y datos numéricos (recaudación y años), R automáticamente convirtió todos los datos a texto. Esto es de hecho visible al ver la matriz, ya que todos los datos están entre comillas, lo que nos indica que son datos de texto:
datos.de.peliculas
titulo recaudacion año
[1,] "Avatar" "2810779794" "2009"
[2,] "Avengers: Endgame" "2797501328" "2019"
[3,] "Titanic" "2194439542" "1997"
[4,] "Star Wars: The Force Awakens" "2068223624" "2015"
[5,] "Avengers: Infinity War" "2048359754" "2018"
[6,] "Jurassic World" "1671713208" "2015"
Y esto nos lleva a nuestra nueva estructura de datos, los data frames, los cuales comparten las ventajas de las matrices pero que además permiten mezclar tipos de datos distintos en su interior. Los data frames son creados de una forma distinta a las matrices, definiendo cada columna por separado, usando vectores e inmediatamente asignando un nombre a la columna:
<- data.frame( titulo = c("Avatar","Avengers: Endgame","Titanic","Star Wars: The Force Awakens","Avengers: Infinity War","Jurassic World"), recaudacion = c(2810779794,2797501328,2194439542,2068223624,2048359754,1671713208), año = c(2009,2019,1997,2015,2018,2015))
datos.de.peliculas.df
datos.de.peliculas.df
titulo recaudacion año
1 Avatar 2810779794 2009
2 Avengers: Endgame 2797501328 2019
3 Titanic 2194439542 1997
4 Star Wars: The Force Awakens 2068223624 2015
5 Avengers: Infinity War 2048359754 2018
6 Jurassic World 1671713208 2015
Con nuestro nuevo data frame, podemos entonces intentar nuevamente el calcular el promedio de recaudación de estas películas:
# Usando coordenadas de posición
mean(datos.de.peliculas.df[,2])
[1] 2265169542
# Usando el nombre de la columna
# ATENCIÓN: Al usar nombres en data frames, estos tienen que estar en un vector
mean(datos.de.peliculas.df[,c("recaudacion")])
[1] 2265169542
Hay otra ventaja adicional en los data frames, a saber, estos permiten referirnos directamente a una columna usando su nombre mediante el uso de un signo peso $
de la siguiente manera:
# Ver las recaudaciones de las películas
$recaudacion datos.de.peliculas.df
[1] 2810779794 2797501328 2194439542 2068223624 2048359754 1671713208
# Calcular el promedio de las recaudaciones
mean(datos.de.peliculas.df$recaudacion)
[1] 2265169542
# Ver el año más antiguo de las películas
min(datos.de.peliculas.df$año)
[1] 1997
La capacidad de guardar datos de distintos tipos, sumado a la posibilidad de referirnos a los datos rápidamente usando los nombres de las columnas hacen de los data frames una de las estructuras más típicamente utilizadas para trabajar con datos en R.