Manipular vectores

Author

Alejandro

Introducción

Existen diferentes formas de lidiar con vectores, como asignarles nombres, extraer entradas individuales o extraer sub-vectores. Dominar estas técnicas permite realizar operaciones complejas de una manera que muy pocos lenguajes pueden igualar. La creación de subconjuntos de un vector en R es fácil de aprender y tiene una sintaxis clara.

Se trabajará con los siguientes vectores:

estaturas <- c(1.49, 1.68, 1.56, 1.74)
sabores <- c("fresa", "chocolate", "vainilla", "chocolate blanco", "menta")

Con la función length() se puede conocer cuántas entradas tiene un vector:

length(estaturas)
[1] 4
length(sabores)
[1] 5

Nombrar vectores

Existe 3 formas de nombrar un vector:

  1. Nombrar cada entrada cuando se crea el vector.

    Al definir el vector se utiliza la notación `nombre = valor`

    estaciones <- c("primavera" = 1, "verano" = 2, "otoño" = 3, "invierno" = 4)
    estaciones
    primavera    verano     otoño  invierno 
            1         2         3         4 

    Nota: como los nombres son muy largos, la definición del vector puede ser poco legible y entonces sería buena idea separar cada entrada por un salto de línea (es decir, escribir cada una en un renglón independiente):

    estaciones <- c("primavera" = 1, 
                    "verano" = 2, 
                    "otoño" = 3,
                    "invierno" = 4
                    )
    estaciones
    primavera    verano     otoño  invierno 
            1         2         3         4 
  2. Asignar los nombres tras crear al vector.

    Esta es la forma más común de asignar nombres. Todos los vectores tienen un atributo de nombres al que se puede acceder aplicando la función names(). Por defecto el valor de este atributo es nulo (NULL):

    names(estaturas)
    NULL

    Para asignar los nombres se debe crear un vector con los nombres deseados que tenga la misma longitud que el vector que se quiere nombrar. Entonces se asigna este nuevo vector al atributo de nombres:

    personas <- c("Andrea", "Zenón", "Yuri", "Jonathan")
    names(estaturas) <- personas
    names(estaturas)
    [1] "Andrea"   "Zenón"    "Yuri"     "Jonathan"

    De este modo el vector ahora tiene los nombres asignados:

    estaturas
      Andrea    Zenón     Yuri Jonathan 
        1.49     1.68     1.56     1.74 
  3. Crear un nuevo vector con nombres a partir del original.

    Este es el método menos común, se utiliza cuando se quiere mantener el vector original sin nombres y crear una copia que posea los nombres deseados. Se utiliza la función setNames con dos argumentos:

    1. El vector que se quiere nombrar.

    2. El vector con los nombres

    El resultado se guarda en un nuevo vector:

    estaturas_nombradas <- setNames(estaturas, personas)
    estaturas_nombradas
      Andrea    Zenón     Yuri Jonathan 
        1.49     1.68     1.56     1.74 

Quitar nombres

Para quitar los nombres de un vector existe dos métodos:

  1. Se asigna de nuevo el valor NULL al atributo de nombres:

    names(estaturas) <- NULL
    estaturas
    [1] 1.49 1.68 1.56 1.74
  2. Se aplica la función unname() y se guarda el resultado en una nueva variable:

    sin_nombres <- unname(estaturas_nombradas)
    sin_nombres
    [1] 1.49 1.68 1.56 1.74

    Claro que si se desea reemplazar el vector con nombres por el mismo vector pero sin nombres simplemente se usa:

    estaturas_nombradas <- unname(estaturas_nombradas)
    estaturas_nombradas
    [1] 1.49 1.68 1.56 1.74

Formas de extraer subconjuntos de vectores

Para extraer subconjuntos de un vector x se utiliza la notación x[y] donde y es un vector que contiene la información sobre las entradas que se quiere extraer. Existe 6 formas de extraer subconjuntos de vectores.

Enteros positivos

