Esta guía explica cómo realizar tareas elementales en R para el análisis de datos. Quienes estén interesados, pueden consultar una referencia más completa aquí.

Cargar datos

Lo primero que haremos será introducir en el programa los datos con los que trabajaremos. Existen diversas formas de hacerlo; veremos dos de ellas. En ambos casos obtendremos una tabla con los datos. En el lenguaje R, este tipo de tabla se llama data frame.

Crear una tabla de datos

La primera forma de hacerlo es la más directa, pero sólo se recomienda cuando son pocas las observaciones a introducir en la tabla. Por ejemplo, si se tomaron 5 medidas del peso de un objeto, utilizando distintos instrumentos, podríamos tener:

tabla_pesos <- data.frame(valor = c(3.44, 3.5, 3.476, 3.51, 3.45),
                          error = c(0.02, 0.1, 0.005, 0.01, 0.05))

Aquí tabla_pesos es el nombre que elegimos para llamar a nuestra tabla de datos. data.frame(...) es una función que crea una talbla a partir de la información contenida entre ( ) y el símbolo <- indica que estamos asignando la tabla creada al nombre elegido. Cada variable a introducir en la tabla se indica por un nombre (por ejemplo, valor), seguido del signo = y la lista de los valores correspondientes. En R, una lista se crea utilizando la función c(valor1, valor2, ... valorN). No confundir puntos (decimales) y comas (separadores). Si queremos incluir múltiples variables en la tabla, se separan con comas.

Veamos qué aspecto tiene la tabla:

print(tabla_pesos)
##   valor error
## 1 3.440 0.020
## 2 3.500 0.100
## 3 3.476 0.005
## 4 3.510 0.010
## 5 3.450 0.050

Importar una tabla de datos

Cuando el volumen de datos es grande, es más práctico escribir los datos en un archivo externo e importarlos. Esto además facilita poder intercambiar los datos con otros programas que tengan la opción de exportarlos como archivos de texto (por ejemplo, .csv o .txt). La importación de los datos puede realizarse mediante una herramienta del RStudio o mediante una función. Cuando se trata de datos utilizados frecuentemente, vale la pena escribir el código para automatizar el proceso; si no, puede resultar más práctica la herramienta del RStudio.

El archivo de texto plano con los datos puede ser, por ejemplo, las posiciones a distintos tiempos de algún objeto:

"t" "x"
0.00 0.0640215430782399
0.01 -0.00536852631498295
0.02 -0.0451131068595618
0.03 0.110196742669278
0.04 0.0992660100158328
0.05 0.138676696970271
0.06 0.114840400695752
0.07 0.149782813549311
0.08 0.130997679563375
0.09 0.172718661614991
0.10 0.192491412537927
...

En este caso, incluye los nombres de las variables (encabezado), los valores están separados por un espacio y para los decimales se utilizó un punto. Esta información es necesaria para que el R interprete correctamente el archivo. Veamos cómo sería el código:

setwd("~/Documentos/Docencia/Labo 2 ByG/Usar R")
tabla <- read.delim("archivo.txt", header = T, sep = " ", dec = ".")
head(tabla)
##      t            x
## 1 0.00  0.064021543
## 2 0.01 -0.005368526
## 3 0.02 -0.045113107
## 4 0.03  0.110196743
## 5 0.04  0.099266010
## 6 0.05  0.138676697

La primera instrucción (setwd(...)) especifica la carpeta de trabajo (de donde leer y/o donde escribir los datos). Basta con hacerlo una sola vez, luego queda definida mientras tengamos abierto el R. Luego realizamos la operación de leer desde el archivo con read.delim(...). Entre los paréntesis debemos indicar el nombre del archivo, si tiene o no encabezado (header = T= sí/F= no), y los separadores (espacio y punto). El comando head(...) hace que nos muestre solo el principio de la tabla (útil cuando se tienen muchas observaciones).

Operar con los datos

