Los condicionales corresponden a una estructura en la cual ejecutaremos una acción si cierta condición es verdadera, y ejecutaremos otra acción para el caso en que dicha condición sea falsa. Para entender de manera más sencilla la idea anterior, consideremos el siguiente ejemplo:
Así, con el ejemplo del semáforo tendríamos el siguiente diagrama
Podemos implementar condicionales en R
siguiendo la
siguiente estructura:
if (condicion) {
acciones a realizar en caso de que la condicion
sea verdadera
} else {
acciones a realizar en caso de que la condicion
sea verdadera
}
Continuando con nuestro ejemplo, escribimos
# Condicion
semaforo_en_verde = TRUE
# Implementamos el condicional if
if (semaforo_en_verde) {
# Accion a realizar en caso de que la condicion sea verdadera:
# Imprimieremos un mensaje
print("No cruzar")
} else {
# Accion a realizar en caso de que la condicion sea falsa:
# Imprimieremos un mensaje
print("Puedes cruzar")
}
## [1] "No cruzar"
Dado que la condición impuesta es verdadera, entonces se ha impreso
el mensaje "No cruzar"
. Veamos ahora el resultado en caso
de que la condición sea falsa
# Condicion
semaforo_en_verde = F
# Implementamos el condicional if
if (semaforo_en_verde) {
# Accion a realizar en caso de que la condicion sea verdadera:
# Imprimieremos un mensaje
print("No cruzar")
} else {
# Accion a realizar en caso de que la condicion sea falsa:
# Imprimieremos un mensaje
print("Puedes cruzar")
}
## [1] "Puedes cruzar"
Veamos otro ejemplo práctico. Escribiremos un código para determinar si un número es par o impar. Para ello utilizaremos el siguiente criterio: un número entero \(n\) es par si el residuo de la división \(\frac{n}{2}\) es cero. En caso contrario el número \(n\) será impar, por ejemplo:
Así:
# Identificador de numeros pares e impares.
# Definimos el numero n:
n = 7
# Implementamos un condicional
if (n %% 2 == 0) {
print("El número considerado es par")
} else {
print("El número considerado es impar")
}
## [1] "El número considerado es impar"
donde el símbolo ==
significa igualdad, pues recordemos
que el símbolo =
significa asignación. Luego, la condición
n %% 2 == 0
puede leerse como: el residuo de dividir n
entre 2 es igual a 0. Lo anterior puede ser verdadero o falso, según sea
el valor de \(n\), lo cual nos arrojará
un booleano (FALSE
o TRUE
), y con base a él
ejecutaremos la acción en caso de que la condición sea verdadera o
falsa. Podemos probar el código anterior con diferentes números de
n
# Identificador de numeros pares e impares.
# Definimos el numero n:
n = 240
# Implementamos un condicional
if (n %% 2 == 0) {
print("El número considerado es par")
} else {
print("El número considerado es impar")
}
## [1] "El número considerado es par"
o también
# Identificador de numeros pares e impares.
# Definimos el numero n:
n = 1179
# Implementamos un condicional
if (n %% 2 == 0) {
print("El número considerado es par")
} else {
print("El número considerado es impar")
}
## [1] "El número considerado es impar"
veamos que, cada que queremos utilizar el código para determinar si
un número n
es par o impar, debemos de escribir de nuevo
todo el código del condicional, lo cual no es lo óptimo. Para este tipo
de situaciones donde queremos utilizar un mismo código
para diferentes valores de una variable, en este caso de la
n
, podemos implementar el concepto de Función definida
por el usuario.
Dentro de R
existen muchas funciones ya integradas, por
ejemplo
# Funcion sample
sample(1:10, 20, replace = T)
## [1] 3 6 2 3 4 6 3 2 3 2 3 6 2 3 9 7 5 1 10 8
# Funcion para crear un vector c()
v1 <- c(1:100)
# Funcion para calcular el promedio de un vector
mean(v1)
## [1] 50.5
etcétera. Asimismo, podremos definir nuestras propias funciones. Para ello utilizaremos la siguiente estructura:
nombre_de_la_funcion <- function(<<parametros>>){
<<acciones que realiza la funcion>>
return(<<valores que regresa la funcion>>)
}
Por ejemplo, en nuestro caso queremos definir una función que, dado
un número n
, nos diga si el número es par o impar. De tal
manera escribimos:
# Definimos nuestra primera funcion
par_impar <- function(n){
# Implementamos un condicional
if (n %% 2 == 0) {
return("El número considerado es par")
} else {
return("El número considerado es impar")
}
}
donde, dado un valor de n
, la función nos regresará un
mensaje diciéndonos si el número es par o impar. Algo que es importante
de mencionar es que, dentro de R
la identación o el
“sangrado” de las líneas de código es importante
Esto es, cada estructura en R
tiene su propio nivel de
identación, además, podemos anidar estructuras (así como lo hicimos
colocando dentro de la función un condicional)
Las funciones definidas por el usuario son realmente flexibles y versátiles, lo que nos permite definir muchas, muchas, cosas. Por ejemplo:
# Definimos una funcion que calcule el promedio de un vector
mi_promedio <- function(vector){
# Calculamos la suma de las entradas del vector
suma = sum(vector)
# Calculamos el numero total de entradas del vector
n = length(vector)
# Regresamos el promedio del vector
return(suma / n)
}
# Probemos la funcion:
mi_promedio(c(1,2,3,4,5))
## [1] 3
# Comprobamos
mean(c(1,2,3,4,5))
## [1] 3
Con esta misma idea, podemos definir, tal cual, funciones matemáticas. Por ejemplo, considerando la función \(f(x)=x^{2}\), escribimos
# Definiendo funciones matematicas
f <- function(x){
return(x ** 2)
}
# Probamos la funcion para distintos valores
f(0)
## [1] 0
f(-5)
## [1] 25
f(25)
## [1] 625
Podemos definir una función que calcule al área de un círculo dependiendo el valor del radio:
area_circ <- function(r){
return(pi * r ^ 2)
}
# Probamos la funcion
area_circ(5)
## [1] 78.53982
donde
pi
## [1] 3.141593
nos da el valor del número \(\pi\).
Para finalizar, notemos que, dado un vector, podemos acceder de manera individual a cada uno de sus elementos. Por ejemplo
# Definimos un vector
vc <- seq(0, 10, by=2)
vc
## [1] 0 2 4 6 8 10
donde el 0
está en la primera posición
del vector; el 2
está en la segunda
posición; el 4
está en la tercera
posición; y así sucesivamente. Podremos acceder a los elementos
de un vector utilizando, el nombre del vector, y corchetes como
sigue
# Elemento en la primera posicion
vc[1]
## [1] 0
# Elemento en la segunda posicion
vc[2]
## [1] 2
# Elemento en la quinta posicion
vc[5]
## [1] 8
Adicionalmente, podemos obtener ciertos elementos del vector
# Obtendremos los elementos de la posicion 1 a la posicion 3
vc[1:3]
## [1] 0 2 4
Los bucles son estructuras que nos permiten realizar cierta acción de
manera repetida. Principalmente tendremos dos tipos de bucles: el bucle
for
y el bucle while
.
El bucle for
nos permitirá repetir una acción un
determinado número de veces.
El bucle while
nos permitirá repetir una acción
mientras cierta condición sea verdadera.
for
Como su nombre lo indica, el bucle for
representa un
proceso repetitivo, donde ciertas instrucciones se estarán
repitiendo un número determinado de veces. Por ejemplo,
consideremos un vector e imprimamos cada uno de sus elementos
# Vector con entradas de varios tipos de datos
vect2 <- c(10, 'nombre', FALSE)
# Podemos imprimir el PRIMER ELEMENTO del vector anterior colocando entre corchetes el numero 1
print(vect2[1])
## [1] "10"
# Imprimimos el segundo elemento
print(vect2[2])
## [1] "nombre"
# Imprimimos el tercer elemento
print(vect2[3])
## [1] "FALSE"
Supongamos que tenemos un vector con 100 entradas y queremos imprimir
cada una de ellas. Si realizamos el mismo proceso anterior pero ahora
para el vector de 100 entradas, tardaremos un tiempo considerable. Como
alternativa podemos utilizar un bucle for
cuya estructura
básica es:
for (recorrido) {
acción a repetir
}
Lo que haremos será imprimir cada uno de los elementos del vector
vect2
utilizando un bucle for
. Notamos que
dicho vector tiene en total 3 elementos, de modo que necesitaremos crear
un vector:
# Creamos un vector
vect_recorrido <- 1:3
vect_recorrido
## [1] 1 2 3
el cual tiene los elementos que ocupamos para acceder a todos los
elementos del vector vect2
. Luego implementamos el
for
for (i in vect_recorrido){
# Accion a ejecutar repetidamente
print(vect2[i])
}
## [1] "10"
## [1] "nombre"
## [1] "FALSE"
donde la i
es una variable propia del bucle
for
(y en realidad puede llamarse como sea). La variable
del for
recorrerá cada elemento del vector
vect_recorrido
de la siguiente manera:
i
vale 1 (que es el primer
valor del vector vect_recorrido
) y así se ejecuta la acción
print(vect2[i])
, pero i
vale 1, por lo cual se
ejecuta print(vect2[1])
, lo que nos arroja
"10"
.i
vale 2 (que es el segundo elemento del
vector vect_recorrido
) y por ello se ejecuta
print(vect2[2])
que nos arroja "nombre"
.print(vect2[3])
que nos arroja
"FALSE"
.El bucle finaliza cuando la i
recorre todos los
elementos de vect_recorrido
. Veamos una alternativa del
código anterior
# directamente colocamos la secuencia del 1 al 3
for (i in 1:3){
# Accion a ejecutar repetidamente
print(vect2[i])
}
## [1] "10"
## [1] "nombre"
## [1] "FALSE"
o también
# directamente colocamos la secuencia del 1 al 3
for (i in 1:length(vect2)){
# Accion a ejecutar repetidamente
print(vect2[i])
}
## [1] "10"
## [1] "nombre"
## [1] "FALSE"
Asimismo, directamente podemos recorrer los elementos del vector
Vect2
sin la necesidad de acceder a las posiciones con los
corchetes:
# Recorremos directamente los elementos de vect2
for (i in vect2){
# Accion a ejecutar repetidamente
print(i)
}
## [1] "10"
## [1] "nombre"
## [1] "FALSE"
donde en este caso:
i
tomará el valor de
"10"
.i
tomará el valor de
"nombre"
.i
tomará el valor de "FALSE"
y el bucle termina.Veamos un ejemplo práctico. Lo que haremos será definir un vector sin elementos, y en éste le iremos agregando únicamente los números pares en el rango del 1 al 50:
# Definimos un vector con la secuencia de numeros del 1 al 50
secuencia <- 1:50
# definimos un vector vacio para ir almacenando los numeros pares
pares <- c()
# Implementamos el for que recorrera cada uno de los numeros de la secuencia anterior
for (i in secuencia){
# Utilizaremos un condicional para detectar los numeros pares
if (i %% 2 == 0){
# Si i es par, lo agregamos a la lista pares
pares = append(pares, i)
}
}
# Veamos
pares
## [1] 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50
donde:
for
recorrimos todos los elementos del 1
al 50.if
filtramos solo los numeros pares.
Dichos paremos los agregamos a la lista pares
append(pares, i)
, pero para guardar la lista paremos con
los elementos nuevos debemos estar actualizando la variable
pares
, por lo cual escribimos
pares = append(pares, i)
.i
vale 1, como el 1 no es
par, entonces pasamos a la siguiente iteración.i
vale 2, como el dos es
par, entonces append(pares, i)
resulta en el vector
c(2)
. Para guardar ese vector resultanto lo almacenamos en
la variable pares
.i
vale 4, de modo que
append(pares, i)
resulta en el vector c(2, 4)
y guardamos ese vector en la variable pares
.Recordemos que definimos la función \(f(x)=x^{2}\). Podemos evaluar con distintos
valores de la \(x\) utilizando un bucle
for
# Evaluamos la funcion para los numeros del -5 al 5
for (x in seq(-5,5)) {
print(f(x))
}
## [1] 25
## [1] 16
## [1] 9
## [1] 4
## [1] 1
## [1] 0
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
while
El bucle while
es muy similar al for
. El
bucle for
repite instrucciones un número determinado de
veces, pero el bucle while
repetirá la instrucción
mientras una condición sea verdadera. Cuando dicha
condición impuesta sea falsa, el bucle while
finalizará. La
estructura básica es
while (condicion) {
acción a repetir mientras la condicion sea verdadera
}
Debemos ser cuidadosos con el bucle while
pues si la
condición que imponemos nunca sea falsa, entonces, en teoría, el bucle
while
tampoco se detendrá. Así, dentro del código del
while
debemos escribir el código necesario para evitar que
el bucle while
sea “infinito”. Una de las tantas
estrategias para hacer que el bucle while
se detenga en
cierto punto es utilizando la idea de un contador, por ejemplo
contador = 0
# Implementamos el while imponiendo que la condicion a evaluar sea que el contador sea menor a 10
while (contador < 10) {
# Imprimimos el valor del contador
print(contador)
# En cada iteracion aumentaremos un 1 el contador
contador = contador + 1
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
en la última iteración tenemos que el contador vale 9, después se le
sumará un 1 y por ello el valor se actualiza al 10. El bucle
while
evalúa contador < 10
, donde en ese
momento el contador vale 10, y como la condición es falsa, entonces el
bucle se detiene.
Veamos otros ejemplos
# Definimos la condicion del while
continuar = TRUE
# Definiremos un contador auxiliar
contador <- 0
while (continuar){
# Imprimimos un mensaje
print("Hola")
# Aumentaremos en uno el contador
contador = contador + 1
# Implementamos un condicional para hacer que el
# bucle no sea infinito
if (contador == 3){
continuar = FALSE
}
}
## [1] "Hola"
## [1] "Hola"
## [1] "Hola"
donde:
continuar
es
verdadera por lo que se ejecuta print("hola")
. Aumentamos
en uno el contador, por lo cual contador
ahora vale 1.
Luego, en el if
vemos su contador==3
, lo cual
es falso pues ahora contador
vale 1, de modo que
continuar
sigue siendo verdadera.contador
vale 2 y de nuevo se
ejecuta print("hola")
.contador
vale 3 y de nuevo se
ejecuta print("hola")
. Pero ahora continuar==3
es verdadera, por lo cual se ejecuta la acción del condicional, así
continuar
ahora será falsa y por ende el bucle
while
finaliza. Es usual utilizar variables como contadores
para hacer que el bucle while
no sea infinito. Abordemos
otro ejemplo# Definimos una variable inicial en 0
suma <- 0
# Definimos un contador
n <- 1
# Ejecutamos un bucle while mientras n sea menor o igual a 100
while (n <= 100){
# En cada iteracion, a la variable suma le sumaremos el valor actual de la n
suma = suma + n
# aumentamos en 1 el valor de la n para que eventualmente el bucle se detenga
n = n + 1
}
# Veamos el resultado final almacenado en la variable suma
suma
## [1] 5050
donde, con el código anterior hemos obtenido el resultado de
\[ 1+2+3+4+\cdots+100 \] donde dicha suma se suele denotar por \(\sum_{i=1}^{100}i\), esto es:
\[ \sum_{i=1}^{100}i=1+2+3+4+\cdots+100 \]
¿Cómo funciona el bucle while
anterior?
n
vale 1 y suma
vale cero, de modo que el resultado de suma + n
es 1, por
lo que ahora la variable suma
vale 1.n
vale 2 y suma
vale uno, de modo que el resultado de suma + n
es \(1+2=3\), por lo que ahora la variable
suma
vale 3. Hasta ahora el proceso es \(1+2\).n
vale 3 y suma
vale tres, de modo que el resultado de suma + n
es \(3+3=6=1+2+3\), por lo que ahora la variable
suma
vale 3. Hasta ahora el proceso es \(1+2+3\).n
vale 4 y suma
vale seis, de modo que el resultado de suma + n
es \(6+4=10=1+2+3+4\), por lo que ahora la
variable suma
vale 3. Hasta ahora el proceso es \(1+2+3+4\).Y así sucesivamente, lo cual nos da como resultado \(\sum_{i=1}^{100}i=1+2+3+4+\cdots+100\).
Podemos utilizar un bucle while
para hallar el valor de
\[ \sum_{i=1}^{100}(2\cdot i+4)=[2\cdot (1)+4]+[2\cdot (2)+4]+[2\cdot (3)+4]+\cdots+[2\cdot (100)+4] \] escribiendo
# Definimos una variable inicial en 0
suma <- 0
# Definimos un contador
n <- 1
# Ejecutamos un bucle while mientras n sea menor o igual a 100
while (n <= 100){
# En cada iteracion, a la variable suma le sumaremos el valor de 2*n + 4
suma = suma + 2 * n + 4
# aumentamos en 1 el valor de la n para que eventualmente el bucle se detenga
n = n + 1
}
# Veamos el resultado final almacenado en la variable suma
suma
## [1] 10500
También podemos calcular
\[ \sum_{i=1}^{100}i^{2}=1^{2}+2^{2}+\cdots+100^{2} \] escribiendo
# Definimos una variable inicial en 0
suma <- 0
# Definimos un contador
n <- 1
# Ejecutamos un bucle while mientras n sea menor o igual a 100
while (n <= 100){
# En cada iteracion, a la variable suma le sumaremos el valor n al cuadrado
suma = suma + (n ^ 2)
# aumentamos en 1 el valor de la n para que eventualmente el bucle se detenga
n = n + 1
}
# Veamos el resultado final almacenado en la variable suma
suma
## [1] 338350
Entro otros muchos ejemplos. Es preciso mencionar que, respecto a la
notación, la \(i\) de las sumas la
representamos por la n
del código, realmente no importa el
nombre que le demos a la \(i\) o a la
n
. No obstante, para que sea más concerde la notación,
podemos escribir
# Definimos una variable inicial en 0
suma <- 0
# Definimos un contador
i <- 1
# Ejecutamos un bucle while mientras n sea menor o igual a 100
while (i <= 100){
# En cada iteracion, a la variable suma le sumaremos el valor n al cuadrado
suma = suma + (i ^ 2)
# aumentamos en 1 el valor de la n para que eventualmente el bucle se detenga
i = i + 1
}
# Veamos el resultado final almacenado en la variable suma
suma
## [1] 338350
En resumen vemos que el funcionamiento del while
y del
for
son muy similares.
Define una función que reciba como parámetro un número
n
. Luego, implementa dentro de dicha función un condicional
que actúe de la siguiente manera: si el número n
es mayor a
5, la función nos deberá regresar el mensaje
"El número que ingresaste es mayor a 5"
. Si el número es
menor o igual a 5, entonces deberá regresar un mensaje indicando
justamente eso.
Define una función para calcular el área de un cuadrado dependiendo la longitud de su lado.
Define una función de dos parámetros para calcular el área y el
perímetro de un rectángulo. Para retornar el resultado deberás de
utilizar return(paste(...))
, donde en
paste(...)
deberás combinar cadenas de texto y los valores
obtenidos del área y el perímetro.
Define una función que reciba como parámetros dos vectores y que retorne la unión por filas (u horizontal) de dichos vectores.
Define en código la función matemática \(f(x)=3x^{3}+2x^{2}-1\).
Observación: Deberás probar todas las funciones que definas.
Calcula el valor de \(\sum_{i=1}^{50}i^{3}\) y \(\sum_{i=}^{50}(2\cdot i - 3)\), utilizando
bucles while
.
Crea un vector aleatorio de 20 entradas y recorre cada uno de sus
elementos utilizando un bucle for
.
Crea una función que reciba como parámetro un vector con entradas
de números enteros (e.j. c(1,2,3)
). Dentro de tu función
define una lista vacía y mediante un bucle for
recorre
todos los elementos del vector que se ingresó como parámetro y agrega a
la lista vacía que creaste aquellos números que sean pares. La función
deberá regresar la lista con los números pares del vector que se
ingresó.
El “esqueleto” de lo que se te pide en el ejercicio anterior es:
tu_funcion <- function(vector_parametro){
# Defines el vector vacio
vect_vacio <- c()
# Recorres el vector vector_parametro
for (i in vector_parametro) {
# con un if filtras los elementos del vector vector_parametro que sean numeros pares y los agregas al vector vacio
if (condition) {
# implementa el codico para hacer el filtro y agregar los pares al vector vect_vacio
}
}
return(vect_vacio)
}