Algunos conceptos básicos

Introducción

Las recetas de este capítulo se encuentran en algún punto entre ideas para la resolución de problemas y tutoriales. Sí, resuelven problemas comunes, pero las Soluciones muestran técnicas y modismos comunes utilizados en la mayoría del código R, incluido el código de este libro de recetas. Si es nuevo en R, le sugerimos que lea este capítulo para familiarizarse con estos modismos.

2.1 Imprimir algo en la pantalla

Problema

Quiere mostrar el valor de una variable o expresión.

Solucion

Si simplemente ingresa el nombre de la variable o la expresión en el símbolo del sistema, R imprimirá su valor. Utilice la función de impresión para la impresión genérica de cualquier objeto. Utilice la función cat para producir resultados con formato personalizado.

Discusión

Es muy fácil pedirle a R que imprima algo: simplemente ingréselo en el símbolo del sistema:

pi
## [1] 3.141593
#> [1] 3.14
sqrt(2)
## [1] 1.414214
#> [1] 1.41

Cuando ingresa expresiones como esa, R evalúa la expresión y luego llama implícitamente a la print función. Entonces el ejemplo anterior es idéntico a este:

print(pi) 
## [1] 3.141593
#>  [1] 3.14
print(sqrt(2)) 
## [1] 1.414214
#> [1] 1.41

Lo bueno print es que sabe cómo formatear cualquier valor R para imprimir, incluidos valores estructurados como matrices y listas:

print(matrix(c(1, 2, 3, 4), 2, 2))
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
#>      [,1] [,2]
#> [1,]    1    3
#> [2,]    2    4
print(list("a", "b", "c"))
## [[1]]
## [1] "a"
## 
## [[2]]
## [1] "b"
## 
## [[3]]
## [1] "c"
#> [[1]]
#> [1] "a"
#> 
#> [[2]]
#> [1] "b"
#> 
#> [[3]]
#> [1] "c"

Esto es útil porque siempre puedes ver tus datos: solo print eso. No es necesario escribir una lógica de impresión especial, ni siquiera para estructuras de datos complicadas.

Sin embargo, la print función tiene una limitación importante: imprime sólo un objeto a la vez. Al intentar printvarios elementos aparece este mensaje de error alucinante:

print(“The zero occurs at”, 2 * pi, “radians.”) #> Error in print.default(“The zero occurs at”, 2 * pi, “radians.”): invalid ‘quote’ argument

La única forma de obtener print varios elementos es imprimirlos uno a la vez, lo que probablemente no sea lo que desea:

print("The zero occurs at")
## [1] "The zero occurs at"
#> [1] "The zero occurs at"
print(2 * pi)
## [1] 6.283185
#> [1] 6.28
print("radians")
## [1] "radians"
#> [1] "radians"

La cat función es una alternativa print que le permite concatenar varios elementos en una salida continua:

cat("The zero occurs at", 2 * pi, "radians.")
## The zero occurs at 6.283185 radians.
#> The zero occurs at 6.28 radians.

Observe que cat coloca un espacio entre cada elemento de forma predeterminada. Debe proporcionar un carácter de nueva línea para terminar la línea.

La cat función también puede imprimir vectores simples:

fib <- c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
cat("The first few Fibonacci numbers are:", fib)
## The first few Fibonacci numbers are: 0 1 1 2 3 5 8 13 21 34
#> The first few Fibonacci numbers are: 0 1 1 2 3 5 8 13 21 34 ...

El uso cat le brinda más control sobre su salida, lo que lo hace especialmente útil en scripts R que generan salida consumida por otros. Sin embargo, una limitación importante es que no puede imprimir estructuras de datos compuestas como matrices y listas. Intentar hacerlo cat sólo produce otro mensaje adormecedor:

cat(list(“a”, “b”, “c”)) #> Error in cat(list(“a”, “b”, “c”)): argument 1 (type ‘list’) cannot be handled by ‘cat’

Ver también

Consulte la Receta 4.2 , “Impresión de menos dígitos” , para controlar el formato de salida.

2.2 Configuración de variables

Problema

Quiere guardar un valor en una variable.

Solución

Utilice el operador de asignación ( <-). No es necesario declarar su variable primero:

x <- 3

Discusión

Usar R en “modo calculadora” envejece bastante rápido. Pronto querrás definir variables y guardar valores en ellas. Esto reduce la escritura, ahorra tiempo y aclara su trabajo.

No es necesario declarar ni crear variables explícitamente en R. Simplemente asigne un valor al nombre y R creará la variable:

x <- 3
y <- 4
z <- sqrt(x^2 + y^2)
print(z)
## [1] 5
#> [1] 5

Observe que el operador de asignación se forma a partir de un carácter menor que ( <) y un guión ( -) sin espacios entre ellos.

Cuando define una variable en el símbolo del sistema como este, la variable se mantiene en su espacio de trabajo. El espacio de trabajo se guarda en la memoria principal de la computadora, pero se puede guardar en el disco. La definición de variable permanece en el espacio de trabajo hasta que la elimine.

R es un lenguaje de tipo dinámico , lo que significa que podemos cambiar el tipo de datos de una variable a voluntad. Podríamos configurarlo xpara que sea numérico, como se acaba de mostrar, y luego dar la vuelta y sobrescribirlo inmediatamente con (digamos) un vector de cadenas de caracteres. R no se quejará:

x <- 3
print(x)
## [1] 3
#> [1] 3

x <- c("fee", "fie", "foe", "fum")
print(x)
## [1] "fee" "fie" "foe" "fum"
#> [1] "fee" "fie" "foe" "fum"

En algunas funciones de R verá declaraciones de asignación que utilizan el operador de asignación de aspecto extraño <<-:

x <<- 3

Eso fuerza la asignación a una variable global en lugar de a una variable local. Sin embargo, el alcance está un poco fuera del alcance de esta discusión.

Con el espíritu de divulgación completa, revelaremos que R también admite otras dos formas de declaraciones de asignación. Se puede utilizar un solo signo igual ( =) como operador de asignación. ->Se puede usar un operador de asignación hacia la derecha ( ) en cualquier lugar donde <-se pueda usar el operador de asignación hacia la izquierda ( ) (pero con los argumentos invertidos):

foo <- 3
print(foo)
## [1] 3
#> [1] 3
5 -> fum
print(fum)
## [1] 5
#> [1] 5

Le recomendamos que los evite también. La asignación del signo igual se confunde fácilmente con la prueba de igualdad. La asignación hacia la derecha puede resultar útil en determinados contextos, pero puede resultar confusa para quienes no están acostumbrados a verla.

Ver también

Consulte la Receta 2.4 , “Eliminar variables” , 2.14 , “Evitar algunos errores comunes” y 3.3 , “Guardar su espacio de trabajo” . Consulte también la página de ayuda de la assign función.

2.3 Listado de variables

Problema

Quiere saber qué variables y funciones están definidas en su espacio de trabajo.

Solución

Utilice la ls función. Úselo ls.str para obtener más detalles sobre cada variable. También puede ver sus variables y funciones en el panel Entorno de RStudio, como se muestra en la Figura 2.1 .

Discusión

La ls función muestra los nombres de los objetos en su espacio de trabajo:

x <- 10
y <- 50
z <- c("three", "blind", "mice")
f <- function(n, p) sqrt(p * (1 - p) / n)
ls()
## [1] "f"   "fib" "foo" "fum" "x"   "y"   "z"
#> [1] "f" "x" "y" "z"

Observe que ls devuelve un vector de cadenas de caracteres en el que cada cadena es el nombre de una variable o función. Cuando su espacio de trabajo está vacío, ls devuelve un vector vacío, lo que produce este resultado desconcertante:

ls()
## [1] "f"   "fib" "foo" "fum" "x"   "y"   "z"
#> character(0)

Esa es la curiosa forma que tiene R de decir que ls devolvió un vector de cadenas de longitud cero; es decir, devolvió un vector vacío porque no hay nada definido en su espacio de trabajo.

Si desea algo más que una lista de nombres, intente ls.str; esto también te dirá algo sobre cada variable:

x <- 10
y <- 50
z <- c("three", "blind", "mice")
f <- function(n, p) sqrt(p * (1 - p) / n)
ls.str()
## f : function (n, p)  
## fib :  num [1:10] 0 1 1 2 3 5 8 13 21 34
## foo :  num 3
## fum :  num 5
## x :  num 10
## y :  num 50
## z :  chr [1:3] "three" "blind" "mice"
#> f : function (n, p)  
#> x :  num 10
#> y :  num 50
#> z :  chr [1:3] "three" "blind" "mice"

La función se llama ls.str porque enumera sus variables y str les aplica la función, mostrando su estructura (consulte Receta ( ??? ) (recipe-id202), “Revelando la estructura de un objeto” ).

