library(learnr) knitr::opts_chunk$set(echo = FALSE)
knitr::include_graphics("images/operadores_logicos_relacionales.jpg")
El presente tutorial pretende ser un vehículo de aprendizaje interactivo para los novatos en el lenguaje R.
Ha sido desarrollado a través del paquete learnr que permite utilizar documentos RMarkdown para generar tutoriales interactivos.
Como se explica en la página de learnr, los tutoriales consisten en contenido (texto, figuras, ilustraciones, ecuaciones, vídeos, etc.) junto con componentes interactivos, como preguntas con múltiples opciones y fragmentos de código de R que los usuarios pueden editar y ejecutar directamente, para verificar y reforzar la comprensión.
Estos tutoriales conservan automáticamente el avance que un usuario realizó, por lo que si un estudiante trabaja en algunos ejercicios o preguntas y vuelve al tutorial más tarde, puede retomarlo exactamente donde lo dejó.
Este tutorial ha sido publicado como el paquete fundamentosr.
Los objetivos de aprendizaje del presente tutorial son los siguientes:
Los operadores relacionales son símbolos mediante los cuales podemos realizar operaciones comparativas cuyos resultados son objetos de la clase logical, que pueden adoptar los valores TRUE o FALSE, según se cumpla o no la relación propuesta en la operación. Las operaciones relacionales son las siguientes:
==),!=), <), <=), >),>=).En la siguiente tabla se muestran ejemplos de uso de los operadores relacionales con los valores literales $7$ y $3$:
Operación | Operador | Ejemplo | Resultado
|:--:|:--:|:--:|:--:|
Igual que | == | 7 == 3 | FALSE
No es igual que | != | 7 != 3 | TRUE
Menor que | < | 7 < 3 | FALSE
Menor o igual que| <= | 7 <= 3 | FALSE
Mayor que | > | 7 > 3 | TRUE
Mayor o igual que| >= | 7 >= 3 | TRUE
Es posible comparar cualquier tipo de dato sin que resulte en un error. Sin embargo, al usar los operadores relacionales con cadenas de caracteres (character), estos tienen un comportamiento especial, permitiendo realizar comparaciones por orden alfabético. Veamos a continuación un ejemplo simple.
"Juan" < "Luis" "Luis" < "Pablo" "Pablo" > "Juan" "Juan" == "Juan" "Juan" != "JUAN"
Con las tres primeras comparaciones podríamos determinar que por orden alfabético "Juan" es anterior a "Luis" y "Luis" es anterior a "Pablo". La cuarta comparación nos presenta dos cadenas idénticas. La última comparación muestra que, obviamente, no es lo mismo mayúscula que minúscula. Cambia los operadores relacionales del código anterior para que los resultados de todas las operaciones sean FALSE.
Los operadores lógicos son usados para operaciones de álgebra booleana, es decir, para describir relaciones lógicas, expresadas como verdadero (TRUE) o falso (FALSE). Pueden ser usados con datos de tipo numérico (numeric) y lógico (logical). Al igual que con los operadores relacionales, los operadores lógicos siempre devuelven TRUE o FALSE. En R están disponibles los siguientes operadores lógicos:
!),isTRUE),&, &&), |, ||), xor).En la siguiente tabla se muestran ejemplos de uso de los operadores relacionales con los valores literales TRUE y FALSE:
Operación | Operador | Ejemplo | Resultado
|:--:|:--:|:--:|:--:|
Negación (NOT) | ! | !TRUE | FALSE
- | - | !FALSE | TRUE
Afirmación (IS) | isTRUE | isTRUE(TRUE) | TRUE
- | - | isTRUE(FALSE) | FALSE
Conjunción (AND) | & | TRUE & FALSE | FALSE
- | && | TRUE && FALSE | FALSE
Disyunción (OR) | | | TRUE | FALSE | TRUE
- | || | TRUE || FALSE | TRUE
Exclusividad (XOR) | xor | xor(TRUE,FALSE) | TRUE
Los operadores lógicos siguen las siguientes reglas:
! devuelve el valor lógico opuesto al resultante de evaluar la expresión que recibe.isTRUE devuelve el valor lógico idéntico al resultante de evaluar la expresión que recibe.&, && devuelven TRUE cuando se produce el cumplimiento en forma simultánea (la evaluación de las expresiones que reciben es TRUE). En otro caso, devuelven FALSE. La diferencia entre ambas es que & se utiliza en tipos de datos compuestos para efectuar la operación elemento a elemento (ya veremos con detalle su uso en otro tutorial).|, || devuelven TRUE cuando al menos la evaluación de una de las expresiones que reciben es TRUE. Si la evaluación de ambas expresiones es FALSE devuelven FALSE. La diferencia entre ambas es que | se utiliza en tipos de datos compuestos para efectuar la operación elemento a elemento (ya veremos con detalle su uso en otro tutorial).xor devuelve TRUE cuando la evaluación de una y solo una de las expresiones que recibe es TRUE. Si ambas expresiones devuelven el mismo valor lógico devuelve FALSE.Vamos a comprobar el uso de los distintos operadores lógicos mediante el uso de expresiones relacionales de comparación de literales numéricos.
#isTRUE(7>5) #Afirmación #!(7>5) #Negación #(7>5)&&(10>=10) #AND (Y lógico) #(5<7)&(10==10) #(7>5)||(10>10) #OR (O lógico) #(7<5)|(10>10) #xor(7>5,10>10) #XOR (O lógico) #xor(7<5,10>10)
Puedes comprobar el efecto de cada operador lógico eliminando el comentario al principio de la línea correspondiente y ejecutando el código.
Como ya sabemos, en R las operaciones tienen un orden de evaluación definido. Cuanto aparecen varias operaciones en una misma expresión, en realidad, algunas de ellas son realizadas antes que otras y el resultado de ellas dependerá de este orden.
El orden de operaciones incluye a las aritméticas, relacionales, lógicas y de asignación. A continuación presentamos una tabla con el orden de precedencia de los diferentes operadores:
# | Operaciones | Operadores
:--:|:--:|:--:|
1º | Potenciación | ^
2º | Unarias | +,-
3º | Módulo | %%
4º | Multiplicación| *
- | División | /
5º | Suma | +
- | Resta | -
6º | Operadores relacionales | -
- | Igual, no es igual | ==,!=
- | Menor, menor o igual | <, <=
- | Mayor, mayor o igual | >, >=
6º | Negación (NOT) | !
- | Afirmación (IS) | isTRUE
7º | Conjunción (AND) | &, &&
8º | Disyunción (OR) | |, ||
- | Exclusividad (XOR) | xor
9º | Asignación | <-
En caso de igual orden de precedencia entra en juego la asociatividad, llevándose a cabo una evaluación de izquierda a derecha en todos los casos excepto con la potenciación, donde la evaluación se lleva a cabo de derecha a izquierda.
Si deseamos que una operación se lleve a cabo antes que otra, con independencia de este orden de evaluación, se deben usar paréntesis. Podemos también tener paréntesis anidados.
En el siguiente ejemplo, podemos comprobar la precedencia de operadores en las expresiones. Una de las conclusiones que obtendrás en el proceso de determinar los operadores que se evalúan con anterioridad a otros es que siempre es mejor utilizar paréntesis. Ayuda a la legibilidad y evita ambigüedades.
7+5>7-5 && 8*2>8/2 3^2>2^3 || 8%/%5 > 8%%5
Coloca paréntesis en la expresiones anteriores y comprueba que el resultado es el mismo:
((7+5)>(7-5)) && ((8*2)>(8/2)).((3^2)>(2^3)) || ((8%/%5) > (8%%5)).La coerción es una característica de los lenguajes de programación que permite, implícita o explícitamente, convertir un objeto de un tipo de datos en otro, sin tener en cuenta la comprobación de tipos. En R, los datos pueden ser coercionados, es decir, forzados, para transformarlos de un tipo a otro.
La coerción es muy importante. Cuando pedimos a R ejecutar una operación, intentará coercionar de manera implícita, sin avisarnos, los datos de su tipo original al tipo correcto que permita realizarla. Habrá ocasiones en las que R tenga éxito y la operación ocurra sin problemas, y otras en las que falle y obtengamos un error. Echa un vistazo al siguiente código.
# 1 + TRUE # (1 + TRUE) > (2 + FALSE) # ! (7 / 2.5) # 8 * "Hola"
Puedes eliminar el comentario al principio de cada línea individual y comprobar qué ocurre con la ejecución.
1 + TRUE, el valor TRUE es coercionado a integer para realizar la operación aritmética.(1 + TRUE) > (2 + FALSE), los valores TRUE y FALSE son coercionados a integer para que se puedan llevar a cabo las operaciones aritméticas antes de la operación relacional. ! (7 / 2.5), el valor literal 7 es coercionado a numeric para que se lleve a cabo la operación aritmética. Tras ello, el resultado de la división es coercionado a logical para que se lleve a cabo la operación lógica de negación.8 * "Hola", la cadena de caracteres intenta ser coercionada (sin éxito) a integer para que se lleve a cabo la multiplicación (operación aritmética). El caso correspondiente a la última línea del ejemplo ocurre porque no todos los tipos de datos pueden ser transformados a los demás. Para la coerción se sigue una regla general: la coerción de tipos se realiza de los tipos de datos más restrictivos a los más flexibles.
Las coerciones implícitas siguen el orden logical -> integer -> numeric -> character.
Las coerciones no pueden ocurrir en orden inverso. Podemos coercionar un dato de tipo lógico (logical) a uno entero (integer), pero no uno de cadena de caracteres (character) a numérico (numeric).
Los datos de tipo lógico son los más restrictivos, pues sólo admiten dos valores (TRUE y FALSE). Los datos de tipo cadena de caracteres son los más flexibles, pues admiten cualquier cantidad y combinación de caracteres.
Veamos a continuación dos ejemplos representativos para poder entender mejor la coerción implícita:
En el primer ejemplo, conocida la altura de cuatro personas, deseamos conocer cuántas de ellas superan los dos metros.
altura_persona1 <- 177 altura_persona2 <- 199 altura_persona3 <- 201 altura_persona4 <- 215 personas_mayores_2m <- (altura_persona1>200)+(altura_persona2>200)+(altura_persona3>200)+(altura_persona4>200) personas_mayores_2m
En este ejemplo, la coerción de lógico (logic) a entero (integer) permite sumar el número de personas que cumplen una determinada condición (altura superior a dos metros). Debes tener en cuenta que TRUE es coercionado a 1 y FALSE es coercionado a 0.
En el segundo ejemplo, dados cuatro nombres de usuario, deseamos conocer los que se colocarían, por orden alfabético, antes que uno de ellos (usuario2).
usuario1 <- 177 usuario2 <- "fenix199" usuario3 <- 201 usuario4 <- "XxpipoxX" anteriores_usuario2 <- (usuario1<usuario2) + (usuario3<usuario2) + (usuario4<usuario2) anteriores_usuario2
En este ejemplo, la coerción de entero (integer) a cadena de caracteres (character) permite comparar cadenas de caracteres, en este caso para comprobar si un nombre de usuario sería anterior, en orden alfabético, al nombre de usuario2. Debes tener en cuenta que, por ejemplo, el número 177 es coercionado a la cadena de caracteres que incluye cada uno de sus dígitos como caracter "177".
Los objetos pueden ser convertidos en otro tipo de datos de foma explícita mediante el uso de:
as.numericas.integeras.complexas.logicalas.characterCuando estas funciones llevan a cabo la coerción, nos devuelven datos del tipo pedido. Si hay problemas, aparece la advertencia correspondiente y obtenemos como resultado NA (usado en R, entre otras posibilidades, para mostrar que una operación realizada no tuvo éxito en su ejecución).
Veamos a continuación algunos ejemplos de coerción explícita con éxito:
#Coerción explícita de lógico ``logical`` as.integer(TRUE) as.numeric(TRUE) as.character(TRUE) #Coerción explícita de entero ``integer`` as.numeric(800) as.character(800) #Coerción explícita de numérico ``numeric`` as.character(755.323)
Puedes comprobar el efecto de la coerción explícita mediante la ejecución del código.
A continuación mostraremos diversos ejemplos de coerción explícita sin éxito (con cadenas de caracteres):
#Coerción explícita de cadena de caracteres ``character`` as.integer("Hola") as.numeric("Hola") as.logical("Hola")
Como ves, aparece la advertencia correspondiente y obtenemos como resultado NA en todas ellas.
Para que haya éxito en la coerción explícita, el orden no debe ser necesariamente: logical -> integer -> numeric -> character. Los ejemplos mostrados a continuación lo demuestran:
#Coerción explícita a lógico ``logical`` as.logical(100) as.logical(800.533) as.logical(0) as.integer(800.533)
En las dos primeras conversiones, podemos comprobar que si el número es distinto de 0 (integer o numeric) será coercionado a TRUE. En la tercera conversión, vemos que si el número es 0 será coercionado a FALSE. Finalmente, en la última conversión vemos cómo podemos coercionar un número flotante a entero a costa de perder la parte decimal.
Vamos a realizar un ejercicio acerca del uso de operadores relacionales y lógicos:
"La siguiente tabla muestra cuatro de las películas de mayor recaudación en salas de cine (millones de dólares) a nivel mundial a lo largo de la historia (hasta 2021).
Película | Recaudación | Año de estreno :--:|:--:|:--:| Avengers: Endgame | 2797.800 | 2019 Avatar | 2787.965 | 2009 Titanic | 2187.463 | 1997 Jurassic World | 1671.713 | 2015
Se desea saber:
Obviamente, es muy sencillo responder a todas las preguntas planteadas mediante la observación de la tabla. Sin embargo, pensemos en su resolución mediante código en R, debido a que el razonamiento nos servirá de punto de partida para cuando tengamos un número de películas mucho mayor y no abarcable visualmente.
Para obtener la solución a las diferentes preguntas del ejercicio comenzaremos definiendo las variables del mismo que tienen un valor inicial.
#Inicializamos variables pelicula1<-"Avengers: Endgame" pelicula2<-"Avatar" pelicula3<-"Titanic" pelicula4<-"Jurassic World" recaudacion1<-2797.800 recaudacion2<-2787.965 recaudacion3<-2187.463 recaudacion4<-1671.713 estreno1<-2019 estreno2<-2009 estreno3<-1997 estreno4<-2015
Hemos proporcionado a cada variable un nombre ilustrativo del valor que contiene y con el orden en que aparece en la tabla.
Para responder a la pregunta acerca de cuántas películas tienen una recaudación superior a los 2000 millones de dólares, debemos comparar la recaudación de cada película con la cantidad proporcionada. Esta comparación debe ser verdadera en caso de que se cumpla la condición (recaudación superior).
#Inicializamos variables recaudacion1<-2797.800 recaudacion2<-2787.965 recaudacion3<-2187.463 recaudacion4<-1671.713 #Inicialización variable recaudación de referencia ref_recaudacion<-2000 #Cálculo número películas con recaudación superior recaudacion_superior=(recaudacion1>ref_recaudacion)+(recaudacion2>ref_recaudacion)+(recaudacion3>ref_recaudacion)+(recaudacion4>ref_recaudacion) recaudacion_superior
En la solución puedes comprobar cómo se hace uso de la coerción de logical a integer en cada comparación para luego calcular el número de películas con recaudación superior a la indicada de referencia.
Para responder a la pregunta acerca de cuántas películas han sido estrenadas antes de 2010 el proceso a seguir es similar a la resolución de la pregunta anterior. La diferencia se encuentra en este caso en que la comparación se realiza con los años de estreno y teniendo de cantidad de referencia en la comparación al año 2010.
#Inicializamos variables estreno1<-2019 estreno2<-2009 estreno3<-1997 estreno4<-2015 #Inicialización estreno de referencia ref_estreno<-2010 #Cálculo número películas con recaudación superior estreno_antes=(estreno1<ref_estreno)+(estreno2<ref_estreno)+(estreno3<ref_estreno)+(estreno4<ref_estreno) estreno_antes
Se hace uso de la coerción de logical a integer en cada comparación para luego calcular el número de películas con año de estreno anterior (operador relacional <) al indicado de referencia.
Para responder a la pregunta acerca de cuántas películas han sido estrenadas fuera del periodo 2005-2015 se puede llevar a cabo de dos formas distintas (comprobándose en todo caso dos condiciones para cada año de estreno):
Comprobación si el año de estreno es inferior a 2005 o el año de estreno es superior a 2015. Las condiciones se unirían por tanto mediante el operador lógico de disyunción (||).
Comprobación si el año de estreno está entre 2005 y 2015. Las condiciones se unirían por tanto mediante el operador lógico de conjunción (&&). Al resultado global habría que aplicarle la negación (!) debido a que deseamos contar las estrenadas fuera del periodo.
Veamos el código correspondiente a la primera solución (disyunción): cuando se cumpla una condición para el año de estreno es suficiente para saber que está fuera del periodo (2005-2015).
#Inicializamos variables estreno1<-2019 estreno2<-2009 estreno3<-1997 estreno4<-2015 #Inicialización periodo de referencia inicio_periodo<-2005 fin_periodo<-2015 #Cálculo número películas con recaudación superior estreno_fuera= ((estreno1<inicio_periodo)||(estreno1>fin_periodo)) + ((estreno2<inicio_periodo)||(estreno2>fin_periodo)) + ((estreno3<inicio_periodo)||(estreno3>fin_periodo)) + ((estreno4<inicio_periodo)||(estreno4>fin_periodo)) estreno_fuera
Veamos el código correspondiente a la segunda solución (conjunción y negación): cuando se cumplan las dos condiciones para el año de estreno está dentro del periodo por lo que no se sumaría para el cálculo (negación). Ten en cuenta la importancia de los paréntesis en la ejecución y el orden de evaluación.
#Inicializamos variables estreno1<-2019 estreno2<-2009 estreno3<-1997 estreno4<-2015 #Inicialización periodo de referencia inicio_periodo<-2005 fin_periodo<-2015 #Cálculo número películas con recaudación superior estreno_fuera= (!((estreno1>=inicio_periodo)&&(estreno1<=fin_periodo))) + (!((estreno2>=inicio_periodo)&&(estreno2<=fin_periodo))) + (!((estreno3>=inicio_periodo)&&(estreno3<=fin_periodo))) + (!((estreno4>=inicio_periodo)&&(estreno4<=fin_periodo))) estreno_fuera
Para responder a la cuestión acerca de cuántos títulos estrenados a partir de 2015 (incluido) han tenido una recaudación superior a 2500 millones de dólares se debe llevar a cabo una doble comparación para cada película (año de estreno y recaudación).
#Inicializamos variables recaudacion1<-2797.800 recaudacion2<-2787.965 recaudacion3<-2187.463 recaudacion4<-1671.713 estreno1<-2019 estreno2<-2009 estreno3<-1997 estreno4<-2015 #Inicialización variables recaudación y estreno de referencia ref_recaudacion<-2500 ref_estreno<-2015 #Cálculo número películas que cumplen dos condiciones num_peliculas_dos_condiciones= ((recaudacion1>ref_recaudacion)&&(estreno1>=ref_estreno))+ ((recaudacion2>ref_recaudacion)&&(estreno2>=ref_estreno))+ ((recaudacion3>ref_recaudacion)&&(estreno3>=ref_estreno))+ ((recaudacion4>ref_recaudacion)&&(estreno4>=ref_estreno)) num_peliculas_dos_condiciones
El papel de los paréntesis es fundamental en la evaluación.
En la resolución de todas las preguntas del ejercicio hemos podido comprobar la redundancia (repetición) de las comparaciones para cada variable. Aparece aquí la necesidad de un nuevo tipo de datos que evite esta repetición y permita generalizar la operación a un número indeterminado de variables. Se trata del tipo de datos vector que abordaremos posteriormente.
Felicidades, has completado el tutorial de Operadores Relacionales y Lógicos. Puedes continuar con el siguiente tutorial: Funciones predefinidas.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.