Facultad de Qu´ımica, UNAM
Curso b´
asico sobre R
1Marcelo F. Lugo L.
Enero de 2015
1Basado en: Alain F. Zuur, Elena N. Ieno, Erik H.W.G.Meesters, A beginner’s Guide
Introducci´
on
R es un lenguaje de computadora que permite escribir funciones, efectuar c´ alcu-los, aplicar muchas t´ecnicas de estad´ıstica, crear gr´aficos e incluso escribir bi-bliotecas de funciones propias.
Adem´as R es gratuito.
Muchas personas no lo usan porque R tiene una curva de aprendizaje. Su uso requiere de la programaci´on y aunque existen varias versiones gr´aficas es muy dif´ıcil prescindir de la programaci´on.
En general, la curva de aprendizaje requiere de utilizar la programaci´on ya hecha por otras personas y modificarla de acuerdo con las necesidades del usua-rio. R fue desarrollado principalmente para c´alculo estad´ıstico, por lo que se tiene una doble curva de aprendizaje, una para la programaci´on y otra para la estad´ıstica.
La instalaci´
on
La instalaci´on del programa requiere primero de su adquisici´on a trav´es de www.r-project.org, luego se selecciona un sitio (cran= Comprehensive R Archive Network ) para descargar el programa en la computadora e instarlarlo.
La primera impresi´on
A diferencia de la mayor´ıa de lo programas comerciales, la ventana inicial de R s´olo contiene algunos “botones” con opciones.
Esto es com´un en muchos programas de distribuci´on libre como Python, Maxima, LaTeX, POV-Ray, etc´etera.
La figura 1 muestra la ventana de inicio a la que llamaremos una sesi´on de R.
Como muchos otros programas, es posible tener varias sesiones abiertas si-mult´aneamente, cada una con su propio proceso.
A partir del s´ımbolo “>”, se puede iniciar cualquier operaci´on admitida por el programa o bien ejecutar cualquiera de las funciones que tiene integradas.
Para empezar, a continuaci´on del s´ımbolo “>” pulse 2 + 2 y luego la tecla “Enter”, con lo que en la ventana de la sesi´on aparecer´a:
> 2 + 2 [1] 4
m´as adelante se describir´a el significado de [1], por lo que ahora s´olo observa-remos la respuesta: 4, como ya se esperaba.
R se instala con manuales de ayuda.
En el men´u Ayuda se encuentran varias opciones para solicitar ayuda y para leer los manuales.
Por ejemplo, la opci´on FAQ en R del men´u Ayuda, despliega las preguntas y respuestas que se han presentado con mayor frecuencia a lo largo del tiempo.
La mayor parte de la informaci´on y ayuda existente en la actualidad est´a escrita en ingl´es, sin embargo, tambi´en hay mucha informacion en espa˜nol y en otros idiomas. Quiz´as la forma m´as r´apida de encontrar la soluci´on a algunas de las preguntas se logra escribi´endolas en el “browser” preferido y dejar que los motores de b´usqueda muestren las opciones disponibles en internet.
Independientemente del idioma, los comandos siempre son los mismos en R, de modo que cuando se copian una o m´as instrucciones encontradas en la red y se “pegan ” en la ventana de una sesi´on de R, es posible observar los resultados y hacer las modificaciones pertinentes al problema que se desea resolver.
La finalizaci´
on de una sesi´
on
Para teminar una sesi´on en R basta con escribir en la consola el comando q(), con lo que apaecer´a un cuadro de di´alogo en el que se decide si se guarda o no el conjunto de instrucciones que se hayan usado hasta el momento, o bien se cancela la finalizaci´on de la sesi´on para continuar trabajando en R.
La inserci´
on de datos
Adem´as de que el programa se puede utilizar como una calculadora com´un, en muchas ocasiones lo que se utilizan son datos o par´ametros.
As´ı, podr´ıan insertarse datos como: > a <- 59
> b <- 55 > c <- 53.5 > d <- 53 > e <- 52.5
El s´ımbolo “<-” es el de asignaci´on de valores, aunque tambi´en se puede usar “=” en su lugar. As´ı, al escribir a y luego la tecla Enter se obtendr´a
> a [1] 59
El programa acepta nombres alfanum´ericos: > paso1 <- 11 > paso2 <- 13 > paso3 <- 15 > paso4 <- 17 > paso5 <- 19
y es posible efectuar operaciones > paso1 + paso2
[1] 24
Aunque el programa efect´ua las operaciones, no almacena los resultados, por lo que es mejor definir, si es necesario, nuevas variables, como
> resultado1 <- paso1 + paso2 > resultado1
La concatenaci´
on de datos con la funci´
on c
Cuando se registran datos experimentales de una o dos variables, lo conveniente es insertarlos como sigue:
> x <- c(1, 2, 3, 7, 11, 13, 17, 19, 23, 29) > x
[1] 1 2 3 7 11 13 17 19 23 29
donde la funci´on c ha creado un vector de longitud 10, que se puede conocer como sigue:
> length(x) [1] 10
Los elementos o componentes del vector x se llaman como sigue, por ejemplo, los elementos 1, 4, y 9:
[1] 1 > x[4] [1] 7 > x[9] [1] 23 o bien > x[1]; x[4]; x[9] [1] 1 [1] 7 [1] 23 o elementos consecutivos > x[3:7] [1] 3 7 11 13 17
> x[-2]
[1] 1 3 7 11 13 17 19 23 29
como puede observarse, el signo “−” omite al valor del elemento. Es posible utilizar otras funciones con los vectores, por ejemplo > sum(x) #la suma de los valores de x
[1] 125
> max(x) #el mayor valor contenido en x [1] 29
> mean(x) #la media o promedio del conjunto de valores de x [1] 12.5
> sd(x) #la desviaci´on t´ıpica o est´andar de x [1] 9.489761
Supongamos que registramos otra variable y la insertamos en R: > y <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
y deseamos aplicar un modelo de regresi´on lineal > M <- lm(y~x) > M Call: lm(formula = y ~ x) Coefficients: (Intercept) x 1.5595 0.3152
Para ver con detalle lo que contiene la variable M obtenida despu´es de aplicar la funci´on lm se escribe
> names(M)
[1] "coefficients" "residuals" "effects" [4] "rank" "fitted.values" "assign" [7] "qr" "df.residual" "xlevels" [10] "call" "terms" "model"
Entonces
> M$coefficients
(Intercept) x 1.5595312 0.3152375
contiene los par´ametros (intersecci´on y pendiente) del modelo lineal que, para efectos de c´alculos posteriores, se pueden almacenar o guardar usando
> pendiente <- M$coefficients[[2]] > interseccion
[1] 1.559531 > pendiente [1] 0.3152375
Los gr´aficos de los datos
Si se consideran los vectores x y y, dados ya anteriormente: > x <- c(1, 2, 3, 7, 11, 13, 17, 19, 23, 29)
> y <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
y se desea trazar un gr´afico que los represente com oparejas de puntos en un plano cartesiano, lo primero que debe considerarse es que ambos vectores tengan la misma “longitud”, es decir, el mismo n´umero de datos como sigue:
[1] 10 > length(y) [1] 10
como puede observarse, ambos vectores contienen el mismo n´umero de datos, es decir, son de la misma longitud, por lo que el trazo de un gr´afico se puede hacer como sigue:
> plot(x,y)
con esta funci´on, se abrir´a una ventana en la que aparecer´a el gr´afico, como en la figura 52. Es importante recordar que no existe el verbo “graficar”, as´ı que cada vez que se hable de un gr´afico se refiere al resultado de trazar puntos, segmentos de recta o de curva en un gr´afico.
N´otese que, a diferencia de muchos otros programas, basta insertar como argumento los nombres de la variables o vectores ya definidos.
Los gr´aficos en R se trazan de la manera m´as simple posible. Como puede verse en la figura 52, la funci´on plot muestra todos los puntos dentro de una escala ajustada autom´aticamente, sin intervenci´on del usuario.
Sin embargo, como se ver´a m´as adelante, es posible a˜nadir elementos infor-mativos al gr´afico.
Debe tomarse en cuenta que cada vez que se utiliza la funci´on plot, se crea una nueva ventana para el gr´afico en cuesti´on.
En cada ventana de un gr´afico es posible a˜nadir varios conjuntos de datos, con la condici´on de que el trazo de cada conjunto estar´a limitado a la escala establecida de acuerdo con el primer conjunto de datos que se hayan trazado.
Los vectores con elementos NA
Suponga que se tienen las siguientes variables
> Wingcrd <- c(59, 55, 53.5, 55, 52.5, 57.5, 53, 55)
> Tarsus <- c(22.3, 19.7, 20.8, 20.3, 20.8, 21.5, 20.6, 21.5) > Head <- c(31.2, 30.4, 30.6, 30.3, 30.3, 30.8, 32.5, NA) > Wt <- c(9.5, 13.8, 14.8, 15.2, 15.5, 15.6, 15.6, 15.7) y que se desea conocer la suma de los valores del vector Head > sum(Head)
[1] NA
como puede verse, la respuesta del programa no es la esperada, pues el ´ultimo dato o elemento del vector es NA (Not Available).
Sin embargo, a pesar de esto, es posible calcular la suma si se hace lo siguiente: > sum(Head, na.rm = TRUE)
[1] 216.1
donde na.rm (rm=remove) indica al programa que omita la presencia de elemen-tos NA y la respuesta corresponde al c´alculo de los valores num´ericos solamente. Cuando se utilizan otras funciones tambi´en es v´alido usar na.rm=TRUE para omitir toda presencia de NA.
La combinaci´
on de variables
Hasta ahora se tienen cuatro vectores o variables con datos. Recordando que la funci´on c se usa para concatenar valores o variables se puede crear una nueva variable:
BirdData <- c(Wingcrd, Tarsus, Head, Wt) por lo que
[1] 59.0 55.0 53.5 55.0 52.5 57.5 53.0 55.0 22.3 19.7 20.8 [12] 20.3 20.8 21.5 20.6 21.5 31.2 30.4 30.6 30.3 30.3 30.8 [23] 32.5 NA 9.5 13.8 14.8 15.2 15.5 15.6 15.6 15.7
que es un vector con 32 elementos o de longitud 32, pero aparecen de tal manera que es indistinguible a cu´al de las variables corresponde cada valor.
Los n´umeros [1], [12] y [23] son el ´ındice del primer elemento de cada rengl´on.
Es posible construir un vector con valores de identificaci´on. Sabemos que la longitud de cada variable es de 8, por lo que:
> Id <- rep(c(1, 2, 3, 4), each = 8) > Id
[1] 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 [28] 4 4 4 4 4
As´ı, el vector Id contiene 32 elementos, num´ericos, que permiten identificar a cu´al variable corresponden los elementos de BirdData, revisando simplemente la lista de valores y la de identificaci´on. Tambi´en
> Id <- rep(1 : 4, each = 8) > Id
[1] 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 [28] 4 4 4 4 4
Como puede advertirse, escribir c(1, 2, 3, 4) es equivalente a escribir 1:4 > 1:4
[1] 1 2 3 4
Otra forma de crear la secuencia de valores: > a <- seq(from = 1, to = 4, by = 1) > a
[1] 1 2 3 4
Hasta aqu´ı s´olo se han concatenado valores, pero supongamos que nos in-teresa crear un vector Id2 de longitud 32 y que contenga la palabra “Wingcrd” 8 veces, la palabra “Tarsus” 8 veces, etc´etera.
Se crea primero al vector VarNames:
> VarNames <- c("Wingcrd", "Tarsus", "Head", "Wt") > VarNames
[1] "Wingcrd" "Tarsus" "Head" "Wt"
Debe notarse que estos son nombres y no variables, entonces > Id2 <- rep(VarNames, each = 8)
> Id2
[1] "Wingcrd" "Wingcrd" "Wingcrd" "Wingcrd" "Wingcrd" [6] "Wingcrd" "Wingcrd" "Wingcrd" "Tarsus" "Tarsus" [11] "Tarsus" "Tarsus" "Tarsus" "Tarsus" "Tarsus"
[16] "Tarsus" "Head" "Head" "Head" "Head" [21] "Head" "Head" "Head" "Head" "Wt" [26] "Wt" "Wt" "Wt" "Wt" "Wt" [31] "Wt" "Wt"
y si se omitiera each=, se obtenr´ıa > rep(VarNames, 8)
[1] "Wingcrd" "Tarsus" "Head" "Wt" [5] "Wingcrd" "Tarsus" "Head" "Wt" [9] "Wingcrd" "Tarsus" "Head" "Wt" [13] "Wingcrd" "Tarsus" "Head" "Wt" [17] "Wingcrd" "Tarsus" "Head" "Wt" [21] "Wingcrd" "Tarsus" "Head" "Wt" [25] "Wingcrd" "Tarsus" "Head" "Wt" [29] "Wingcrd" "Tarsus" "Head" "Wt"
> Z <- cbind(Wingcrd, Tarsus, Head, Wt) > Z
Wingcrd Tarsus Head Wt [1,] 59.0 22.3 31.2 9.5 [2,] 55.0 19.7 30.4 13.8 [3,] 53.5 20.8 30.6 14.8 [4,] 55.0 20.3 30.3 15.2 [5,] 52.5 20.8 30.3 15.5 [6,] 57.5 21.5 30.8 15.6 [7,] 53.0 20.6 32.5 15.6 [8,] 55.0 21.5 NA 15.7
Si se dese tener acceso a los datos de la primera columna: > Z[,1]
[1] 59.0 55.0 53.5 55.0 52.5 57.5 53.0 55.0
> Z[1:3,1]
[1] 59.0 55.0 53.5
Para conocer el segundo rengl´on: > Z[2, ]
Wingcrd Tarsus Head Wt 55.0 19.7 30.4 13.8
Otras operaciones de acceso a los datos de Z:
> Z[1, 1] #acceso al primer valor de Wingcrd Wingcrd
> Z[,2:3] #todos los datos de las columnas 2 y 3 Tarsus Head [1,] 22.3 31.2 [2,] 19.7 30.4 [3,] 20.8 30.6 [4,] 20.3 30.3 [5,] 20.8 30.3 [6,] 21.5 30.8 [7,] 20.6 32.5 [8,] 21.5 NA
> X<-Z[4, 4] #el peso de la cuarta ave > X
Wt 15.2
> Y<-Z[,4] #igual que Wt > Y
[1] 9.5 13.8 14.8 15.2 15.5 15.6 15.6 15.7
> W<-Z[,-3] #W contiene todas las variables, excepto Head > W Wingcrd Tarsus Wt [1,] 59.0 22.3 9.5 [2,] 55.0 19.7 13.8 [3,] 53.5 20.8 14.8 [4,] 55.0 20.3 15.2 [5,] 52.5 20.8 15.5 [6,] 57.5 21.5 15.6 [7,] 53.0 20.6 15.6 [8,] 55.0 21.5 15.7
> D<-Z[, c(1, 3, 4)] #D contiene las columnas 1, 3 y 4 de Z > D Wingcrd Head Wt [1,] 59.0 31.2 9.5 [2,] 55.0 30.4 13.8 [3,] 53.5 30.6 14.8 [4,] 55.0 30.3 15.2 [5,] 52.5 30.3 15.5 [6,] 57.5 30.8 15.6 [7,] 53.0 32.5 15.6 [8,] 55.0 NA 15.7
> E<-Z[, c(-1, -3)] #E contiene las columnas 2 y 4 de Z > E Tarsus Wt [1,] 22.3 9.5 [2,] 19.7 13.8 [3,] 20.8 14.8 [4,] 20.3 15.2 [5,] 20.8 15.5 [6,] 21.5 15.6 [7,] 20.6 15.6 [8,] 21.5 15.7
El acceso a los datos de cualquiera de las variables que se han definido an-teriorment es importante tomar en cuenta el n´umero de renglones y columnas de cada variable para evitar escribir ´ındices que no corresponden a la variable, por ejemplo, al escribir Z[4,1], nos referimos al rengl´on 4 y la columna 1 de Z
> Z[4,1] Wingcrd
55
Y si escribimos > E[4,3]
Error en E[4, 3] : sub´ındice fuera de los l´ımites
se observa el hecho de que la variable E no tiene una tercera columna, aunque el aviso de error no lo especifica, indicando simplemente que la variable tiene menos de 4 renglones o tiene menos de 3 columnas.
Para conocer el n´umero de renglones y columnas basta con escribir: > dim(Z)
[1] 8 4
La funci´on rbind permite combinar variables en renglones: > Z2 <- rbind(Wingcrd, Tarsus, Head, Wt)
> Z2 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] Wingcrd 59.0 55.0 53.5 55.0 52.5 57.5 53.0 55.0 Tarsus 22.3 19.7 20.8 20.3 20.8 21.5 20.6 21.5 Head 31.2 30.4 30.6 30.3 30.3 30.8 32.5 NA Wt 9.5 13.8 14.8 15.2 15.5 15.6 15.6 15.7
La combinaci´on de datos con la funci´on vector : En lugar de la funci´on c se puede usar la funci´on vector para almacenar datos. Si se conoce la longitud del vector, entonces se puede escribir lo siguiente:
> W <- vector(length = 8) > W[1]<- 59
> W[2]<- 55 > W[3]<- 53.5
> W[4]<- 55 > W[5]<- 52.5 > W[6]<- 57.5 > W[7]<- 53 > W[8]<- 55 > W [1] 59.0 55.0 53.5 55.0 52.5 57.5 53.0 55.0
N´otese que el resutlado es pr´acticamente igual al de la funci´on c, excepto que con la funci´on vector es posible definir de antemano la longitud del vector, que se puede utilizar en tareas que incluyan ciclos, por ejemplo.
Tambi´en se pueden combinar datos mediante la funci´on matrix . Primero se crea la matriz y se observa su contenido:
> Dmat <- matrix(nrow = 8, ncol = 4) > Dmat
[,1] [,2] [,3] [,4] [1,] NA NA NA NA [2,] NA NA NA NA [3,] NA NA NA NA [4,] NA NA NA NA [5,] NA NA NA NA [6,] NA NA NA NA [7,] NA NA NA NA [8,] NA NA NA NA
Lo que se observa es la creaci´on de una matriz vac´ıa. Para llenarla se hace lo siguiente:
> Dmat[,1]<- c(59, 55, 53.5, 55, 52.5, 57.5, 53, 55)
> Dmat[,2]<- c(22.3, 19.7, 20.8, 20.3, 20.8, 21.5, 20.6, 21.5) > Dmat[,3]<- c(31.2, 30.4, 30.6, 30.3, 30.3, 30.8, 32.5, NA) > Dmat[,4]<- c(9.5, 13.8, 14.8, 15.2, 15.5, 15.6, 15.6, 15.7)
Ahora: > Dmat [,1] [,2] [,3] [,4] [1,] 59.0 22.3 31.2 9.5 [2,] 55.0 19.7 30.4 13.8 [3,] 53.5 20.8 30.6 14.8 [4,] 55.0 20.3 30.3 15.2 [5,] 52.5 20.8 30.3 15.5 [6,] 57.5 21.5 30.8 15.6 [7,] 53.0 20.6 32.5 15.6 [8,] 55.0 21.5 NA 15.7
Como puede observarse, el resultado es casi el mismo que el que se obtuvo con la funci´on cbind, excepto que Dmat carece de encabezados, pues no se han escrito aun.
Para asignar nombres a las columnas se puede utilizar la funci´on colnames : > colnames(Dmat) <- c("Wingcrd", "Tarsus", "Head","Wt")
> Dmat
Wingcrd Tarsus Head Wt [1,] 59.0 22.3 31.2 9.5 [2,] 55.0 19.7 30.4 13.8 [3,] 53.5 20.8 30.6 14.8 [4,] 55.0 20.3 30.3 15.2 [5,] 52.5 20.8 30.3 15.5 [6,] 57.5 21.5 30.8 15.6 [7,] 53.0 20.6 32.5 15.6 [8,] 55.0 21.5 NA 15.7
Hasta aqu´ı, el proceso de la construcci´on de la matriz ha sido largo, sin em-bargo, recordando que ya se tienen los vectores Wingcrd, Tarsus, Head, Wt, entonces:
> Dmat2 <- as.matrix(cbind(Wingcrd, Tarsus, Head, Wt)) > Dmat2
Wingcrd Tarsus Head Wt [1,] 59.0 22.3 31.2 9.5 [2,] 55.0 19.7 30.4 13.8 [3,] 53.5 20.8 30.6 14.8 [4,] 55.0 20.3 30.3 15.2 [5,] 52.5 20.8 30.3 15.5 [6,] 57.5 21.5 30.8 15.6 [7,] 53.0 20.6 32.5 15.6 [8,] 55.0 21.5 NA 15.7
como ya se hab´ıa obtenido anteriormente.
Otra funci´on ´util para la combinaci´on de datos es data.frame , as´ı:
> Dfrm <- data.frame(WC = Wingcrd, TS = Tarsus, HD = Head, W = Wt) > Dfrm
WC TS HD W 1 59.0 22.3 31.2 9.5 2 55.0 19.7 30.4 13.8 3 53.5 20.8 30.6 14.8 4 55.0 20.3 30.3 15.2 5 52.5 20.8 30.3 15.5 6 57.5 21.5 30.8 15.6 7 53.0 20.6 32.5 15.6 8 55.0 21.5 NA 15.7
Con este tipo de datos es posible hacer otras operaciones sin alterar a Dfrm, por ejemplo:
> M <- lm(WC~Wt, data = Dfrm) > M
Call: lm(formula = WC ~ Wt, data = Dfrm) Coefficients: (Intercept) Wt 65.5315 -0.7239 o bien > summary(M) Call: lm(formula = WC ~ Wt, data = Dfrm) Residuals:
Min 1Q Median 3Q Max -1.8115 -1.2589 -0.0984 0.5618 3.2609
Coefficients:
Estimate Std. Error t value Pr(>|t|) (Intercept) 65.5315 4.6113 14.211 7.59e-06 *** Wt -0.7239 0.3159 -2.291 0.0618 .
---Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 1.757 on 6 degrees of freedom
Multiple R-squared: 0.4666, Adjusted R-squared: 0.3777 F-statistic: 5.249 on 1 and 6 DF, p-value: 0.06184
Almacenamiento de la tabla de valores
Si por alguna raz´on se desea almacenar a Dfrm en un archivo se puede proce-der como sigue, primero se especifica el directorio, mediente la funcion setwd , en el que se almacenar´a o guardar´a la informacion y luego se utiliza la funci´on
write.table o write.csv para guardar la tabla en un archivo: > setwd("d:/Working/Quimica/Ejercicios/Presentaciones/") > write.table(Dfrm,"Dfrm.txt")
donde "d:/Working/Quimica/Ejercicios/Presentaciones/" indica el direc-torio en el que se almacenar´a el archivo y write.table(Dfrm,"Dfrm.txt") es la instrucci´on que contiene como argumento el objeto Dfrm que se almacenar´a en el archivo Dfrm.txt.
Seleccione el archivo Dfrm.txt en el directorio especificado y verifique que el contenido es el esperado.
Si se desea suprimir los n´umeros de rengl´on y los encabezados de las columnas basta con escribir:
> write.table(Dfrm,"Dfrm.txt", row.names=FALSE, col.names=FALSE) con lo que el archivo de texto guardado aparecer´a sin los n´umeros de rengl´on y sin los encabezados.
Una vez que se ha especificado el directorio de almacenamiento de archivos, es posible almacenar el contenido de Dfrm con otro formato:
> write.csv(Dfrm,"Dfrm.csv", row.names=FALSE) donde las siglas “csv” significan comma separated values.
Este tipo de archivo es com´un, y es posible editarlo con hojas de c´alculo como MS Excel. Para los usuarios acostumbrados a MS Excel, los archivos de datos separados por comas son muy atractivos, aunque pronto dejar´an a un lado a dicho programa cuando consideren la eficiencia y facilidad de uso de R.
El trazo de gr´
aficos y sus opciones
Aunque ya se ha dado un ejemplo del trazo de gr´aficos es ahora cuando inicia-remos un uso m´as completo en la presentaci´on de gr´aficos de datos.
El primer tipo de gr´afico que estudiaremos ser´a el de dispersi´on.
Un gr´afico de dispersi´on de datos de dos variables x y y se presenta en R con la funci´on plot como se describe a continuaci´on.
Suponga que se tienen dos conjuntos de datos: > x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) > y <- c(1, 2, 3, 7, 11, 13, 17, 19, 23, 29)
Para representarlos como puntos en un gr´afico de dispersi´on como puntos en el plano, basta con escribir
El programa presenta una venta-na exclusiva para el trazo de los gr´aficos como el de la figura 53. N´otese que se trata del gr´afico de dispersi´on m´as sencillo que per-mite la funci´on plot.
Si el usuario est´a satisfecho con este tipo de gr´afico, puede quedarse tal com se observa.
Para usuarios m´as exigentes, la funci´on plot tiene opciones que pueden modificar la presen-taci´on del gr´afico, como por ejem-plo, se pueden cambiar las
El usuario puede especificar las etiquetas de los ejes como sigue: > plot(x,y, xlab="variable independiente",
ylab="variable dependiente")
El usuario puede especificar los s´ımbolos de los puntos: > plot(x,y, xlab="variable independiente",
ylab="variable dependiente", pch=0)
Fig. 5. Se pueden tener diferentes s´ımbolos (pch=0, 1, 2..., 25, o cracteres ASCII) para trazar los puntos.
Los s´ımbolos pueden aparecer unidos mediante segmentos de recta: > plot(x,y, xlab="X", ylab="Y", pch=16, type="b")
O simplemente segmentos de recta:
> plot(x,y, xlab="X", ylab="Y", type="l")
Tambi´en se puede dar color:
> plot(x,y, xlab="X", ylab="Y", type="b", pch=19, col=2)
Se puede cambiar el espesor de la l´ınea:
> plot(x,y, xlab="X", ylab="Y", type="b", pch=19, col=2, lwd=3)
Se puede a˜nadir una ret´ıcula alineada con las marcas de la escala: > plot(x,y, xlab="X", ylab="Y", pch=19,col=4,
panel.first=grid(col="orange"))
Se puede a˜nadir un t´ıtulo y un subt´ıtulo:
> plot(x,y, xlab="X", ylab="Y", main="T´ıtulo", sub="Subt´ıtulo", pch=19, col=4, panel.first=grid(col=3))
M´
as de un grupo de datos en los gr´
aficos
Hasta ahora, olamente se ha utilizado un par de vectores que contienen el mismo n´umero de datos, es decir, son vectores de la misma longitud.
En muchas ocasiones se tiene la necesidad de trazar m´as de un par de vectores o variables en un gr´afico de dispersi´on o bien comparar dos gr´aficos por separado. A continuaci´on consideraremos dos conjuntos de datos de dos variables cada uno, es decir, como si se tratara de datos de dos experimentos, a saber,
x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) y <- c(1, 2, 3, 7, 11, 13, 17, 19, 23, 29) y
xx <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
yy <- c(0.7, 4.5, 10, 15, 23, 38, 50, 61, 85)
Tracemos primero las variables o vectores x y y, con puntos de color azul:
plot(x,y, xlab="X", ylab="Y", pch=19, col=4,
panel.first=grid(col= "orange"))
Fig. 12.Gr´afico de dispersi´on de las varia-bles x y y.
El trazo de xx y yy en el mismo gr´afico con puntos en color rojo se hace con la funci´on points : points(xx, yy, pch=19,
col=2)
Como puede observarse, s´olo aparecen cinco de los diez pun-tos, debido a que la escala qued´o definida a partir del primer par de variables.
Fig. 13.Aparecen s´olo algunos puntos del segundo par devariables.
Entonces lo conveniente es tra-zar primero xx y yy y despu´es x y y plot(xx,yy, xlab="X", ylab="Y", pch=19, col=4, panel.first=grid(col= "orange")) points(x, y, pch=19, col=2) Como puede observarse en la figura 29.
Fig. 14.Aparecen todos los puntos de las cuatro variables.
En otras condiciones, a veces se requiere de trazar las parejas de variables en gr´aficos separados.
Ya se us´o la funci´on plot que abre una ventana para trazar un gr´afico de dispersi´on o bien traza el gr´afico en una ventana gr´afica ya abierta.
Para trazar otro gr´afico en otra ventana gr´afica se usa la funci´on windows() que permite abrir una ventana gr´afica vac´ıa, que permite insertar varios tipos de gr´aficos dem´as de los gr´aficos de dispersi´on. M´as adelante se considerar´a el contenido del argumento de esta funci´on, que permite especificar las condiciones en las que se abre cada nueva ventana, Dado que por ahora el argumento est´a vac´ıo, la ventana gr´afica que se abre tiene las especificaciones establecida por omisi´on.
El hecho de crear m´as de una ventana gr´afica permite mover a cada una a trav´es de la consola o ventana de una sesi´on de manera independiente. A continuaci´on se describe el proceso de creaci´on de m´as de una ventana gr´afica.
plot(x,y, xlab="X", ylab="Y", pch=19, col=4, panel.first=grid(col="orange"))
windows()
plot(xx,yy, xlab="X", ylab="Y", pch=19, col=4, panel.first=grid(col="orange"))
Varios gr´
aficos en una misma ventana
Adem´as de que es posible abrir varias ventanas gr´aficas que pueden contener diferentes tipos de gr´aficos, en R existe la funci´on par con una gran cantidad de opciones en su argumento para especificar una gran cantidad de par´ametros en la presentaci´on de gr´aficos.
Entre otras opciones, la funci´on par permite la creaci´on de espacios para m´as de un gr´afico en una ventana gr´afica.
Por ejemplo, al hacer an´alisis multivariante se puede crear una “matriz” de gr´aficos que permiten visualizar las dispersiones de datos entre varias parejas de variables.
A continuaci´on se describe c´omo se presentar´an los gr´aficos correspondientes a las parejas x y y en un gr´afico y xx y yy en otro gr´afico, pero dentro de una misma ventana gr´afica.
par(mfrow=c(1,2))
plot(x,y, xlab="X", ylab="Y", pch=19, col=4, panel.first= grid(col="orange"))
plot(xx,yy, xlab="XX", ylab="YY", pch=19, col=4, panel.first= grid(col="orange"))
La funci´on par(mfrow=c(1,2)), indica que la ventana contendr´a dos espacios para gr´aficos, uno al lado de otro, as´ı, en cuanto se escribe esta funci´on y se pulsa la tecla “Retorno” en el teclado, aparece una ventana vac´ıa, del mismo modo que cuando se us´o la funci´on windows, excepto que en este caso se ha especificado que la ventana tendr´a reservados dos espacios uno a la derecha del otro. En el primer espacio se trazar´a el gr´afico de dispersi´on de las variables x y y usando la funci´on plot y en el espacio a la derecha del primero se trazar´a el gr´afico de dispersi´on de las variables xx y yy tambi´en con la funci´on plot.
En la figura 51 se observa el resultado de la aplicaci´on de los comandos anteriores.
Es posible construir ventanas gr´aficas con m´as gr´aficos cambiando los valores de par(mfrow=c(m,n)), donde m es el n´umero de renglones y n el n´umero de columnas que se dejar´an como espacios para insertar gr´aficos.
A partir de ahora los gr´aficos se presentar´an sin la ventana que se ha venido presentando hasta este momento, pues se trataba de capturas de la pantalla.
Si bien las capturas de pantalla tienen la calidad suficiente para presentarlas en este documento, se har´a uso de la capacidad de R para exportar los gr´aficos en diferentes formatos y estos ser´an los que se presentar´an a continuacion.
El control de la presentaci´
on de los gr´
aficos
Como el usuario ya se habr´a percatado, los m´argenes alrededor de un gr´afico en una ventana gr´afica son amplios.
La separaci´on entre los valores de la escalas tambi´en son bastante amplios, por lo que resultar´ıa ´util o est´eticamente m´as atractivo cambiar estas condicio-nes.
Como ya se mencion´o anteriormente, la funci´on par tiene muchas opciones para ajustar muchos par´ametros (utilice help(par)) para consultar el manual.
En primer lugar se ajustar´an los m´argenes alrededor del gr´afico.
La l´ınea de comandos par(mar=c(0, 0, 0, 0)) abre una ventana gr´afica vac´ıa y ajusta los m´argenes inferior, izquierdo, superior y derecho a cero, 0, como sigue:
> par(mar=c(0, 0, 0, 0))
> plot(x,y, xlab="X", ylab="Y", pch=19, col=4, panel.first=grid(col="orange"))
Fig. 17.Los m´argenes externos se ajustaron a cero, 0.
N´otese que desapareci´o el espacio necesario para la escala y sus marcas, e incluso tampoco queda espacio para escribir t´ıtulo ni subt´ıtulo.
El modo m´as conveniente para controlar los ajustes que el programa utiliza por omisi´on consiste en conocer algunas funciones m´as, tanto para el control de las marcas de las escalas como los valores num´ericos de las mismas.
En el ejercicio que se presenta a continuaci´on se ha pretendido optimizar todos los par´ametros, pero el usuario los puede ajustar seg´un su deseo o nece-sidades.
Teniendo en mente que se optimizar´a el espacio para el trazo de los gr´aficos, inserte los comandos siguientes:
> par(mar=c(3, 2, 1, 0.1))
> plot(x, y, axes = FALSE, xlab = NA, ylab = NA, type="n", panel.first=grid(col="orange"))
La primera l´ınea de comandos establece los m´argenes inferior, izquierdo, superior y derecho dentro de los cuales se insertar´a el gr´afico, como puede verse, los valores num´ericos corresponden a los m´argenes.
En el ejercicio anterior se ob-serv´o que un margen de cero no deja espacio ni para que se mues-tren los l´ımites de la caja que con-tiene al gr´afico.
La segunda l´ınea de comandos inserta un gr´afico sin ejes (axes = FALSE), sin etiquetas en los ejes (xlab = NA y ylab = NA), sin puntos de los datos (type="n") pero s´ı con la ret´ıcula.
Para crear un marco dentro del cual se inserta el gr´afico se usa la funci´on box . Usando esta funci´on y points, se obtiene lo que se observa en la figura 54. > box(col=4)
> points(x,y, pch=19, type="b", col=2)
N´otese que ya es posible ob-servar los m´argenes alrededor del gr´afico, que se han reservado pa-ra incluir las escalas, sus marcas
y otros textos. Fig. 19. Gr´afico de dispersi´on con marco
Ahora, se colocar´an las marcas de la escala dentro del gr´afico, co-mo en la figura 42. La funci´on que permite colocar las marcas de es-cala es axis .
> axis(side = 1, tck = .01, labels = NA, col=4) donde side=1 se refiere al lado in-ferior de la gr´afica; el par´ametro tck=0.01 indica que las marcas de la escala tienen una longitud de un cent´esimo de la altura del gr´afico. El par´ametro labels=NA inhibe la colocaci´on autom´atica de los valores num´ericos de la es-cala.
Fig. 20.Gr´afico de dispersi´on al que se ha a˜nadido las marcas de la escala.
Ahora, se colocar´an los valores num´ericos de la escala, como en la figura 43:
> axis(side = 1, lwd = 0, line = -0.9, col=4) donde lwd=0 inhibe la colocaci´on autom´atica de las marcas de la escala en tanto que line = -0.9 indica la posici´on en ala que se colocan los valores num´ericos de la escala.
Fig. 21.Gr´afico de dispersi´on al que se ha a˜nadido los valores num´ericos de la escala.
Ahora, se colocar´an los valores num´ericos y las marcas de la es-cala, como en la figura 44:
> axis(side = 2, tck = .01, labels = NA, col=4) > axis(side = 2, lwd = 0,
line = -0.9, las = 1, col=4)
donde side=2 se refiere al mar-gen izquierdo del gr´afico y las=1 cambia la orientaci´on de los va-lores num´ericos de la escala, ve-rifique esto ´ultimo omitiendo el par´ametro las=1 en la funci´on
axis. Fig. 22. Gr´afico de dispersi´on con marcas
Ahora, se insertar´a la etiqueta del eje horizontal con la funci´on mtext : > mtext(side = 1, "x [unidades]", line = 1)
Ahora, se insertar´a la etiqueta del eje vertical: > mtext(side = 2, "y [unidades]", line = 1.2)
Ahora, se insertar´a el subt´ıtulo:
> mtext(side = 1, "Subt´ıtulo", line = 2)
Finalmente se insertar´a el t´ıtulo:
> mtext(side = 3, "T´ıtulo", line = 0)
Quiz´as esta forma de ir insertando elementos paso a paso haga pensar al usuario que se trata de un proceso tedioso, pero si se copian todas las instruc-ciones y se pegan en R para su compilaci´on, se observar´a la rapidez con la que se puede trazar un gr´afico una vez que se han especificado razonablemente todos los par´ametros.
El script completo es:
x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) y <- c(1, 2, 3, 7, 11, 13, 17, 19, 23, 29) par(mar=c(3, 2, 1, 0.1))
plot(x, y, axes = FALSE, xlab = NA, ylab = NA, type="n", panel.first=grid(col="orange"))
box(col=4)
points(x,y, pch=19, type="b", col=2)
axis(side = 1, tck = .01, labels = NA, col=4) axis(side = 1, lwd = 0, line = -0.9, col=4)
axis(side = 2, tck = .01, labels = NA, col=4)
axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) mtext(side = 1, "x [unidades]", line = 1)
mtext(side = 2, "y [unidades]", line = 1.2) mtext(side = 1, "Subt´ıtulo", line = 2) mtext(side = 3, "T´ıtulo", line = 0)
El trazo de un histograma
Adem´as de los gr´aficos de dispersi´on, a veces se necesita trazar histogramas de frecuencias para observar la forma en la que se distribuyen los datos de las mediciones de una variable aleatoria.
A continuaci´on se describir´a la construcci´on de un histograma de frecuencias para representar una distribuci´on de datos.
La generaci´on de n´umeros aleatorios
Supongamos que los valores de la variable aleatoria son los que se presentan a continuaci´on y que se asignan al vector x. Los valores se generan usando la funci´on rnorm :
Esta funci´on genera 157 n´umeros aleatorios con distribuci´on gaussiana con media mean y desviaci´on t´ıpica sd ; si se omiten dichos par´ametros, entonces se considera un adistribuci´on normal, con media igual a cero y desviaci´on t´ıpica igual a 1.
En este ejercicio el lector no debe esperar obtener un gr´afico igual al que se obtiene de la distribuci´on de datos, pues en cada computadora los valores aleatorios generados son diferentes. Sin embargo, a grosso modo, los histogramas se pareceran en algo, pues proceden de l amisma funci´on generadora.
Adicionalmente a esto, el lector puede generar un conjunto de n´umeros alea-torios diferente si usa otro valor que no sea 157, y una media y desviaci´on t´ıpica de su agrado. A pesar de que puedan presentarse diferencias notables, el procedimiento es el mismo en todos los casos.
Para trazar el histograma se usa la funci´on hist que resulta en el gr´afico de la figura 27:
> hist(x)
As´ı, se ha logrado trazar el histograma de frecuencias del modo m´as simple posible en R, dejando que el programa aplique los par´ametros de construcci´on que tiene ya por omisi´on.
Sin embargo, lo que conviene es utilizar la l´ınea de comandos que se presenta m´as abajo, en la que la construcci´on del histograma se asigna a una variable, almacenando as´ı informaci´on que, a primera vista, est´a oculta a los ojos del usuario.
> h <- hist(x)
en este caso, adem´as de que el histograma aparece en una ventana gr´afica, los resultados de los c´alculos que hace el programa y no se muestran, quedan almacenados en la variable h.
Antes de conocer el contenido de la variable h, quiz´as convenga averiguar algunos valores de la distribuci´on, como:
> min(x) [1] 2.963557 > max(x) [1] 20.96525 > mean(x) [1] 12.7569 > sd(x) [1] 3.258798
Como puede verse, la media y la desviaci´on t´ıpica difieren de los valores es-pecificados al usar la funci´on rnorm, pero la diferencia no es muy importante por lo que se pueden aceptar los resultados que se obtuvieron con las funciones anteriores (min, max, mean, sd). Despu´es de todo, la funci´on rnorm se utiliza para generar muestras n´umeros aleatorios, as´ı que todo va bien hasta ahora.
Al igual que muchas de las funciones de R, hist cuenta con par´ametros definidos por omisi´on. Para conocerlos basta con escribir:
> h
que es la variable en la que se almacenaron los resultados de la funci´on hist, para que se observe
$breaks [1] 2 4 6 8 10 12 14 16 18 20 22 $counts [1] 2 3 9 15 27 44 34 17 4 2 $density [1] 0.006369427 0.009554140 0.028662420 0.047770701 0.085987261 0.140127389 [7] 0.108280255 0.054140127 0.012738854 0.006369427 $mids [1] 3 5 7 9 11 13 15 17 19 21
$xname [1] "x" $equidist [1] TRUE attr(,"class") [1] "histogram"
Como puede verse, aparecen los nombres de las secciones que contiene la variable, como cuando escribimos names(hist), solo que ahora el programa muestra tambi´en los valores contenidos en cada secci´on.
Analicemos algunas secciones. Para empezar veamos el contenido de la sec-ci´on breaks.
[1] 2 4 6 8 10 12 14 16 18 20 22
Al observar el hsitograma y este conjunto de valores se tiene que > min(h$breaks)
[1] 2 y que
> max(h$breaks) [1] 22
y hagamos dos comparaciones:
primero min(h$breaks)<min(x) y luego max(h$breaks)>max(x)
as´ı, la construccion del histograma se hace considerando un intervalo de valores m´as amplio que x, por lo que la funci´on hist, en su forma m´as simple, desarrolla los c´alculos sin intervenci´on del usuario.
Luego > h$counts
[1] 2 3 9 15 27 44 34 17 4 2 > length(h$counts)
[1] 10
Se trata de diez valores que contiene la secci´on, que es el mismo n´umero de barras en el histograma. Cada uno de estos valores es igual a la frecuencia del intervalo de clase.
Otro modo de observar los valroes num´ericos de las frecuencias se logra pre-senta´andolos directamente sobre el histograma, como sigue:
> h <- hist(x, labels=TRUE)
Como se puede ver en la figura 28, los valores de las frecuencias aparecen en la parte superior de las columnas del histograma.
El n´umero de barras o columnas que aparecen se debe a que el programa utiliza el criterio de Sturges, por omisi´on, sin embargo, es posible cambiar el n´umero de barras como sigue:
> h <- hist(x, labels=TRUE, breaks=15)
Tambi´en puede dar color a las barras
> h <- hist(x, labels=TRUE, col="gray")
Puede asignarse un color espec´ıfico al borde de las barras > h <- hist(x, labels=TRUE, col="gray", border="red")
Las barras pueden llenarse con un patr´on de l´ıneas
> h <- hist(x, border="red", density=10, angle=45, col="darkgreen")
La construcci´
on de funciones
R tiene tambi´en la opci´on de que el usuario construya sus propias funciones. Cuando se conoce una funci´on es posible trazarla en un gr´afico, de modo semejante al como ya se hizo en ocasiones pasadas.
Las funciones que R permite construir pueden contener uno o m´as argumen-tos, f (x1, x2, ...).
Adem´as, el programa permite construir funciones que tienen consisten en procedimientos completos, como leer archivos de datos, escribir archivos de re-sultados, efectuar los c´alculos correspondientes, etc´etera.
Considerando que R es un programa /lenguaje que se dise˜n´o originalmente solo para hacer c´alculos estad´ısticos y calculo num´erico es natural que todo tipo de operaciones se haga alrededor de valores num´ericos. Sin embargo, la posibilidad de construir funciones y trazar gr´aficos mucho m´as comlicados que los de dispersi´on han venido haciendo de R un programa muy atractivo.
La construcci´on de una funci´on simple
En la cinem´atica se acostumbra a tratar con las leyes de Newton, de manera que lo m´as frecuente es escribir las ecuaciones de movimiento de una part´ıcula puntual.
As´ı, la ecuaci´on de movimiento unidimensional de una part´ıcula en un mo-vimiento rectil´ıneo uniforme se expresa
x(t) = x0 + v0t
donde x0 es la posici´on inicial de la part´ıcula y v0 la rapidez de movimiento.
La construcci´on de la ecuaci´on de movimiento en R se hace como sigue: > x0 <- 1
> v0 <- 1.25
Debe notarse la ausencia del argumento en la definici´on de la funci´on. Como puede verse, el argumento se encuentra a continuaci´on de function y que los par´ametos x0(=x0) y v0(=v0) se han definido previamente, antes de escribir la
funci´on.
Al tratarse de un progrma a base de comandos, se considerar´ıa atractivo que fuese posible excribir ´ındices o sub´ındices en las variables, sin emabrgo, esto no es obst´aculo alguno para programa suficientemente bien lo que se desea.
La evaluaci´on
La simple construcci´on de las funciones no es la meta, lo que se pretende es efectuar evaluaciones e incluso trazar gr´aficos que representen aquello que se desea transmitir.
Empecemos por evaluar la funci´on x, para ello, basta con escribir, por ejem-plo:
> x(0) [1] 1
como puede verse, el programa eval´ua la funci´on tal como se esperaba, sin problema alguno.
Pero en muchas ocasiones las funciones no se construyen para evaluar punto a punto, se construyen para hacer evaluaciones usando conjuntos de valores.
As´ı, si se desea evaluar la funci´on usando valores t=(0, 1, 2, 3, 4, 5) se procede como sigue:
> t <- seq(0,5,1) > x(t)
[1] 1.00 2.25 3.50 4.75 6.00 7.25
los resultados son los esperados, pero como se acostumbra acad´emicamente, la lectura de valores es m´as atractiva si los resultados se persentan en forma de tabla.
Dado que ya hemos aprendido a unir variables, entonces podemos escribir: > data.frame(t, x=x(t)) t x 1 0 1.00 2 1 2.25 3 2 3.50 4 3 4.75 5 4 6.00 6 5 7.25
como se esperaba, los resultados aparecen en dos columnas.
El trazo de un gr´afico que involucre el uso de funciones se hace pr´acticamente del mismo modo que cuando se trazaron pares de vectores o variables. R trata a las variables de acuerdo con la estructura de su construcci´on, en este caso como vectores de n = 6 dimensiones o componentes.
As´ı, pues, tracemos la funci´on en un gr´afico de dispersi´on. > par(mar=c(3, 2, 1, 0.1))
> plot(t, x(t), axes = FALSE, xlab = NA, ylab = NA, type="n", panel.first=grid(col="orange"))
> box(col=4)
> points(t, x(t), pch=19, type="b", col=2) > axis(side = 1, tck = .01, labels = NA, col=4) > axis(side = 1, lwd = 0, line = -0.9, col=4) > axis(side = 2, tck = .01, labels = NA, col=4)
> axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) > mtext(side = 1, "t [s]", line = 1)
> mtext(side = 2, "x [m]", line = 1.2)
> mtext(side = 3, "Movimiento rectil´ıneo uniforme", line = 0) En la figura 51 se presenta el gr´afico de dispersi´on.
Textos dentro de un gr´afico
Alguna veces es necesario incluir textos descriptivos dentro de un gr´afico, con el fin de resumir explicaciones que pudieanran ser de mayor longtud.
La insercion de textos dentro de un gr´afico requiere de localizar un punto dentro del gr´afico, de modo que al momento de incluir el texto, ´este no que fuera del ´area visible.
Aunque es posible dar alg´un formato a los textos, por el momento nos limi-taremos a escribir textos sencillo y cortos.
Por ejemplo:
> text(1, 7, "la posici´on inicial xo=1.0 m") > text(1, 6.7, "la rapidez inicial vo=1.25 m/s")
como puede observarse en el gr´afico de la figura 52, el texto queda colocado en el punto (1, 7) y (1, 6.7) y est´a centrado con respecto a dicho punto.
Al texto tambi´en se le pueden asignar algunos atributos. Por ejemplo: > text(1, 7, "la posici´on inicial xo=1.0 m", col=2)
> text(1, 6.7, "la rapidez inicial vo=1.25 m/s", col=4)
O bien, atributos de alineaci´on:
> text(1, 7, "la posici´on inicial xo=1.0 m", pos=4) > text(1, 6.7, "la rapidez inicial vo=1.25 m/s", pos=4)
Alineaci´on por la derecha:
> text(1, 7, "la posici´on inicial xo=1.0 m", pos=2) > text(1, 6.7, "la rapidez inicial vo=1.25 m/s", pos=2)
Otras funciones para el trazo de gr´
aficos
Hasta ahora, se han trazado gr´aficos que incluyen s´ımbolos y lineas, combi-nados o por separado, para lo cual se han utilizado las funciones plot y points. Como argumento de plot se incluye el par´ametro type que puede tener valores como type="l" (lines), type="n" (ninguno), type="b" (ambos, l´ıneas y s´ımbolos), type="p" (s´ımbolos) entre otros.
La funci´on points se utiliza s´olo para a˜nadir puntos representados por s´ımbo-los en un gr´afico creado previamente con la funci´on plot. Los diferentes s´ımbolos se seleccionan con la funci´on pch, como ya se vi´o anteriormente.
Adem´as existen otras funciones para el trazo de gr´aficos, entre ellas est´an lines , segments y arrows . Con estas funciones se pueden a˜nadir elementos a los gr´aficos creados perviamente con la funci´on plot.
Primero se utilizar´a el siguiente conjunto de datos:
> x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
> y <- c(0.7, 4.5, 10, 15, 23, 38, 50, 61, 85)
y se traza el gr´afico correspondiente
par(mar=c(3, 2, 1, 0.1))
plot(x, y, axes = FALSE, xlab = NA, ylab = NA, pch=19, col=2) box(col=4)
axis(side = 1, tck = .01, labels = NA, col=4) axis(side = 1, lwd = 0, line = -0.9, col=4) axis(side = 2, tck = .01, labels = NA, col=4)
axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) mtext(side = 1, "x", line = 1)
mtext(side = 2, "y", line = 1.2)
mtext(side = 1, "Ajuste de datos", line = 2) mtext(side = 3, "Par´abola", line = 0)
experi-Fig. 38.El trazo de los puntos experimentales.
mentales con un s´ımbolo, a saber, un c´ırculo en color rojo. A continuaci´on se construir´a una funcion que se ajuste a los valores expereimentales.
Ahora haremos un ajuste semejante al de los cuadrados m´ınimos mediante la funci´on lm que ya se encuentra en el programa desde que inici´o la sesi´on. Los resultados del c´alculo se almacenar´an en la variable ajuste.
> ajuste <- lm(y~I(x^2)) > ajuste Call: lm(formula = y ~ I(x^2)) Coefficients: (Intercept) I(x^2) -0.3983 1.0203
Como puede verse, es necesario conocer el contenido de la variable ajuste, para extraer la informaci´on necesaria en la construcci´on de la curva ajustada. La formula tiene la forma de una par´abola m´as que de un arecta, por esa raz´on, el ajuste se hace usando lm(formula = y ~ I(x^2)). La extracci´on de los coeficientes del polinomio ajustado se extraen como sigue:
> a <- ajuste$coefficients[[1]] > b <- ajuste$coefficients[[2]] > a; b
[1] -0.3982932 [1] 1.020297
Con los coeficientes asignados a una variable, es posible construir la funci´on ajustada:
> Y <- function(z) a + b*z^2
que ya se puede usar para hacer evaluaciones, por ejemplo
> tabla <- data.frame(x, Y=Y(x)) > tabla[1:3,]
x Y
1 1 0.6220038 2 2 3.6828947 3 3 8.7843796
As´ı, ya se puede usar la funci´on lines , como sigue:
> lines(x, Y(x), lty=6, col=4, lwd=2)
A continuaci´on se trazar´a una funci´on y se utilizar´a la funci´on arrows Para hacer algunos se˜nalamientos.
La funci´on es g(x; µ, σ) = A σ√2πe −1 2 x − µ σ 2 donde se usar´an A = 90, µ =12.5 y σ =3.8. > g <- function(x) 90*exp(-0.5*((x-12.5)/3.8)^2)/(3.8*sqrt(2*pi)) > x <- seq(0, 25, length.out=100)
y a continuacion el gr´afico de los cian valores.
> par(mar=c(3, 2, 1, 0.1))
> plot(x, g(x), axes = FALSE, xlab = NA, ylab = NA, type="l") > box(col=4)
> axis(side = 1, tck = .01, labels = NA, col=4) > axis(side = 1, lwd = 0, line = -0.9, col=4)
> axis(side = 2, tck = .01, labels = NA, col=4)
> axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) > mtext(side = 1, "x", line = 1)
> mtext(side = 2, "y", line = 1.2)
> mtext(side = 1, "Puntos cr´ıticos", line = 2) > mtext(side = 3, "Gaussiana", line = 0)
Ahora se a˜nadir´an algunos elementos usando la funci´on arrows .
> text(5, 8, "m´aximo", pos=2)
> arrows(5, 8, 12.5, g(12.5), col=2, length=0.1)
Fig. 41. Se identifica al m´aximo de la funci´on.
> text(12.5, 2, "puntos de inflexi´on", pos=1)
> arrows(12.5, 2, (12.5-3.8), g(12.5-3.8), col=2, length=0.1) > arrows(12.5, 2, (12.5+3.8), g(12.5+3.8), col=4, length=0.1)
La construcci´on y trazo de vectores
Con las herramientas que ya conocemos, estamos en condiciones de abordar el estudio de los vectores, tanto num´erica com gr´aficamente.
Simb´olicamente, los vectores en el plano se representan como v = vxˆi + vyˆj,
as´ı que adoptaremos esta notaci´on
Primero abordaremos los vectores num´ericamente, considerando los vectores de posici´on (auqellos cuyo extremo inicial es el origen del sistema de coordena-das.)
> v <- c(2, 3) > w <- c(1, 4)
> v[1] [1] 2 > v[2] [1] 3 y para w se tiene > w[1] [1] 1 > w[2] [1] 4
La suma se obtiene simplemente sumando como en el caso de los reales
> suma <- v+w > suma
[1] 3 7
Es decir
o bien
> suma[1] [1] 3 > suma[2] [1] 7
que bien puede entenderse como sumax = 3 y sumay = 7, es decir, las
compo-nentes del vector suma, o bien sumax = vx+ wx y sumay = vy + wy, como se
sabe del curso de ´algebra.
Pr´acticamente todas la operaciones algebraicas entre vectores en R se ha-cen componente a componente, como acaba de verse; esto facilita mucho las operaciones y c´alculos entre vectores.
A continuaci´on se har´a la representaci´on gr´afica de los tres vectores, v, w y suma. Recuerde que se dijo que se tratar´ıa de vectores de posici´on (todos tienen su extremo inicial en el origen del sistema de coordenadas), pues todos los vectores en el plano est´an definidos mediante dos puntos: inicio y fin.
> plot(c(0,10), c(0,10), type ="n", panel.first=grid(col="orange")) > abline(h=0, v=0, lty=2)
> arrows(0, 0, v[1], v[2], length=0.2, col=2) > arrows(0, 0, w[1], w[2], length=0.2, col=2) > arrows(0, 0, suma[1], suma[2], length=0.2, col=4) > text(v[1], v[2], "v", pos=3)
> text(w[1], w[2], "w", pos=3)
> text(suma[1], suma[2], "suma", pos=3)
Ahora algunos detalles.
La magnitud de cada uno de los vectores anteriores se obtiene como sigue.
> sqrt(sum(v^2)) [1] 3.605551 > sqrt(sum(w^2)) [1] 4.123106 > sqrt(sum(suma^2)) [1] 7.615773
Una forma alternativa y ´util para representar los vectores
Otro modo para escribir los vectores en R, consiste en escribir todas las abscisas en una variable y todas las ordenadas en otra variable, por ejemplo, si se tienen tres vectores de posici´on cuyos extremos finales son (2, 3), (1, 4) y (5, 1) conviene escribirlos como sigue:
> y <- c(3, 4, 1)
De modo que al trazarlos en un gr´afico
> par(mar=c(3, 2, 1, 0.1))
> plot(c(0,10), c(0,10), type ="n", xlab="", ylab="", axes=FALSE, + panel.first=grid(col="orange"))
> box(col=4)
> axis(side = 1, tck = .01, labels = NA, col=4) > axis(side = 1, lwd = 0, line = -0.9, col=4) > axis(side = 2, tck = .01, labels = NA, col=4)
> axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) > mtext(side = 1, "x", line = 1)
> mtext(side = 2, "y", line = 1.2) > mtext(side = 3, "Vectores", line = 0) > arrows(0, 0, x, y, length=0.2, col=2)
no es necesario trazarlos uno a uno, la funci´on arrow traza a los tres vectores con los mismos atributos, excepto por las cooredenadas de sus extremos finales, considerandolos como vectores de posici´on, ver la figura 44.
Y la suma tambi´en es sencilla
> s <- c(sum(x), sum(y))
> arrows(0, 0, s[1], s[2], length=0.2, col=4)
La traslaci´on de los vectores
La definici´on de “vector” incluye la indicaci´on de cu´al es la localizaci´on del extremo inicial y la del final, es decir un vector queda completamente definido gr´aficamente como sigue:
v = (x1− x0)ˆi + (y1− y0)ˆj
donde (x0, y0) son las coordenadas del extremo inicial y (x1, y1) (donde se traza
la punta de flecha).
Cuando se trata de un vector de posici´o, claramente (x0, y0) = (0, 0) y
v = x1ˆi + y1ˆj.
As´ı, es posible distinguir un vector de posici´on de uno que no lo es pero, ¿por qu´e es dif´ıcil hacer la distincion?, la respuesta es sencilla, porque al escribir expl´ıcitamente los vectores, la mayor´ıa de las ocasiones escribirmos el resultado de las resta, m´as que los valores de los extremos inicial y final del vector.
Esto da lugar a considerar la traslaci´on como una operaci´on que suma n´ ume-ros reales a los extremos de los vectores, para trasladarlos, as´ı si la traslaci´on a lo largo del eje horizontal es T x = 1 y a lo largo del eje vertical es T y = 2, entonces, la traslaci´on convertir´ıa a
v = (x1− x0)ˆi + (y1− y0)ˆj en v = ((T x + x1) − (T x + x0))ˆi + ((T y + y1) − (T y + y0))ˆj v = ((1 + x1) − (1 + x0))ˆi + ((2 + y1) − (2 + y0))ˆj o v = ((1 + x1) − (1 + 0))ˆi + ((2 + y1) − (2 + 0))ˆj o v = ((1 + x1) − 1)ˆi + ((2 + y1) − 2)ˆj
y, como es de esperarse, si se desarrollan todas las operaciones v = x1ˆi + y1ˆj.
¡se trata del mismo vector!... como ya se sab´ıa, pues una de las propiedades de los vectores es que se pueden trasladar sin que esto lo afecte en magnitud y direcci´on.
Esperando que quede claro el procedimiento para distinguir a un vector de posici´on de uno que no lo es, veamos un ejercicio a continuaci´on. Primero se definen y trazan los vectores de posicion y luego indicamos los valores de la traslaci´on en cada direccion y tres colores diferentes entre s´ı para asignar un color a cada vector (los del ejercicio anterior son tres vectores)
> x <- c(-2, 1, 5) > y <- c(3, 4, -1)
> par(mar=c(3, 2, 1, 0.1))
> plot(c(-3,10), c(-2,10), type ="n", xlab="", ylab="", axes=FALSE, panel.first=grid + (col="orange"))
> box(col=4) > abline(h=0, v=0)
> text(-0.25, -0.25, "0")
> axis(side = 1, lwd = 0, line = -0.9, col=4) > axis(side = 2, tck = .01, labels = NA, col=4)
> axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) > mtext(side = 1, "x", line = 1)
> mtext(side = 2, "y", line = 1.2) > mtext(side = 3, "Vectores", line = 0) > arrows(0, 0, x, y, length=0.2, col=2) > s <- c(sum(x), sum(y))
> arrows(0, 0, s[1], s[2], length=0.2, col=4)
ver la figura 51.
Se han considerado abscisas y ordenadas con signo negativo para ilustrar el hecho de que todos los resultados son coherentes con las operaciones y la notaci´on que se usa en R
Com puede notarse, basta una sola instrucci´on para trazar los tres vectores que se sumar´an y el vector que resulta de la suma se traza por separado, con otro color, con el fin de distinguirlo de los vectores de los que procede.
Una vez trazados los vectores de posici´on se procede a definir la traslaci´on y los colores, > Tx <- 2 > Ty <- 4 > c1 <- rgb(240, 120, 65, maxColorValue=255) > c2 <- rgb(221, 30, 180, maxColorValue=255) > c3 <- rgb(25, 35, 45, maxColorValue=255)
A continuacion se hace las traslaci´on y se trazan los vectores trasladados, junto con el vector resultante de la suma:
> arrows(Tx, Ty, Tx + x, Ty+y, col=c(c1, c2, c3)) > arrows(Tx, Ty, Tx+s[1], Ty+s[2], length=0.2, col=4)
En la figura 52 se observa el conjunto de vectores trasladados, adem´as de los de posicion y, en ambos casos, el vector suma, pues ´este tambi´en debe resul-tar trasladado. As´ı, cuando se efect´uen operaciones num´ericas con vectores y adem´as deban trazarse, es indispensable definir ambos extremos de cada vector.
Si se hace una nueva traslaci´on de los vectores originales, con T x = 4 y T y = 2, se obtiene el gr´afico de la figura 2:
Ajuste de una recta mediante cuadrados m´ınimos
Con todas las herramientas que ya se estudiaron, ahora es posible estudiar una aplicaci´on.
Si bien casi todos los programas actuales permiten efectuar c´alculos con el m´etodo de los cuadrados m´ınimos, son pocos los que efect´uan los c´alculos consi-derando las incertidumbres en los datos. Todos los programas pueden presentar gr´aficamente las incertidumbres o barras de error, pero pocos las incluyen en los c´alculos.
La diferencia que resulta al hacer el ajuste por cuadrados m´ınimos tomando en cuenta o no las incertidumbres se puede observar al calcuoar el coeficiente de regresi´on, que siempre es m´as cercano a 1 cuando se consideran las incerti-dumbres en los datos que en el caso contrario.
As´ı, consideremos el siguiente conjunto de mediciones de dos variables que llamaremos x y y y sus respectivas incertidumbres ux y uy.
Los datos que se usar´an son los siguientes: x <- c(5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47) y <- c(88.12, 94.05, 97.45, 100.32, 103.09, 103.15, 109.32, 112.34, 115.32, 118.47, 121.24, 124.43, 127.43, 132.00, 133.47) y sus incertidumbres ux <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) uy <- c(1, 1.2, 1.8, 0.9, 0.7, 0.6, 1.2, 0.8, 0.6, 1.5, 0.8, 0.9, 1.5, 1.8, 0.9)
Estos datos y sus incertidumbres se almacenar´an en una estructura data.frame como sigue:
> datos <- data.frame(x, y, ux, uy)
Entonces, empezaremos a hacer el ajuste por cuadrados m´ınimos definiendo algunas operaciones y almacen´andolas en variables.
N <- length(x); alfa <- 0.05 df <- N-2 mx <- mean(x) my <- mean(y) Sx <- sum(x/uy^2) Sy <- sum(y/uy^2) Sxy <- sum(x*y/uy^2) Sx2 <- sum(x^2/uy^2) Su <- sum(1/uy^2)
Como puede verse, lo primero es determinar el n´umero, N , de parejas de datos de las variables independiente, x, y dependiente y. Com haremos un trabajo completo, tambi´en definimos el n´umero de grados de libertad, df necesario al establecer la banda de confianza. Luego, pueden verse la sumas (con incerti-dumbres) necesarias en la construccion de la matriz cuyo determinante se usar´a para efectuar los c´alculos por cuadrados m´ınimos.
de t´erminos independientes y se resuelve el sistema. N´otese que el resultado de c´ada c´alculo siempre se almacena en una variable:
> matriz1 <- matrix(c(Sx2, Sx, Sx, Su), nrow=2, ncol=2) > matriz2 <- matrix(c(Sxy, Sy), nrow=2, ncol=1)
> solucion <- solve(matriz1, matriz2)
La pendiente y la ordenada al origen se definen como:
> m <- solucion[1] > b <- solucion[2]
que son elementos de solucion.
Las incertidumbres en los par´ametros:
> ub<-sqrt(Sx2/abs(det(matriz1))) > um<-sqrt(Su/abs(det(matriz1)))
> fit <- function(z) m*z+b
A continuaci´on se calcula el coeficiente de regresi´on, R, el error est´andar, std err, el valor de intervalo de confianza, CI, y la funci´on para establecer la banda de confianza, conf y
> R <-1-sum((y/uy^2-fit(x)/uy^2)^2)/sum((y/uy^2-mean(y/uy^2))^2) > std_err <- sqrt(sum((y-my)^2)/df)
> CI <- qt(1-alfa, df)
> confy <- function(z) CI*std_err*sqrt(1/N + (z-mx)^2/(sum((x-mx)^2)))
Ahora se construir´an las funciones que formar´an la frontera de la banda de confianza:
> y1 <- function(x) m*x+b+confy(x) > y2 <- function(x) m*x+b-confy(x)
Ya con los resultados num´ericos listos procederemos a trazar los gr´aficos, primero el marco para los datos experimentales:
> par(mar=c(2,2,1,1))
> plot(x, y, type="n", axes=FALSE, panel.first = grid(lty=4,lwd=1,col="orange")) > box(col=4)
> axis(side = 1, tck = .01, labels = NA, col=4) > axis(side = 2, tck = .01, labels = NA, col=4) > axis(side = 1, lwd = 0, line = -0.9, col=4)
> axis(side = 2, lwd = 0, line = -0.9, las = 1, col=4) > mtext(side = 1, "x", line = 1)
> mtext(side = 2, "y", line = 1.2)
Ahora los datos experimentales con sus barras de incertidumbre y la recta ajustada:
> points(x,y, pch=19, cex=0.5)
> arrows(x,y,x+ux,y, col=’blue’, length=0.02, angle=90) > arrows(x,y,x-ux,y, col=’blue’, length=0.02, angle=90) > arrows(x, y, x, y+uy, col=’blue’, length=0.02, angle=90) > arrows(x, y, x, y-uy, col=’blue’, length=0.02, angle=90) > z <- seq(0.9*min(x), 1.1*max(x), length.out=99)
Ahora se trazar´a la banda de confianza:
> xpol <- c(z,rev(z))
> ypol <- c(y1(z), rev(y2(z)))
> polygon(xpol, ypol, col="#FFAAff90", border="white")
N´otese que se han insertado nuevas funciones que no hab´ıamos considerado hasta ahora, a saber rev y polygon . Tambi´en se ha incluido una forma diferente para definir un color (el de la banda de confianza). En este caso el color est´a definido por #FFAAff y la transparencia como 90, con el fin de que la mancha de color debida a la funci´on polygon “deje ver” los gr´aficos que, de otro modo, quedar´ıan ocultos a la vista.
Ahora se insertar´an los textos siguientes:
pp <- paste("y(x)=", format(m, digits=2, nsmall=4), " *x + (", format(b, digits=2, nsmall=4),")")
pp2 <- paste("Um=", format(um, digits=2, nsmall=4), ", Ub=", format(ub, digits=2, nsmall=4))
pp3 <- paste("R^2=", format (R,digits=2,nsmall=4)) legend(min(x), max(y), pp, cex=0.8, bty="n") legend(min(x), max(y)*0.95, pp2, cex=0.8, bty="n") legend(min(x), max(y)*0.9, pp3, cex=0.8, bty="n")
No se profundizar´a en describir las nuevas funciones insertadas, b´astele al lector con conocer su uso, por ahora. Si requiere de mayor informaci´on solicite la ayuda al programa, usando, por ejemplo, help(legend).
Y para completar el trabajo, debe trazarse el gr´afico de residuos.
> windows(xpos=10, ypos=10)
> plot(x,fit(x)/y, type="b", main="Residuos", xlab="x", ylab="", col="blue", panel.first = grid (lty=4,lwd=1,col="orange")) > segments(0,1,max(x),1, col="black", lwd=2)