Normalmente, ls no devuelve ningún nombre que comience con un punto ( .). Estos nombres se consideran ocultos y normalmente no interesan a los usuarios. (Esto refleja la convención de Unix de no enumerar archivos cuyos nombres comiencen con un punto). Puede forzar ls la lista de todo estableciendo el all.names argumento en TRUE:

ls()
## [1] "f"   "fib" "foo" "fum" "x"   "y"   "z"
#> [1] "f" "x" "y" "z"
ls(all.names = TRUE)
## [1] "f"   "fib" "foo" "fum" "x"   "y"   "z"
#> [1] ".Random.seed" "f"            "x"            "y"           
#> [5] "z"

El panel Entorno de RStudio también oculta objetos con nombres que comienzan con un punto.

Ver también

Consulte la Receta 2.4 , “Eliminar variables” , para eliminar variables y la Receta 12.13 , “Revelar la estructura de un objeto” , para inspeccionar sus variables.

2.4 Eliminar variables

Problema

Quiere eliminar variables o funciones innecesarias de su espacio de trabajo o borrar su contenido por completo.

Solución

Utilice la rm función.

Discusión

Su espacio de trabajo puede verse abarrotado rápidamente. La rm función elimina, de forma permanente, uno o más objetos del espacio de trabajo:

x <- 2 * pi
x
## [1] 6.283185
#> [1] 6.28

rm(x) x #> Error in eval(expr, envir, enclos): object ‘x’ not found

No hay “deshacer”; una vez que la variable desaparece, desaparece.

Puedes eliminar varias variables a la vez:

rm(x, y, z)

Incluso puedes borrar todo tu espacio de trabajo a la vez. La rm función tiene un list argumento que consta de un vector de nombres de variables a eliminar. Recuerde que la ls función devuelve un vector de nombres de variables; por lo tanto, puedes combinar rm y ls borrar todo:

ls()
## [1] "f"   "fib" "foo" "fum"
#> [1] "f" "x" "y" "z"
rm(list = ls())
ls()
## character(0)
#> character(0)

Alternativamente, puede hacer clic en el ícono de la escoba en la parte superior del panel Entorno en RStudio, como se muestra en la Figura 2.1 .

Panel de entorno en RStudio
Panel de entorno en RStudio

Nunca incluyas rm(list=ls()) código que compartas con otros, como una función de biblioteca o un código de muestra enviado a una lista de correo o Stack Overflow. Eliminar todas las variables en el espacio de trabajo de otra persona es peor que de mala educación y te hará extremadamente impopular.

Ver también

Consulte la Receta 2.3 , “Listado de variables” .

2,5 Creando un vector

Problema

Quieres crear un vector

Solución

Utilice el c(…)operador para construir un vector a partir de valores dados.

Discusión

Los vectores son un componente central de R, no simplemente otra estructura de datos. Un vector puede contener números, cadenas o valores lógicos, pero no una mezcla.

El c(…) operador puede construir un vector a partir de elementos simples:

c(1, 1, 2, 3, 5, 8, 13, 21)
## [1]  1  1  2  3  5  8 13 21
#> [1]  1  1  2  3  5  8 13 21
c(1 * pi, 2 * pi, 3 * pi, 4 * pi)
## [1]  3.141593  6.283185  9.424778 12.566371
#> [1]  3.14  6.28  9.42 12.57
c("My", "twitter", "handle", "is", "@cmastication")
## [1] "My"            "twitter"       "handle"        "is"           
## [5] "@cmastication"
#> [1] "My"            "twitter"       "handle"        "is"           
#> [5] "@cmastication"
c(TRUE, TRUE, FALSE, TRUE)
## [1]  TRUE  TRUE FALSE  TRUE
#> [1]  TRUE  TRUE FALSE  TRUE

Si los argumentos de c(…) son vectores, los aplana y los combina en un solo vector:

v1 <- c(1, 2, 3)
v2 <- c(4, 5, 6)
c(v1, v2)
## [1] 1 2 3 4 5 6
#> [1] 1 2 3 4 5 6

Los vectores no pueden contener una combinación de tipos de datos, como números y cadenas. Si crea un vector a partir de elementos mixtos, R intentará adaptarse convirtiendo uno de ellos:

v1 <- c(1, 2, 3)
v3 <- c("A", "B", "C")
c(v1, v3)
## [1] "1" "2" "3" "A" "B" "C"
#> [1] "1" "2" "3" "A" "B" "C"