El vector y contiene las posiciones de las entradas que se desea obtener. Es decir, si se desea la primera y la cuarta entrada del vector x, entonces y = c(1, 4).

y <- c(1, 4)
sabores[y]
[1] "fresa"            "chocolate blanco"
# el vector `y` puede usarse directamente sin tener que guardarlo previamente
sabores[c(2, 3)]
[1] "chocolate" "vainilla" 

Un caso particular es cuando solo se desea una entrada del vector, pues en tal caso en lugar de usar un vector de longitud 1, se podría simplemente usar el número de la posición buscada, es decir, x[c(2)] es lo mismo que x[2].

sabores[c(4)]
[1] "chocolate blanco"
sabores[4]
[1] "chocolate blanco"

Enteros negativos

Si las entradas del vector y son enteros negativos, entonces se excluyen dichas posiciones. Por ejemplo, x[c(-1, -2)] extrae todas las entradas salvo las dos primeras.

sabores[c(-1, -2)]
[1] "vainilla"         "chocolate blanco" "menta"           

No hace falta poner el signo - en cada entrada de y, pues basta crear un vector con entradas positivas y poner un signo - antes de él (porque entonces todas las entradas se multiplican por -1):

-c(1,2)
[1] -1 -2
sabores[-c(1, 2)]
[1] "vainilla"         "chocolate blanco" "menta"           

Vectores lógicos

Los valores lógicos son TRUE y FALSE, los cuales se pueden pensar como “prendido” y “apagado”, respectivamente. Surgen cuando se usan pruebas lógicas:

4 < 5
[1] TRUE
0 < -2
[1] FALSE

Los vectores lógicos son vectores cuyas entradas son valores lógicos, por ejemplo c(TRUE, FALSE, TRUE).

Para usar un vector lógico y para extraer entradas de x, dicho vector y debe tener la misma longitud que x y entonces solo se extraerá las entradas de x cuya posición es TRUE en y. Por tanto los valores TRUE señalan las entradas que se conservan, mientras que los valores FALSE indican las entradas que se eliminan. Por ejemplo, x[c(FALSE; TRUE, TRUE, FALSE)] extrae las entradas 2 y 3.

sabores[c(TRUE, FALSE, FALSE, TRUE, FALSE)]
[1] "fresa"            "chocolate blanco"

Como R está vectorizado, aplicar una prueba lógica en un vector es equivalente a aplicar la prueba en cada entrada y formar un vector lógico con los resultados correspondientes.

estaturas < 1.50
[1]  TRUE FALSE FALSE FALSE

Aquí surge la importancia de los vectores lógicos: se puede extraer las entradas de x que satisfacen cierta condición lógica. En el vector de estaruras supongamos que quisieramos extraer las entradas cuyo valor es superior a 1.65. Comenzamos creando el vector con las pruebas lógicas:

y <- estaturas > 1.65
y
[1] FALSE  TRUE FALSE  TRUE

Entonces, usamos a y para extraer entradas de estaturas: es decir, extraemos las entradas de x cuyo valor es mayor que 1.65:

estaturas[y]
[1] 1.68 1.74

De manera compacta:

estaturas[estaturas > 1.65]
[1] 1.68 1.74

Vectores de nombres

Una de las principales ventajas de los vectores con nombres es que podemos usar dichos nombres para extraer las entradas correspondientes de los vectores.

names(estaturas) <- personas

En este caso y es un vector con nombres y cuando se usa para extraer conjuntos, se extrae las entradas cuyos nombres están en y

y <- c("Andrea", "Zenón")
estaturas[y]
Andrea  Zenón 
  1.49   1.68 
estaturas[c("Yuri", "Jonathan")]
    Yuri Jonathan 
    1.56     1.74 

Aprender más

La mejor referencia es el libro avanzado R avanzado de Hadley Wickham. El capítulo relevante es el número 4, para entenderlo completamente se requiere conocer los 3 anteriores, los cuales no son sencillos y se pueden estudiar cuando se haya desarrollado cierta soltura con el lenguaje.