Conocer los principales comandos en la programación en R
Desarrollar diagramas de flujos
Crear algoritmos y opciones avanzadas de manipulación de dataframes
Nos permite controlar la manera en cómo se ejecuta nuestro código (establecen condicionales).
Las estructuras de control más usadas en R son las siguiente:
if se usa cuando deseamos que una operación se ejecute cuando cumple una condición deseada (Ej. Si esta condición es cierta, entonces haz una operación específica)
else se usa para indicarle a R qué hace en caso de que la condición de un if no se cumpla.
La estructura de un la función if es la siguiente
#if (condicion) {
# proceso_si_se_cumple_condicion
#}
Si la condición es verdadera, entonces se realiza la operación. En caso contrario, no se realiza la operación. Veamos algunos ejemplos:
#Se cumple la condición y se muestra "verdadero".
if (19 > 15) {
"verdadero"
}
## [1] "verdadero"
#Si no se cumple la condición, el código no se ejecuta.
if (10 > 15) {
"verdadero"
}
la función else complementa a if, es decir, le asigna un proceso siempre en cuando la condición inicial no se cumpla. En otras palabras, un if con else es la manera de decirle a R:
La estructura de in if con else es el siguiente:
#if (condition) {
# proceso1
#} else {
# proceso2
#}
Del ejemplo anterior podemos hacer las siguientes modificaciones:
#Se cumple condición
if (18 > 15) {
"Verdadero"
} else {
"Falso"
}
## [1] "Verdadero"
#No se cumple condición
if (10 > 15) {
"Verdadero"
} else {
"Falso"
}
## [1] "Falso"
Para ilustrar el uso de if y else definiremos una función que calcule el promedio de calificaciones de un estudiante y, dependiendo de la calificación calculada, nos devuelva un mensaje específico.
promedio <-
function(nota){
mean(nota)
}
promedio(c(5,8,9,6,5))
## [1] 6.6
Ahora realizaremos un proceso de tal forma que la función nos muestre si un estudiante ha aprobado o no. Si asumimos que un estudiante necesita obtener 5 o más en promedio para aprobar podemos decir:
promedio <-
function(notas) {
media <- mean(notas)
if (media >= 5) {
print("Aprobado")
} else{
print("Desaprobado")
}
}
promedio(c(6,4,5,7,5,6))
## [1] "Aprobado"
promedio(c(3,4,4,4,5,3))
## [1] "Desaprobado"
La función ifelse() permite vectorizar if, else. En lugar de escribir una línea de código para cada comparación, podemos usar una sola llamada a esta función, que se aplicará a todos los elementos de un vector.
Si intentamos usar if else con un vector, se nos mostrará una advertencia:
if (1:10 < 3) {
"Verdadero"
}
## Warning in if (1:10 < 3) {: the condition has length > 1 and only the first element will be
## used
## [1] "Verdadero"
El mensaje muestra que la condición sólo es evaluada para el primer elemento del vector 1:10, es decir para 1. Los demás elementos son ignorados.
Por el contrario, con ifelse le indicamos que la condición debe de cumplirse para cada uno de los elementos del vector. Esta función tiene tres argumentos:
un condicional
un valor que indique qué mostrar si la condición se cumple
un valor que indique qué mostrar si la condición no se cumple
vector <- 1:10
ifelse(vector > 5, "TRUE", "FALSE")
## [1] "FALSE" "FALSE" "FALSE" "FALSE" "FALSE" "TRUE" "TRUE" "TRUE" "TRUE" "TRUE"
edad <- c(10,15,17,19, 20, 13, 11, 16, 15)
ifelse(edad >= 15, "TRUE", "FALSE")
## [1] "FALSE" "TRUE" "TRUE" "TRUE" "TRUE" "FALSE" "FALSE" "TRUE" "TRUE"
#Determinar cual de los números del 1 al 60 son pares y cuales impares ¿que se debe cumplir?
numeros <- 1:60
ifelse(numeros %% 2 == 0, "par", "impar")
## [1] "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar"
## [12] "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par"
## [23] "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar"
## [34] "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par"
## [45] "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar" "par" "impar"
## [56] "par" "impar" "par" "impar" "par"
Otro ejemplo más complejo. Solicitamos sólo los números que son exactamente divisibles entre 2 y 3.
numeros <- 1:20
ifelse(numeros %% 2 == 0 & numeros %% 3 == 0,
"Divisible",
"No divisible")
## [1] "No divisible" "No divisible" "No divisible" "No divisible" "No divisible" "Divisible"
## [7] "No divisible" "No divisible" "No divisible" "No divisible" "No divisible" "Divisible"
## [13] "No divisible" "No divisible" "No divisible" "No divisible" "No divisible" "Divisible"
## [19] "No divisible" "No divisible"
Conocer esta función puede ser particularmente útil para recodificar datos. Por ejemplo:
sexo <- c(0, 1, 0, 0, 0, 0, 0, 1, 1, 0)
sexo <- ifelse(sexo == 0, "hembra", "macho")
sexo
## [1] "hembra" "macho" "hembra" "hembra" "hembra" "hembra" "hembra" "macho" "macho" "hembra"
Recordemos que para hacer uso de las condicionales podemos hacer uso de las funciones if, else, if else y/o uso de indexaciones combinado con operadores lógicos y/o relacionales. (https://github.com/AngeloCris/computacionCientifica_2021/blob/master/semana7_8/Semana7-y-8.md).
datosCrangrejo <-
read.table("datos/datos_cangrejos.txt",
sep = ",",
header = TRUE)
datosCrangrejo
Para determinar el total de filas de mi data frame usamos la función length.
attach(datosCrangrejo)
length(datosCrangrejo$Year)
## [1] 71013
La base de datos muestra los registros mensuales de la longitud y sexo de un cangrejo para el periodo 2008 y 2014. En función a lo mencionado anteriormente, resolvamos lo siguiente.
Crear una columna denominada “sexo” que reemplace las categorías de la columna “sex”. Considere lo siguiente
“F” = “female”
“0” = “ovígera”
#Uso del ifelse
#Para condicionales vectorizados
unique(datosCrangrejo$Sex)
datosCrangrejo$sexo <-
ifelse(datosCrangrejo$Sex == "F", "Females", "Ovigera")
head(datosCrangrejo)
table(datosCrangrejo$sexo)
Crear una columna denominada “estacion” que reemplace las categorías de la columna “Month”. Considere lo siguiente:
verano = 12, 1, 2
otoño = 3, 4, 5
invierno = 6, 7, 8
primavera = 9, 10, 11
datosCrangrejo$estacion <- "NA"
datosCrangrejo$estacion[datosCrangrejo$Month %in% c(12,1,2)] <- "verano"
datosCrangrejo$estacion[datosCrangrejo$Month %in% c(3,4,5)] <- "otoño"
datosCrangrejo$estacion[datosCrangrejo$Month %in% c(6,7,8)] <- "invierno"
datosCrangrejo$estacion[datosCrangrejo$Month %in% c(9,10,11)] <- "primavera"
head(datosCrangrejo)
## Year Sector Month Sex C_Length sexo estacion
## 1 2013 Sector_1 11 F 123.64 Females primavera
## 2 2013 Sector_1 11 F 118.47 Females primavera
## 3 2013 Sector_1 11 F 115.53 Females primavera
## 4 2013 Sector_1 11 F 113.98 Females primavera
## 5 2013 Sector_1 11 F 108.75 Females primavera
## 6 2013 Sector_1 11 F 106.12 Females primavera
#Deseamos extraer las posiciones de las categorías que pertenecen a la estación primavera.
which(datosCrangrejo$estacion == "primavera")
#Extrayendo los valores de las variables de esta categoría
datosCrangrejo[which(datosCrangrejo$estacion == "primavera"),]
media <- mean(datosCrangrejo$C_Length, na.rm = T)
head(which(datosCrangrejo$C_Length > media))
## [1] 1 2 3 4 5 6
head(datosCrangrejo[which(datosCrangrejo$C_Length > media),])
## Year Sector Month Sex C_Length sexo estacion
## 1 2013 Sector_1 11 F 123.64 Females primavera
## 2 2013 Sector_1 11 F 118.47 Females primavera
## 3 2013 Sector_1 11 F 115.53 Females primavera
## 4 2013 Sector_1 11 F 113.98 Females primavera
## 5 2013 Sector_1 11 F 108.75 Females primavera
## 6 2013 Sector_1 11 F 106.12 Females primavera
head(datosCrangrejo[datosCrangrejo$C_Length > media,])
## Year Sector Month Sex C_Length sexo estacion
## 1 2013 Sector_1 11 F 123.64 Females primavera
## 2 2013 Sector_1 11 F 118.47 Females primavera
## 3 2013 Sector_1 11 F 115.53 Females primavera
## 4 2013 Sector_1 11 F 113.98 Females primavera
## 5 2013 Sector_1 11 F 108.75 Females primavera
## 6 2013 Sector_1 11 F 106.12 Females primavera
datosCrangrejo$C_Length > media
which(datosCrangrejo$C_Length > media & datosCrangrejo$sexo == "Females")
head(datosCrangrejo[which(datosCrangrejo$C_Length > media & datosCrangrejo$sexo == "Females"),])
tmin <- 110
datosCrangrejo$lengthMin <- "NA"
datosCrangrejo$lengthMin <- ifelse(datosCrangrejo$C_Length > 110, ">tmin", "<tmin")
head(datosCrangrejo)
## Year Sector Month Sex C_Length sexo estacion lengthMin
## 1 2013 Sector_1 11 F 123.64 Females primavera >tmin
## 2 2013 Sector_1 11 F 118.47 Females primavera >tmin
## 3 2013 Sector_1 11 F 115.53 Females primavera >tmin
## 4 2013 Sector_1 11 F 113.98 Females primavera >tmin
## 5 2013 Sector_1 11 F 108.75 Females primavera <tmin
## 6 2013 Sector_1 11 F 106.12 Females primavera <tmin
La estructura for permite ejecutar bucles realizando una operación para cada elemento de un conjunto de datos, es decir, hace un proceso de iteración.
#la estructura es
#for (variable in vector) {
# proceso
#}
Esta estructura le dice a R:
Cuando observamos la estructura del bucle, la “variable” puede ser un elemento cualquiera (la podemos llamar como nosotros queramos) pero el objeto “vector” tiene que ser un objeto existente.
Algunos ejemplo:
vector <- 5:10
vector[1] + 2
## [1] 7
vector[2] + 2
## [1] 8
vector[3] + 2
## [1] 9
vector[4] + 2
## [1] 10
vector[5] + 2
## [1] 11
for (i in length(vector)) {
vector1 <- vector[i] + 2
}
vector1
## [1] 12
print(paste("El año es", 1990))
## [1] "El año es 1990"
print(paste("El año es", 1991))
## [1] "El año es 1991"
print(paste("El año es", 1992))
## [1] "El año es 1992"
print(paste("El año es", 1993)) #asi sucesivamente
## [1] "El año es 1993"
print(paste("El año es", 2019))
## [1] "El año es 2019"
print(paste("El año es", 2020))
## [1] "El año es 2020"
print(paste("El año es", 2021))
## [1] "El año es 2021"
Cuando la longitud del vector x es grande, este proceso se vuelve tedioso. En este caso se recomienda usar un loop en R para que el proceso se repita continuamente.
for (year in 1990:2021) {
print(paste("El año es", year))
}
#Vector u1
u1 <- rnorm(30)
print("Este loop calculará el cuadrado de los 10 primeros elementos del vector u1")
## [1] "Este loop calculará el cuadrado de los 10 primeros elementos del vector u1"
usq <- 0
for (i in 1:10) {
usq[i] <- u1[i] * u1[i]
print(usq[i])
}
## [1] 0.7238214
## [1] 1.139243
## [1] 0.3262812
## [1] 0.5664337
## [1] 0.005021815
## [1] 1.810217
## [1] 1.192867
## [1] 0.4257675
## [1] 0.08065857
## [1] 0.003153246
Tipo de bucle que realizará un proceso mientras la condición propuesta sea verdadera.
#while (condicion) {
# operaciones
#}
Algunos ejemplos:
limite <- 5
inicio <- 0
while (inicio < limite) {
print("Cuando el valor de inicio sea mayor o igual a 5, detener operación")
inicio <- inicio + 1
}
## [1] "Cuando el valor de inicio sea mayor o igual a 5, detener operación"
## [1] "Cuando el valor de inicio sea mayor o igual a 5, detener operación"
## [1] "Cuando el valor de inicio sea mayor o igual a 5, detener operación"
## [1] "Cuando el valor de inicio sea mayor o igual a 5, detener operación"
## [1] "Cuando el valor de inicio sea mayor o igual a 5, detener operación"
Tener cuidado con crear bucles infinitos! Si se ejecuta el While con una condición que nunca termine, este no se detendrá.
#while (inicio < limite) {
# print("Cuando el valor de inicio sea mayor a 5, detener la operación")
#}
#Crear una variable con valor 1
inicio <- 1
#Create un loop
while (inicio <= 10) {
cat("Este es el loop número", inicio)
inicio <- inicio + 1
print(inicio)
}
## Este es el loop número 1[1] 2
## Este es el loop número 2[1] 3
## Este es el loop número 3[1] 4
## Este es el loop número 4[1] 5
## Este es el loop número 5[1] 6
## Este es el loop número 6[1] 7
## Este es el loop número 7[1] 8
## Este es el loop número 8[1] 9
## Este es el loop número 9[1] 10
## Este es el loop número 10[1] 11
#Variable de inicialización
n <- 0
potencia <- 0
#While loop
while (potencia <= 4000) {
n <- n + 1 #definiendo número entero positivo
potencia <- n ^ 2 #definiendo el cuadrado de ese número
}
x <- c(1, 2, 3, 4)
y <- c(0, 0, 5, 1)
n <- length(x)
i <- 0
z <- numeric(n)
while (i <= n) {
z[i] <- x[i] + y[i]
i <- i + 1
}
z
## [1] 1 2 8 5
contador <- 0
suma <- 0
while (suma < 50) {
suma <- suma + sample(x = 1:10, size = 1)
contador <- contador + 1
}
En clase se vió un ejemplo en donde los elementos de un vector x correspondían a conteos de animales avistados a lo largo de un transecto. Solicitaban encontrar en punto a lo largo del transecto en que el número acumulado de animales avistados es al menos 50
x <- c(1,0,1,2,1,4,7,2,6,1,8,2,0,3,0,10,8,5,4,5,8,2,0,5,8)
sum <- 0
i <- 0
while (sum < 50) {
i = i + 1
sum = sum + x[i]
print(sum)
}
## [1] 1
## [1] 1
## [1] 2
## [1] 4
## [1] 5
## [1] 9
## [1] 16
## [1] 18
## [1] 24
## [1] 25
## [1] 33
## [1] 35
## [1] 35
## [1] 38
## [1] 38
## [1] 48
## [1] 56