Aquí, el usuario intentó crear un vector a partir de números y cadenas. R convirtió todos los números en cadenas antes de crear el vector, haciendo así compatibles los elementos de datos. Tenga en cuenta que R hace esto sin previo aviso ni queja.

Técnicamente hablando, dos elementos de datos pueden coexistir en un vector sólo si tienen el mismo modo. Las modas de 3.1415y “foo”son numeric y character, respectivamente:

mode(3.1415)
## [1] "numeric"
#> [1] "numeric"
mode("foo")
## [1] "character"
#> [1] "character"

Esos modos son incompatibles. Para crear un vector a partir de ellos, R los convierte 3.1415a charactermodo para que sea compatible con “foo”:

c(3.1415, "foo")
## [1] "3.1415" "foo"
#> [1] "3.1415" "foo"
mode(c(3.1415, "foo"))
## [1] "character"
#> [1] "character"
Advetencia

c Es un operador genérico, lo que significa que funciona con muchos tipos de datos y no sólo con vectores. Sin embargo, es posible que no haga exactamente lo que espera, así que verifique su comportamiento antes de aplicarlo a otros tipos de datos y objetos.

Ver también

Consulte la introducción al Capítulo (Estructuras de datos) para obtener más información sobre vectores y otras estructuras de datos.

2,6 Computación de estadísticas básicas

Problema

Quiere calcular estadísticas básicas: media, mediana, desviación estándar, varianza, correlación o covarianza.

Solución

Utilice una de estas funciones, suponiendo que x y y son vectores:

mean(x)

median(x)

sd(x)

var(x)

cor(x, y)

cov(x, y)

Discusión

Cuando utilice R por primera vez, puede abrir la documentación y comenzar a buscar material titulado “Procedimientos para calcular la desviación estándar”. Parece que un tema tan importante probablemente requeriría un capítulo completo.

No es tan complicado.

La desviación estándar y otras estadísticas básicas se calculan mediante funciones simples. Normalmente, el argumento de la función es un vector de números y la función devuelve la estadística calculada:

x <- c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
mean(x)
## [1] 8.8
#> [1] 8.8
median(x)
## [1] 4
#> [1] 4
sd(x)
## [1] 11.03328
#> [1] 11
var(x)
## [1] 121.7333
#> [1] 122

La sd función calcula la desviación estándar de la muestra y var calcula la varianza de la muestra.

Las funciones cory covpueden calcular la correlación y la covarianza, respectivamente, entre dos vectores:

x <- c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
y <- log(x + 1)
cor(x, y)
## [1] 0.9068053
#> [1] 0.907
cov(x, y)
## [1] 11.49988
#> [1] 11.5

Todas estas funciones son exigentes con los valores que no están disponibles (NA). Incluso un valor NA en el argumento vector hace que cualquiera de estas funciones devuelva NA o incluso se detenga por completo con un error críptico:

x <- c(0, 1, 1, 2, 3, NA)
mean(x)
## [1] NA
#> [1] NA
sd(x)
## [1] NA
#> [1] NA

Es molesto cuando R es tan cauteloso, pero es apropiado. Debes pensar detenidamente en tu situación. ¿Un NA en sus datos invalida la estadística? En caso afirmativo, entonces R está haciendo lo correcto. De lo contrario, puede anular este comportamiento configurando na.rm=TRUE, que le indica a R que ignore los valores de NA:

x <- c(0, 1, 1, 2, 3, NA)
sd(x, na.rm = TRUE)
## [1] 1.140175
#> [1] 1.14

En versiones anteriores de R, mean eran sd inteligentes con los marcos de datos. Entendieron que cada columna del marco de datos es una variable diferente, por lo que calcularon su estadística para cada columna individualmente. Este ya no es el caso y, como resultado, es posible que leas comentarios confusos en línea o en libros más antiguos (como la primera edición de este libro). Para aplicar las funciones a cada columna de un marco de datos, ahora necesitamos usar una función auxiliar. La familia tidyverse de funciones auxiliares para este tipo de cosas está en el purrr paquete. Al igual que con otros paquetes de tidyverse, este se carga cuando ejecutas library(tidyverse). La función que usaremos para aplicar una función a cada columna de un marco de datos es map_dbl:

data(cars)

library(purrr)

map_dbl(cars, mean)
## speed  dist 
## 15.40 42.98
#> speed  dist 
#>  15.4  43.0
map_dbl(cars, sd)
##     speed      dist 
##  5.287644 25.769377
#> speed  dist 
#>  5.29 25.77
map_dbl(cars, median)
## speed  dist 
##    15    36
#> speed  dist 
#>    15    36

