Esta página muestra algunos ejercicios básicos para empezar a familiarizarse con el ambiente de trabajo R. Las funciones que veremos a continuación son las que todo principiante en R debería conocer y tratar de memorizar puesto que le servirán por siempre. A medida que el estudiante se familiarice con estas funciones podrá continuar con funciones y códigos un poco más complejos. Tengan paciencia y mucha persistencia.
# Direccionar un directorio-folder de trabajo
setwd("C:/Users/juvel/Dropbox/Cursos_Charlas/Iztacala_2018/Scripts/")
Subir un conjunto de datos en formato CSV (comma-separated-value). Estos archivos se pueden abrir con Excel.
mis_datos <- read.csv("distancias_islas_caribe.csv", header = TRUE)
Funciones básicas para empezar a explorar
# head me muestra el encabezado del archivo que acabo de subir (las primeras filas)
head(mis_datos)
## ID Island species distance
## 1 11342 Not assigned aeneus 6.075
## 2 11359 Southern Lesser Antilles aeneus 8.194
## 3 11360 Not assigned aeneus 4.618
## 4 11361 Not assigned aeneus 4.382
## 5 11362 Not assigned aeneus 4.611
## 6 11363 Not assigned aeneus 2.855
# tail me muestra la parte final del archivo
tail(mis_datos)
## ID Island species distance
## 129312 919813 Southern Lesser Antilles whitemani 9.946
## 129313 919816 Southern Lesser Antilles whitemani 8.92
## 129314 919817 Southern Lesser Antilles whitemani 8.755
## 129315 919818 Southern Lesser Antilles whitemani 8.831
## 129316 919831 Southern Lesser Antilles whitemani 8.73
## 129317 919833 Not assigned whitemani 8.848
# class: indica que tipo de archivo estoy usando, e.g., un vector, una lista, un dataframe, una matriz, etc.
class(mis_datos)
## [1] "data.frame"
# str: me muestra la estructura de los datos que estoy visualizando. Es útil para ver donde esta algo que luego necesito extraer o indexar.
str(mis_datos)
## 'data.frame': 129317 obs. of 4 variables:
## $ ID : int 11342 11359 11360 11361 11362 11363 11364 11366 11375 11377 ...
## $ Island : Factor w/ 9 levels "Cayman Islands",..: 6 8 6 6 6 6 6 6 6 6 ...
## $ species : Factor w/ 80 levels "aeneus","ahli",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ distance: Factor w/ 10219 levels " NA","0.46","0.536",..: 6944 8975 5488 5252 5481 3649 3214 461 3201 336 ...
# dim: permite ver las dimensiones de mi objeto ya sea un dataframe o una matriz.
dim(mis_datos)
## [1] 129317 4
# length: es igual que el anterior pero solo para objetos tipo lista
length(mis_datos)
## [1] 4
#names: permite ver los nombres de las columnas
names(mis_datos)
## [1] "ID" "Island" "species" "distance"
Ahora carguemos el mismo archivo pero que cada fila tenga un nombre único usando la primera columna (ID).
mis_datos <- read.csv("distancias_islas_caribe.csv", header=TRUE, row.names=1)
Ahora carguemos otro archivo con datos para unas especies
datos <- read.csv("areas_nichos.csv", header = TRUE, row.names = 1)
Hasta ahora hemos aprendido a cargar archivos en formato CSV y a visualizar sus dimensiones y estructura. Ahora pasaremos a una de las cosas más importante de trabajar con R que es la INDEXACIÓN. La indexación es clave para aprender a dominar R.
Primero, vamos a generar un vector númerico a partir del segundo archivo que subimos (datos)
var1 <- datos[,1]
head(var1)
## [1] 5.373085 4.209303 12.610739 6.441746 2.915383 9.306049
dim(var1)
## NULL
class(var1)
## [1] "numeric"
length(var1)
## [1] 131
Queremos asignarle los nombres de las especies a cada valor del vector númerico
names(var1)<-row.names(datos)
Ahora vamos a indexar cada una de las variables del primer archivo (mis_datos):
# voy a indexar la columna 2 y 3.
variables1 <- mis_datos[,c(2,3)]
# indexar la columna 1 y 3
variables2 <- mis_datos[,c(1,3)]
# indexar de la columna 2 a la 3 de forma continua.
variables3 <- mis_datos[,c(2:3)]
Voy a convertir el objeto lista en un dataframe
dataframe1 <- as.data.frame(variables1)
class(dataframe1)
## [1] "data.frame"
Ahora de dataframe a lista
data.list1 <- as.list(variables1)
class(data.list1)
## [1] "list"
De dataframe a matriz
vars.matrix <- as.matrix(variables1)
vars.matrix[1:100] # voy a visualizar los primeros 100 datos de esta matriz.
## [1] "aeneus" "aeneus" "aeneus" "aeneus" "aeneus" "aeneus"
## [7] "aeneus" "aeneus" "aeneus" "aeneus" "aeneus" "aeneus"
## [13] "aeneus" "aeneus" "aeneus" "aeneus" "aeneus" "aeneus"
## [19] "aeneus" "aeneus" "aeneus" "aeneus" "aeneus" "aeneus"
## [25] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [31] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [37] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [43] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [49] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [55] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [61] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [67] "ahli" "ahli" "ahli" "ahli" "ahli" "ahli"
## [73] "ahli" "ahli" "ahli" "ahli" "ahli" "aliniger"
## [79] "aliniger" "aliniger" "aliniger" "aliniger" "aliniger" "aliniger"
## [85] "aliniger" "aliniger" "aliniger" "aliniger" "aliniger" "aliniger"
## [91] "aliniger" "aliniger" "aliniger" "aliniger" "aliniger" "aliniger"
## [97] "aliniger" "aliniger" "aliniger" "aliniger"
Ahora empezaremos a jugar con las tablas. Vamos a UNIR tres tablas diferentes con base en una columna en común.
species <- read.csv("datos_especies_islas.csv")
areas <- read.csv("areas_islas.csv")
distancias <- read.csv("distancias.csv")
Concatenar dos tablas - dos dataframes-
species.areas <- merge(species, areas, by="Islands")
Concatenar esta tabla nueva con la de distancias
spp.areas.dist <- merge(species.areas, distancias, by="species")
Ahora vamos a indexar por subconjuntos (subsets)
dactyloa <- subset(spp.areas.dist, clades=="Dactyloa")
homolechis <- subset(spp.areas.dist, species=="homolechis")
Miremos como podemos indexar una columna de dos formas diferentes
dist.homo1 <- homolechis[,7]
dist.homo2 <- homolechis$distancias
Para evitar que se convierta en factor usar lo siguiente:
dist.homo <- as.numeric(as.vector(homolechis$distancias))
Algunas estadísticas y gráficas básicas en R
# Histograma de frecuencias
hist(dist.homo)
mean(dist.homo)
## [1] 3.917335
min(dist.homo)
## [1] 1.233
max(dist.homo)
## [1] 29.516
sd(dist.homo)
## [1] 1.909522
var(dist.homo)
## [1] 3.646274
Vamos a indexar el promedio
a <- mean(dist.homo)
Guardar y cargar un objeto de R (RData)
save.image("misDatos.RData")
load("misDatos.RData")
Gráficas sencillas y transformación de datos
hist(dist.homo, main="histograma",xlab="distancias")
Transformación logarítmica
log.dist <- log(dist.homo)
hist(log.dist, main="histograma", xlab="distancias")
Correlaciones y regresión lineal
cor(datos$nicho, datos$area)
## [1] 0.09052859
# primero x y luego y
plot(datos$nicho, datos$area)
reg.l <- lm(datos$nicho~datos$area)
Hacer un histograma de los residuales Usaré la indexación de los residuales del objeto reg.l con el simbolo de $
hist(reg.l$residuals)
plot(datos$area, datos$nicho)
Voy a crear una columna nueva que contenga los valores de la variable “nicho” pero transformados con log10
datos["logNicho"] <- log(datos$nicho)
plot(datos$area, datos$logNicho)
Vuelvo a hacer el modelo de regresión lineal
reg.l2 <- lm(datos$logNicho~datos$area)
reg.l2
##
## Call:
## lm(formula = datos$logNicho ~ datos$area)
##
## Coefficients:
## (Intercept) datos$area
## 1.75181 0.03249
Extraigo los valores de la línea de tendencia (intercepto y la pendiente). Uso str para saber donde están.
str(reg.l2)
## List of 12
## $ coefficients : Named num [1:2] 1.7518 0.0325
## ..- attr(*, "names")= chr [1:2] "(Intercept)" "datos$area"
## $ residuals : Named num [1:131] -0.2301 -0.4484 0.6436 -0.0346 -0.8426 ...
## ..- attr(*, "names")= chr [1:131] "1" "2" "3" "4" ...
## $ effects : Named num [1:131] -21.1738 -0.4626 0.6935 0.0209 -0.7738 ...
## ..- attr(*, "names")= chr [1:131] "(Intercept)" "datos$area" "" "" ...
## $ rank : int 2
## $ fitted.values: Named num [1:131] 1.91 1.89 1.89 1.9 1.91 ...
## ..- attr(*, "names")= chr [1:131] "1" "2" "3" "4" ...
## $ assign : int [1:2] 0 1
## $ qr :List of 5
## ..$ qr : num [1:131, 1:2] -11.4455 0.0874 0.0874 0.0874 0.0874 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:131] "1" "2" "3" "4" ...
## .. .. ..$ : chr [1:2] "(Intercept)" "datos$area"
## .. ..- attr(*, "assign")= int [1:2] 0 1
## ..$ qraux: num [1:2] 1.09 1.07
## ..$ pivot: int [1:2] 1 2
## ..$ tol : num 1e-07
## ..$ rank : int 2
## ..- attr(*, "class")= chr "qr"
## $ df.residual : int 129
## $ xlevels : Named list()
## $ call : language lm(formula = datos$logNicho ~ datos$area)
## $ terms :Classes 'terms', 'formula' language datos$logNicho ~ datos$area
## .. ..- attr(*, "variables")= language list(datos$logNicho, datos$area)
## .. ..- attr(*, "factors")= int [1:2, 1] 0 1
## .. .. ..- attr(*, "dimnames")=List of 2
## .. .. .. ..$ : chr [1:2] "datos$logNicho" "datos$area"
## .. .. .. ..$ : chr "datos$area"
## .. ..- attr(*, "term.labels")= chr "datos$area"
## .. ..- attr(*, "order")= int 1
## .. ..- attr(*, "intercept")= int 1
## .. ..- attr(*, "response")= int 1
## .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
## .. ..- attr(*, "predvars")= language list(datos$logNicho, datos$area)
## .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric"
## .. .. ..- attr(*, "names")= chr [1:2] "datos$logNicho" "datos$area"
## $ model :'data.frame': 131 obs. of 2 variables:
## ..$ datos$logNicho: num [1:131] 1.68 1.44 2.53 1.86 1.07 ...
## ..$ datos$area : num [1:131] 4.92 4.12 4.28 4.48 4.95 ...
## ..- attr(*, "terms")=Classes 'terms', 'formula' language datos$logNicho ~ datos$area
## .. .. ..- attr(*, "variables")= language list(datos$logNicho, datos$area)
## .. .. ..- attr(*, "factors")= int [1:2, 1] 0 1
## .. .. .. ..- attr(*, "dimnames")=List of 2
## .. .. .. .. ..$ : chr [1:2] "datos$logNicho" "datos$area"
## .. .. .. .. ..$ : chr "datos$area"
## .. .. ..- attr(*, "term.labels")= chr "datos$area"
## .. .. ..- attr(*, "order")= int 1
## .. .. ..- attr(*, "intercept")= int 1
## .. .. ..- attr(*, "response")= int 1
## .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
## .. .. ..- attr(*, "predvars")= language list(datos$logNicho, datos$area)
## .. .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric"
## .. .. .. ..- attr(*, "names")= chr [1:2] "datos$logNicho" "datos$area"
## - attr(*, "class")= chr "lm"
intercepto <- reg.l2$coefficients[1] # intercepto en Y
pendiente <- reg.l2$coefficients[2] # pendiente
Ploteo con la línea de ajuste
plot(datos$area, datos$logNicho)
abline(a=intercepto, b=pendiente)
plot(datos$area, datos$logNicho, xlab="Area", ylab="Nicho")
abline(a=intercepto, b=pendiente)
EJERCICIO 1
Hagamos lo mismo, pero con un conjunto de datos más grandes.
datos_grandes <- spp.areas.dist
datos_grandes["log_Nichos"]<- NA
Extraigo los datos de distancias
nichos <- as.numeric(as.vector(datos_grandes$distancias))
## Warning: NAs introducidos por coerción
Transformación logarítmica
log_nichos<-log(nichos)
Ahora se los pego a mis datos
datos_grandes$log_Nichos <- log_nichos
Ahora cada uno debe hacer la regresión y gráficar con la línea de ajuste del modelo.
Ahora trabajaremos con archivos tipo ASCII (rasters) y localidades georeferenciadas.
library(raster)
## Loading required package: sp
Subo los datos de localidades de una especie
cardon <- read.csv("cardon.csv")
Cargo los archivos ASCII de la región
varclim <- list.files(path="./", pattern = "asc", full.names = TRUE)
varclim
## [1] "./bio12.asc" "./bio5.asc" "./bio6.asc"
Hago un stack (una pila de rasters) con los tres archivos ascii
capas <- stack(varclim)
Puedo convertir las capas climáticas a puntos
puntos <- rasterToPoints(capas[[1]], fun=NULL, spatial=TRUE)
Extraigo los datos de cada capa climática de cada punto
bios_pts <- extract(capas, puntos)
Generamos un dataframe con las coordenadas geográficas
bios_pts <- data.frame(coordinates(puntos), bios_pts)
class(bios_pts)
## [1] "data.frame"
También se puede hacer de esta forma, pero hay una diferencia. ¿Cuál es?
pts <- rasterToPoints(capas[[1]], fun=NULL, spatial=TRUE)
bios_points <- extract(capas, pts)
coordinates<-coordinates(pts)
bios_points <- cbind(coordinates, bios_points)
class(bios_points)
## [1] "matrix"
Para cambiar de matriz a dataframe, ¿Cómo lo hago?
bios_points <- as.data.frame(bios_points)
class(bios_points)
## [1] "data.frame"
Veamos si son iguales los dos dataframes. Gráficamos ambas.
plot(bios_points$bio12, bios_pts$bio12)
Convertir el dataframe en un objeto espacial (tipo SIG). En este caso, convertiremos el archivo de coordenadas de una especie de cactus (Cardon) en una objeto espacial.
coordinates(cardon)=~LONGITUDE+LATITUDE
class(cardon)
## [1] "SpatialPointsDataFrame"
## attr(,"package")
## [1] "sp"
Extraer los datos climáticos para el Cardon
cardon_clima <- extract(capas, cardon)
cardon_clima <- data.frame(coordinates(cardon), cardon_clima)
Renombrar las columnas de un dataframe
library(plyr)
cardon_clima<-rename(cardon_clima, c("LONGITUDE"="x", "LATITUDE"="y"))
Adicionar una columna a un daframe con un identicador
cardon_clima["sitio"] <- "cardon"
bios_points["sitio"] <- "entorno"
Combinar los dos dataframes usando la misma columna nueva (sitio). Aunque ambos tienen diferentes filas es posible hacerlo porque tienen el mismo número de columnas.
cardon_entorno <- rbind(cardon_clima, bios_points)
Lo vuelvo objeto espacial y luego dataframe. Importante que aprendan esto para ir de un tipo de objeto en R a otro y poder hacer muchísimas cosas.
coordinates(cardon_entorno)=~x+y
cardon_entorno <- as.data.frame(cardon_entorno)
Eso es todo por ahora!
Escrito por Julián A. Velasco, 5 de Julio de 2018.
```