c(1, 2, 3)
[1] 1 2 3
c("uno", "dos", "tres")
[1] "uno" "dos" "tres"
# Vector vacío
c()
NULL
# Vector con elementos perdidos
c(1, NA, 3)
[1] 1 NA 3
# Vector de números enteros consecutivos del 2 al 6
2:6
[1] 2 3 4 5 6
Los tipos estructurados de datos, a diferencia de los simples, son colecciones de datos con una determinada estructura. En R existen varios tipos tipos estructurados de datos que pueden clasificarse de acuerdo a su dimensión y a si son homogéneos (todos sus elementos son del mismo tipo) o heterogéneos.
Dimensiones | Homogéneos | Heterogéneos |
---|---|---|
1 | Vector | Lista |
2 | Matriz | Data frame |
n | Array |
Para averiguar la estructura de un dato estructurado se puede utilizar la función siguiente:
str(x)
: Devuelve una cadena de texto con la estructura de x
en un formato amigable para las personas.El vector es el tipo de dato estructurado más básicos en R. Un vector es una colección ordenada de elementos del mismo tipo.
Para construir un vector se utiliza la función de combinación c()
:
c(x1, x2, ...)
: Devuelve el vector formado por los elementos x1
, x2
, etc.También es posible utilizar el operador :
para generar un vector de números enteros consecutivos:
x:y
: Devuelve el vector de números enteros consecutivos desde x
hasta y
.Ejemplo 3.1
c(1, 2, 3)
[1] 1 2 3
c("uno", "dos", "tres")
[1] "uno" "dos" "tres"
# Vector vacío
c()
NULL
# Vector con elementos perdidos
c(1, NA, 3)
[1] 1 NA 3
# Vector de números enteros consecutivos del 2 al 6
2:6
[1] 2 3 4 5 6
Es posible asignar un nombre a cada elemento de un vector. Los nombres son etiquetas de texto que se asocian a cada elemento. Para asociar un nombre a un elemento se utiliza la sintaxis nombre = valor
, donde nombre
es una cadena de caracteres y valor
es el elemento del vector.
Ejemplo 3.2
c("Matemáticas" = 8.2, "Física" = 6.5, "Economía" = 4.5)
Matemáticas Física Economía
8.2 6.5 4.5
Para acceder a los nombres de un vector se utiliza la siguiente función:
names(x)
: Devuelve un vector de cadenas de caracteres con los nombres de los elementos del vector x
.Ejemplo 3.3
<- c("Matemáticas" = 8.2, "Física" = 6.5, "Economía" = 4.5)
notas names(notas)
[1] "Matemáticas" "Física" "Economía"
El número de elementos de un vector es su tamaño y puede averiguarse con la siguiente función.
lenght(x)
: Devuelve el número de elementos del vector x
.Ejemplo 3.4
length(c(1, 2, 3))
[1] 3
length(c())
[1] 0
Puesto que los elementos de un vector tienen que ser del mismo tipo, cuando se crea un vector con datos de distintos tipos, la función c()
los convertirá al mismo tipo, lo que se conoce como coerción de tipos. La coerción se produce de los tipos menos flexibles a los más flexibles: logical
< integer
< double
< character
.
Ejemplo 3.5
c(1, 2.5)
[1] 1.0 2.5
c(FALSE, TRUE, 2)
[1] 0 1 2
c(FALSE, TRUE, 2, "tres")
[1] "FALSE" "TRUE" "2" "tres"
Para acceder a los elementos de un vector se utiliza un índice. Como veremos a continuación, este índice puede ser entero, lógico o de cadena de caracteres y se indica siempre entre corchetes [ ]
a continuación del vector.
Los elementos de un vector están ordenados y el acceso más simple a ellos es mediante su número de orden, es decir, indicando entre corchetes [ ]
el entero que corresponde a su número de orden. Se puede acceder simultáneamente a varios elementos mediante un vector con sus números de orden.
En R los índices enteros para acceder a los elementos de un vector comienzan en 1, a diferencia de otros lenguajes de programación que empiezan en 0.
Ejemplo 3.6
<- c(2,4,6,8,10)
x # Acceso al elemento que está en la tercera posición
3] x[
[1] 6
# Acceso a los elementos de las posiciones 2 y 4
c(2, 4)] x[
[1] 4 8
# Acceso a los elementos de la posición 2 a la 4
2:4] x[
[1] 4 6 8
# Acceso a todos los elementos excepto el primero y el cuarto
c(-1, -4)] x[
[1] 4 6 10
Cuando se utiliza un índice lógico, se obtienen los elementos correspondientes a las posiciones donde está el valor booleano TRUE
.
Ejemplo 3.7
<- c(2,4,6,8,10)
x # Acceso al elemento que está en la tercera posición
c(F,F,T,F,F)] x[
[1] 6
# Acceso a los elementos de las posiciones 2 y 4
c(F,T,F,T,F)] x[
[1] 4 8
Esta forma de acceder es útil cuando se genera el vector de índices mediante operadores relacionales. Cuando se aplica un operador relacional a un vector se obtiene otro vector lógico que resulta de aplicar el operador relacional a cada uno de los elementos del vector. De esta manera se puede realizar filtros para obtener los elementos de un vector que cumplen una determinada condición.
Ejemplo 3.8
<- 1:6
x %% 2 == 0 x
[1] FALSE TRUE FALSE TRUE FALSE TRUE
# Filtrado de los valores pares
%% 2 == 0] x[x
[1] 2 4 6
# Filtrado de los valores pares menores que 5
%% 2 == 0 & x < 5] x[x
[1] 2 4
Si los elementos de un vector tienen nombre, es posible acceder a ellos usando sus nombres como índices.
Ejemplo 3.9
<- c("Matemáticas" = 8.2, "Física" = 6.5, "Economía" = 4.5)
notas "Física"] notas[
Física
6.5
c("Matemáticas", "Economía")] notas[
Matemáticas Economía
8.2 4.5
Para comprobar si un valor en particular es un elemento de un vector se puede utilizar el operador %in%
:
x %in% y
: Devuelve el booleano TRUE
si x
es un elemento del vector y
, y FALSE
en caso contrario.Ejemplo 3.10
<- 1:3
x 2 %in% x
[1] TRUE
4 %in% x
[1] FALSE
Para modificar uno o varios elementos de un vector basta con acceder a esos elementos y usar el operador de asignación para asignar nuevos valores.
v[i] <- x
: Asigna el dato x
a la posición i
del vector v
.v[c(i,j,...)] <- x
: Asigna el dato x
a las posiciones i
, j
, etc. del vector v
.Ejemplo 3.11
<- c(1, 2, 3)
x 2] <- 0
x[ x
[1] 1 0 3
c(1, 3)] <- 1
x[ x
[1] 1 0 1
Para añadir nuevos elementos a un vector pueden usarse las siguientes funciones:
c(x, y)
: Devuelve el vector que resulta de añadir al vector x
los elementos del vector y
.append(x, y, pos)
: Devuelve el vector que resulta de añadir al vector x
los elementos del vector y
, a continuación de la posición pos
. El parámetro pos
es opcional y si no se indica, los elementos de y
se añaden al final de los de x
.Ejemplo 3.12
<- c(1, 2, 3)
x c(x, c(4, 5))
[1] 1 2 3 4 5
append(x, c(4, 5), 2)
[1] 1 2 4 5 3
Para eliminar los elementos que ocupan una determinada posición se utiliza el operador de acceso, es decir, los corchetes [ ]
pero con los índices correspondientes a las posiciones a eliminar, en negativo.
Ejemplo 3.13
<- c("a", "b", "c", "d", "e")
x -3] x[
[1] "a" "b" "d" "e"
-c(2,4)] x[
[1] "a" "c" "e"
Para eliminar los elementos de un vector basta con asignar NULL
a la variable que lo contiene, pero si se quiere liberar la memoria que ocupa la variable se utiliza la función rm()
.
Para vectores numéricos las operaciones aritméticas habituales se aplican elemento a elemento. Si los vectores tienen distinto tamaño, el tamaño del vector más pequeño se equipara al tamaño del mayor, reutilizando sus elementos, empezando por el primero.
Ejemplo 3.14
<- c(1, 2, 3)
x <- c(0, 1, -1)
y + y x
[1] 1 3 2
* y x
[1] 0 2 -3
/ y x
[1] Inf 2 -3
^ y x
[1] 1.0000000 2.0000000 0.3333333
Para calcular el producto escalar de dos vectores numéricos se utiliza el operador %*%
. Si los vectores tienen distinto tamaño se produce un error.
Ejemplo 3.15
<- c(1, 2, 3)
x <- c(0, 1, -1)
y %*% y x
[,1]
[1,] -1
Un factor es una estructura de datos especial que se utiliza para representar categorías de variables cualitativas y por tanto puede tomar un conjunto finito de valores predefinidos conocido como niveles del factor.
Para definir un factor se utiliza la siguiente función:
factor(x, levels = niveles)
: Crea un dato de tipo factor con los elementos del vector x
. Los niveles del factor pueden indicarse mediante el parámetro levels
, pasándole un vector con los valores posibles. Si no se indica el parámetro levels
los niveles del factor se obtienen automáticamente a partir de los elementos del vector x
(tantos niveles con valores distintos tenga).Los factores son en realidad vectores de números enteros a los que se le añade un atributo especial para indicar los niveles del factor.
Ejemplo 3.16
<- factor(c("mujer", "hombre", "mujer"))
sexo sexo
[1] mujer hombre mujer
Levels: hombre mujer
class(sexo)
[1] "factor"
str(sexo)
Factor w/ 2 levels "hombre","mujer": 2 1 2
<- factor(c("B", "A", "A"), levels = c("A", "B", "AB", "0"), )
grupo.sanguineo grupo.sanguineo
[1] B A A
Levels: A B AB 0
Es posible establecer un orden entre los niveles de un factor añadiendo el parámetro ordered = TRUE
a la función anterior. Esto es útil para representar categorías ordinales entre las que existe un orden natural.
Ejemplo 3.17
<- factor(c("Secundarios", "Graduado", "Bachiller"), levels = c("Sin estudios", "Primarios", "Secundarios", "Bachiller", "Graduado"), ordered = TRUE)
nivel.estudio nivel.estudio
[1] Secundarios Graduado Bachiller
Levels: Sin estudios < Primarios < Secundarios < Bachiller < Graduado
Para comprobar si una estructura es del tipo factor se utiliza la siguiente función:
is.factor(x)
: Devuelve el booleano TRUE
si x
es del tipo factor, y FALSE
en caso contrario.Se puede acceder a los elementos de un factor de la misma manera que se accede a los elementos de un vector. Y para obtener sus niveles se utiliza la siguiente función:
levels(x)
: Devuelve un vector con los niveles del factor x
.Ejemplo 3.18
<- factor(c("mujer", "hombre", "mujer"))
sexo 2] sexo[
[1] hombre
Levels: hombre mujer
c(1, 2)] sexo[
[1] mujer hombre
Levels: hombre mujer
-2] sexo[
[1] mujer mujer
Levels: hombre mujer
levels(sexo)
[1] "hombre" "mujer"
Se puede modificar los elementos de un factor de manera similar a como se modifican los elementos de un vector, es decir accediendo al elemento que se quiere modificar y asignándole un nuevo valor. La única diferencia con los vectores es que si el nuevo valor que se quiere asignar no está entre los niveles del factor, se obtiene el valor NA
.
Ejemplo 3.19 A continuación se muestran varios de modificación de los elementos de un factor.
<- factor(c("B", "A", "A"), levels = c("A", "B", "AB", "0"))
grupo.sanguineo grupo.sanguineo
[1] B A A
Levels: A B AB 0
2] <- "AB"
grupo.sanguineo[ grupo.sanguineo
[1] B AB A
Levels: A B AB 0
1] <- "C" grupo.sanguineo[
Warning in `[<-.factor`(`*tmp*`, 1, value = "C"): invalid factor level, NA
generated
grupo.sanguineo
[1] <NA> AB A
Levels: A B AB 0
Obsérvese en el ejemplo anterior que cuando se intenta asignar un valor a un factor que no está entre sus niveles, se produce un error.
Las listas son colecciones ordenadas de elementos que pueden ser de distintos tipos. Los elementos de una lista también pueden ser de tipos estructurados (vectores o listas), lo que las convierte en el tipo de dato más versátil de R. Como veremos más adelante, otras estructuras de datos como los data frames o los propios modelos estadísticos se construyen usando listas.
Para construir una lista se utiliza la función list()
:
list(x1, x2, ...)
: Devuelve la lista con los elementos x1
, x2
, etc.Ejemplo 3.20
list(1, "dos", TRUE)
[[1]]
[1] 1
[[2]]
[1] "dos"
[[3]]
[1] TRUE
# Lista con vectores y listas
<- list(1, c("dos", "tres"), list(4, "cinco"))
x x
[[1]]
[1] 1
[[2]]
[1] "dos" "tres"
[[3]]
[[3]][[1]]
[1] 4
[[3]][[2]]
[1] "cinco"
str(x)
List of 3
$ : num 1
$ : chr [1:2] "dos" "tres"
$ :List of 2
..$ : num 4
..$ : chr "cinco"
# Lista vacía
list()
list()
Al igual que con los vectores, es posible asignar un nombre a cada uno de los elementos de una lista.
Ejemplo 3.21
list("nombre" = "María", "edad" = 21, "dirección" = list("calle" = "Delicias", "número" = 24, "municipio" = "Madrid"))
$nombre
[1] "María"
$edad
[1] 21
$dirección
$dirección$calle
[1] "Delicias"
$dirección$número
[1] 24
$dirección$municipio
[1] "Madrid"
Para obtener los nombres de una lista se utiliza la siguiente función:
names(x)
: Devuelve un vector de cadenas de caracteres con los nombres de los elementos de la lista x
.Ejemplo 3.22
<- list("nombre" = "María", "edad" = 21, "dirección" = list("calle" = "Delicias", "número" = 24, "municipio" = "Madrid"))
persona names(persona)
[1] "nombre" "edad" "dirección"
El número de elementos de una lista es su tamaño y puede averiguarse con la siguiente función:
lenght(x)
: Devuelve el número de elementos de la lista x
.Ejemplo 3.23
length(list(1, "dos", TRUE))
[1] 3
length(list(1, c("dos", "tres"), list(4, "cinco")))
[1] 3
length(list())
[1] 0
Se accede a los elementos de una lista de forma similar a los vectores, mediante índices enteros, lógicos o de cadena, entre corchetes [ ]
.
Al igual que los vectores, los elementos de una lista están ordenados y se puede utilizar un índice entero para acceder a los elementos que ocupan una determinada posición.
Ejemplo 3.24
<- list(1, "dos", TRUE, 4.5)
x # Acceso al elemento que está en la segunda posición
2] x[
[[1]]
[1] "dos"
# Acceso a los elementos de las posiciones 1 y 3
c(1, 3)] x[
[[1]]
[1] 1
[[2]]
[1] TRUE
# Acceso a todos los elementos excepto el primero y el cuarto
c(-1, -4)] x[
[[1]]
[1] "dos"
[[2]]
[1] TRUE
Cuando se utiliza un índice lógico, se obtienen los elementos correspondientes a las posiciones donde está el valor booleano TRUE
.
Ejemplo 3.25
<- list(1, "dos", TRUE, 4.5)
x c(T,F,F,T)] x[
[[1]]
[1] 1
[[2]]
[1] 4.5
< 2 x
Warning: NAs introducidos por coerción
[1] TRUE NA TRUE FALSE
# Filtrado de valores menores que 2
< 2] x[x
Warning: NAs introducidos por coerción
[[1]]
[1] 1
[[2]]
NULL
[[3]]
[1] TRUE
Obsérvese que para los elementos que no tiene sentido la comparación se obtiene NA
, y que el acceso mediante este índice devuelve NULL
.
Si los elementos de una lista tienen nombre, se puede acceder a ellos utilizando sus nombres como índices. La única diferencia con el acceso mediante cadenas de vectores es que se obtiene siempre una lista, incluso cuando sólo se quiere acceder a un elemento. Para obtener un elemento, y no una lista con ese único elemento, se utilizan dobles corchetes [[ ]]
.
Ejemplo 3.26
<- list("nombre" = "María", "edad" = 21, "dirección" = list("calle" = "Delicias", "número" = 24, "municipio" = "Madrid"))
persona c("edad", "nombre")] persona[
$edad
[1] 21
$nombre
[1] "María"
"nombre"] persona[
$nombre
[1] "María"
typeof(persona["nombre"])
[1] "list"
# Acceso a un único elemento
"nombre"]] persona[[
[1] "María"
# Acceso a una lista anidada
"dirección"]][["municipio"]] persona[[
[1] "Madrid"
Una alternativa a los dobles corchetes es el operador de acceso a listas $
. Este operador además permite utilizar coincidencias parciales en los nombres de los elementos para acceder a ellos.
<- list("nombre" = "María", "edad" = 21, "dirección" = list("calle" = "Delicias", "número" = 24, "municipio" = "Madrid"))
persona # Acceso a un único elemento
$nombre persona
[1] "María"
# Acceso mediante coincidencia parcial
$nom persona
[1] "María"
# Acceso a una lista anidada
$dirección$municipio persona
[1] "Madrid"
Para modificar uno o varios elementos de una lista basta con acceder a esos elementos y reasignarles valores con el operador de asignación.
Ejemplo 3.27
<- list("nombre" = "María", "edad" = 21)
persona $edad <- 22
persona persona
$nombre
[1] "María"
$edad
[1] 22
La forma más sencilla de añadir un elemento con nombre a una lista es indicando el nombre con el operador $
y asignándole un valor con el operador de asignación <-
:
x$nombre <- y
: Añade el elemento y
a la lista x
con el nombre nombre
.El nuevo elemento se añade siempre al final de la lista.
Para añadir elementos sin nombre o en una posición determinada se puede utilizar la función append()
:
append(x, y, pos)
: Devuelve la lista vector que resulta de añadir a x
los elementos de la lista y
, a continuación de la posición pos
. El parámetro pos
es opcional y si no se indica, los elementos de y
se añaden al final de los de x
.Ejemplo 3.28
<- list("nombre" = "María", "edad" = 21)
persona $email <- "maria@ceu.es"
persona persona
$nombre
[1] "María"
$edad
[1] 21
$email
[1] "maria@ceu.es"
append(persona, list("sexo" = "Mujer"), 2)
$nombre
[1] "María"
$edad
[1] 21
$sexo
[1] "Mujer"
$email
[1] "maria@ceu.es"
Es posible convertir una lista en un vector con la siguiente función:
unlist(x)
: Devuelve el vector que resulta de aplanar recursivamente la lista x
y convertir todos los elementos al mismo tipo mediante coerción de tipos.Ejemplo 3.29
<- list("nombre" = "María", "edad" = 21, "dirección" = list("calle" = "Delicias", "número" = 24, "municipio" = "Madrid"))
persona unlist(persona)
nombre edad dirección.calle dirección.número
"María" "21" "Delicias" "24"
dirección.municipio
"Madrid"
typeof(unlist(persona))
[1] "character"
Obsérvese que cuando se convierte una lista en un vector, los elementos de la lista se convierten al tipo más general mediante coerción.
Una matriz es una estructura de datos bidimensional de elementos del mismo tipo organizados en filas y columnas. Una matriz es similar a un vector pero contiene una atributo adicional con sus dimensiones (número de filas y número de columnas).
Para crear una matriz se utiliza la siguiente función:
matrix(x, nrow = m, ncol = n)
: Devuelve la matriz con los elementos del vector x
organizados en n
filas y m
columnas. Habitualmente basta con especificar el número de filas o el número de columnas.Ejemplo 3.30
matrix(1:6, nrow = 2, ncol = 3)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
matrix(1:6, nrow = 2)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
matrix(1:6, ncol = 3)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
# La matriz de 1 x 1
matrix()
[,1]
[1,] NA
Como se puede observar en el ejemplo anterior, los elementos se disponen por columnas, pero se pueden disponer los elementos por filas pasando el parámetro byrow = TRUE
a la función matrix
.
Ejemplo 3.31
matrix(1:6, nrow = 2)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
matrix(1:6, nrow = 2, byrow = TRUE)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
Es posible poner nombres a las filas y a las columnas de una matriz añadiendo el parámetro dimnames
y pasándole una lista de dos vectores de cadenas con los nombres de las filas y las columnas respectivamente.
Ejemplo 3.32
matrix(1:6, nrow = 2, ncol = 3, dimnames = list(c("fila1", "fila2"), c("columna1", "columna2", "columna3")))
columna1 columna2 columna3
fila1 1 3 5
fila2 2 4 6
Para obtener los nombres de las filas y las columnas de una matriz se utilizan las siguientes funciones:
rownames(x)
: Devuelve un vector de cadenas de caracteres con los nombres de las filas de la matriz x
.colnames(x)
: Devuelve un vector de cadenas de caracteres con los nombres de las columnas de la matriz x
.Ejemplo 3.33
<- matrix(1:6, nrow = 2, ncol = 3, dimnames = list(c("fila1", "fila2"), c("columna1", "columna2", "columna3")))
x rownames(x)
[1] "fila1" "fila2"
colnames(x)
[1] "columna1" "columna2" "columna3"
Para obtener el número de elementos y las dimensiones de una matriz se pueden utilizar las siguientes funciones:
length(x)
: Devuelve un entero con el número de elementos de la matriz x
.nrow(x)
: Devuelve un entero con el número de filas de la matriz x
.ncol(x)
: Devuelve un entero con el número de columnas de la matriz x
.dim(x)
: Devuelve un vector de dos enteros con el número de filas y el número de columnas de la matriz x
.Ejemplo 3.34
<- matrix(1:6, nrow = 2)
x length(x)
[1] 6
nrow(x)
[1] 2
ncol(x)
[1] 3
dim(x)
[1] 2 3
Usando esta última función se pueden modificar las dimensiones de una matriz asignando un vector de dos enteros con las nuevas dimensiones. Esto también permite crear una matriz a partir de un vector.
Ejemplo 3.35
<- 1:6
x dim(x) <- c(2, 3)
x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
dim(x) <- c(3, 2)
x
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
Para acceder a los elementos de una matriz se utilizan dos índices (uno para las filas y otro para las columnas), separados por comas y entre corchetes []
a continuación de la matriz. Al igual que para los vectores, los índices pueden ser enteros, lógicos o de cadenas de caracteres.
Para acceder a los elementos de una matriz mediante índices enteros se indica el número de fila y el número de columna del elemento entre corchetes:
x[i,j]
: Devuelve el elemento de la matriz x
que está en la fila i
y la columna j
.Se puede acceder a más de un elemento indicando un vector de enteros para las filas y otro para las columnas. De esta manera se obtiene una submatriz. Si no se indica la fila o la columna se obtienen todos los elementos de todas las filas o columnas. Al igual que para vectores, se pueden utilizar enteros negativos para descartar filas o columnas
Ejemplo 3.36
<- matrix(1:9, nrow = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
# Acceso al elemento de la segunda fila y tercera columna
2,3] x[
[1] 8
# Acceso a la submatriz de la primera y tercera filas, y tercera y segunda columnas
c(1, 3), c(3, 2)] x[
[,1] [,2]
[1,] 7 4
[2,] 9 6
# Acceso a la primera fila
1, ] x[
[1] 1 4 7
# Acceso a la segunda columna
2] x[,
[1] 4 5 6
# Acceso a la submatriz con todos los elementos salvo la tercera fila y la segunda columna
-3, -2] x[
[,1] [,2]
[1,] 1 7
[2,] 2 8
Cuando se utilizan índices lógicos, se obtienen los elementos correspondientes a las filas y columnas donde está el valor booleano TRUE
.
Ejemplo 3.37
<- matrix(1:9, nrow = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
# Acceso al elemento de la segunda fila y tercera columna
c(F, T, F), c(F, F, T)] x[
[1] 8
# Acceso a la submatriz de la primera y tercera filas, y segunda y tercera columnas
c(T, F, T), c(F, T, T)] x[
[,1] [,2]
[1,] 4 7
[2,] 6 9
# Acceso a la primera fila
c(T, F, F), ] x[
[1] 1 4 7
# Acceso a la segunda columna
c(F, T, F)] x[,
[1] 4 5 6
Si las filas y las columnas de una matriz tienen nombre, es posible acceder a sus elementos usando los nombres de las filas y columnas como índices.
Ejemplo 3.38
<- matrix(1:9, nrow = 3, dimnames = list(c("f1", "f2", "f3"), c("c1", "c2", "c3")))
x x
c1 c2 c3
f1 1 4 7
f2 2 5 8
f3 3 6 9
# Acceso al elemento de la segunda fila y tercera columna
"f2", "c3"] x[
[1] 8
# Acceso a la submatriz de la primera y tercera filas, y tercera y segunda columnas
c("f1", "f3"), c("c3", "c2")] x[
c3 c2
f1 7 4
f3 9 6
Finalmente, es posible combinar distintos tipos de índices (enteros, lógicos o de cadena) para indicar las filas y las columnas a las que acceder.
Para comprobar si un valor en particular es un elemento de una matriz se puede utilizar el operador %in%
:
x %in% y
: Devuelve el booleano TRUE
si x
es un elemento de la matriz y
, y FALSE
en caso contrario.Ejemplo 3.39
<- matrix(1:9, nrow = 3)
x 2 %in% x
[1] TRUE
-1 %in% x
[1] FALSE
Para modificar uno o varios elementos de una matriz basta con acceder a esos elementos y usar el operador de asignación para asignar nuevos valores.
Ejemplo 3.40
<- matrix(1:9, nrow = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
2,3] <- 0
x[ x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 0
[3,] 3 6 9
c(1, 3), 1:2] <- -1
x[ x
[,1] [,2] [,3]
[1,] -1 -1 7
[2,] 2 5 0
[3,] -1 -1 9
Para añadir nuevas filas o columnas a una matriz se utilizan las siguientes funciones:
rbind(x, y)
: Devuelve la matriz que resulta de añadir nuevas filas a la matriz x
con los elementos del vector y
.cbind(x, y)
: Devuelve la matriz que resulta de añadir nuevas columnas a la matriz x
con los elementos del vector y
.Ejemplo 3.41
<- matrix(1:6, nrow = 2)
x x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
# Añadir una nueva fila
rbind(x, c(7, 8, 9))
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[3,] 7 8 9
# Añadir una nueva columna
cbind(x, c(7, 8))
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
Obsérvese que si el número de elementos proporcionados en el vector es menor del necesario para completar la fila o columna, se reutilizan los elementos del vector empezando desde el principio.
Para trasponer una matriz se utiliza la función siguiente:
t(x)
: Devuelve la matriz traspuesta de la matriz x
.Ejemplo 3.42 A continuación se muestran un ejemplo de la trasposición de una matriz.
<- matrix(1:6, nrow=2)
x t(x)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
Para matrices numéricas las operaciones aritméticas habituales se aplican elemento a elemento. Si las dimensiones de las matrices son distintas se produce un error.
Ejemplo 3.43
<- matrix(1:6, nrow = 2)
x x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
<- matrix(c(0, 1, 0, -1, 0, 1), nrow = 2)
y y
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 -1 1
+ y x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 3 3 7
* y x
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 2 -4 6
/ y x
[,1] [,2] [,3]
[1,] Inf Inf Inf
[2,] 2 -4 6
^ y x
[,1] [,2] [,3]
[1,] 1 1.00 1
[2,] 2 0.25 6
Obsérvese en el ejemplo anterior que la división por 0 produce el valor Inf
que representa infinito.
Para multiplicar dos matrices numéricas se utiliza el operador %*%
.
Ejemplo 3.44
<- matrix(1:6, ncol = 3)
x <- matrix(1:6, nrow = 3)
y %*% y x
[,1] [,2]
[1,] 22 49
[2,] 28 64
%*% x y
[,1] [,2] [,3]
[1,] 9 19 29
[2,] 12 26 40
[3,] 15 33 51
Para poder multiplicar dos matrices deben tener dimensiones compatibles. Si el número de columnas de la primera matriz no es igual que el número de filas de la segunda se produce un error.
Para calcular el determinante de una matriz numérica cuadrada se utiliza la siguiente función:
det(x)
: Devuelve el determinante de la matriz x
. Si x
no es una matriz numérica cuadrada produce un error.Ejemplo 3.45
<- matrix(1:4, ncol = 2)
x det(x)
[1] -2
Para calcular la matriz inversa de una matriz numérica cuadrada se utiliza la siguiente función:
solve(x)
: Devuelve la matriz inversa de la matriz x
. Si x
no es una matriz numérica cuadrada produce un error. Si la matriz no es invertible por tener determinante nulo también se obtiene un error.Ejemplo 3.46
<- matrix(1:4, nrow = 2)
x solve(x)
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
# El producto de una matriz por su inversa es la matriz identidad.
%*% solve(x) x
[,1] [,2]
[1,] 1 0
[2,] 0 1
Para calcular los autovalores y los autovectores de una matriz numérica cuadrada se utiliza la siguiente función:
eigen(x)
: Devuelve una lista con los autovalores y los autovectores de la matriz x
. Para acceder a los autovalores se utiliza el nombre values
y para acceder a los autovectores se utiliza el nombre vectors
. Si x
no es una matriz numérica cuadrada produce un error.Ejemplo 3.47
<- matrix(1:4, nrow = 2)
x x
[,1] [,2]
[1,] 1 3
[2,] 2 4
# Autovalores
eigen(x)$values
[1] 5.3722813 -0.3722813
# Autovectores
eigen(x)$vectors
[,1] [,2]
[1,] -0.5657675 -0.9093767
[2,] -0.8245648 0.4159736
Un data frame es una estructura bidimensional cuyos elementos se organizan por filas y columnas de manera similar a una matriz. La principal diferencia con las matrices es que sus columnas están formadas por vectores, pero pueden tener tipos de datos distintos. Un data frame es un caso particular de lista formada por vectores del mismo tamaño con nombre.
Los data frames son las estructuras de datos más utilizadas en R para almacenar los datos en los análisis estadísticos.
Para crear un data frame se utiliza la siguiente función:
data.frame(nombrex = x, nombrey = y, ...)
: Devuelve el data frame con columnas los vectores x
, y
, etc. y nombres de columna nombrex
, nombrey
, etc.Ejemplo 3.48
<- data.frame(asignatura = c("Matemáticas", "Física", "Economía"), nota = c(8.5, 7, 4.5))
df df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 4.5
str(df)
'data.frame': 3 obs. of 2 variables:
$ asignatura: chr "Matemáticas" "Física" "Economía"
$ nota : num 8.5 7 4.5
# Data frame vacío
data.frame()
data frame with 0 columns and 0 rows
Para grandes conjuntos de datos es más común crear un data frame a partir de un fichero en formato csv mediante la siguiente función:
read.csv(f)
: Devuelve el data frame que se genera a partir de los datos del fichero csv f
. Cada fila del fichero csv se corresponde con una fila del data frame y por defecto utiliza la coma ,
parara separar los datos de las columnas y punto .
como separador de decimales de los datos numéricos. Los nombres de las columnas se obtienen automáticamente a partir de la primera fila del fichero.read.csv2(f)
: Funciona igual que la función anterior pero utiliza como separador de columnas el punto y coma ;
y como separador de decimales la coma ,
.Ejemplo 3.49
<- read.csv('https://raw.githubusercontent.com/asalber/manual-r/master/datos/colesterol.csv')
df df
nombre edad sexo peso altura colesterol
1 José Luis Martínez Izquierdo 18 H 85 1.79 182
2 Rosa Díaz Díaz 32 M 65 1.73 232
3 Javier García Sánchez 24 H NA 1.81 191
4 Carmen López Pinzón 35 M 65 1.70 200
5 Marisa López Collado 46 M 51 1.58 148
6 Antonio Ruiz Cruz 68 H 66 1.74 249
7 Antonio Fernández Ocaña 51 H 62 1.72 276
8 Pilar Martín González 22 M 60 1.66 NA
9 Pedro Gálvez Tenorio 35 H 90 1.94 241
10 Santiago Reillo Manzano 46 H 75 1.85 280
11 Macarena Álvarez Luna 53 M 55 1.62 262
12 José María de la Guía Sanz 58 H 78 1.87 198
13 Miguel Angel Cuadrado Gutiérrez 27 H 109 1.98 210
14 Carolina Rubio Moreno 20 M 61 1.77 194
Para convertir otras estructuras de datos en data frames, se utiliza la siguiente función:
as.data.frame(x)
: Devuelve el data frame que se obtiene a partir la estructura de datos x
a plicanco las siguientes reglas de coerción:
x
es un vector se obtiene un data frame con una sola columna.x
es una lista se obtiene un data frame con tantas columnas como elementos tenga la lista. Si los elementos de la lista tienen tamaños distintos se obtiene un error.x
es una matriz se obtiene un data frame con el mismo número de columnas y filas que la matriz.Puesto que un data frame es una lista, se puede acceder a sus elementos como se accede a los elementos de una lista utilizando índices. Con corchetes simples [ ]
se obtiene siempre un data frame, mientras que con corchetes dobles [[ ]]
o $
se obtiene un vector. Pero también se puede acceder a los elementos de un data frame como si fuese una matriz, indicando un par de índices para las filas y las columnas respectivamente.
Ejemplo 3.50
<- data.frame(asignatura = c("Matemáticas", "Física", "Economía"), nota = c(8.5, 7, 4.5))
df df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 4.5
# Acceso como lista
"asignatura"] df[
asignatura
1 Matemáticas
2 Física
3 Economía
$asignatura df
[1] "Matemáticas" "Física" "Economía"
# Acceso como matriz
2:3, "nota"] df[
[1] 7.0 4.5
$nota >= 5, ] df[df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
Obsérvese en el último ejemplo anterior cómo se pueden utilizar condiciones lógicas para filtrar un data frame.
Para acceder a las primeras o últimas filas de un data frame se pueden utilizar las siguientes funciones:
head(df, n)
: Devuelve un data frame con las n
primeras filas del data frame df
.
tail(df, n)
: Devuelve un data frame con las n
últimas filas del data frame df
.
Estas funciones son útiles para darse una idea del contenido de un data frame con muchas filas.
Ejemplo 3.51
<- data.frame(x = 1:26, y = letters) # letters es un vector predefinido con las letras del abecedario.
df head(df, 3)
x y
1 1 a
2 2 b
3 3 c
tail(df, 2)
x y
25 25 y
26 26 z
Para modificar uno o varios elementos de un data frame basta con acceder a esos elementos y usar el operador de asignación para asignar nuevos valores.
Ejemplo 3.52
<- data.frame(asignatura = c("Matemáticas", "Física", "Economía"), nota = c(8.5, 7, 4.5))
df df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 4.5
3, "nota"] <- 5
df[ df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 5.0
Para añadir nuevas filas o columnas a una data frame se utilizan las mismas funciones que para matrices:
rbind(df, x)
: Devuelve el data frame que resulta de añadir nuevas filas al data frame df
con los elementos de la lista x
.
cbind(df, nombrex = x)
: Devuelve el data frame que resulta de añadir nuevas columnas al data frame df
con los elementos del vector x
con nombre nombrex
.
Ejemplo 3.53
<- data.frame(asignatura = c("Matemáticas", "Física", "Economía"), nota = c(8.5, 7, 4.5))
df df
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 4.5
# Añadir una nueva fila
rbind(df, list("Programación" , 10))
asignatura nota
1 Matemáticas 8.5
2 Física 7.0
3 Economía 4.5
4 Programación 10.0
# Añadir una nueva columna
cbind(df, créditos = c(6, 4, 3))
asignatura nota créditos
1 Matemáticas 8.5 6
2 Física 7.0 4
3 Economía 4.5 3
Para eliminar una columna de un data frame basta con acceder a la columna y asignarle el valor NULL
, mientras que para eliminar una fila basta con acceder a la fila con índice negativo.
Ejemplo 3.54
<- data.frame(asignatura = c("Matemáticas", "Física", "Economía"), nota = c(8.5, 7, 4.5), créditos = c(6, 4, 3))
df df
asignatura nota créditos
1 Matemáticas 8.5 6
2 Física 7.0 4
3 Economía 4.5 3
# Eliminar una columna
$nota <- NULL
df df
asignatura créditos
1 Matemáticas 6
2 Física 4
3 Economía 3
# Eliminar una fila
-2, ] df[
asignatura créditos
1 Matemáticas 6
3 Economía 3
Ejercicio 3.1 La siguiente tabla recoge las notas de los alumnos de un curso con dos asignaturas.
Alumno | Sexo | Física | Química |
---|---|---|---|
Carlos | H | 6.7 | 8.1 |
María | M | 7.2 | 9.5 |
Carmen | M | 5.5 | 5 |
Pedro | H | 4.5 | |
Luis | H | 3.5 | 5 |
Sara | M | 6.2 | 4 |
Definir cuatro vectores con el nombre, el sexo y las notas de Física y Química.
<- c("Carlos", "María", "Carmen", "Pedro", "Luis", "Sara")
nombre <- c("H", "M", "M", "H", "H", "M")
sexo <- c(6.7, 7.2, 5.5, NA, 3.5, 6.2)
fisica <- c(8.1, 9.5, 5, 4.5, 5, 4) quimica
Convertir el sexo en un factor y mostrar sus niveles.
<- factor(sexo)
sexo levels(sexo)
[1] "H" "M"
Crear un nuevo vector con la nota media de Física y Química.
<- (fisica + quimica) / 2
media media
[1] 7.40 8.35 5.25 NA 4.25 5.10
Crear la variable booleana aprobado
que tenga el valor TRUE
si la media es mayor o igual que 5 y FALSE
en caso contrario.
<- media >= 5
aprobado aprobado
[1] TRUE TRUE TRUE NA FALSE TRUE
Aplicar un filtro al vector de nombres para quedarse con los nombres de los alumnos que han aprobado.
& !is.na(aprobado)] nombre[aprobado
[1] "Carlos" "María" "Carmen" "Sara"
Crear un data frame con el nombre, sexo y las notas de Física y Química.
<- data.frame(nombre, sexo, fisica, quimica)
df df
nombre sexo fisica quimica
1 Carlos H 6.7 8.1
2 María M 7.2 9.5
3 Carmen M 5.5 5.0
4 Pedro H NA 4.5
5 Luis H 3.5 5.0
6 Sara M 6.2 4.0
Añadir el vector con la media al data frame.
$media <- media
df df
nombre sexo fisica quimica media
1 Carlos H 6.7 8.1 7.40
2 María M 7.2 9.5 8.35
3 Carmen M 5.5 5.0 5.25
4 Pedro H NA 4.5 NA
5 Luis H 3.5 5.0 4.25
6 Sara M 6.2 4.0 5.10
Filtrar el data frame para quedarse con el nombre y la media de las mujeres que han aprobado.
== "M" & media >= 5, c("nombre", "media")] df[sexo
nombre media
2 María 8.35
3 Carmen 5.25
6 Sara 5.10