Observe en este ejemplo que mean y sd cada uno devuelve dos valores, uno para cada columna definida por el marco de datos. (Técnicamente, devuelven un vector de dos elementos cuyo names atributo se toma de las columnas del marco de datos).

La var función comprende marcos de datos sin la ayuda de una función de mapeo. Calcula la covarianza entre las columnas del marco de datos y devuelve la matriz de covarianza:

var(cars)
##           speed     dist
## speed  27.95918 109.9469
## dist  109.94694 664.0608
#>       speed dist
#> speed    28  110
#> dist    110  664

Del mismo modo, si x es un marco de datos o una matriz, cor(x) devuelve la matriz de correlación y cov(x) la matriz de covarianza:

cor(cars)
##           speed      dist
## speed 1.0000000 0.8068949
## dist  0.8068949 1.0000000
#>       speed  dist
#> speed 1.000 0.807
#> dist  0.807 1.000
cov(cars)
##           speed     dist
## speed  27.95918 109.9469
## dist  109.94694 664.0608
#>       speed dist
#> speed    28  110
#> dist    110  664

Ver también

Consulte las Recetas 2.14 , “Evitar algunos errores comunes” , 5.27 , “Aplicar una función a cada columna” y 9.17 , “Prueba de significancia de una correlación” .

2,7 Creando Secuencias

Problema

Quieres crear una secuencia de números.

Solución

Utilice una n:m expresión para crear la secuencia simple n , n +1, n +2,…, m :

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

Utilice la seq función para secuencias con un incremento distinto de 1:

seq(from = 1, to = 5, by = 2)
## [1] 1 3 5
#> [1] 1 3 5

Utilice la rep función para crear una serie de valores repetidos:

rep(1, times = 5)
## [1] 1 1 1 1 1
#> [1] 1 1 1 1 1

Discusión

El operador de dos puntos ( n:m) crea un vector que contiene la secuencia n , n +1, n +2,…, m :

0:9
##  [1] 0 1 2 3 4 5 6 7 8 9
#>  [1] 0 1 2 3 4 5 6 7 8 9
10:19
##  [1] 10 11 12 13 14 15 16 17 18 19
#>  [1] 10 11 12 13 14 15 16 17 18 19
9:0
##  [1] 9 8 7 6 5 4 3 2 1 0
#>  [1] 9 8 7 6 5 4 3 2 1 0

R fue inteligente con la última expresión ( 9:0 ). Debido a que 9 es mayor que 0, cuenta hacia atrás desde el valor inicial hasta el final. También puedes usar el operador de dos puntos directamente con la tubería para pasar datos a otra función:

10:20 %>% mean()
## [1] 15

El operador de dos puntos funciona para secuencias que crecen solo en 1. La seq función también crea secuencias pero admite un tercer argumento opcional, que es el incremento:

seq(from = 0, to = 20)
##  [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
#>  [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
seq(from = 0, to = 20, by = 2)
##  [1]  0  2  4  6  8 10 12 14 16 18 20
#>  [1]  0  2  4  6  8 10 12 14 16 18 20
seq(from = 0, to = 20, by = 5)
## [1]  0  5 10 15 20
#> [1]  0  5 10 15 20

Alternativamente, puede especificar una longitud para la secuencia de salida y luego R calculará el incremento necesario:

seq(from = 0, to = 20, length.out = 5)
## [1]  0  5 10 15 20
#> [1]  0  5 10 15 20
seq(from = 0, to = 100, length.out = 5)
## [1]   0  25  50  75 100
#> [1]   0  25  50  75 100

No es necesario que el incremento sea un número entero. R también puede crear secuencias con incrementos fraccionarios:

seq(from = 1.0, to = 2.0, length.out = 5)
## [1] 1.00 1.25 1.50 1.75 2.00
#> [1] 1.00 1.25 1.50 1.75 2.00

Para el caso especial de una “secuencia” que es simplemente un valor repetido, debes usar la repfunción, que repite su primer argumento:

rep(pi, times = 5)
## [1] 3.141593 3.141593 3.141593 3.141593 3.141593
#> [1] 3.14 3.14 3.14 3.14 3.14

Ver también

Consulte la Receta 7.13 , “Creación de una secuencia de fechas” , para crear una secuencia de Dateobjetos.

2.8 Comparación de vectores

Problema

Quiere comparar dos vectores o quiere comparar un vector completo con un escalar.

Solucion