Para acceder a los valores de una variable en particular, se utiliza el signo $. Así, tabla$t corresponde a los tiempos y tabla$x a las posiciones. Supongamos que queremos incorporar a la tabla una columna con los errores de las posiciones. El manual del instrumento utilizado para medir las posiciones dice tener una exactitud del 5% y una dispersión de 0.1 mm. El error de cada punto sería \[ \Delta x = \sqrt{(0.05 \cdot x)^2 + (0.1~\mathrm{mm})^2} \] Entonces, para agregarlo a la tabla (suponiendo que las posiciones estaban en milímetros)

tabla$deltax <- sqrt((0.05 * tabla$x)^2 + 0.1^2)
head(tabla)
##      t            x    deltax
## 1 0.00  0.064021543 0.1000512
## 2 0.01 -0.005368526 0.1000004
## 3 0.02 -0.045113107 0.1000254
## 4 0.03  0.110196743 0.1001517
## 5 0.04  0.099266010 0.1001231
## 6 0.05  0.138676697 0.1002401

Graficos

La función con la que construimos gráficos es plot(...). Esta función admite muchas opciones, algunas de las cuales veremos en los ejemplos que siguen. Primero graficaremos simplemente los datos de la tabla.

plot(x = tabla$t, y = tabla$x, xlab = "t [s]", ylab = "x [mm]", type = "p")

Entre las opciones de la función, especificamos qué variable corresponde a cada eje (x = ..., y = ...), cómo rotular los ejes (xlab = "...", ylab = "...") e indicamos que debía graficar puntos (type = "p", otras opciones: "l" para líneas, "b" para puntos + líneas). Otras opciones que se pueden incluir son col = "..." (especifica el color: red, blue, y muchos más…), cex = ... (controla el tamaño de punto), pch = ... (cambia el tipo de punto: 21 círculo, 22 cuadrado, 23 rombo, 24 y 25 triángulos, etc.). Para gráficos de línea hay otras opciones específicas como lty = ... (tipo de línea: 1 continua, 2 a trazos, 3 punteada, etc.) y lwd = ... (controla el grosor).

Lamentablemente, R no sabe graficar barras de error por sí solo. Existen algunos paquetes adicionales que incorporan la funcionalidad, pero también hay una solución más simple: aprovechar que R nos deja dibujar flechas sobre el gráfico y usarlas para representar las barras de error.

plot(x = tabla$t, y = tabla$x, xlab = "t [s]", ylab = "x [mm]", 
     type = "p", xlim = c(0.0, 0.245), ylim = c(-0.2,0.8))
arrows(tabla$t, tabla$x-tabla$deltax, tabla$t, tabla$x+tabla$deltax,
       length=0.05, angle=90, code=3)

Esta vez, usamos las opciones xlim e ylim para especificar el rango de valores a mostrar (o sea, la escala del gráfico). Luego, agregamos las barras de error con arrows( ... ). Los primeros cuatro parámetros de arrows( ... ) son las coordenadas x e y de ambos extremos de la flecha que se corresponden con los extremos de las cotas de error. Las siguientes opciones controlan la forma de la flecha para que tenga aspecto de barra de error.

Ajustes

Se pueden ajustar diversos modelos en R mediante métodos de cuadrados mínimos o máxima verosimilitud. Los más usuales (por ejemplo, modelos lineales y regresiones logísticas) ya vienen implementados. Existen paquetes que añaden muchas otras capacidades. Aquí desarrollaremos dos ejemplos simples y frecuentes de ajustes.

Ajuste lineal

Los modelos que se denominan lineales son lineales en los coeficientes, no necesariamente en las variables. Por esto, un ajuste lineal no sirve exclusivamente para ajustar una recta, sino que es una herramienta mucho más general. Algunos ejemplos comunes son:

Para ajustar un polinomio \[y = a_0 + a_1 x + a_2 x^2\] podemos pensar a \(x^2\) como una variable distinta de \(x\) (de hecho, lo es). Por ejemplo, llamando \(z = x^2\), queda \[y = a_0 + a_1 x + a_2 z\]

