Análisis espaciales y multivariantes con R (AEMeR) aplicados a estudios de biodiversidad

Ejercicios de introducción a R

Autor/a

Diego Nieto Lugilde

Fecha de publicación

14 de octubre de 2024

Nota

Los ejercicios tendréis que entregarlos para la evaluación del curso. Para ello, crea un script de R con RStudio. Ponle el nombre ejercicios_t1_[nombre]_[apellido].R. Dicho script deberá estar organizado con comentarios en castellano (poniendo una almohadilla # delante) y justo detrás el código necesario para realizar el ejercicio (ver ejemplo debajo). Además, si el ejercicio pide reflexionar sobre el resultado use los comentarios (con la #) para indicar sus reflexiones debajo del código. Una vez los tengáis completos podéis mandármelos por email.

# Ejercicio 1.
# Parte 1
seq(1, 40, by = 2)

# Parte 2
seq(1, 40, by = -2)
# Este código da error porque especifiqué algo mal :)

Parte 1: Trabajando con vectores

1. Como muchas funciones en R, seq() es flexible y puede trabajar de formas muy diferentes. Merece la pena entender cómo y porqué funciona de la forma en la que lo hace. Prueba los siguientes comandos:

seq()
seq(0, 5)
seq(from = 0, to = 5)
seq(to = 5)
seq(to = 5, by = 0.5)
seq(from = 10, to = 1, length.out = 10)
seq(from = 5, to = 1, by = -2)
seq(from = 5, to = 1, by = 2)

¿Tienen sentido el resultado de todos estos comandos?

2. Fijaros que se pueden pasar argumentos a una función en R ya sea por su nombre (por ejemplo, to = 5 o by = 0.1), o simplemente colocando los parámetros en el orden correcto. La función seq espera que le des argumentos en el orden (from, to, by). Puede averiguarlo revisando el archivo de ayuda ejecutando el código ?seq. En caso de duda, es más seguro especificar argumentos por su nombre, en cuyo caso cualquier orden está bien. Puedes probar por ejemplo con los siguientes comandos:

seq(4, 8, 1)
seq(by = 1, to = 8, from = 4)
seq(to = 8, by = 1, from = 4)

¿Se interpretan y devuelven el mismo resultado todos estos comandos?

3. Si se está interesado en generar una secuencia entera, a menudo es más rápido usar un operador (un símbolo reservado para una tarea especial). Aquí, podríamos generar la secuencia anterior usando el operador :.

4:8

Otros operadores comunes son +, -, *, /, ^, entre otros. Prueba todos ellos y explica que hace cada uno.

4. Usa seq() y c() para crear un vector llamado a que contenga los enteros del 1 al 10, seguido de los enteros pares del 20 al 30, seguidos de los múltiplos de 5 del 150 al 100 (cuenta regresiva).

¿Cuál es el decimocuarto elemento del vector “a”?

Aquí deberás usar primero la función seq() para generar las secuencias que necesitas y luego encadenarlas con la función c(). Además, necesitarás hacer uso de los corchetes para extraer la información del vector en las posiciones que te interese. Recuerda que el valor que se especifica dentro del corchete es la posición, o posiciones, que se desea obtener.

Usa length() para averiguar la longitud de a y en una sola línea de código R encuentra los elementos 2º, 23º y 10º de a, en ese mismo orden.

5. Crea cuatro vectores diferentes. El primero llamado “nombres” con los nombres de 15 personas ficticias. El segundo llamado “sexo” con el sexo biológico de esas mismas 15 personas ficticias. El tercero llamado “peso” con el peso en kilogramos de cada una de esas 15 personas. Finalmente, el cuarto vector llamado “altura” deberá tener la estatura en metros de cada uno de ellos. Tened en cuenta, que los 4 vectores se ordenarán de forma correlativa: El primer peso que especifiquéis en el vector “peso” corresponderá al peso de la persona cuyo nombre aparezca en primera posición en el vector “nombres”. Una vez que hayas creado los cuatro vectores, calcula el índice de masa corporal (IMC), usando la siguiente fórmula: IMC = peso / estatura^2. Con esta información crear un vector con los nombres de las personas que hayan obtenido un IMC superior a 25.

Aquí tendrás que combinar el uso de varias funciones. Por un lado los operadores condicionales (<, <=, >, >=, ==, !=…) permiten realizar una comprobación sobre todos los valores de un vector. El resultado es un vector de valores lógicos (TRUE o FALSE) dependiendo de si cada elemento cumple la condición, o no. Posteriormente, podrás usar la función which(), que al pasarle un vector de valores lógicos, nos dice que posiciones de dicho vector son TRUE. Esto nos permite generar un índice, al que solemos llamar i, con las posiciones de los valores que nos interesan. Una vez que tengas ese índice, sólo necesitas usarlo dentro de un corchete ([]) para extraer los valores de las posiciones de interés.

Parte 2: Trabajando con matrices, data.frames y listas

1. Crea una matriz llamada “A” que tenga 12 filas y 8 columnas, donde cada elemento en la matriz sea un número diferente generado aleatoriamente de una distribución normal con una media de 3 y una desviación estándar de 2. Establece una nueva variable “b” que sea igual al elemento en la quinta fila y la sexta columna de “A”.

Tened en cuenta que, una vez que se establece, “b” es independiente de “A”. Mantendrá su valor como esté definido, incluso si los elementos de “A” cambian posteriormente.

Aquí necesitas usar la función matrix(). Esta función admite una serie de valores, que usará para rellenar los datos de una matriz. Además, admite los argumentos nrow y ncol especificando las dimensiones de dicha matriz. Para generar los valores aleatorios con los que rellenar la matriz puedes usar la función rnorm a la que le puedes pasar el número de valores que necesitas generar, además de los argumentos meany sd, que permiten especificar los valores de la media y desviación estandar, respectivamente, que van a tener el conjunto de datos generado.

2. Crea un data frame llamado “datos” que contenga la información de los cuatro vectores (i.e., nombres, sexo, altura y peso) de los ejercicios anteriores. Vuelve a calcular el IMC, pero usando los datos almacenados dentro de este data frame e incorpora el resultado como una nueva columna dentro del propio data frame.

Aquí deberás usar la función data.frame(). Esta función acepta como argumentos vectores con un nombre. La forma de especificarlos es la siguiente: data.frame(nombre = vector). Puedes especificar tantos argumentos como necesites: data.frame(nombre1 = vector1, nombre2 = vector2, nombre3 = vector3). Recuerda que para extraer la información de las columnas de un data frame, puedes usar tanto corchetes ([]), como $.

3. Crea 10 matrices como “A”, pero con diferentes valores (solo tendrás que ejecutar 10 veces el mismo comando) y guarda cada una de ellas como un elemento dentro de una lista, llamada “matrix_list”.

Aquí deberás usar la función list(), la cual acepta también múltiples argumentos. Cada argumento es un objeto de la sesión de R, con un nombre. En este sentido funciona parecido a data.frame(), pero a diferencia de esta, los objetos no tienen que ser todos vectores de la misma longitud. Si no que cada objeto puede ser de una clase y tipo diferente.

Parte 3: Usando ficheros de datos

1. Lee en R un fichero de datos de ejemplo (“Abundancia.csv”) que incluye información sobre la abundancia de varias especies en diferentes sitios y llama al data frame resultante “abundancia”. Usa head(), names() y str() para explorar la estructura del data frame “abundancia”.

Usa la función read.csv(path), donde path indica la ubicación del archivo en el disco duro y este argumento se introduce como una cadena de texto (entre comillas). Ten en cuenta que los datos se leen en la memoria RAM del ordenador para que R trabaje con ellos. Los cambios que realices en los datos se almacenan solo en la memoria (NO alteran el archivo de datos original). Esta y otras funciones relacionadas (read.delim(), read.table() y otras) devuelven un data frame. A menudo es una buena idea usar la opción as.is = T, que impide la conversión de variables de tipo character en variables de tipo factor.

2. Usa la función apply() para calcular la abundancia promedio de cada especie en los 10 sitios.

Ten en cuenta que ahora estamos trabajando con un data frame, por lo que no todas las columnas son numéricas. La columna con el nombre de especie no puede realizar operaciones numéricas, por lo que tendrás que excluir esa columna de alguna manera. Para ello puedes usar los corchetes [] de forma similar a como hacíamos para seleccionar elementos dentro de un vector o de una matriz.

La función apply(X, MARGIN, FUN) realiza alguna función (FUN) en cada fila o columna de una matriz o marco de datos (X). MARGIN permite especificar si se debe realizar la función en filas (MARGIN = 1) o en columnas (MARGIN = 2). FUN permite especificar la función a realizar (e.g. FUN = mean, FUN = sd o FUN = sum)

Algunas funciones útiles para usar aquí son max, min, mean, sum, entre otras. Explora con todas ellas e intenta averiguar que hace cada una.

3. Usa la función which() para determinar qué sitios tienen al menos 10 individuos de Lupinus bicolor. Usa la función which() para determinar qué especies tienen una abundancia de al menos 5 en el Site5.

La función which(x) devuelve los índices de los elementos de x que son TRUE. Nota que x debe ser un vector o matriz de tipo logic (i.e. todos los valores son TRUE o FALSE).

4. Crea una nueva matriz llamada “presencia” donde cada elemento de “presencia” es 1, si el valor correspondiente de “abundancia” es mayor que 0, y 0 en el caso contrario.

La función ifelse(test, yes, no) comprueba una condición (test) y si se cumple devuelve el valor especificado en el argumento yes. Si la condición no se cumple, devuelve el valor especificado en el argumento no. Las condiciones se especifican con los operadores lógicos (v.gr. >) de la siguiente manera: vector > 25 lo que comparará cada valor del objeto vector y lo compara con 25, devolviendo TRUE o FALSE en cada caso dependiendo del resultado de la comparación. Por tanto, el resultado de la función es otro vector de la misma longitud pero de tipo lógico.

5. Usando la matriz “presencia” que creaste y la función apply(), calcula la riqueza de especies (i.e. el número de especies) de cada sitio.

6. Escribe la matriz “presencia” que creaste en un archivo “Presencia.csv”.

La función write.csv(x, file) te permitirá guardar el objeto x con el nombre especificado en file. Al tratarse de un nombre de fichero se especifica entre comillas file = "fichero.csv".

Parte 4: Gráficas y figuras

1. Dibuja un histograma del vector “a” que creaste en los Ejercicios de la parte 1. Cambia el color de las barras con la opción col y cambia el color de los cuadros con la opción de border. Usa abline() para dibujar la media de la distribución como una línea vertical punteada.

Aquí deberás usar la función mean para calcular la media antes.

La función hist (x) dibuja un histograma de los valores almacenados en x. Se puede personalizar de varias maneras, incluido el uso de puntos de cambio para cambiar la definición de la anchura de las barras. Explora las posibilidades con ?hist

La función abline (a, b) dibuja una línea en la gráfica ya existente con la pendiente especificada b e intercepto a. También puede dibujar líneas horizontales o verticales. Para ello, en lugar de especificar los argumentos a y b, deberás especificar un valor concreto usando h = valor o v = valor, dependiendo si quieres dibujar una línea horizontal o vertical.

2. Crea dos variables correlacionadas “x” e “y”, usando x <- rnorm (200) e y = x + rnorm (200). Dibuja “x” vs. “y” y juega con los parámetros de trazado. Usa la abline para incluir una recta de regresión entre las dos variables.

La función plot (x, y,...) dibuja los datos de x contra los datos de y. Es personalizable utilizando una amplia gama de opciones. Puedes consultar todas las opciones con ?plot

Recuerda, además, que la función abline (a, b) dibuja una línea en la gráfica ya existente con la pendiente especificada b e intercepto a. Para calcular los valores de la pendiente, puedes usar la función lm(x, y), que genera un modelo lineal entre las dos variables.

3. Genera un nuevo conjunto de datos “w” correlacionado con “x”, usando w <- 2*x * rnorm(200). Añade esta nuevo conjunto de datos al gráfico anterior pero cambiando el color para que se distingan bien los datos de “y” y “w”. Además, añade otra recta de regresión entre “w” y “x”.

Hay varias funciones (points(x, y), segments(x0, y0, x1, y1), arrows(x0, y0, x1, y1), polygons(x, y), que en lugar de generar gráficos nuevos, dibuja puntos, segmentos de línea, flechas o polígonos en el último gráfico que se haya generado.