Los operadores de comparación ( ==, !=, <, >, <=, >=) pueden realizar una comparación elemento por elemento de dos vectores. También pueden comparar el elemento de un vector con un escalar. El resultado es un vector de valores lógicos en el que cada valor es el resultado de una comparación de elementos.

Discusión

R tiene dos valores lógicos TRUE y FALSE. En otros lenguajes de programación, estos suelen denominarse valores booleanos .

Los operadores de comparación comparan dos valores y devuelven TRUE o FALSE, según el resultado de la comparación:

a <- 3
a == pi # Test for equality
## [1] FALSE
#> [1] FALSE
a != pi # Test for inequality
## [1] TRUE
#> [1] TRUE
a < pi
## [1] TRUE
#> [1] TRUE
a > pi
## [1] FALSE
#> [1] FALSE
a <= pi
## [1] TRUE
#> [1] TRUE
a >= pi
## [1] FALSE
#> [1] FALSE

Puedes experimentar el poder de R comparando vectores completos a la vez. R realizará una comparación elemento por elemento y devolverá un vector de valores lógicos, uno para cada comparación:

v <- c(3, pi, 4)
w <- c(pi, pi, pi)
v == w # Compare two 3-element vectors
## [1] FALSE  TRUE FALSE
#> [1] FALSE  TRUE FALSE
v != w
## [1]  TRUE FALSE  TRUE
#> [1]  TRUE FALSE  TRUE
v < w
## [1]  TRUE FALSE FALSE
#> [1]  TRUE FALSE FALSE
v <= w
## [1]  TRUE  TRUE FALSE
#> [1]  TRUE  TRUE FALSE
v > w
## [1] FALSE FALSE  TRUE
#> [1] FALSE FALSE  TRUE
v >= w
## [1] FALSE  TRUE  TRUE
#> [1] FALSE  TRUE  TRUE

También puede comparar un vector con un solo escalar, en cuyo caso R expandirá el escalar a la longitud del vector y luego realizará la comparación por elementos. El ejemplo anterior se puede simplificar de esta manera:

v <- c(3, pi, 4)
v == pi # Compare a 3-element vector against one number
## [1] FALSE  TRUE FALSE
#> [1] FALSE  TRUE FALSE
v != pi
## [1]  TRUE FALSE  TRUE
#> [1]  TRUE FALSE  TRUE

(Esta es una aplicación de la regla de reciclaje analizada en la Receta 5.3 , “Comprensión de la regla de reciclaje” .)

Después de comparar dos vectores, a menudo querrás saber si alguna de las comparaciones fue verdadera o si todas las comparaciones fueron verdaderas. Las funciones any y all manejan esas pruebas. Ambos prueban un vector lógico. La any función regresa TRUE si algún elemento del vector es TRUE. La all función regresa TRUE si todos los elementos del vector son TRUE:

v <- c(3, pi, 4)
any(v == pi) # Return TRUE if any element of v equals pi
## [1] TRUE
#> [1] TRUE
all(v == 0) # Return TRUE if all elements of v are zero
## [1] FALSE
#> [1] FALSE

Ver también

Consulte la Receta 2.9 , “Selección de elementos vectoriales” .

2.9 Seleccionar elementos vectoriales

Problema

Quiere extraer uno o más elementos de un vector.

Solucion

Seleccione la técnica de indexación adecuada para su problema:

Utilice corchetes para seleccionar elementos vectoriales por su posición, como v[3]para el tercer elemento de v.

Utilice índices negativos para excluir elementos.

Utilice un vector de índices para seleccionar múltiples valores.

Utilice un vector lógico para seleccionar elementos según una condición.

Utilice nombres para acceder a elementos con nombre.

Discusión

Seleccionar elementos de vectores es otra característica poderosa de R. La selección básica se maneja igual que en muchos otros lenguajes de programación: use corchetes y un índice simple:

fib <- c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
fib
##  [1]  0  1  1  2  3  5  8 13 21 34
#>  [1]  0  1  1  2  3  5  8 13 21 34
fib[1]
## [1] 0
#> [1] 0
fib[2]
## [1] 1
#> [1] 1
fib[3]
## [1] 1
#> [1] 1
fib[4]
## [1] 2
#> [1] 2
fib[5]
## [1] 3
#> [1] 3

Observe que el primer elemento tiene un índice de 1, no 0 como en otros lenguajes de programación.

Una característica interesante de la indexación de vectores es que puede seleccionar varios elementos a la vez. El índice en sí puede ser un vector, y cada elemento de ese vector de indexación selecciona un elemento del vector de datos:

