Este curso está diseñado para equipar a los estudiantes de la UNAL sede La Paz con habilidades prácticas en la manipulación eficiente de datos utilizando el lenguaje de programación R a través de los Grupos de Estudio Autónomo. El curso se sustenta en la asignatura de computación estadística ofertado por el docente Luis Hernando Vanegas del departamento de estadística de la sede Bogotá, el cual cursó y aprobó el tutor Juan Daniel Diaz y que aspiro compartir con los estudiantes de estadística de la sede La Paz. Desde la instalación de Rstudio, importación, exportación, manipulación y visualización de datos. Los participantes explorarán cada paso del proceso con sesiones interactivas y aplicadas.
Instalación de Rstudio y R, conceptos fundamentales sobre R como calculadora, operaciones matemáticas básicas, creación de vectores y matrices, y sintaxis de R.
R es un lenguaje de programación utilizado para realizar procedimientos estadísticos y gráficos de alto nivel. Fue creado en 1993 por los profesores e investigadores Robert Gentleman y Ross Ihaka. Inicialmente, el lenguaje se utilizó para apoyar los cursos a cargo de los profesores, pero debido a la utilidad de la herramienta desarrollada, decidieron distribuir copias de R. A partir de 1995 el código fuente de R estuvo disponible para diferentes sistemas operativos.
Como mencionamos anteriormente, R es un lenguaje de programación que nos permite dar instrucciones específicas a una computadora para realizar diversas operaciones. Para simplificar, podríamos decir que es una manera organizada de comunicarnos con el ordenador. Aunque técnicamente podríamos interactuar con R directamente desde una consola o terminal, similar a las que suelen aparecer en las películas sobre hackers, esto puede resultar poco práctico para la mayoría de los usuarios. Es por eso que existe RStudio, una interfaz de usuario más amigable y accesible que se ha convertido en la opción preferida para trabajar con R. RStudio, también de código abierto, ofrece un entorno integrado que facilita la escritura, ejecución y visualización de código R. Además, es constantemente actualizado por un equipo de programadores, lo que garantiza una experiencia óptima para los usuarios.
Recuperado de: Pepi Amodeo (2022).
¿Tienes problemas con la instalación? usa esta ayuda.
Si has podido descargar e instalar R y RStudio, simplemente abre este último para comenzar a trabajar. Encontrarás una pantalla similar a la siguiente figura:
Francisco Urdinez & Andrés Cruz Labrín
(2021)
El panel inferior izquierdo de RStudio es nuestro espacio de comunicación directa con la computadora, donde le pedimos que realice tareas específicas utilizando el lenguaje R. Nos referimos a estas peticiones como comandos. A Continuación se muestra los principales operadores aritméticos.
| Operación | Operador en R | Ejemplo |
|---|---|---|
| Suma | + |
a + b |
| Resta | - |
a - b |
| Multiplicación | * |
a * b |
| División | / |
a / b |
| Potencia | ^ |
a ^ b |
| Residuo (Módulo) | %% |
a %% b |
| Cociente entero | %/% |
a %/% b |
| Raíz cuadrada | sqrt() |
sqrt(a) |
| Logaritmo natural | log() |
log(a) |
| Logaritmo base 10 | log10() |
log10(a) |
| Valor absoluto | abs() |
abs(a) |
| Seno | sin() |
sin(a) |
| Coseno | cos() |
cos(a) |
| Tangente | tan() |
tan(a) |
La consola corresponde al entorno computacional de este lenguaje. Es aquí donde nuestro código es interpretado, si escribimos los siguiente en la consola y presionamos Enter, estamos pidiendo que se ejecute esta operación:
[1] 7
[1] 3
[1] 10
[1] 2.5
[1] 25
[1] 25
[1] 1
El panel superior izquierdo de RStudio puede describirse como un ‘registro de comandos’. Aunque la consola puede ser útil para algunos comandos, los análisis complejos requerirán que llevemos un registro de nuestro código.
Escribir un nuevo script es tan fácil como presionar Ctrl + Shift + N o ir a Archivo > Nuevo archivo > R Script. La pantalla blanca de un nuevo script es similar a un bloc de notas en blanco, con la característica de que cada línea debe ser pensada como un comando. Ten en cuenta que escribir un comando en el script y presionar ‘Enter’ solo realiza un salto de línea. Para ejecutar el comando en una línea, debes presionar Ctrl + Enter (o Cmd + Enter si usas Mac). También es posible seleccionar varias líneas/comandos a la vez y ejecutarlos todos con Ctrl + Enter.
Los operadores lógicos son usados para hacer comparaciones y siempre
devuelven como resultado TRUE o FALSE
(verdadero o falso, respectivamente).
[1] FALSE
[1] FALSE
[1] TRUE
[1] TRUE
[1] FALSE
[1] TRUE
Es posible comparar cualquier tipo de dato sin que resulte en un error. Sin embargo, al usar los operadores >, >=, < y <= con cadenas de texto, estos tienen un comportamiento especial. Por ejemplo, “casa” > “barco” nos devuelve TRUE.
[1] TRUE
Este resultado se debe a que se ha hecho una comparación por orden alfabético. En este caso, la palabra “casa” tendría una posición posterior a “barco”, pues empieza con “c” y esta letra tiene una posición posterior a la “b” en el alfabeto. Por lo tanto, es verdadero que sea “mayor”.
Este es probablemente el operador más importante de todos, pues nos permite asignar datos a variables. Definiendo mi primera variable :
# Todos estos operadores Asigna un valor a una variable
a = 5 # Opción 1
a <-5 # Opción 2
5 -> a
# para pedir que me muestre lo que contiene
a[1] 5
Entonces podemos operar:
[1] 7
Nota 0.2: Aunque podemos usar el signo igual para una asignación, a lo largo de este libro utilizaremos <-, por ser característico de R y fácil de reconocer visualmente.
Nota 0.3: Después de realizar la operación de asignación, podemos usar el nombre de la variable para realizar operaciones con ella, como si fuera del tipo de datos que le hemos asignado. Si asignamos un valor a una variable a la que ya habíamos asignado datos, nuestra variable conserva el valor más reciente.
Nota 0.4: En R, usamos NA para representar datos perdidos, mientras que NULL representa la ausencia de datos.
Los operadores lógicos son usados para operaciones de álgebra Booleana, es decir, para describir relaciones lógicas, expresadas como verdadero (TRUE) o falso (FALSO).
[1] TRUE
[1] FALSE
[1] FALSE
[1] TRUE
| devuelve TRUE si alguno de los datos es
TRUE.
& solo devuelve TRUE si ambos datos es
TRUE.
| solo devuelve FALSE si ambos datos son
FALSE.
& devuelve FALSE si alguno de los datos es
FALSE.
Para realizar operaciones lógicas, todos los valores numéricos y complejos distintos a 0 son coercionados a TRUE, mientras que 0 siempre es coercionado a FALSE.
Nota 0.5: En R, los datos pueden ser coercionados, es decir, forzados, para transformarlos de un tipo a otro.
[1] FALSE
[1] FALSE
[1] TRUE
Una función es una serie de operaciones a la que les hemos asignados un nombre. Las funciones aceptan argumentos, es decir, especificaciones sobre cómo deben funcionar. Cuando llamamos una función, se realizan las operaciones que contiene, usando los argumentos que hemos establecido.
Para el cálculo de las razones trigonométricas se tiene que considerar al ángulo en pi radianes.
En R reconocemos a una función usando la notación: nombre_de_la_función(). Para el cálculo de las razones trigonométricas se tiene que considerar al ángulo en \(\pi_{rad}\).
[1] 120
[1] 10
[1] -0.9589243
[1] 0.2836622
[1] -3.380515
¿Como de creo una función en R?
[1] 2
En ocasiones, tenemos datos pero no sabemos de simple vistazo de qué tipo son. Para esto casos, podemos usar la función class() para determinar el tipo de un dato. Esto es de utilidad para asegurarnos que las operaciones que deseamos realizar tendrán los datos apropiados para llevarse a cabo con éxito.
[1] "numeric"
[1] "UNAL"
[1] "character"
Ejercicio 0.3: realice la verificación con la familia de funciones is() a la variable a y Nombre
En R, hay varios tipos de objetos que permiten a los usuarios almacenar información para realizar procedimientos estadísticos y gráficos. Los principales objetos en R son vectores, matrices, arreglos, marcos de datos y listas. A continuación, se presentan las características de estos objetos y cómo crearlos.
Las estructuras de datos son objetos que contienen datos. Cuando trabajamos con R, lo que estamos haciendo es manipular estas estructuras. Las estructuras tienen diferentes características. Entre ellas, las que distinguen a una estructura de otra son su número de dimensiones y si son homogeneas o hereterogeneas.
Es la estructura de datos más sencilla en R. Un vector es una colección de uno o más datos del mismo tipo. Todos los vectores tienen las siguientes propiedades:
Tipo. Un vector tiene el mismo tipo que los datos que contiene. Si tenemos un vector que contiene datos de tipo numérico, el vector será también de tipo numérico, sólo pueden contener datos de un sólo tipo.
Largo. Es el número de elementos que contiene un vector. Este corresponde a la dimensión que contiene la estructura.
Creamos vectores usando la función c()
(combinar/concatenar). Llamamos esta función y le damos como argumento
los elementos que deseamos combinar en un vector, separados por
comas.
[1] TRUE
[1] 1
[1] TRUE
[1] 6
Lo mismo ocurre con los demás tipos de datos, por ejemplo, con cadenas de texto y datos lógicos.
[1] TRUE
# length(Nombre)
# Vector de cadena de texto
caracterisricas <- c("arbol", "casa", "persona")
# Vector lógico
c(TRUE, TRUE, FALSE, FALSE, TRUE)[1] TRUE TRUE FALSE FALSE TRUE
Si deseamos agregar un elemento a un vector ya existente, podemos hacerlo combinando nuestro vector original con los elementos nuevos y asignando el resultado a nuestro vector original.
[1] TRUE FALSE TRUE FALSE
Naturalmente, podemos crear vectores que son combinación de vectores.
mi_vector_1 <- c(1, 3, 5)
mi_vector_2 <- c(2, 4, 6)
mi_vector_3 <- c(mi_vector_1, mi_vector_2)
mi_vector_3[1] 1 3 5 2 4 6
Podemos crear vectores de secuencias numéricas usando :.
De un lado de los dos puntos escribimos el número de inicio de la
secuencia y del otro el final.
[1] 1 2 3 4 5 6 7 8 9 10
[1] -43 -42 -41 -40 -39 -38 -37 -36 -35 -34 -33 -32 -31 -30
[1] 67.23 68.23 69.23 70.23 71.23 72.23 73.23 74.23
[1] -2.48 -1.48 -0.48 0.52 1.52
[1] 166 167 168 169 170
Pueden ser descritas como vectores multidimensionales. Al igual que un vector, únicamente pueden contener datos de un sólo tipo, pero además de largo, tienen más dimensiones. Específicamente dos dimensiones, un “largo”” y un “alto”. Las matrices son, por lo tanto, una estructura con forma rectangular, con filas y columnas.
La creación de matrices es con la función
matrix(). Esta acepta dos argumentos, nrow
y ncol. Con ellos especificamos el número de renglones
y columnas que tendrá nuestra matriz.
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
[9,] 9
[10,] 10
[11,] 11
[12,] 12
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
Los datos que intentemos agrupar en una matriz serán acomodados en
orden, de arriba a abajo, y de izquierda a derecha, hasta formar un
rectángulo. Otro procedimiento para crear matrices es la unión vectores
con las siguientes funciones: - cbind() para unir vectores,
usando cada uno como una columna. - rbind() para unir
vectores, usando cada uno como una fila.
Usamos rbind() para crear un matriz, en la que cada
vector será un renglón
[,1] [,2] [,3] [,4]
vector_1 1 2 3 4
vector_2 5 6 7 8
vector_3 9 10 11 12
vector_4 13 14 15 16
Ejercicio: ¿Si utilizamos cbind(), entonces cada vector será? y ¿cuál es la dimención de la matriz?
Las matrices y arrays pueden tener más de una dimensión.
Operaciones básicas de matriciales en R
| Operación | Símbolo | Descripción | Ejemplo |
|---|---|---|---|
| Suma | + |
Suma de elementos correspondientes | A + B |
| Resta | - |
Resta de elementos correspondientes | A - B |
| Multiplicación | %*% |
Multiplicación de matrices | A %*% B |
| Multiplicación por escalar | * |
Multiplicación de cada elemento por un escalar | A * 2 |
| Transposición | t() |
Transpone la matriz | t(A) |
| Determinante | det() |
Calcula el determinante de la matriz | det(A) |
| Inversa | solve() |
Calcula la inversa de la matriz | solve(A) |
| Producto Hadamard | * |
Multiplica elemento por elemento | A * B |
| Producto de Kronecker | %x% |
Producto de Kronecker | kronecker(A, B) |
Los data frames son estructuras de datos de dos dimensiones (rectangulares) que pueden contener datos de diferentes tipos, por lo tanto, son heterogéneas. Esta estructura de datos es la más usada para realizar análisis de datos y seguro te resultará familiar si has trabajado con otros paquetes estadísticos. Si bien los data frames parece similar a una matriz y se puede ver como tal, internamente no es una matriz, es decir, no es un objeto tipo array. Por último, Un data frame está compuesto por vectores.
mi_df <- data.frame(
"entero" = 1:4,
"factor" = c("a", "b", "c", "d"),
"numero" = c(1.2, 3.4, 4.5, 5.6),
"cadena" = as.character(c("a", "b", "c", "d"))
)
mi_df entero factor numero cadena
1 1 a 1.2 a
2 2 b 3.4 b
3 3 c 4.5 c
4 4 d 5.6 d
Podemos acceder a la dimensión (dim), a los nombres de las columnas/variables (names) y a la clase de un dataframe.
[1] 4 4
[1] "entero" "factor" "numero" "cadena"
[1] "function"
Usamos as.data.frame() para coercionar una matriz a este
tipo de objeto.
[1] "data.frame"
V1 V2 V3 V4
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
Para acceder a los columnas de un marco de datos se hace uno de los corchetes (parentesis rectangulares) seguido del nombre del dataframe. También se puede acceder por medio de del signo peso ($) seguido del nombre del marco de datos, como muestra a continuación:
[1] 4 5 6
[1] 4 5 6
[1] 4 5 6
V2
1 4
2 5
3 6
Si solo nos interesa la información de ciertas columnas o variables se puede realizar de la siguiente manera:
factor numero
1 a 1.2
2 b 3.4
3 c 4.5
4 d 5.6
En caso tal, quisieramos acceder a las columnas y filas especificas se haría uso de los parentesis rectangulares como muestra a continuación:
factor numero
1 a 1.2
3 c 4.5
R puede ser expandido con paquetes. Cada paquete es una colección de funciones diseñadas para atender una tarea específica. Por ejemplo, hay paquetes para trabajo visualización geoespacial, análisis psicométricos, mineria de datos, interacción con servicios de internet y muchas otras cosas más.
Estos paquetes se encuentran alojados en CRAN, así que pasan por un
control riguroso antes de estar disponibles para su uso generalizado.
Podemos instalar paquetes usando la función
install.packages(), dando como argumento el nombre del
paquete que deseamos instalar, entre comillas.
Una vez concluida la instalación de un paquete, podrás usar sus funciones con la función library(). Sólo tienes que llamar esta función usando como argument oel nombre del paquete que quieres utilizar.
El directorio o carpeta de trabajo es el lugar en nuestra computadora en el que se encuentran los archivos con los que estamos trabajando en R. Este es el lugar donde R buscara archivos para importarlos y al que serán exportados, a menos que indiquemos otra cosa. Puedes encontrar cuál es tu directorio de trabajo con la función getwd(). Sólo tienes que escribir la función en la consola y ejecutarla.
[1] "C:/Users/USUARIO/Documents/Universidad/2024-1S/GEA/Cursillo"
Puedes cambiar el directorio de trabajo usando la función setwd(), dando como argumento la ruta del directorio que quieres usar.
Por último, si deseas conocer el contenido de tu directorio de trabajo, puedes ejecutar. la función list.files(), sin argumentos, que devolverá una lista con el nombre de los archivos de tu directorio de trabajo. La función list.dirs(), también sin argumentos` te dará una lista de los directorios dentro del directorio de trabajo.
En este apartado trabajamos la importación de datos usando las librerías readxl y readr para archivos con extensiones xls y xlsx.
tibble [1,118 × 8] (S3: tbl_df/tbl/data.frame)
$ Departamento: chr [1:1118] "Ant%ioqUia" "Ant%ioquia" "Ant%ioquia" "Ant%io>qUia" ...
$ Dep : chr [1:1118] "05" "05" "05" "05" ...
$ Municipio : chr [1:1118] "Mede&l'lín" "Abej!&orr*al" "A?br'&iaquí" "Alej#andr&'ía" ...
$ Depmun : chr [1:1118] "05001" "05002" "05004" "05021" ...
$ Superficie : num [1:1118] 374.8 507.1 297 128.9 84.1 ...
$ Poblacion : num [1:1118] 2483545 20258 2710 4669 30777 ...
$ Irural : num [1:1118] 5 45 58 48 28 54 38 37 47 58 ...
$ Region : chr [1:1118] "Región Eje Cafetero" "Región Eje Cafetero" "Región Eje Cafetero" "Región Eje Cafetero" ...
# A tibble: 5 × 8
Departamento Dep Municipio Depmun Superficie Poblacion Irural Region
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <chr>
1 Ant%ioqUia 05 Mede&l'lín 05001 375. 2483545 5 Región Ej…
2 Ant%ioquia 05 Abej!&orr*al 05002 507. 20258 45 Región Ej…
3 Ant%ioquia 05 A?br'&iaquí 05004 297. 2710 58 Región Ej…
4 Ant%io>qUia 05 Alej#andr&'ía 05021 129. 4669 48 Región Ej…
5 Antioquia 05 Am#a?&'*gá 05030 84.1 30777 28 Región Ej…
# A tibble: 5 × 8
Departamento Dep Municipio Depmun Superficie Poblacion Irural Region
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <chr>
1 Vaup>és 97 Y#*ava'ra?t!é 97889… 4660. 1067 92 Regió…
2 Vi%ch>ada 99 Puerto Carr#eñ… 99001… 12205. 20474 81 Regió…
3 Vichada 99 La Prima&*'!ve#ra 99524… 18569. 9799 85 Regió…
4 Vi%ch>ada 99 Santa ?Rosalía 99624… 3692. 4130 81 Regió…
5 Vichada 99 C#u'?mar!ibo 99773… 65597. 76196 87 Regió…
col_names), especificar la hoja la
cual queremos importar (sheet), numeros máximmos de
registros (n_max), entre otras.Municipios <- read_excel("Datos/Municipios.xlsx", sheet = 1, skip = 1,
col_names = c("Depto", "Dep", "Mcpio", "Codmun",
"Super", "Pob", "Irural", "Region"),
col_types = c("text", "text", "text", "text",
"numeric", "numeric", "numeric", "text"),
n_max = 1118)
dim(Municipios)[1] 1118 8
Existen diferentes extensiones de archivos, por lo tanto la libreria
readr nos permite importar extensiones de archivos
diferentes a xls y xlsx con la función read_delim.
spc_tbl_ [699 × 8] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
$ A: chr [1:699] "IBM" "IBM" "IBM" "IBM" ...
$ B: chr [1:699] "01DEC05" "01NOV05" "03OCT05" "01SEP05" ...
$ C: num [1:699] 8915 8185 8022 8016 8300 ...
$ D: num [1:699] 8992 8994 8460 8211 8420 ...
$ E: num [1:699] 8156 8064 7870 7693 7987 ...
$ F: num [1:699] 8220 8890 8188 8022 8062 ...
$ G: chr [1:699] "5.976.252" "5.556.471" "7.019.666" "5.772.280" ...
$ H: chr [1:699] "81,37" "88,01" "80,86" "79,22" ...
- attr(*, "spec")=
.. cols(
.. A = col_character(),
.. B = col_character(),
.. C = col_number(),
.. D = col_number(),
.. E = col_number(),
.. F = col_number(),
.. G = col_character(),
.. H = col_character()
.. )
- attr(*, "problems")=<externalptr>
help(cols)
stocks2 <- read_delim("Datos/stocks.dlm", delim = " ",
locale = locale(decimal_mark = ",", grouping_mark = "."),
col_types = cols("f", col_date("%d%b%y"), "d", "d", "d",
"d", "n", "d"), skip = 1,
col_names = c("Stock", "Date","Open","High", "Low","Close",
"Volume"," AdjClose"))
str(stocks2)spc_tbl_ [699 × 8] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
$ Stock : Factor w/ 3 levels "IBM","Intel",..: 1 1 1 1 1 1 1 1 1 1 ...
$ Date : Date[1:699], format: "2005-12-01" "2005-11-01" ...
$ Open : num [1:699] 89.2 81.8 80.2 80.2 83 ...
$ High : num [1:699] 89.9 89.9 84.6 82.1 84.2 ...
$ Low : num [1:699] 81.6 80.6 78.7 76.9 79.9 ...
$ Close : num [1:699] 82.2 88.9 81.9 80.2 80.6 ...
$ Volume : num [1:699] 5976252 5556471 7019666 5772280 4801386 ...
$ AdjClose: num [1:699] 81.4 88 80.9 79.2 79.6 ...
- attr(*, "spec")=
.. cols(
.. Stock = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
.. Date = col_date(format = "%d%b%y"),
.. Open = col_double(),
.. High = col_double(),
.. Low = col_double(),
.. Close = col_double(),
.. Volume = col_number(),
.. ` AdjClose` = col_double()
.. )
- attr(*, "problems")=<externalptr>
Usaremos la libería stringr para la manipulación de cadenas de texto y limpieza de base de datos. Para esto, realizaremos uso del conjunto de datos Municipios.
library(stringr)
Municipios <- within(Municipios,{
Mcpio2 <- str_to_lower(Mcpio)
Mcpio2 <- str_replace_all(Mcpio2,"[^a-záéíóúüñ ]","")
Mcpio2 <- str_squish(Mcpio2)
Mcpio2 <- str_to_title(Mcpio2)
})
head(Municipios[,c("Mcpio","Mcpio2")], n=10)# A tibble: 10 × 2
Mcpio Mcpio2
<chr> <chr>
1 Mede&l'lín Medellín
2 Abej!&orr*al Abejorral
3 A?br'&iaquí Abriaquí
4 Alej#andr&'ía Alejandría
5 Am#a?&'*gá Amagá
6 Am?al#'*fi Amalfi
7 Andes*! Andes
8 &# Angelópoli?s Angelópolis
9 Ang#'ostura Angostura
10 An*'#?orí Anorí
Municipios <- within(Municipios,{
Depto2 <- str_to_lower(Depto)
Depto2 <- str_replace_all(Depto2,"[^a-záéíóúüñ ]","")
Depto2 <- str_squish(Depto2)
Depto2 <- str_to_title(Depto2)
})
head(Municipios[,c("Depto","Depto2")], n=5)# A tibble: 5 × 2
Depto Depto2
<chr> <chr>
1 Ant%ioqUia Antioquia
2 Ant%ioquia Antioquia
3 Ant%ioquia Antioquia
4 Ant%io>qUia Antioquia
5 Antioquia Antioquia
#Guardamos Departamento2 en Departamento, es decir, guardamos los cambios.
Municipios <- within(Municipios,{
Depto <- Depto2
rm(Depto2)
})Municipios <- within(Municipios,{
Region2 <- str_to_lower(Region)
Region2 <- str_replace_all(Region2,"[^a-záéíóúüñ ]","")
Region2 <- str_replace_all(Region2, "región ", "")
Region2 <- str_squish(Region2)
Region2 <- str_to_title(Region2)
})
head(Municipios[,c("Region","Region2")], n=5)# A tibble: 5 × 2
Region Region2
<chr> <chr>
1 Región Eje Cafetero Eje Cafetero
2 Región Eje Cafetero Eje Cafetero
3 Región Eje Cafetero Eje Cafetero
4 Región Eje Cafetero Eje Cafetero
5 Región Eje Cafetero Eje Cafetero
Haremos uso de las expresiones regulares y las funciones subset y str_detect de la librería stringr.
Santos <- subset(Municipios, str_detect(Mcpio, "(^| )San( |ta |to )"),
select = c(Depto, Codmun, Mcpio))
head(Santos, n = 5)# A tibble: 5 × 3
Depto Codmun Mcpio
<chr> <chr> <chr>
1 Antioquia 05647 San Andrés De Cuerquía
2 Antioquia 05649 San Carlos
3 Antioquia 05652 San Francisco
4 Antioquia 05656 San Jerónimo
5 Antioquia 05658 San José De La Montaña
Aes <- subset(Municipios, str_detect(Mcpio, "^(A|Á).{2}(e|é).*"),
select = -c(Pob,Super,Irural))
head(Aes, n=5)# A tibble: 5 × 5
Depto Dep Mcpio Codmun Region
<chr> <chr> <chr> <chr> <chr>
1 Antioquia 05 Andes 05034 Eje Cafetero
2 Antioquia 05 Angelópolis 05036 Eje Cafetero
3 Antioquia 05 Argelia 05055 Eje Cafetero
4 Antioquia 05 Armenia 05059 Eje Cafetero
5 Boyacá 15 Almeida 15022.0 Centro Oriente
# A tibble: 5 × 8
Depto Dep Mcpio Codmun Super Pob Irural Region
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <chr>
1 Antioquia 05 San José De La Montaña 05658 126. 3706 50 Eje C…
2 Cundinamarca 25 San Juan De Río Seco 25662… 314. 8324 47 Centr…
3 Cundinamarca 25 Villa De San Diego De Uba… 25843… 102. 44802 29 Centr…
4 Chocó 27 El Cantón Del San Pablo 27135… 380. 6210 54 Pacíf…
5 Chocó 27 El Litoral Del San Juan 27250… 4135. 22242 67 Pacíf…
Realizamos la exportación de todos las modificaciones realizadas al conjunto de datos.
A continuación se muestra el proceso de instalación de la librería dplyr
asi como su ayuda. Esta tiene la particularidad de usar un operador
%>% el cual se conoce como pip y se
puede entender como el que indica que sigue otra operación teniendo
en cuenta lo que se realizó en la linea anterior.
En el ejemplo que sigue haremos uso del marco de datos Municipios que se exportó en la Sesión 1 después de haberse realizado la limpieza.
library(dplyr)
Municipios %>%
select(Depto, Dep, Codmun, Mcpio, Super, Pob) %>%
filter(Dep %in% c("05", "17") & Pob > 20000) %>%
arrange(Dep,desc(Pob)) %>%
head(n = 5) %>%
as.data.frame() Depto Dep Codmun Mcpio Super Pob
1 Antioquia 05 05001 Medellín 374.83062 2483545
2 Antioquia 05 05088 Bello 147.75842 538527
3 Antioquia 05 05360 Itagui 19.64956 283794
4 Antioquia 05 05266 Envigado 77.99670 236114
5 Antioquia 05 05615 Rionegro 195.94015 139553
Municipios %>%
mutate(denspobl = Pob/Super) %>%
filter(Dep != "15" & Dep != "68" & Super < 300) %>%
mutate(denspoblC=case_when(denspobl > 85 ~ "Alta",
denspobl < 30 ~ "Baja",
TRUE ~ "Media")) %>%
arrange(Dep,desc(Pob)) %>%
select(Depto, Dep, Codmun, Mcpio, Super, Pob, denspoblC) %>%
head(n = 5) %>%
as.data.frame() Depto Dep Codmun Mcpio Super Pob denspoblC
1 Antioquia 05 05088 Bello 147.75842 538527 Alta
2 Antioquia 05 05360 Itagui 19.64956 283794 Alta
3 Antioquia 05 05266 Envigado 77.99670 236114 Alta
4 Antioquia 05 05615 Rionegro 195.94015 139553 Alta
5 Antioquia 05 05631 Sabaneta 15.83532 85484 Alta
# A tibble: 0 × 2
# ℹ 2 variables: Codmun <chr>, repetidos <int>
Municipios %>%
group_by(Dep,Depto) %>%
summarise(mun=n(),cv = sd(Super)/mean(Super)) %>%
filter(mun > 1) %>%
arrange(desc(cv)) %>%
head(n=1)# A tibble: 1 × 4
# Groups: Dep [1]
Dep Depto mun cv
<chr> <chr> <int> <dbl>
1 18 Caquetá 16 1.94
Municipios %>%
group_by(Dep, Depto) %>%
summarise(nmunicipios=n(), totpob=sum(Pob),
totsup = sum(Super),denspob=totpob/totsup,
Irural = sum(Irural*Pob)/totpob,
totpobC = case_when(totpob > 1.5e6 ~ "Grande",
totpob < 3e5 ~ "Pequeño",
TRUE ~ "Mediano")) %>%
arrange(desc(totpob)) %>%
head(n = 5) %>%
as.data.frame() Dep Depto nmunicipios totpob totsup denspob Irural totpobC
1 11 Bogotá D C 1 7592871 1622.853 4678.7188 6.00000 Grande
2 05 Antioquia 125 6550206 62804.709 104.2948 21.31877 Grande
3 76 Valle Del Cauca 42 4506768 20665.545 218.0813 22.57578 Grande
4 25 Cundinamarca 116 3085522 22370.489 137.9282 26.53255 Grande
5 08 Atlántico 23 2638151 3315.752 795.6418 10.92753 Grande
Municipios %>%
group_by(Region) %>%
summarise(Deps=n_distinct(Dep)) %>%
arrange(desc(Deps)) %>%
head(n=1)# A tibble: 1 × 2
Region Deps
<chr> <int>
1 Caribe 8
Municipios %>%
select(Dep, Depto, Mcpio, Codmun) %>%
filter(str_detect(Mcpio,"^(A|Á)|(o|ó)$") & str_count(Mcpio," ") == 0) %>%
head(n = 5) %>%
as.data.frame() Dep Depto Mcpio Codmun
1 05 Antioquia Abejorral 05002
2 05 Antioquia Abriaquí 05004
3 05 Antioquia Alejandría 05021
4 05 Antioquia Amagá 05030
5 05 Antioquia Amalfi 05031
Tomado de: Rahman, Z. (2020). JOINs [Image]. LearnSQL. https://learnsql.com/blog/learn-and-practice-sql-joins/.
A <- data.frame(id=c(1,2,2,3), cod=c(23,65,60,87),
name=c("Leia","Luke","Yoda","Hank"))
B <- data.frame(id=c(2,3,4), cod=c(65,87,29), age=c(23,20,25))
A id cod name
1 1 23 Leia
2 2 65 Luke
3 2 60 Yoda
4 3 87 Hank
id cod age
1 2 65 23
2 3 87 20
3 4 29 25
id cod name age
1 2 65 Luke 23
2 3 87 Hank 20
id cod age name
1 2 65 23 Luke
2 3 87 20 Hank
id cod name age
1 1 23 Leia NA
2 2 65 Luke 23
3 2 60 Yoda NA
4 3 87 Hank 20
id cod name age
1 2 65 Luke 23
2 3 87 Hank 20
3 4 29 <NA> 25
id cod name age
1 1 23 Leia NA
2 2 65 Luke 23
3 2 60 Yoda NA
4 3 87 Hank 20
5 4 29 <NA> 25
A continuación tengase en cuenta el siguiente conjunto de datos Brasil contiene tres hojas: Municipios, Estados y Costeros. La hoja Municipios lista los municipios del Brasil, en que las columnas CODESTAD, CODMUNIC, NOMMUNIC, POB y SUP corresponden a código del estado, código del municipio, nombre del municipio, número de habitantes y superficie (en kilómetros cuadrados), respectivamente. La hoja Estados lista los estados del Brasil, en que las columnas CODESTAD, NOMESTAD y REGIAO corresponden a código del estado, nombre del estado y región, respectivamente. La hoja Costeros lista los municipios costeros del Brasil, en que la columna CODMUNIC corresponde al código del municipio. Tenga en cuenta que los nombres de los municipios, estados y regiones están escritos en portugués, y en esa lengua, a diferencia del español, se tiene que: (i) existen los siguientes acentos: â, ê, ô, á, é, í, ó, ú, ã, õ, à; (ii) no existe la letra ñ; y (iii) existe la letra ç.
A continuación se crea una función para “limpiar” la base de datos, la cual recibe un vector x el cual se le aplica lo visto en la Sesión 1 y regresa el vector arreglado.
# A tibble: 5 × 5
CODESTAD CODMUNIC NOMMUNIC POB SUP
<dbl> <dbl> <chr> <dbl> <dbl>
1 11 1100015 A/+lta Flor?esta D'Oeste 22516 7067.
2 11 1100023 Ar¡*i/quemes 111148 4427.
3 11 1100031 Cab¡i^xi¡ 5067 1314.
4 11 1100049 Cac$oa{|l 86416 3793
5 11 1100056 Ce~:rej=eiras 16088 2783.
# A tibble: 5 × 3
NOMESTAD REGIAO CODESTAD
<chr> <chr> <dbl>
1 Ro|n¿dônia* Região Norte 11
2 Ac(=re) Região Norte 12
3 Am]^azonas¡ Região Norte 13
4 R_(orai=ma Região Norte 14
5 Par_?~á Região Norte 15
Costeros <- read_excel("Datos/Brasil.xlsx", sheet = 3)
Costeros <- within(Costeros, Costero <- 1)
head(Costeros, n = 5)# A tibble: 5 × 2
CODMUNIC Costero
<dbl> <dbl>
1 4323804 1
2 4323002 1
3 4322327 1
4 4321832 1
5 4321667 1
clean <- function(x){
x <- str_to_lower(x)
x <- str_replace_all(x,"[^a-zâêôáéíóúãõàç'\\- ]","")
x <- str_squish(x)
x <- str_to_title(x)
return(x)
}
Municipalidad <- Municipalidad %>%
mutate(NOMMUNIC = clean(NOMMUNIC)) %>%
as.data.frame()
Estados <- Estados %>%
mutate(NOMESTAD = clean(NOMESTAD),
REGIAO = clean(REGIAO)) %>%
as.data.frame()Ahora, procede unir los tres conjuntos de datos por medio del identificador (id) que tiene cada uno de marco de datos. ¿Cuál es el tipo de unión que nos sirve para este caso?
Municipalidad2 <- Municipalidad %>% left_join(Estados, by = c("CODESTAD" = "CODESTAD")) %>%
as.data.frame()
head(Municipalidad2, n = 5) CODESTAD CODMUNIC NOMMUNIC POB SUP NOMESTAD REGIAO
1 11 1100015 Alta Floresta D'oeste 22516 7067.127 Rondônia Região Norte
2 11 1100023 Ariquemes 111148 4426.571 Rondônia Região Norte
3 11 1100031 Cabixi 5067 1314.352 Rondônia Região Norte
4 11 1100049 Cacoal 86416 3793.000 Rondônia Região Norte
5 11 1100056 Cerejeiras 16088 2783.300 Rondônia Região Norte
Municipalidad3 <- Municipalidad2 %>% left_join(Costeros, by =c("CODMUNIC" = "CODMUNIC")) %>%
mutate(Costero = ifelse(is.na(Costero), 0, Costero)) %>%
as.data.frame()
head(Municipalidad3, n = 5) CODESTAD CODMUNIC NOMMUNIC POB SUP NOMESTAD REGIAO
1 11 1100015 Alta Floresta D'oeste 22516 7067.127 Rondônia Região Norte
2 11 1100023 Ariquemes 111148 4426.571 Rondônia Região Norte
3 11 1100031 Cabixi 5067 1314.352 Rondônia Região Norte
4 11 1100049 Cacoal 86416 3793.000 Rondônia Região Norte
5 11 1100056 Cerejeiras 16088 2783.300 Rondônia Região Norte
Costero
1 0
2 0
3 0
4 0
5 0
# A tibble: 5 × 2
REGIAO Nmun
<chr> <int>
1 Região Norte 450
2 Região Centro-Oeste 467
3 Região Sul 1191
4 Região Sudeste 1668
5 Região Nordeste 1794
Ejercicio 2.1: ¿Cuál es la región (REGIAO) con la mayor población?
Ejercicio 2.2: ¿Cuál es la región (REGIAO) con la menor superficie?
Ejemplo 2.9: ¿Cuál es el estado (CODESTAD y NOMESTAD) con el mayor número de municipios costeros?
Municipalidad3 %>%
filter(Costero==1) %>%
group_by(CODESTAD, NOMESTAD) %>%
summarise(Costeros = n()) %>%
arrange(desc(Costeros))# A tibble: 17 × 3
# Groups: CODESTAD [17]
CODESTAD NOMESTAD Costeros
<dbl> <chr> <int>
1 29 Bahia 53
2 15 Pará 47
3 42 Santa Catarina 41
4 21 Maranhão 40
5 43 Rio Grande Do Sul 39
6 33 Rio De Janeiro 33
7 24 Rio Grande Do Norte 29
8 27 Alagoas 27
9 28 Sergipe 24
10 23 Ceará 23
11 32 Espírito Santo 18
12 26 Pernambuco 17
13 35 São Paulo 16
14 25 Paraíba 13
15 16 Amapá 11
16 41 Paraná 7
17 22 Piauí 5
Ejercicio 2.3: ¿Cuál es el estado (CODESTAD y NOMESTAD) con la mayor superficie en municipios costeros?
Ejercicio 2.4: ¿Cuál es el estado (CODESTAD y NOMESTAD) con la mayor población en municipios costeros?
Ejercicio 2.5: ¿Cuál es el estado (CODESTAD y NOMESTAD) con la mayor densidad poblacional en municipios costeros?
ggplot2 es la mejor librería para graficar en R, ya que genera graficas más estéticas que las funciones de base. Además que su uso es intuitivo y permite potenciar el proceso de análisis de datos. Antes de iniciar es importante instalar y llamar ggplot2. Para los ejemplos que siguen téngase en cuenta el siguiente el conjunto de datos Advertising.
#install.packages("ggplot2")
library(ggplot2)
advertising <- read_excel("Datos/Advertising.xlsx")
str(advertising)tibble [200 × 4] (S3: tbl_df/tbl/data.frame)
$ TV : num [1:200] 230.1 44.5 17.2 151.5 180.8 ...
$ radio : num [1:200] 37.8 39.3 45.9 41.3 10.8 48.9 32.8 19.6 2.1 2.6 ...
$ newspaper: num [1:200] 69.2 45.1 69.3 58.5 58.4 75 23.5 11.6 1 21.2 ...
$ sales : num [1:200] 22.1 10.4 9.3 18.5 12.9 7.2 11.8 13.2 4.8 10.6 ...
ggplot(advertising,aes(x = TV, y = sales)) +
geom_point() +
labs(title = "Ventas versus inversión en publicidad en TV",
x = "Publicidad en TV", y = "Ventas") +
theme_gray()La figura anterior, es muy básica, por lo tanto a continuación se personaliza el gráfico anterior. Utilizando el color para especificar el color de los puntos, shape para la forma de estos y size para el tamaño. Dentro de aes proviene de aesthetic el describe cómo se asignan las variables de los datos a las visuales. En labs se establece todo lo relacionado con las etiquetas. Y en theme controla casi cualquier elemento visual de la gráfica que no esté controlado por el datos y, por lo tanto, es importante para la apariencia.
ggplot(advertising,aes(x = TV, y = sales)) +
geom_point(color = "red", shape = 16, size = 3) +
labs(title = "Ventas versus inversión en publicidad en TV", x = "Publicidad en TV", y = "Ventas") +
scale_x_continuous(breaks = seq(from=0, to=300, by=50)) +
scale_y_continuous(breaks=seq(from=0, to=30, by=5)) +
theme(plot.title = element_text(family="sans", face="bold", size=20, vjust=0.5,
hjust=0.5, color="black", angle=0),
axis.title.x = element_text(family="sans", face="bold", size=18, vjust=0.5,
hjust=0.5, color="blue", angle=0),
axis.title.y = element_text(family="sans", face="bold", size=18, vjust=0.5,
hjust=0.5, color="blue", angle=0),
axis.text.x = element_text(family="mono", face="bold", size=14, vjust=0.5,
hjust=0.5, color="black", angle=0),
axis.text.y = element_text(family="mono", face="bold", size=14, vjust=0.5,
hjust=0.5, color="black", angle=0),
panel.background = element_rect(fill="gray92"),
panel.grid.major = element_line(color="white", size=1),
panel.grid.minor = element_line(color="white", size=0.5)
) Ahora, crearemos un tema personalizado para el gráfico.
mitema <- theme(plot.title=element_text(family="sans", face="bold", size=20,
vjust=0.5, hjust=0.5, color="black", angle=0),
axis.title.x=element_text(family="sans", face="bold", size=18,
vjust=0.5, hjust=0.5, color="blue", angle=0),
axis.title.y=element_text(family="sans", face="bold", size=18,
vjust=0.5, hjust=0.5, color="blue", angle=90),
axis.text.x=element_text(family="mono", face="bold", size=14,
vjust=0.5, hjust=0.5, color="black", angle=0),
axis.text.y=element_text(family="mono", face="bold", size=14,
vjust=0.5, hjust=0.5, color="black", angle=0),
panel.background=element_rect(fill="gray92"),
panel.grid.major=element_line(color="white",size=1),
panel.grid.minor=element_line(color="white",size=0.5)
)names <- c("Baja","Media","Alta")
advertising <- within(advertising,radioC <- cut_number(radio,n=3,labels=names))
with(advertising,table(radioC))radioC
Baja Media Alta
68 65 67
ggplot(advertising, aes(x=TV, y=sales, color=radioC, shape=radioC)) +
geom_point(size=3.5) +
labs(title="Ventas versus inversión en publicidad para TV",x="Publicidad para TV",
y="Ventas",color="Publicidad\n en radio",shape="Publicidad\n en radio") +
scale_x_continuous(breaks=seq(from=0, to=300, by=50)) +
scale_y_continuous(breaks=seq(from=0, to=30, by=5)) +
scale_color_manual(values=c("blue","black","red")) +
scale_shape_manual(values=c(15,16,17)) + mitemaAhora añadimos una regresión polinómica en cada uno a las ventas por publicidad en TV y publicidad en radio.
ggplot(advertising, aes(x=TV, y=sales, color=radioC, shape=radioC)) +
geom_point(size=3.5) +
geom_smooth(method="lm", formula=y ~ poly(x,degree=3), se=FALSE, size=1, linetype="solid") +
labs(title="Ventas versus inversión en publicidad para TV",x="Publicidad para TV",
y="Ventas",color="Publicidad\n en radio",shape="Publicidad\n en radio") +
scale_x_continuous(breaks=seq(from=0, to=300, by=50)) +
scale_y_continuous(breaks=seq(from=0, to=30, by=5)) +
scale_color_manual(values=c("blue","black","red")) +
scale_shape_manual(values=c(15,16,17)) + mitemaPREGUNTA: ¿cómo haría si quiero un tipo de linea por cada valor de la publicidad en radio?
Se crea una nueva variable newspaperC de 4 niveles, por cada nivel se grafica la ventas en función de la inversión de publicidad en TV diferenciado por el nivel de publicidad en radio con su respectiva linea de tendencia polinómica.
names <- c("Baja", "Media baja", "Media alta", "Alta")
advertising <- within(advertising,newspaperC <- cut_number(newspaper, n=4, labels=names))
with(advertising,table(newspaperC))newspaperC
Baja Media baja Media alta Alta
50 50 51 49
ggplot(advertising,aes(x=TV, y=sales, color=radioC)) +
geom_point(size=3.5, shape=16) +
geom_smooth(method="lm", formula=y ~ poly(x,degree=3), se=FALSE, size=1, linetype="solid") +
labs(title="Ventas versus inversión en publicidad para TV", x="Publicidad para TV",
y="Ventas", subtitle="Publicidad en periodico", color="Publicidad\n en radio") +
scale_color_manual(values=c("blue", "black", "red")) +
facet_wrap(vars(newspaperC), ncol=2, nrow=2, strip.position="top",dir="h", scales="free") + mitema +
theme(plot.subtitle=element_text(face="bold", size=16, vjust=0.5, hjust=0.5, color="salmon"),
strip.background=element_rect(color="black", fill="gray80", size=1),
strip.text=element_text(face="bold", size=13, vjust=0.5, hjust=0.5, color="black", angle=0)
)En estos datos, sacados de Diggle P.J., Heagarty P., Liang K.-Y. y Zeger S.L. (2002) Analysis of Longitudinal Data. Oxford University Press, Oxford, el principal objetivo del análisis es evaluar el efecto de la contaminación por ozono en el crecimiento de los árboles. En un primer grupo (treat=“normal”), se cultivaron un total de 54 árboles en una atmósfera enriquecida con ozono, mientras que en un segundo grupo (treat=“enriquecida con ozono”), 25 árboles se cultivaron en una atmósfera normal. El tamaño de cada árbol (size) se observó 13 veces a lo largo del tiempo (days), es decir, 152, 174, 201, 227, 258, 469, 496, 528, 556, 579, 613, 639 y 674 días desde el inicio del experimento.
'data.frame': 1027 obs. of 4 variables:
$ tree : Factor w/ 79 levels "N1T01","N1T02",..: 1 1 1 1 1 1 1 1 1 1 ...
$ days : num 152 174 201 227 258 469 496 528 556 579 ...
$ size : num 92.8 156 177.7 223.6 225.9 ...
$ treat: Factor w/ 2 levels "normal","ozone-enriched": 1 1 1 1 1 1 1 1 1 1 ...
ggplot(spruces,aes(x=factor(days), y=size, fill=treat)) +
geom_boxplot(outlier.shape=16, outlier.color="red", outlier.size=1, color="black", linetype="solid") +
labs(x="Días desde el comienzo del experimento", y="Tamaño", fill="Atmósfera") +
scale_fill_manual(values=c("salmon2","green2")) + mitema +
theme(legend.position="right",
legend.text=element_text(size=14,hjust=0),
legend.title=element_text(face="bold",size=15)
)En esta sección, exploraremos la tarea de la cartografía mediante el
uso de las herramientas que nos ofrecen las bibliotecas sf,
ggplot2, y dplyr en R. Estas herramientas nos
permiten importar, manipular y visualizar datos espaciales de manera
eficiente y elegante. La biblioteca sf nos brinda la
capacidad de importar archivos que contienen información geoespacial,
representada comúnmente como polígonos que definen áreas geográficas.
Con sf, podemos cargar datos espaciales en formato simple y
flexible. Y por último, nos apoyaremos en ggplot2 para la
visualización y generación de los mapas.
A continuación téngase en cuenta el conjunto de datos Municipios trabajados en la sesión 1 y los archivos en esta carpeta, los cuales servirán de insumos para el mapa a continuación.
depto <- Municipios %>% group_by(Depto, Dep) %>%
summarise(Irural=sum(Pob*Irural)/sum(Pob)) %>%
as.data.frame()
deptoshp <- st_read("Datos/Mapas/COL/MGN_DPTO_POLITICO.shp",quiet=TRUE)
todo <- deptoshp %>% left_join(depto, by = c('DPTO_CCDGO' = 'Dep')) %>%
select(DPTO_CCDGO, Depto, Irural, geometry) %>%
st_as_sf()
head(todo)Simple feature collection with 6 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -77.12783 ymin: 3.730633 xmax: -71.94885 ymax: 11.10537
Geodetic CRS: MAGNA-SIRGAS
DPTO_CCDGO Depto Irural geometry
1 05 Antioquia 21.31877 MULTIPOLYGON (((-76.41355 8...
2 08 Atlántico 10.92753 MULTIPOLYGON (((-74.84946 1...
3 11 Bogotá D C 6.00000 MULTIPOLYGON (((-74.07059 4...
4 13 Bolívar 31.39577 MULTIPOLYGON (((-76.17318 9...
5 15 Boyacá 37.21662 MULTIPOLYGON (((-72.17368 7...
6 17 Caldas 29.41638 MULTIPOLYGON (((-74.67154 5...
A continuación se presentan el mapa de los departamentos de Colombia que muestra las diferencias entre el Índice de ruralidad ponderado por población. Se destacan los nombres de los departamentos con un índice de ruralidad mayor a 70.
ggplot(data = todo, aes(fill = Irural)) +
geom_sf() + geom_sf_text(aes(label = ifelse(Irural >70, Depto, "")),
col = "black", fontface="bold", size=4,
fun.geometry = function(x) st_centroid(x)) +
labs(x = "Longitud", y ="Latitud", title = "Colombia", fill = "Índice de\nRuralidad") +
scale_fill_gradient(low = "white", high = "red", n.breaks = 5) +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))El mapa anterior está bien, pero lo podríamos mejorar para que sea veas más estético como añadirle los países vecinos, añadir el colo de los océanos.
mundo <- st_read("Datos/Mapas/Mundo/Paises_Mundo.shp", quiet = TRUE)
mundocol <- mundo %>%
filter(PAÍS %in% c("Perú","Brasil","Venezuela","Ecuador","Panamá"))
box <- st_bbox(todo)
ggplot() + geom_sf(data = mundocol) +
geom_sf(data = todo, aes(fill = Irural)) +
coord_sf(xlim=c(box$xmin,box$xmax), ylim=c(box$ymin,box$ymax), expand=FALSE) +
labs(x = "Longitud", y ="Latitud", title = "Colombia", fill = "Índice de\nRuralidad") +
scale_fill_gradient(low = "white", high = "red", n.breaks = 5) +
theme(plot.title = element_text(hjust = 0.5, face = "bold")) +
annotate("text", x=c(-74.5,-68,-78,-69,-78.5), y=c(-2.5,0,-1,9,9), colour="blue",
label=c("Perú","Brasil","Ecuador","Venezuela","Panamá")) +
theme(panel.background=element_rect(fill="lightblue"))En en el siguiente enlace se encuentran los puntajes promedios de las pruebas saber 11 del período 2022-2. Por lo tanto, realizamos una clasificación de los departamentos en 5 grupos teniendo en cuenta los puntajes usando la tecnica de kmeans.
icfes <- readxl::read_excel("Datos/IcfesDepto.xlsx")
set.seed(1)
clusters <- kmeans(icfes$Media, centers = 5)
icfes$cluster <- clusters$cluster
centros <- clusters$centers
icfes$etiquetas <- paste("Grupo", icfes$cluster, ": ", round(centros[icfes$cluster], 0))
icfes %>% right_join(deptoshp, by = c('Dep' = 'DPTO_CCDGO')) %>%
filter(Dep != "88") %>%
select(Dep, Depto, Media, cluster, etiquetas, geometry) %>%
st_as_sf() %>%
ggplot() + geom_sf(aes(fill=etiquetas)) +
scale_fill_manual(values = c("#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd")) +
labs(title = 'Agrupamiento de Departamentos', x = 'Longitud', y = 'Latitud', fill = '') +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'),
legend.position = "bottom")REFERENCIAS