Vectorización
Last updated on 2023-12-06 | Edit this page
Estimated time 25 minutes
Overview
Questions
- ¿Cómo puedo operar sobre todos los elementos de un vector a la vez?
Objectives
- Entender las operaciones vertorizadas en R.
La mayoría de las funciones en R están vectorizadas, lo que significa que la función operará sobre todos los elementos de un vector sin necesidad de hacer un bucle a través de cada elemento y actuar sobre cada uno de ellos. Esto hace la escritura de código más concisa, fácil de leer y menos propenso a errores.
R
x <- 1:4
x * 2
OUTPUT
[1] 2 4 6 8
La multiplicación se aplicó a cada elemento del vector.
También podemos sumar dos vectores juntos:
R
y <- 6:9
x + y
OUTPUT
[1] 7 9 11 13
Cada elemento de x
fue sumado a su correspondiente
elemento de y
:
R
: 1 2 3 4
x+ + + +
: 6 7 8 9
y---------------
7 9 11 13
Intenta esto en la columna pop
del
dataset gapminder
.
Haz una nueva columna en el data frame
gapminder
que contiene población en unidades de millones de
personas. Comprueba el principio o el final del data
frame para asegurar que funcionó.
R
gapminder$pop_millions <- gapminder$pop / 1e6
head(gapminder)
OUTPUT
country year pop continent lifeExp gdpPercap pop_millions
1 Afghanistan 1952 8425333 Asia 28.801 779.4453 8.425333
2 Afghanistan 1957 9240934 Asia 30.332 820.8530 9.240934
3 Afghanistan 1962 10267083 Asia 31.997 853.1007 10.267083
4 Afghanistan 1967 11537966 Asia 34.020 836.1971 11.537966
5 Afghanistan 1972 13079460 Asia 36.088 739.9811 13.079460
6 Afghanistan 1977 14880372 Asia 38.438 786.1134 14.880372
Recuerda tus habilidades de graficación al crear una gráfica con la población en millones en comparación con el año.
R
ggplot(gapminder, aes(x = year, y = pop_millions)) +
geom_point()

R
countryset <- c("China","India","Indonesia")
ggplot(gapminder[gapminder$country %in% countryset,],
aes(x = year, y = pop_millions)) +
geom_point()

Operadores de comparación, operadores lógicos y muchas otras funciones también están vectorizadas:
Operadores de Comparación
R
x > 2
OUTPUT
[1] FALSE FALSE TRUE TRUE
Operadores Lógicos
R
a <- x > 3 # o, para más claridad, a <- (x > 3)
a
OUTPUT
[1] FALSE FALSE FALSE TRUE
La mayoría de las funciones también operan elemento por elemento en los vectores:
Funciones
R
x <- 1:4
log(x)
OUTPUT
[1] 0.0000000 0.6931472 1.0986123 1.3862944
Operaciones vectorizadas en matrices:
R
m <- matrix(1:12, nrow=3, ncol=4)
m * -1
OUTPUT
[,1] [,2] [,3] [,4]
[1,] -1 -4 -7 -10
[2,] -2 -5 -8 -11
[3,] -3 -6 -9 -12
Sugerencia: multiplicación elemento por elemento vs. multiplicación de matriz
Muy importante: el operador*
te da una multiplicación de
elemento por elemento! Para hacer multiplicación de matrices, necesitás
usar el operador %*%
:
R
m %*% matrix(1, nrow=4, ncol=1)
OUTPUT
[,1]
[1,] 22
[2,] 26
[3,] 30
R
matrix(1:4, nrow=1) %*% matrix(1:4, ncol=1)
OUTPUT
[,1]
[1,] 30
Para saber más sobre Álgebra de matrices, ver Quick-R reference guide
Desafío 3
Dada la siguiente matriz:
R
m <- matrix(1:12, nrow=3, ncol=4)
m
OUTPUT
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
Escribe lo que crees que sucederá cuando se ejecute:
m ^ -1
m * c(1, 0, -1)
m > c(0, 20)
m * c(1, 0, -1, 2)
¿Obtuviste la salida que esperabas? Si no, pregunta a un ayudante!
Dada la siguiente matriz:
R
m <- matrix(1:12, nrow=3, ncol=4)
m
OUTPUT
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
Escribe lo que piensas que sucederá cuando ejecutes:
m ^ -1
OUTPUT
[,1] [,2] [,3] [,4]
[1,] 1.0000000 0.2500000 0.1428571 0.10000000
[2,] 0.5000000 0.2000000 0.1250000 0.09090909
[3,] 0.3333333 0.1666667 0.1111111 0.08333333
m * c(1, 0, -1)
OUTPUT
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 0 0 0 0
[3,] -3 -6 -9 -12
m > c(0, 20)
OUTPUT
[,1] [,2] [,3] [,4]
[1,] TRUE FALSE TRUE FALSE
[2,] FALSE TRUE FALSE TRUE
[3,] TRUE FALSE TRUE FALSE
Estamos interesados en encontrar la suma de la siguiente secuencia de fracciones:
R
x = 1/(1^2) + 1/(2^2) + 1/(3^2) + ... + 1/(n^2)
Esto sería tedioso de escribir, e imposible para valores altos de n. ¿Puedes usar vectorización para calcular x, cuando n=100? ¿Qué tal cuando n=10,000?
R
sum(1/(1:100)^2)
OUTPUT
[1] 1.634984
R
sum(1/(1:1e04)^2)
OUTPUT
[1] 1.644834
R
n <- 10000
sum(1/(1:n)^2)
OUTPUT
[1] 1.644834
Podemos obtener el mismo resultado usando una función:
R
inverse_sum_of_squares <- function(n) {
sum(1/(1:n)^2)
}
inverse_sum_of_squares(100)
OUTPUT
[1] 1.634984
R
inverse_sum_of_squares(10000)
OUTPUT
[1] 1.644834
R
n <- 10000
inverse_sum_of_squares(n)
OUTPUT
[1] 1.644834