fib[1:3] # Select elements 1 through 3
## [1] 0 1 1
#> [1] 0 1 1
fib[4:9] # Select elements 4 through 9
## [1]  2  3  5  8 13 21
#> [1]  2  3  5  8 13 21

Un índice de 1:3 significa seleccionar los elementos 1, 2 y 3, como se acaba de mostrar. Sin embargo, el vector de indexación no tiene por qué ser una secuencia simple. Puede seleccionar elementos en cualquier lugar dentro del vector de datos, como en este ejemplo, que selecciona los elementos 1, 2, 4 y 8:

fib[c(1, 2, 4, 8)]
## [1]  0  1  2 13
#> [1]  0  1  2 13

R interpreta que los índices negativos significan excluir un valor. Un índice de –1, por ejemplo, significa excluir el primer valor y devolver todos los demás valores:

fib[-1] # Ignore first element
## [1]  1  1  2  3  5  8 13 21 34
#> [1]  1  1  2  3  5  8 13 21 34

Puede ampliar este método para excluir sectores completos utilizando un vector de indexación de índices negativos:

fib[1:3] # As before
## [1] 0 1 1
#> [1] 0 1 1
fib[-(1:3)] # Invert sign of index to exclude instead of select
## [1]  2  3  5  8 13 21 34
#> [1]  2  3  5  8 13 21 34

Otra técnica de indexación utiliza un vector lógico para seleccionar elementos del vector de datos. Dondequiera que esté el vector lógico TRUE, se selecciona un elemento:

fib < 10 # This vector is TRUE wherever fib is less than 10
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
#>  [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
fib[fib < 10] # Use that vector to select elements less than 10
## [1] 0 1 1 2 3 5 8
#> [1] 0 1 1 2 3 5 8
fib %% 2 == 0 # This vector is TRUE wherever fib is even
##  [1]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
#>  [1]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
fib[fib %% 2 == 0] # Use that vector to select the even elements
## [1]  0  2  8 34
#> [1]  0  2  8 34

Normalmente, el vector lógico debe tener la misma longitud que el vector de datos para que esté claramente incluyendo o excluyendo cada elemento. (Si las longitudes difieren, entonces necesita comprender la regla de reciclaje, que se analiza en la Receta 5.3 , “Comprensión de la regla de reciclaje” .)

Al combinar comparaciones de vectores, operadores lógicos e indexación de vectores, puede realizar selecciones potentes con muy poco código R.

Seleccione todos los elementos mayores que la mediana:

v <- c(3, 6, 1, 9, 11, 16, 0, 3, 1, 45, 2, 8, 9, 6, -4)
v[ v > median(v)]
## [1]  9 11 16 45  8  9
#> [1]  9 11 16 45  8  9

Seleccione todos los elementos en el 5% inferior y superior:

v[ (v < quantile(v, 0.05)) | (v > quantile(v, 0.95)) ]
## [1] 45 -4
#> [1] 45 -4

El ejemplo anterior utiliza el |operador, que significa “o” al indexar. Si quisiera “y”, usaría el & operador.

Seleccione todos los elementos que excedan ±1 desviaciones estándar de la media:

v[ abs(v - mean(v)) > sd(v)]
## [1] 45 -4
#> [1] 45 -4

Seleccione todos los elementos que no son NA ni ni NULL:

v <- c(1, 2, 3, NA, 5)
v[!is.na(v) & !is.null(v)]
## [1] 1 2 3 5
#> [1] 1 2 3 5

Una última característica de indexación le permite seleccionar elementos por nombre. Se supone que el vector tiene un names atributo, definiendo un nombre para cada elemento. Puedes definir los nombres asignando un vector de cadenas de caracteres al atributo:

years <- c(1960, 1964, 1976, 1994)
names(years) <- c("Kennedy", "Johnson", "Carter", "Clinton")
years
## Kennedy Johnson  Carter Clinton 
##    1960    1964    1976    1994
#> Kennedy Johnson  Carter Clinton 
#>    1960    1964    1976    1994

Una vez definidos los nombres, puede hacer referencia a elementos individuales por nombre:

years["Carter"]
## Carter 
##   1976
#> Carter 
#>   1976
years["Clinton"]
## Clinton 
##    1994
#> Clinton 
#>    1994

Esto se generaliza para permitir la indexación por vectores de nombres; R devuelve cada elemento nombrado en el índice:

