3.2 Vectores

R es un lenguaje basado en vectores. La estructura de almacenamiento de datos más básica es el vector. Un vector contiene elementos, que pueden ser números, textos, valores lógicos, y de cualquier clase atómica. No obstante, solamente puede almacenar elementos de una única clase atómica a la vez. Solo números, solo texto, solo valores lógicos.

3.2.1 Crear un vector

Para crear un vector, se utiliza la función c() donde especifíco los elementos directamente:

# Vector numérico
numeros <- c(1,2,3,4,5,6)
numeros
# [1] 1 2 3 4 5 6

Un operador de gran utilidad es : que permite crear rangos de números enteros.

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

Además de c(), existe la función vector() para crear vectores vacíos de una longitud y clase atómica determinado.

# Vector lógico de longitud (length) 10
vLog <- vector("logical", length=10)
vLog
#  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# Vector de caracteres de longitud (length) 15
vCha <- vector("character", length=15)
vCha
#  [1] "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""

# Vector de números de longitud (length) 20
vNum <- vector("numeric", length=20)
vNum
#  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

La razón para usar vector() es para crear un contenido vacío de una longitud determinada, el cual podremos ir llenando con los resultados de un loop. Nos adelantaremos un poco con el código un tanto más avanzado, pero verás el uso de esta función.

vNum <- vector("numeric", length=6)
vNum
# [1] 0 0 0 0 0 0

# Loop donde a una secuencia de números del 1 al 6
# se le multiplica a cada uno por 100
for (i in 1:6){
  vNum[i] <- i * 100
}

# Vector ya rellenado por el loop
vNum
# [1] 100 200 300 400 500 600

3.2.2 Vectores de secuencias y repeticiones

Existen formas especiales de crear vectores implica el uso de seq() para crear secuencias numéricas, o rep() para repetir de algún valor una determinada cantidad de veces.

Para crear una secuencia del 10 al 100 cada 5 elementos, se usa el argument by = dentro de seq()

seq(10, 100, by=5)
#  [1]  10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90  95 100

Para crear una secuencia del 36 números entre 10 y 100, se usa el argument length = dentro de seq()

seq(10, 100, length=36)
#  [1]  10.00  12.57  15.14  17.71  20.29  22.86  25.43  28.00  30.57  33.14  35.71
# [12]  38.29  40.86  43.43  46.00  48.57  51.14  53.71  56.29  58.86  61.43  64.00
# [23]  66.57  69.14  71.71  74.29  76.86  79.43  82.00  84.57  87.14  89.71  92.29
# [34]  94.86  97.43 100.00

Las repeticiones implica definir dos argumentos: lo que se repetirá, y la cantidad de veces. Para repetir el carácter América 10 veces, se usa:

rep("América", 10)
#  [1] "América" "América" "América" "América" "América" "América" "América" "América"
#  [9] "América" "América"

3.2.3 Funciones útiles para vectores

Resulta útil conocer algunas de las funciones básicas en R para trabajar con vector.

Tabla 3.1: Operaciones (símbolos) aritméticas en R
Función Descripción Ejmplo.de.uso
length() Reporta el número de elementos de un vector, o la cantidad de columnas de una base de datos. length(x) o length(iris)
max() Valor máximo de un conjunto de datos x. max(x)
mean() Promedio de un conjunto de datos x. mean(x)
median() Mediana de un conjunto de datos x. median(x)
min() Valor mínimo de un conjunto de datos x. min(x)
range() Valor mínimo y máximo de un conjunto de datos x. range(x)
sd() Desviación estándar de un conjunto de datos x. sd(x)
sum() Suma de todos los elementos numéricos de un conjunto de datos x. sum(x)
var() Varianza de un conjunto de datos x. var(x)
prod() Multiplica de todos los elementos numéricos de un conjunto de datos x. prod(x)
rep() Repite un vector una cantidad de veces definida. rep("Perú", 15)
seq() Calcula una secuencia de números al ofrecerle un inicio, un final y cada cuántos valores. seq(0, 10, 2)

3.2.4 Operaciones numéricas con vectores

Las operaciones matemáticas que involucran vectores se aplican con lo que se denomina element-wise, que se traduce como elemento a elemento.

vector2 <- 10:20
vector2 + 5
#  [1] 15 16 17 18 19 20 21 22 23 24 25

En la operación anterior, se le sumó 5 unidades a cada elemento de vector2. Si se operan dos vectores de igual longitud, los elementos del primer vector se van operando uno por uno contra el elemento correspondiente en la posición homóloga del segundo vector.

vector3 <- 0:10
vector2 * vector3
#  [1]   0  11  24  39  56  75  96 119 144 171 200

Si se operan dos vectores de diferente longitud de elementos, el resultado tendrá la longitud del mayor, y el menor se irá operando elemento a elemento, y se recliclará desde su primer elemento para aplicarse hasta culminar de operar todo.

vector4 <- 1:3

# Revisar el contenido de los vectores
vector2
#  [1] 10 11 12 13 14 15 16 17 18 19 20
vector4
# [1] 1 2 3