Una exponencial \[y = a ~ e^{b x}\] puede linealizarse aplicando logaritmo a ambos lados de la igualdad. Así queda \[\log y = \log a + b x\] Solo hace falta redefinir la variable independiente \(z = \log y\) y uno de los coeficientes \(c = \log a\) para llegar a una expresión evidentemente lineal \[z = c + b x\]

Ajustes lineales en R

La función para realizar ajustes lineales es lm(formula, data = ..., weights = ... ).

El modelo se especifica en formula siguiendo una convención particular: y ~ x1 + x2 + ... es equivalente a \(y = a_0 + a_1 x_1 + a_2 x_2 + \cdots \). Como se ve, R incluye una ordenada al origen por defecto. Si no queremos que lo haga, se lo indicamos en la fómula añadiendo un -1. Si quisiéramos aplicar alguna transformación sobre las variables, como en los ejemplos anteriores, puede explicitarse en la fómula misma, sin necesidad de agregar variables nuevas a la tabla. Dado que en las fórmulas lo operadores +, -, * y ^ tienen un significado especial (agregan y quitan términos, no suman y restan valores), se debe indicar usando I( ... ). Por ejemplo, para ajustar una función cuadrática, la fórmula sería y ~ x + I(x^2).

El parámetro data sirve para especificar en qué tabla están los datos y de esa manera no tener que escribir el nombre de la tabla junto a cada variable que incluimos en la fórmula.

El parámetro weights permite ponderar las observaciones. Esto es necesario cuando los errores difieren entre las observaciones. El factor de peso que se debe utilizar es la inversa del cuadrado del error.

Como ejemplo, tomemos la tabla de posiciones y tiempos y supongamos que no estamos seguros de que el movimiento fuera acelerado o a velocidad constante. En principio, proponemos una relación cuadrática para la posición en función del tiempo:

ajuste <- lm(x ~ t + I(t^2), tabla, weights = 1/deltax^2)
summary(ajuste)
## 
## Call:
## lm(formula = x ~ t + I(t^2), data = tabla, weights = 1/deltax^2)
## 
## Weighted Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.91683 -0.05573 -0.00142  0.05900  1.04940 
## 
## Coefficients:
##               Estimate Std. Error  t value Pr(>|t|)    
## (Intercept) -1.404e-03  2.356e-03   -0.596    0.551    
## t            2.400e+00  2.296e-03 1045.377   <2e-16 ***
## I(t^2)       7.557e-05  3.134e-04    0.241    0.810    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1625 on 998 degrees of freedom
## Multiple R-squared:  0.9999, Adjusted R-squared:  0.9999 
## F-statistic: 4.02e+06 on 2 and 998 DF,  p-value: < 2.2e-16

Vemos que al hacer ajuste <- lm (...) estamos guardando toda la información relacionada con la regresión lineal bajo el nombre ajuste. Luego, pedimos un resumen de la regresión usando summary(ajuste). Así obtenemos los valores de los coeficientes y sus errores.

Para graficar el resultado del ajuste, repetimos los pasos del gráfico anterior y le agregamos la curva nueva usando lines(). Entre los paréntesis indicamos los valores a graficar en cada eje. En este caso, usamos los mismos tiempos de la tabla, pero en vez de graficar las posiciones medidas queremos mostrar las ajustadas. Para eso R dispone de la función predict(...) que nos da los valores ajustados.

plot(x = tabla$t, y = tabla$x, xlab = "t [s]", ylab = "x [mm]", 
     type = "p", xlim = c(0.0, 0.495), ylim = c(-0.2,1.6))
arrows(tabla$t, tabla$x-tabla$deltax, tabla$t, tabla$x+tabla$deltax,
       length=0.05, angle=90, code=3)
lines(x = tabla$t, y=predict(ajuste), col = "red", lwd = 2)