years[c("Carter", "Clinton")]
##  Carter Clinton 
##    1976    1994
#>  Carter Clinton 
#>    1976    1994

Ver también

Consulte la Receta 5.3 , “Comprensión de la regla de reciclaje” , para obtener más información sobre la regla de reciclaje.

2.10 Realizar aritmética vectorial

Problema

Quiere operar en un vector completo a la vez.

Solucion

Los operadores aritméticos habituales pueden realizar operaciones elemento a elemento en vectores completos. Muchas funciones también operan en vectores completos y devuelven un resultado vectorial.

Discusión

Las operaciones vectoriales son una de las grandes fortalezas de R. Todos los operadores aritméticos básicos se pueden aplicar a pares de vectores. Operan de manera elemental; es decir, el operador se aplica a los elementos correspondientes de ambos vectores:

v <- c(11, 12, 13, 14, 15)
w <- c(1, 2, 3, 4, 5)
v + w
## [1] 12 14 16 18 20
#> [1] 12 14 16 18 20
v - w
## [1] 10 10 10 10 10
#> [1] 10 10 10 10 10
v * w
## [1] 11 24 39 56 75
#> [1] 11 24 39 56 75
v / w
## [1] 11.000000  6.000000  4.333333  3.500000  3.000000
#> [1] 11.00  6.00  4.33  3.50  3.00
w^v
## [1]           1        4096     1594323   268435456 30517578125
#> [1] 1.00e+00 4.10e+03 1.59e+06 2.68e+08 3.05e+10

Observe que la longitud del resultado aquí es igual a la longitud de los vectores originales. La razón es que cada elemento proviene de un par de valores correspondientes en los vectores de entrada.

Si un operando es un vector y el otro es un escalar, entonces la operación se realiza entre cada elemento del vector y el escalar:

w
## [1] 1 2 3 4 5
#> [1] 1 2 3 4 5
w + 2
## [1] 3 4 5 6 7
#> [1] 3 4 5 6 7
w - 2
## [1] -1  0  1  2  3
#> [1] -1  0  1  2  3
w * 2
## [1]  2  4  6  8 10
#> [1]  2  4  6  8 10
w / 2
## [1] 0.5 1.0 1.5 2.0 2.5
#> [1] 0.5 1.0 1.5 2.0 2.5
2^w
## [1]  2  4  8 16 32
#> [1]  2  4  8 16 32

Por ejemplo, puedes volver a centrar un vector completo en una expresión simplemente restando la media de su contenido:

w
## [1] 1 2 3 4 5
#> [1] 1 2 3 4 5
mean(w)
## [1] 3
#> [1] 3
w - mean(w)
## [1] -2 -1  0  1  2
#> [1] -2 -1  0  1  2

Del mismo modo, puedes calcular la puntuación z de un vector en una expresión: restar la media y dividir por la desviación estándar:

w
## [1] 1 2 3 4 5
#> [1] 1 2 3 4 5
sd(w)
## [1] 1.581139
#> [1] 1.58
(w - mean(w)) / sd(w)
## [1] -1.2649111 -0.6324555  0.0000000  0.6324555  1.2649111
#> [1] -1.265 -0.632  0.000  0.632  1.265

Sin embargo, la implementación de operaciones a nivel vectorial va mucho más allá de la aritmética elemental. Impregna el lenguaje y muchas funciones operan en vectores completos. Las funciones sqrt y log, por ejemplo, se aplican a cada elemento de un vector y devuelven un vector de resultados:

w <- 1:5
w
## [1] 1 2 3 4 5
#> [1] 1 2 3 4 5
sqrt(w)
## [1] 1.000000 1.414214 1.732051 2.000000 2.236068
#> [1] 1.00 1.41 1.73 2.00 2.24
log(w)
## [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379
#> [1] 0.000 0.693 1.099 1.386 1.609
sin(w)
## [1]  0.8414710  0.9092974  0.1411200 -0.7568025 -0.9589243
#> [1]  0.841  0.909  0.141 -0.757 -0.959

Las operaciones vectoriales tienen dos grandes ventajas. La primera y más obvia es la conveniencia. Las operaciones que requieren bucles en otros lenguajes son breves en R. La segunda es la velocidad. La mayoría de las operaciones vectorizadas se implementan directamente en código C, por lo que son sustancialmente más rápidas que el código R equivalente que podría escribir.

Ver también

Realizar una operación entre un vector y un escalar es en realidad un caso especial de la regla de reciclaje; consulte la Receta 5.3 , “Comprensión de la regla de reciclaje” .