# Producto de dos vectores de longitud desigual
vector2 * vector4
# Warning in vector2 * vector4: longitud de objeto mayor no es múltiplo de la longitud
# de uno menor
#  [1] 10 22 36 13 28 45 16 34 54 19 40

3.2.5 Valores perdidos en vectores

Estos elementos son los tipicos NA que aparecen cuando no hay un dato disponible en un conjunto de datos. Si operamos un vector con funciones estadísticas, como mean() o sd(), el resultado se verá afectado por la presencia del NA, y este impedirá que se genere el resultado correcto. Para evitarlo, es importante incorporar el argumento na.rm = TRUE para remover los NA de un conjunto de datos y operar sin ellos.

vectorNA <- c(10, 20, NA, 40, 50)

# Operar directo (errado)
mean(vectorNA)
# [1] NA

# Operar incluyendo el argumento para remover NAs
mean(vectorNA, na.rm = TRUE)
# [1] 30

3.2.6 Indexación de vectores

Indexar significa ubicar posiciones. Cada elemento dentro del vector tiene una posición única. Se puede extraer el contenido de una posición única definida dentro de un vector utilizando el operador []. Utilicemos el objeto vectorNA creado en la sección anterior:

vectorNA[1]
# [1] 10

vectorNA[3]
# [1] NA

vectorNA[5]
# [1] 50

Para extraer más de un elemento a la vez, en lugar de colocar una sola posición dentro de [], se coloca un vector con las posiciones.

vectorNA[c(1,3)]
# [1] 10 NA

vectorNA[c(1,3,5)]
# [1] 10 NA 50

Otro modo es crear un vector de índice, index, que contenga las posiciones de interés:

index <- c(1,3,5)
vectorNA[index]
# [1] 10 NA 50

Indexar con operaciones lógicas también es posible. El operador [] puede recibir vectores lógicos, para entregar como resultado aquellos elementos cuyas posiciones sean TRUE dentro del vector lógico. Si se define una operación lógica como ¿Qué elementos de un vector numérico x son valores mayores iguales a 25?, se debe escribir en R: x>=25.

# Veamos el resultado para entender la operación lógica
# (nota que los elemento NA no se convierten a TRUE o FALSE)
vectorNA>=25
# [1] FALSE FALSE    NA  TRUE  TRUE

Conociendo esto, el resultado de la indexación sería:

# En dos pasos
index <- vectorNA>=25
vectorNA[index]
# [1] NA 40 50

# En un paso
vectorNA[vectorNA>=25]
# [1] NA 40 50

En caso se requiera conocer en qué posiciones se cumple la condición lógica anterior, usa la función which():

which(vectorNA>=25)
# [1] 4 5

Dado que which() solo reporta posiciones TRUE y obvia las posiciones con NA, usarlo en la indexación es la mejor manera de reportar los elementos sin incluir en el resultado los valores NA:

vectorNA[which(vectorNA>=25)]
# [1] 40 50

3.2.7 Muestreo de vectores

En ocasiones es requerido realizar muestreos virtuales, en la que se especifique cuántos elementos se requieren extraer de un vector. En R, la extracción se realiza con la función sample(), como:

  • Muestreo con reemplazamiento: donde cada elemento extraído se devuelve al conjunto inicial. Este elemento ya muestreado permanecer disponible para aparecer en siguiente muestreo aleatorio. Se especifica con el argumento replace = TRUE.

  • Muestreo sin reemplazamiento: donde cada elemento extraído no vuelve a aparecer en el conjunto inicial. Este elemento ya muestreado no estará disponible para aparecer en siguiente muestreo aleatorio. Se especifica con el argumento replace = FALSE.

Si el muestreo es sin reemplazamiento, solo se puede extraer un máximo de elementos igual a la cantidad de elementos del conjunto inicial.

Antes de cualquier función de aleatorización, es importante establecer un conjunto de números aleatorios para que el código sea replicable. Asegurar replicabilidad de los experimentos y análisis es importante para las publicaciones científicas. Utiliza la función set.seed(123) definiendo un número cualquiera, como aquí se colocó 123.
# Muestreo con reemplazamiento
# de un conjunto de 2 elementos
conjuntoInicial <- c("A","Z")

set.seed(123)
sample(conjuntoInicial, 25, replace = TRUE)
#  [1] "A" "A" "A" "Z" "A" "Z" "Z" "Z" "A" "A" "Z" "Z" "Z" "A" "Z" "A" "Z" "A" "A" "A"
# [21] "A" "Z" "A" "A" "A"

# Muestreo sin reemplazamiento
# de un conjunto con 30 elementos
conjuntoInicial2 <- rep(c("A","Z"), c(10,20))

set.seed(321)
sample(conjuntoInicial2, 25, replace = FALSE)
#  [1] "Z" "Z" "Z" "Z" "Z" "Z" "Z" "A" "Z" "Z" "Z" "Z" "A" "A" "Z" "Z" "Z" "Z" "A" "Z"
# [21] "Z" "A" "Z" "A" "A"