Este capítulo contiene un breve tutorial de R con muchos ejemplos. Si
nunca antes has usado R, este es un buen momento para iniciarlo e
intentar jugar con él. No hay mejor manera de aprender algo que
intentarlo tú mismo. Puedes seguir escribiendo el mismo texto que se
muestra en el libro. O intentar cambiarlo un poco para ver qué sucede.
(Por ejemplo, si el código de muestra dice 3 + 4, intenta
escribir 3 - 4 en cambio).
Comencemos a usar R. Cuando ingresas una expresión en la consola de R y presionas la tecla Enter, R evaluará esa expresión y mostrará los resultados (si los hay). Si la declaración da como resultado un valor, R imprimirá ese valor. Por ejemplo, puedes usar R para hacer cálculos simples:
1 + 2 + 3
## [1] 6
1 + 2 * 3
## [1] 7
(1 + 2) * 3
## [1] 9
El intérprete interactivo de R imprimirá automáticamente un objeto devuelto por una expresión ingresada en la consola de R. Observa el divertido “[1]” que acompaña a cada valor devuelto. En R, cualquier número que ingreses en la consola se interpreta como un vector. Un vector es una colección ordenada de números. El “[1]” significa que el índice del primer elemento mostrado en la fila es 1. En cada uno de estos casos, también hay un solo elemento en el vector.
Puedes construir vectores más largos usando la función
c(...). (c significa “combinar”). Por
ejemplo:
c(0, 1, 1, 2, 3, 5, 8)
## [1] 0 1 1 2 3 5 8
es un vector que contiene los primeros siete elementos de la secuencia de Fibonacci. Como ejemplo de un vector que abarca varias líneas, usemos el operador de secuencia para producir un vector con cada número entero entre 1 y 50:
1: 50
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
## [26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
Observe los números entre paréntesis en el lado izquierdo de los resultados. Estos indican el índice del primer elemento que se muestra en cada fila. Cuando realiza una operación en dos vectores, R hará coincidir los elementos de los dos vectores por pares y devolverá un vector. Por ejemplo:
c(1, 2, 3, 4) + c(10, 20, 30, 40)
## [1] 11 22 33 44
c(1, 2, 3, 4) * c(10, 20, 30, 40)
## [1] 10 40 90 160
c(1, 2, 3, 4) - c(1, 1, 1, 1)
## [1] 0 1 2 3
Si los dos vectores no tienen el mismo tamaño, R repetirá la secuencia más pequeña varias veces:
c(1, 2, 3, 4) + 1
## [1] 2 3 4 5
1/c(1, 2, 3, 4, 5)
## [1] 1.0000000 0.5000000 0.3333333 0.2500000 0.2000000
c(1, 2, 3, 4) + c(10, 100)
## [1] 11 102 13 104
Mensaje de advertencia:
c(1, 2, 3, 4, 5) + c(10, 100)
## Warning in c(1, 2, 3, 4, 5) + c(10, 100): longer object length is not a
## multiple of shorter object length
## [1] 11 102 13 104 15
En R, también puedes ingresar expresiones con caracteres:
"Hola mundo"
## [1] "Hola mundo"
Esto se llama un vector de caracteres en R. Este ejemplo es en realidad un vector de caracteres de longitud 1. Aquí hay un ejemplo de un vector de caracteres de longitud 2:
c("Hola mundo", "Hola intérprete de R")
## [1] "Hola mundo" "Hola intérprete de R"
(En otros lenguajes, como C, “carácter” se refiere a un solo carácter, y un conjunto ordenado de caracteres se llama cadena. Una cadena en C es equivalente a un valor de carácter en R). Puede agregar comentarios al código R. Todo lo que esté después del signo de almohadilla (“#”) en una línea se ignora:
# Aquí hay un ejemplo de un comentario al principio de una línea.
1 + 2 + # y aquí hay un ejemplo en el medio
+ 3
## [1] 6
En R, las operaciones que hacen todo el trabajo se llamanfunciones. Ya hemos usado algunas funciones arriba (no puedes hacer nada interesante en R sin ellas). Las funciones son como las que recuerdas de la clase de matemáticas. La mayoría de las funciones tienen la siguiente forma: f(argumento1, argumento2, …) DóndeFes el nombre de la función, yargumento1, argumento2, . . .son los argumentos de la función. Aqui hay algunos ejemplos mas:
exp(1)
## [1] 2.718282
cos(3.141593)
## [1] -1
log2(1)
## [1] 0
En cada uno de estos ejemplos, las funciones solo tomaron un argumento. Muchas funciones requieren más de un argumento. Puede especificar los argumentos por nombre:
log(x=64, base=4)
## [1] 3
O, si proporciona los argumentos en el orden predeterminado, puede omitir los nombres:
log(64,4)
## [1] 3
No todas las funciones son de la forma F(...). Algunos
de ellos tienen forma de operadores.
17 + 2
## [1] 19
2 ^ 10
## [1] 1024
3 == 4
## [1] FALSE
Ya hemos visto el primero: es solo una suma. El segundo operador es el operador de exponenciación, lo cual es interesante porque no es un operador conmutativo. El tercer operador es el operador de igualdad. (Observe que el resultado devuelto es FALSO;R tiene un tipo de datos booleano).
Como la mayoría de los otros lenguajes, R le permite asignar valores a variables y hacer referencia a ellas por su nombre. En R, el operador de asignación es <-. Por lo general, esto se pronuncia como “obtiene”. Por ejemplo, la declaración:
x <- 1
generalmente se lee como “x obtiene 1”. (Si alguna vez ha trabajado en informática teórica, probablemente le gustará esta notación: parece un pseudocódigo de algoritmo).
Después de asignar un valor a una variable, el intérprete de R sustituirá ese valor en lugar del nombre de la variable cuando evalúe una expresión. He aquí un ejemplo sencillo:
x <- 1
y <- 2
z <- c(x,y)
# evaluate z to see what's stored as z
z
## [1] 1 2
Observe que la sustitución se realiza en el momento en que se asigna el valor a z, no en el momento que z es evaluado. Supongamos que escribe las tres expresiones anteriores y luego cambia el valor de y. El valor de z no cambiaría:
y <- 4
z
## [1] 1 2
R proporciona varias formas diferentes de referirse a un miembro (o conjunto de miembros) de un vector. Puede hacer referencia a elementos por ubicación en un vector:
b <- c(1,2,3,4,5,6,7,8,9,10,11,12)
b
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
# let's fetch the 7th item in vector b
b[7]
## [1] 7
# fetch items 1 through 6
b[1:6]
## [1] 1 2 3 4 5 6
# fetch only members of b that are congruent to zero (mod 3)
# (in non-math speak, members that are multiples of 3)
b[b %% 3 == 0]
## [1] 3 6 9 12
Puede recuperar varios elementos en un vector especificando los índices de cada elemento como un vector entero:
# fetch items 1 through 6
b[1:6]
## [1] 1 2 3 4 5 6
# fetch 1, 6, 11
b[c(1,6,11)]
## [1] 1 6 11
Puede recuperar elementos fuera de orden. Los artículos se devuelven en el orden en que se hace referencia:
b[c(8,4,9)]
## [1] 8 4 9
También puede especificar qué elementos recuperar a través de un vector lógico. Como ejemplo, busquemos solo múltiplos de 3 (seleccionando elementos que sean congruentes con 0 mod 3):
b %% 3 == 0
## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE
b[b %% 3 == 0]
## [1] 3 6 9 12
En R, hay dos operadores adicionales que se pueden usar para asignar valores a símbolos. En primer lugar, puede utilizar un único signo igual (“=”) para la asignación.†Este operador asigna el símbolo de la izquierda al objeto de la derecha. En muchos otros idiomas, todas las declaraciones de asignación utilizan el signo igual. Si se siente más cómodo con esta notación, puede utilizarla. Sin embargo, usaré sólo el operador de asignación <- en este libro porque creo que es más fácil de leer. Cualquiera que sea la notación que prefiera, tenga cuidado porque el operador = no significa “igual”. Para eso, necesitas usar el operador ==:
one <- 1
two <- 2
# This means: assign the value of "two" to the variable "one"
one = two
one
## [1] 2
two
## [1] 2
# let's start again
one <- 1
two <- 2
# This means: does the value of "one" equal the value of "two"
one == two
## [1] FALSE
En R, también puedes asignar un objeto de la izquierda a un símbolo de la derecha:
3 -> three
three
## [1] 3
† Tenga en cuenta que no puede utilizar el operador <- al pasar argumentos a una función; necesitas mapear valores a nombres de argumentos usando el símbolo “=”. El uso del operador <- en una función asignará el valor a la variable en el entorno actual y luego pasará el valor devuelto a la función. Puede que esto sea lo que quieres, pero probablemente no lo sea.
En algunos contextos de programación, esta notación puede ayudarle a escribir código más claro. (También puede resultar conveniente si escribe una expresión larga y luego se da cuenta de que olvidó asignar el resultado a un símbolo). Una función en R es simplemente otro objeto asignado a un símbolo. Puede definir sus propias funciones en R, asignarles un nombre y luego llamarlas como a las funciones integradas:
f <- function(x,y) {c(x+1, y+1)}
f(1,2)
## [1] 2 3
Esto lleva a un truco muy útil. A menudo puedes escribir el nombre de una función para ver el código correspondiente. He aquí un ejemplo:
f
## function(x,y) {c(x+1, y+1)}
En R, puedes construir estructuras de datos más complicadas que solo vectores. Un formaciónes un vector multidimensional. Los vectores y las matrices se almacenan de la misma manera internamente, pero una matriz se puede mostrar de manera diferente y se puede acceder a ella de manera diferente. Un objeto de matriz es solo un vector asociado con un atributo de dimensión. He aquí un ejemplo sencillo.
Primero, definamos una matriz explícitamente:
a <- array(c(1,2,3,4,5,6,7,8,9,10,11,12),dim=c(3,4))
Así es como se ve la matriz:
a
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
Y así es como haces referencia a una celda:
a[2,2]
## [1] 5
Ahora, definamos un vector con el mismo contenido:
v <- c(1,2,3,4,5,6,7,8,9,10,11,12)
v
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
Una matriz es simplemente una matriz bidimensional:
m <- matrix(data=c(1,2,3,4,5,6,7,8,9,10,11,12),nrow=3,ncol=4)
m
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
Las matrices pueden tener más de dos dimensiones. Por ejemplo:
w <- array(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18),dim=c(3,3,2))
w
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 10 13 16
## [2,] 11 14 17
## [3,] 12 15 18
w[1,1,1]
## [1] 1
R usa una sintaxis muy limpia para referirse a parte de una matriz. Especifique índices separados para cada dimensión, separados por comas:
a[1,2]
## [1] 4
a[1:2,1:2]
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
Para obtener todas las filas (o columnas) de una dimensión, simplemente omita los índices:
# first row only
a[1,]
## [1] 1 4 7 10
# first column only
a[,1]
## [1] 1 2 3
# you can also refer to a range of rows
a[1:2,]
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
# you can even refer to a noncontiguous set of rows
a[c(1,3),]
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 3 6 9 12
En todos los ejemplos anteriores, acabamos de analizar estructuras de datos basadas en un único tipo de datos subyacente. En R, es posible construir estructuras más complicadas con múltiples tipos de datos. R tiene un tipo de datos incorporado para mezclar objetos de diferentes tipos, llamadoliza. Las listas en R son sutilmente diferentes de las listas en muchos otros lenguajes. Las listas en R pueden contener una selección heterogénea de objetos. Puede nombrar cada componente en una lista. Se puede hacer referencia a los elementos de una lista por ubicación o nombre.
A continuación se muestra un ejemplo de una lista con dos componentes con nombre:
# a list containing a number and string
e <- list(thing="hat", size="8.25")
e
## $thing
## [1] "hat"
##
## $size
## [1] "8.25"
Puede acceder a un elemento de la lista de varias formas:
e$thing
## [1] "hat"
e[1]
## $thing
## [1] "hat"
e[[1]]
## [1] "hat"
Una lista puede incluso contener otras listas:
g <- list("this list references another list", e)
g
## [[1]]
## [1] "this list references another list"
##
## [[2]]
## [[2]]$thing
## [1] "hat"
##
## [[2]]$size
## [1] "8.25"
A marco de datos es una lista que contiene varios vectores con nombre que tienen la misma longitud. Un marco de datos se parece mucho a una hoja de cálculo o una tabla de base de datos. Los marcos de datos son particularmente buenos para representar datos experimentales. Como ejemplo, voy a utilizar algunos datos de béisbol. Construyamos un marco de datos con los resultados de victorias/derrotas en la Liga Nacional (NL) Este en 2008:
teams <- c("PHI","NYM","FLA","ATL","WSN")
w <- c(92, 89, 94, 72, 59)
l <- c(70, 73, 77, 90, 102)
nleast <- data.frame(teams,w,l)
nleast
Puede hacer referencia a los componentes de un marco de datos (o elementos de una lista) por su nombre utilizando el operador $:
nleast$w
## [1] 92 89 94 72 59
A continuación se muestra una forma de encontrar un valor específico en un marco de datos. Suponga que desea encontrar el número de pérdidas de los Florida Marlins (FLA). Una forma de seleccionar un miembro de una matriz es utilizar un vector de valores booleanos para especificar qué elemento devolver de una lista. Puedes calcular un vector apropiado como este:
nleast$teams=="FLA"
## [1] FALSE FALSE TRUE FALSE FALSE
Luego puedes usar este vector para referirte al elemento correcto en el vector de pérdidas:
nleast$l[nleast$teams=="FLA"]
## [1] 77
Puede importar datos a R desde otro archivo o desde una base de datos. Además de las listas, R tiene otros tipos de estructuras de datos para contener una colección heterogénea de objetos, incluidas definiciones de clases formales a través de objetos S4.
R es un lenguaje orientado a objetos. Cada objeto en R tiene un tipo. Además, cada objeto en R es miembro de unclase. Ya hemos encontrado varias clases diferentes: vectores de caracteres, vectores numéricos, marcos de datos, listas y matrices. Puedes usar el clase Función para determinar la clase de un objeto. Por ejemplo:
class(teams)
## [1] "character"
class(w)
## [1] "numeric"
class(nleast)
## [1] "data.frame"
class(class)
## [1] "function"
Observe el último ejemplo: una función es un objeto en R con la clasefunción. Algunas funciones están asociadas con una clase específica. estos se llamanmétodos. (No todas las funciones están estrechamente vinculadas a una clase particular; el sistema de clases en R es mucho menos formal que el de un lenguaje como Java). En R, los métodos de diferentes clases pueden compartir el mismo nombre. estos se llaman funciones genéricas. Las funciones genéricas tienen dos propósitos. Primero, facilitan adivinar el nombre de función correcto para una clase desconocida. En segundo lugar, las funciones genéricas permiten utilizar el mismo código para objetos de diferentes tipos. Por ejemplo, + es una función genérica para agregar objetos. Puedes sumar números junto con el operador +:
17 + 6
## [1] 23
Se podría suponer que el operador de suma funcionaría de manera similar con otros tiposde objetos. Por ejemplo, también puedes usar el operador + con un objeto de fecha y un número:
as.Date("2009-09-08") + 7
## [1] "2009-09-15"
Por cierto, el intérprete de R llama a la función genérica. imprimiren cualquier objeto devuelto en la consola R. Supongamos que usted define X como:
x <- 1 + 2 + 3 + 4
Cuando escribes:
x
## [1] 10
el intérprete realmente llama a la funciónimprimir(x)para imprimir los resultados. Esto significa que si define una nueva clase, puede definir un método de impresión para especificar cómo se imprimen los objetos de esa nueva clase en la consola. Algunas funciones aprovechan esta funcionalidad para hacer otras cosas cuando ingresas una expresión en la consola.‡
Para los estadísticos, unamodeloEs una forma concisa de describir un conjunto de datos, generalmente con una fórmula matemática. A veces, el objetivo es construir unproféticomodelo con capacitacióndatos para predecir valores basados en otros datos. Otras veces, el objetivo es construir undescriptivomodelo que le ayuda a comprender mejor los datos. R tiene una notación especial para describir relaciones entre variables. Suponga que está asumiendo un modelo lineal para una variabley,predicho a partir de las variablesx1, x2, …, xn. (Los estadísticos suelen referirse aycomo eldependientevariable, yx1, x2, …, xncomo elindependientevariables.) En forma de ecuación, esto implica una relación como:
En R, escribirías la relación comoy ~ x1 + x2 + … + xn,que es un objeto de fórmula. Entonces, intentemos usar una regresión lineal para estimar la relación. La fórmula es dist~velocidad.Usaremos el y o función para estimar los parámetros de un modelo lineal. El lm la función devuelve un objeto de clase lm, que asignaremos a una variable llamada coches.lm:
cars.lm <- lm(formula=dist~speed,data=cars)
‡ Un ejemplo muy importante de esto son los gráficos reticulares. Trazar funciones en el retorno de la biblioteca de celosía objetos de celosía pero no trazar resultados. Si llama a una función de celosía en la consola R, la consola imprimirá el objeto y trazará así los resultados. Sin embargo, si llama a una función de red dentro de otra función, o en un script, R no trazará los resultados a menos que imprima explícitamente el objeto de red.
Ahora, echemos un vistazo rápido a los resultados obtenidos:
cars.lm
##
## Call:
## lm(formula = dist ~ speed, data = cars)
##
## Coefficients:
## (Intercept) speed
## -17.579 3.932
Como puede ver, imprimir un lm El objeto le muestra la llamada a la función original (y por lo tanto el conjunto de datos y la fórmula) y los coeficientes estimados. Para obtener más información, podemos utilizar el resumen función:
summary(cars.lm)
##
## Call:
## lm(formula = dist ~ speed, data = cars)
##
## Residuals:
## Min 1Q Median 3Q Max
## -29.069 -9.525 -2.272 9.215 43.201
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -17.5791 6.7584 -2.601 0.0123 *
## speed 3.9324 0.4155 9.464 1.49e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15.38 on 48 degrees of freedom
## Multiple R-squared: 0.6511, Adjusted R-squared: 0.6438
## F-statistic: 89.57 on 1 and 48 DF, p-value: 1.49e-12
Como puede ver, la opción de resumen le muestra la llamada a la función, la distribución de los residuos del ajuste, los coeficientes e información sobre el ajuste. Por cierto, es posible simplemente llamar alyofuncionar o llamar resumen(lm(…))y no asignar un nombre al objeto modelo:
lm(dist~speed,data=cars)
##
## Call:
## lm(formula = dist ~ speed, data = cars)
##
## Coefficients:
## (Intercept) speed
## -17.579 3.932
summary(lm(dist~speed,data=cars))
##
## Call:
## lm(formula = dist ~ speed, data = cars)
##
## Residuals:
## Min 1Q Median 3Q Max
## -29.069 -9.525 -2.272 9.215 43.201
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -17.5791 6.7584 -2.601 0.0123 *
## speed 3.9324 0.4155 9.464 1.49e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15.38 on 48 degrees of freedom
## Multiple R-squared: 0.6511, Adjusted R-squared: 0.6438
## F-statistic: 89.57 on 1 and 48 DF, p-value: 1.49e-12
En algunos casos, esto puede resultar más conveniente. Sin embargo, a menudo desea realizar análisis adicionales, como trazar residuos, calcular estadísticas adicionales o actualizar un modelo para sumar o restar variables. Al asignar un nombre al modelo, puede hacer que su código sea más fácil de entender y modificar. Además, reajustar un modelo puede llevar mucho tiempo en el caso de modelos complejos y grandes conjuntos de datos. Al asignar el modelo a un nombre de variable, puede evitar estos problemas.
R incluye varios paquetes para visualizar datos:gráficos, cuadrícula,y enrejado.Por lo general, encontrará que las funciones dentro del gráficos y enrejado Los paquetes son los más útiles.§Si está familiarizado con Microsoft Excel, descubrirá que R puede generar todos los gráficos con los que está familiarizado: gráficos de columnas, gráficos de barras, gráficos de líneas, gráficos circulares y gráficos de dispersión. Incluso si eso es todo lo que necesita, R hace que sea mucho más fácil que Excel automatizar la creación de gráficos y personalizarlos. Sin embargo, hay muchísimos más tipos de gráficos disponibles en R, muchos de ellos bastante intuitivos y elegantes. Para hacer esto un poco más interesante, trabajemos con algunos datos reales. Vamos a analizar todos los intentos de gol de campo en la Liga Nacional de Fútbol Americano (NFL) en 2005.‖ Para aquellos que no estén familiarizados con el fútbol americano, aquí hay una explicación rápida. Un equipo puede intentar patear una pelota de fútbol entre un conjunto de postes para recibir 3 puntos. Si falla el tiro de campo, la posesión del balón vuelve al otro equipo (en el lugar del campo donde se intentó el tiro). Vamos a echar un vistazo a los intentos de patadas en la NFL en 2005. Primero, echemos un vistazo rápido a la distribución de distancias. R proporciona una función, historia,que puede hacer esto rápidamente por nosotros. Comencemos cargando el conjunto de datos apropiado.
nos encantaria hacerlo con nutshell pero por temas de descarga no se pudo descargar ya que ese paquete no aparece.
library(MASS)
Boston