getwd()[1] "C:/Users/FCA-UN-2240386/OneDrive - Universidad Nacional de Colombia/1_Periodos_Asignaturas/Cursos_2026_2/Geomatica_Basica_20262/Practical/Introduccion_R"
Geomática Básica · Ingeniería Agronómica
Lo que está leyendo es una página publicada en RPubs: es la guía del taller. Su tarea es construir en RStudio su propio documento que la replique: escribir los títulos y explicaciones, escribir y ejecutar cada bloque de código, obtener los mismos resultados y resolver los ejercicios. Al final, usted tendrá una página como esta, hecha por usted.
Trabaje con dos ventanas lado a lado: esta guía en el navegador y RStudio con su documento.
RPubs es un sitio web gratuito de Posit (la empresa que hace RStudio) para publicar en internet documentos creados con R. Se publica directamente desde RStudio con un botón, y el resultado es una página web con texto, código y resultados (tablas, mapas, gráficos), como la que está leyendo.
Algunas cosas que debe saber:
.qmd): un archivo de texto que mezcla explicaciones y código. Ese es el tipo de archivo que usted va a crear.C:/Users/...). En su computador esas rutas serán diferentes, y está bien.Todo el trabajo de este taller lo hará desde cero, en un proyecto de RStudio creado por usted. Un proyecto es una carpeta que RStudio reconoce como “mi carpeta de trabajo”. Gracias a eso podemos escribir rutas cortas como "datos/municipios.shp" en vez de "C:/Users/.../Descargas/curso/datos/municipios.shp", y el código funciona igual en cualquier computador.
La profesora solo le entrega la carpeta datos, con los shapefiles: descárguela aquí. Todo lo demás lo crea usted.
taller1_geomatica (sin espacios ni tildes).C:/geomatica.taller1_geomatica.RStudio creó la carpeta taller1_geomatica con un archivo taller1_geomatica.Rproj. La próxima vez que quiera trabajar en el taller, abra el proyecto con doble clic en ese archivo .Rproj, o desde RStudio en File → Open Project…
Guarde el proyecto fuera de OneDrive y en una ruta sin tildes, eñes ni espacios (por ejemplo C:/geomatica/taller1_geomatica). La sincronización de OneDrive y los caracteres especiales causan errores difíciles de entender al leer y escribir archivos.
.zip..zip (clic derecho → Extraer todo…).taller1_geomatica y asegúrese de que se llame exactamente datos (en minúsculas) y que los archivos del shapefile estén directamente adentro, no en otra subcarpeta.datos. Haga clic en ella y compruebe que contiene mun_santander_boyaca.shp junto con sus archivos acompañantes (.dbf, .shx, .prj…).Un shapefile no es un solo archivo: son varios con el mismo nombre y distinta extensión. Si falta alguno, R no podrá leer la capa. Copie siempre la carpeta completa.
Al terminar el taller, su proyecto debe verse así:
taller1_geomatica/
├── taller1_geomatica.Rproj ← lo crea RStudio en el paso 1
├── taller1_su_apellido.qmd ← el documento que usted crea
├── taller1_su_apellido.html ← la página que se genera al renderizar
├── datos/ ← la carpeta que entrega la profesora
└── salidas/ ← aquí guardaremos resultados (se crea en el taller)
taller1_geomatica abierto, vaya a File → New File → Quarto Document…Taller 1: Primeros pasos en R) y su nombre como autor. Deje el formato HTML y haga clic en Create.---).Ctrl + S) en la carpeta del proyecto con el nombre taller1_su_apellido.qmd.Deje el encabezado así (cambie su nombre). La línea embed-resources: true hace que la página quede en un solo archivo, necesario para publicarla:
---
title: "Taller 1: Primeros pasos en R"
author: "Su nombre completo"
format:
html:
toc: true
number-sections: true
embed-resources: true
---Un documento Quarto tiene tres ingredientes:
El texto se escribe normalmente y se le da formato con algunos símbolos:
| Usted escribe | Se ve como |
|---|---|
# Título |
título de sección |
## Subtítulo |
subtítulo |
**negrita** |
negrita |
*cursiva* |
cursiva |
`codigo` |
codigo |
- elemento |
viñeta de una lista |
Un bloque de código empieza con ```{r} y termina con ```. Insértelo con Ctrl + Alt + I (Mac: Cmd + Option + I). Por ejemplo, así se ve en su documento una sección con texto y un bloque:
# R como calculadora
Lo más sencillo que R puede hacer es calcular.
```{r}
2 + 3
10 / 4
```Para ejecutar código:
| Acción | Windows / Linux | Mac |
|---|---|---|
| Ejecutar la línea donde está el cursor | Ctrl + Enter |
Cmd + Enter |
| Ejecutar todo el bloque | Ctrl + Shift + Enter |
Cmd + Shift + Enter |
| Insertar un bloque nuevo | Ctrl + Alt + I |
Cmd + Option + I |
También puede hacer clic en el triángulo verde ▶ en la esquina del bloque.
Cuando haga clic en el botón Render (flecha azul, arriba del editor; atajo Ctrl + Shift + K), RStudio ejecuta todo el documento de principio a fin y genera el archivo .html. Hágalo con frecuencia, por ejemplo al terminar cada sección:
Su primer bloque: compruebe dónde está trabajando R.
getwd()[1] "C:/Users/FCA-UN-2240386/OneDrive - Universidad Nacional de Colombia/1_Periodos_Asignaturas/Cursos_2026_2/Geomatica_Basica_20262/Practical/Introduccion_R"
🤔 Pregunta: ¿La ruta que aparece en su documento termina en taller1_geomatica? Si no, guarde su documento, cierre RStudio y vuelva a abrir el proyecto con doble clic en el archivo taller1_geomatica.Rproj. Revise también que su .qmd esté guardado dentro de esa carpeta.
Lo más sencillo que R puede hacer es calcular. Ejecute cada línea con Ctrl + Enter:
2 + 3[1] 5
10 - 4[1] 6
6 * 7[1] 42
10 / 4[1] 2.5
2^3 # potencia: 2 elevado a 3[1] 8
sqrt(16) # raíz cuadrada[1] 4
Todo lo que está después de # es un comentario: R lo ignora. Los comentarios sirven para explicarle a otras personas (y a usted mismo en el futuro) qué hace el código. Úselos mucho.
R respeta el orden de las operaciones de la matemática. Use paréntesis cuando lo necesite:
2 + 3 * 4 # primero multiplica[1] 14
(2 + 3) * 4 # primero suma[1] 20
Un lote rectangular mide 150 m de largo y 80 m de ancho. Calcule su área en m² y luego en hectáreas (1 ha = 10 000 m²).
En el ejercicio anterior tuvo que escribir los números varias veces. En programación preferimos guardar los valores en variables. Una variable es como una caja con una etiqueta: adentro está el valor y la etiqueta es el nombre.
En R se guarda con la flecha <- (se lee “recibe”). Atajo: Alt + -.
largo <- 150
ancho <- 80Fíjese que no apareció nada debajo: R guardó los valores sin mostrarlos. Ahora mire el panel Environment (arriba a la derecha): ahí están largo y ancho. Para ver lo que hay en una variable, escriba su nombre:
largo[1] 150
Ahora podemos calcular con los nombres en vez de con los números:
area_m2 <- largo * ancho
area_ha <- area_m2 / 10000
area_ha[1] 1.2
_ y ., pero no pueden empezar con número ni tener espacios.Largo y largo son dos variables distintas.area_ha es mejor que x.area, no área; ano, no año).R ejecuta las líneas en el orden en que usted las ejecuta, no en el orden en que están escritas. Haga este experimento:
largo <- 200
area_ha[1] 1.2
🤔 Pregunta: Cambiamos el largo a 200, pero area_ha sigue igual. ¿Por qué? ¿Qué tendría que hacer para que area_ha se actualice?
Cree una variable rendimiento con el valor 22 (toneladas de papa por hectárea). Usando area_ha, calcule la producción total del lote y guárdela en una variable llamada produccion_t. Muestre el resultado.
No todo es un número. Los tres tipos de datos que más usaremos son:
| Tipo | Ejemplo | Para qué sirve |
|---|---|---|
numeric (número) |
22.5, 150 |
medir, calcular |
character (texto) |
"papa", "Tunja" |
nombres, categorías, códigos |
logical (lógico) |
TRUE, FALSE |
responder preguntas de sí o no |
El texto siempre va entre comillas. La función class() dice de qué tipo es algo:
cultivo <- "papa"
class(cultivo)[1] "character"
class(area_ha)[1] "numeric"
class(TRUE)[1] "logical"
Las comparaciones producen valores lógicos:
area_ha > 1 # ¿el lote tiene más de 1 ha?[1] TRUE
cultivo == "papa" # ¿el cultivo es papa? (dos signos igual para comparar)[1] TRUE
cultivo != "maiz" # ¿el cultivo es distinto de maíz?[1] TRUE
15 (número) y "15" (texto) no son lo mismo para R. Ejecute:
codigo_numero <- 15
codigo_texto <- "15"
codigo_numero + 1[1] 16
codigo_texto + 1Error in `codigo_texto + 1`:
! argumento no-numérico para operador binario
La última línea da error porque no se puede sumar a un texto. En los datos geográficos de Colombia, los códigos DANE de departamentos y municipios suelen guardarse como texto (por ejemplo "15" para Boyacá o "05" para Antioquia, con el cero a la izquierda). Recuérdelo en la Parte B.
Casi nunca trabajamos con un solo dato. Un vector es una fila de valores del mismo tipo. Se crea con c() (de “combinar”):
# Rendimiento de papa (t/ha) en cinco lotes de una finca
rendimiento <- c(18.5, 22.1, 15.3, 25.0, 19.8)
rendimiento[1] 18.5 22.1 15.3 25.0 19.8
Las funciones de resumen trabajan sobre todo el vector:
length(rendimiento) # ¿cuántos valores hay?[1] 5
mean(rendimiento) # promedio[1] 20.14
max(rendimiento) # máximo[1] 25
min(rendimiento) # mínimo[1] 15.3
sum(rendimiento) # suma[1] 100.7
Las operaciones se aplican a cada elemento a la vez. Para pasar de t/ha a kg/ha:
rendimiento * 1000[1] 18500 22100 15300 25000 19800
Con corchetes [ ] indicamos la posición del elemento (en R se empieza a contar desde 1):
rendimiento[2] # el segundo[1] 22.1
rendimiento[c(1, 3)] # el primero y el tercero[1] 18.5 15.3
Esta es una de las ideas más poderosas de todo el taller. Fíjese en lo que produce una comparación sobre un vector:
rendimiento > 20[1] FALSE TRUE FALSE TRUE FALSE
Es un vector de TRUE/FALSE: uno por cada lote. Si lo ponemos dentro de los corchetes, R se queda solo con los TRUE:
rendimiento[rendimiento > 20][1] 22.1 25.0
Leído en voz alta: “del vector rendimiento, dame los valores donde rendimiento es mayor que 20”. Exactamente esta idea es la que usamos después para seleccionar municipios en un mapa.
lluvia_mm con la precipitación de seis meses: 120, 85, 210, 160, 45, 98.sum() cuenta los TRUE).Ya usó varias funciones: mean(), max(), class(), sqrt(). Una función es una máquina: le entrega algo (los argumentos, dentro de los paréntesis), hace un trabajo y le devuelve un resultado.
Algunas funciones reciben varios argumentos, separados por coma y a veces con nombre:
promedio <- mean(rendimiento)
promedio[1] 20.14
round(promedio, digits = 1) # redondear a 1 decimal[1] 20.1
Para saber qué hace una función y qué argumentos recibe, escriba ? y su nombre en la consola. La ayuda aparece en el panel Help:
?roundCuando un cálculo se repite, conviene convertirlo en una función:
m2_a_ha <- function(m2) {
m2 / 10000
}
m2_a_ha(12000)[1] 1.2
m2_a_ha(c(5000, 25000, 80000)) # ¡también funciona con vectores![1] 0.5 2.5 8.0
Partes de una función: el nombre (m2_a_ha), los argumentos entre paréntesis (m2) y el cuerpo entre llaves { } con el cálculo. La última línea del cuerpo es lo que la función devuelve.
Cree una función llamada produccion que reciba dos argumentos, area_ha y rendimiento_t_ha, y devuelva la producción en toneladas. Pruébela con un lote de 3.5 ha que rinde 20 t/ha.
Los datos reales casi siempre vienen en tablas: filas (observaciones) y columnas (variables), como en Excel. En R una tabla se llama data frame. Cada columna es un vector.
lotes <- data.frame(
lote = c("A", "B", "C", "D", "E", "F"),
cultivo = c("papa", "papa", "maiz", "cafe", "maiz", "papa"),
area_ha = c(2.5, 1.8, 4.0, 3.2, 2.0, 1.2),
rendimiento = c(18.5, 22.1, 5.3, 1.9, 6.1, 25.0) # t/ha
)
lotes lote cultivo area_ha rendimiento
1 A papa 2.5 18.5
2 B papa 1.8 22.1
3 C maiz 4.0 5.3
4 D cafe 3.2 1.9
5 E maiz 2.0 6.1
6 F papa 1.2 25.0
Haga clic en lotes en el panel Environment: se abre como hoja de cálculo.
nrow(lotes) # número de filas[1] 6
ncol(lotes) # número de columnas[1] 4
names(lotes) # nombres de las columnas[1] "lote" "cultivo" "area_ha" "rendimiento"
str(lotes) # estructura: tipo de cada columna'data.frame': 6 obs. of 4 variables:
$ lote : chr "A" "B" "C" "D" ...
$ cultivo : chr "papa" "papa" "maiz" "cafe" ...
$ area_ha : num 2.5 1.8 4 3.2 2 1.2
$ rendimiento: num 18.5 22.1 5.3 1.9 6.1 25
$lotes$area_ha[1] 2.5 1.8 4.0 3.2 2.0 1.2
sum(lotes$area_ha) # área total de la finca[1] 14.7
Crear una columna nueva es asignarle un valor:
lotes$produccion_t <- lotes$area_ha * lotes$rendimiento
lotes lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 C maiz 4.0 5.3 21.20
4 D cafe 3.2 1.9 6.08
5 E maiz 2.0 6.1 12.20
6 F papa 1.2 25.0 30.00
Igual que con los vectores, se usa una condición dentro de corchetes. En una tabla los corchetes llevan dos partes: [filas, columnas]. Dejar vacío después de la coma significa “todas las columnas”:
lotes[lotes$cultivo == "papa", ] lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
6 F papa 1.2 25.0 30.00
La forma anterior funciona, pero se vuelve difícil de leer. El paquete dplyr ofrece funciones con nombres de verbos. Primero hay que cargarlo (en la sección 9 explicamos qué es un paquete):
library(dplyr)lotes |> filter(cultivo == "papa") lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 F papa 1.2 25.0 30.00
El símbolo |> se llama pipe (tubería). Léalo como “y luego”: “tome lotes y luego filtre los de papa”. Atajo: Ctrl + Shift + M. Permite encadenar pasos:
lotes |>
filter(cultivo == "papa") |>
arrange(desc(produccion_t)) # ordenar de mayor a menor producción lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 F papa 1.2 25.0 30.00
| Verbo de dplyr | Qué hace |
|---|---|
filter() |
se queda con algunas filas |
select() |
se queda con algunas columnas |
mutate() |
crea o modifica columnas |
arrange() |
ordena las filas |
lote y produccion_t.Todos los programadores, incluso los expertos, ven errores todo el día. La diferencia es que saben leerlos. Ejecute cada línea de este bloque; todas tienen un error a propósito:
rendimeinto # 1
Mean(rendimiento) # 2
c(1, 2 3) # 3
"papa" * 2 # 4Error in parse(text = input): <text>:3:8: unexpected numeric constant
2: Mean(rendimiento) # 2
3: c(1, 2 3
^
| Mensaje (puede salir en inglés o español) | Qué significa casi siempre |
|---|---|
object 'x' not found / objeto 'x' no encontrado |
Nombre mal escrito, mayúscula/minúscula, o no ejecutó la línea donde se creó |
could not find function "f" / no se pudo encontrar la función |
Nombre de función mal escrito o no cargó el paquete con library() |
unexpected symbol / unexpected ')' |
Falta o sobra una coma, comilla o paréntesis |
non-numeric argument / argumento no numérico |
Está haciendo matemáticas con un texto |
Cannot open file / cannot open data source |
La ruta del archivo está mal o el archivo no está en esa carpeta |
Copie a su documento las cuatro líneas con error y, en un bloque nuevo, escriba la versión corregida de cada una. Para que su documento se pueda renderizar con los errores incluidos, empiece el bloque de las líneas con error con la línea #| error: true. Esa línea le dice a Quarto que muestre el error y siga adelante.
+ y no responde
Significa que R está esperando que cierre algo (un paréntesis o una comilla). Haga clic en la consola y presione Esc para cancelar.
R trae funciones básicas. Para tareas especiales (mapas, estadística avanzada, etc.) se usan paquetes que escribe la comunidad. Funciona como las aplicaciones del celular:
install.packages()) es descargar la aplicación: se hace una sola vez en cada computador.library()) es abrirla: se hace cada vez que abre R.Este bloque instala solo los paquetes que le falten. Ejecútelo una vez (puede tardar algunos minutos):
paquetes <- c("sf", "dplyr")
faltan <- setdiff(paquetes, rownames(installed.packages()))
if (length(faltan) > 0) install.packages(faltan)Ejecute este bloque una sola vez. Después, agregue como primera línea del bloque #| eval: false. Así, cada vez que renderice, Quarto mostrará el código pero no volverá a instalar los paquetes.
🤔 Pregunta: Lea el bloque anterior con lo que ya sabe. ¿Qué contiene paquetes? ¿Qué cree que hace setdiff()? ¿Qué pregunta hace el if?
El paquete sf (simple features) permite trabajar con datos vectoriales (puntos, líneas, polígonos), igual que en QGIS.
library(sf)
library(dplyr)Leemos el shapefile de municipios de Boyacá y Santander. Fíjese que la ruta es relativa a la carpeta del proyecto:
ruta_shp <- "datos/mun_santander_boyaca.shp"
municipios <- st_read(ruta_shp)Reading layer `mun_santander_boyaca' from data source
`C:\Users\FCA-UN-2240386\OneDrive - Universidad Nacional de Colombia\1_Periodos_Asignaturas\Cursos_2026_2\Geomatica_Basica_20262\Practical\Introduccion_R\datos\mun_santander_boyaca.shp'
using driver `ESRI Shapefile'
Simple feature collection with 210 features and 90 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -74.66496 ymin: 4.655196 xmax: -71.94885 ymax: 8.14501
Geodetic CRS: MAGNA-SIRGAS
🤔 Pregunta: En el mensaje que apareció, identifique: ¿cuántos municipios (features) hay? ¿cuántos atributos (fields)? ¿qué tipo de geometría? ¿en qué sistema de coordenadas (CRS)?
class(municipios)[1] "sf" "data.frame"
municipios es a la vez sf y data.frame. Es decir: es una tabla como lotes, con una columna especial llamada geometry donde está la forma de cada municipio. Por eso todo lo que aprendió en la Parte A funciona aquí:
nrow(municipios)[1] 210
names(municipios) [1] "DPTO_CCDGO" "MPIO_CCDGO" "MPIO_CNMBR" "MPIO_CDPMP" "VERSION"
[6] "AREA" "LATITUD" "LONGITUD" "STCTNENCUE" "STP3_1_SI"
[11] "STP3_2_NO" "STP3A_RI" "STP3B_TCN" "STP4_1_SI" "STP4_2_NO"
[16] "STP9_1_USO" "STP9_2_USO" "STP9_3_USO" "STP9_4_USO" "STP9_2_1_M"
[21] "STP9_2_2_M" "STP9_2_3_M" "STP9_2_4_M" "STP9_2_9_M" "STP9_3_1_N"
[26] "STP9_3_2_N" "STP9_3_3_N" "STP9_3_4_N" "STP9_3_5_N" "STP9_3_6_N"
[31] "STP9_3_7_N" "STP9_3_8_N" "STP9_3_9_N" "STP9_3_10" "STP9_3_99"
[36] "STVIVIENDA" "STP14_1_TI" "STP14_2_TI" "STP14_3_TI" "STP14_4_TI"
[41] "STP14_5_TI" "STP14_6_TI" "STP15_1_OC" "STP15_2_OC" "STP15_3_OC"
[46] "STP15_4_OC" "TSP16_HOG" "STP19_EC_1" "STP19_ES_2" "STP19_EE_1"
[51] "STP19_EE_2" "STP19_EE_3" "STP19_EE_4" "STP19_EE_5" "STP19_EE_6"
[56] "STP19_EE_9" "STP19_ACU1" "STP19_ACU2" "STP19_ALC1" "STP19_ALC2"
[61] "STP19_GAS1" "STP19_GAS2" "STP19_GAS9" "STP19_REC1" "STP19_REC2"
[66] "STP19_INT1" "STP19_INT2" "STP19_INT9" "STP27_PERS" "STPERSON_L"
[71] "STPERSON_S" "STP32_1_SE" "STP32_2_SE" "STP34_1_ED" "STP34_2_ED"
[76] "STP34_3_ED" "STP34_4_ED" "STP34_5_ED" "STP34_6_ED" "STP34_7_ED"
[81] "STP34_8_ED" "STP34_9_ED" "STP51_PRIM" "STP51_SECU" "STP51_SUPE"
[86] "STP51_POST" "STP51_13_E" "STP51_99_E" "Shape_Leng" "Shape_Area"
[91] "geometry"
Para ver la tabla sin la geometría:
municipios |>
st_drop_geometry() |>
select(DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR, STP27_PERS) |>
head() DPTO_CCDGO MPIO_CCDGO MPIO_CNMBR STP27_PERS
1 15 001 TUNJA 167991
2 15 022 ALMEIDA 1582
3 15 047 AQUITANIA 13860
4 15 051 ARCABUCO 5465
5 15 087 BELÉN 7322
6 15 090 BERBEO 1453
Las columnas que empiezan por STP vienen del Censo Nacional de Población y Vivienda 2018 del DANE. Por ejemplo, STP27_PERS es el total de personas del municipio. Consulte el diccionario de datos del DANE para el significado de las demás.
plot() dibuja la capa. Con st_geometry() dibujamos solo los contornos:
plot(st_geometry(municipios))Si elegimos una columna con corchetes, el mapa se colorea según sus valores:
plot(municipios["DPTO_CCDGO"])plot(municipios["STP27_PERS"], main = "Población total (Censo 2018)")Haga un mapa con otra columna de la tabla y póngale un título con main = "...".
Revise en qué sistema de referencia están los datos:
st_crs(municipios)$epsg[1] 4686
st_bbox(municipios) xmin ymin xmax ymax
-74.664960 4.655196 -71.948854 8.145010
Los datos están en MAGNA-SIRGAS geográficas (EPSG 4686): las coordenadas son grados de longitud y latitud (fíjese en los valores de st_bbox: alrededor de −74 y 4 a 8).
En Colombia, el sistema oficial para cartografía es MAGNA-SIRGAS 2018 / Origen-Nacional (EPSG 9377), una proyección cuyas coordenadas están en metros. Para reproyectar se usa st_transform():
municipios_9377 <- st_transform(municipios, 9377)
st_crs(municipios_9377)$epsg[1] 9377
st_bbox(municipios_9377) xmin ymin xmax ymax
4815712 2072396 5116057 2458100
🤔 Pregunta: Compare los dos st_bbox(). ¿Por qué los números ahora están en los millones? (Pista: busque false easting y false northing en st_crs(municipios_9377)).
Si quiere ver la descripción completa de un sistema de coordenadas, ejecute st_crs(municipios_9377) sin el $epsg.
Como la capa ya está en metros, podemos calcular el área de cada municipio. st_area() devuelve m²; dividimos por 1 000 000 para tener km². Usamos as.numeric() para quedarnos solo con el número, sin la unidad:
municipios_9377$area_km2 <- as.numeric(st_area(municipios_9377)) / 1e6Es exactamente lo mismo que hicimos con lotes$produccion_t: crear una columna nueva a partir de otras. Ahora calculamos la densidad de población (habitantes por km²):
municipios_9377$densidad <- municipios_9377$STP27_PERS / municipios_9377$area_km2
municipios_9377 |>
st_drop_geometry() |>
select(MPIO_CNMBR, STP27_PERS, area_km2, densidad) |>
arrange(desc(densidad)) |>
head(5) MPIO_CNMBR STP27_PERS area_km2 densidad
1 BUCARAMANGA 528855 152.62869 3464.9776
2 FLORIDABLANCA 275109 100.13660 2747.3373
3 TUNJA 167991 119.48492 1405.9599
4 BARBOSA 28769 46.59283 617.4555
5 SOGAMOSO 120462 207.88393 579.4676
plot(municipios_9377["densidad"],
breaks = "quantile",
main = "Densidad de población (hab/km²)")🤔 Pregunta: ¿Qué municipios tienen la mayor densidad? ¿Tiene sentido según lo que conoce de la región?
Recuerde la advertencia de la sección 4. ¿De qué tipo es la columna del código de departamento?
class(municipios_9377$DPTO_CCDGO)[1] "character"
unique(municipios_9377$DPTO_CCDGO)[1] "15" "68"
Los códigos son texto, y en esta capa solo hay dos departamentos: "15" (Boyacá) y "68" (Santander). Por eso el filtro se escribe con comillas:
boyaca <- municipios_9377 |>
filter(DPTO_CCDGO == "15")
nrow(boyaca)[1] 123
plot(st_geometry(boyaca), main = "Municipios de Boyacá")🤔 Pregunta: ¿Qué pasaría si filtrara con un código que no está en la capa, por ejemplo "18"? Pruébelo y mire con nrow() cuántas filas quedan. ¿Le daría R un error, o algo más difícil de detectar?
grandes <- municipios_9377 |>
filter(area_km2 > 1000)
grandes |> st_drop_geometry() |> select(MPIO_CNMBR, area_km2) MPIO_CNMBR area_km2
1 PUERTO BOYACÁ 1512.084
2 CUBARÁ 1174.692
3 BARRANCABERMEJA 1324.926
4 CIMITARRA 3170.518
5 RIONEGRO 1166.437
6 SABANA DE TORRES 1400.656
7 SAN VICENTE DE CHUCURÍ 1114.575
8 PUERTO WILCHES 1505.814
9 BOLÍVAR 1008.889
santander con solo los municipios de Santander y dibújelo.Todo lo que ha hecho vive en la memoria de R: si cierra RStudio sin guardar, se pierde. Para usar los resultados en QGIS hay que escribirlos en un archivo.
Usaremos el formato GeoPackage (.gpkg): es un solo archivo (el shapefile son al menos cuatro), admite nombres de columna largos (el shapefile los corta a 10 caracteres) y QGIS lo abre directamente.
dir.create("salidas", showWarnings = FALSE) # crea la carpeta si no existe
st_write(municipios_9377, "salidas/municipios_9377.gpkg", delete_dsn = TRUE)Deleting source `salidas/municipios_9377.gpkg' using driver `GPKG'
Writing layer `municipios_9377' to data source
`salidas/municipios_9377.gpkg' using driver `GPKG'
Writing 210 features with 92 fields and geometry type Polygon.
st_write(boyaca, "salidas/boyaca_9377.gpkg", delete_dsn = TRUE)Deleting source `salidas/boyaca_9377.gpkg' using driver `GPKG'
Writing layer `boyaca_9377' to data source
`salidas/boyaca_9377.gpkg' using driver `GPKG'
Writing 123 features with 92 fields and geometry type Polygon.
delete_dsn = TRUE reemplaza el archivo si ya existe. Sin eso, la segunda vez que ejecute el bloque obtendrá un error.
Guarde su objeto santander en salidas/santander_9377.gpkg. Si su profesora lo pide, guárdelo también como shapefile cambiando la extensión a .shp. 🤔 Mire la carpeta salidas en el panel Files: ¿cuántos archivos se crearon para el shapefile y cuántos para el GeoPackage?
datos/mun_santander_boyaca.shp y su archivo salidas/municipios_9377.gpkg.area_km2 y densidad?🤔 Pregunta: ¿Qué ventajas y desventajas le ve a reproyectar y calcular atributos con código, comparado con hacerlo con clics en QGIS? Piense en qué pasaría si tuviera que repetir el proceso para los 32 departamentos.
Con todo lo aprendido, en una sección nueva de su documento:
km2_a_ha() que convierta km² a hectáreas.mutate() para agregar a boyaca una columna area_ha usando su función.salidas/reto_boyaca.gpkg.Su entrega es su propia página en RPubs, igual que esta guía.
Taller 1 R - Su nombre completo.https://rpubs.com/su_usuario/123456) y envíelo en el aula virtual.Haga los cambios, vuelva a hacer clic en Render y luego en Publish. RStudio le preguntará si quiere actualizar la publicación existente: diga que sí. Así el enlace sigue siendo el mismo.
Lo que se publica en RPubs es público: cualquiera con el enlace puede verlo. No incluya datos personales como su número de documento o su teléfono.
Marque lo que ya puede hacer sin mirar el taller:
| Término | Significado |
|---|---|
| Variable / objeto | Nombre que guarda un valor (area_ha <- 2.5) |
| Asignar | Guardar un valor en una variable con <- |
| Vector | Varios valores del mismo tipo, creado con c() |
| Data frame | Tabla de filas y columnas; cada columna es un vector |
| Función | Instrucción que recibe argumentos y devuelve un resultado: mean(x) |
| Argumento | Lo que va dentro de los paréntesis de una función |
| Paquete | Conjunto de funciones extra que se instala una vez y se carga con library() |
| Pipe | El símbolo de tubería de la sección 7, que se lee “y luego”: pasa el resultado de un paso al siguiente |
Proyecto (.Rproj) |
Carpeta de trabajo que RStudio reconoce; al abrirlo, las rutas se cuentan desde ahí |
| Ruta relativa | Ubicación de un archivo a partir de la carpeta del proyecto |
Quarto (.qmd) |
Documento que mezcla texto y código, y se convierte en página web al renderizarlo |
| Renderizar | Ejecutar todo el documento y generar el resultado (HTML) |
| RPubs | Sitio gratuito para publicar en internet documentos hechos con R |
| sf | Paquete para datos espaciales vectoriales; un objeto sf es una tabla con columna geometry |
| CRS / EPSG | Sistema de referencia de coordenadas y su código numérico (4686, 9377) |
Lo que está leyendo es una página publicada en RPubs: es la guía del taller. Su tarea es construir en RStudio su propio documento que la replique: escribir los títulos y explicaciones, escribir y ejecutar cada bloque de código, obtener los mismos resultados y resolver los ejercicios. Al final, usted tendrá una página como esta, hecha por usted.
Trabaje con dos ventanas lado a lado: esta guía en el navegador y RStudio con su documento.
RPubs es un sitio web gratuito de Posit (la empresa que hace RStudio) para publicar en internet documentos creados con R. Se publica directamente desde RStudio con un botón, y el resultado es una página web con texto, código y resultados (tablas, mapas, gráficos), como la que está leyendo.
Algunas cosas que debe saber:
.qmd): un archivo de texto que mezcla explicaciones y código. Ese es el tipo de archivo que usted va a crear.C:/Users/...). En su computador esas rutas serán diferentes, y está bien.Todo el trabajo de este taller lo hará desde cero, en un proyecto de RStudio creado por usted. Un proyecto es una carpeta que RStudio reconoce como “mi carpeta de trabajo”. Gracias a eso podemos escribir rutas cortas como "datos/municipios.shp" en vez de "C:/Users/.../Descargas/curso/datos/municipios.shp", y el código funciona igual en cualquier computador.
La profesora solo le entrega la carpeta datos, con los shapefiles: descárguela aquí. Todo lo demás lo crea usted.
taller1_geomatica (sin espacios ni tildes).C:/geomatica.taller1_geomatica.RStudio creó la carpeta taller1_geomatica con un archivo taller1_geomatica.Rproj. La próxima vez que quiera trabajar en el taller, abra el proyecto con doble clic en ese archivo .Rproj, o desde RStudio en File → Open Project…
Guarde el proyecto fuera de OneDrive y en una ruta sin tildes, eñes ni espacios (por ejemplo C:/geomatica/taller1_geomatica). La sincronización de OneDrive y los caracteres especiales causan errores difíciles de entender al leer y escribir archivos.
.zip..zip (clic derecho → Extraer todo…).taller1_geomatica y asegúrese de que se llame exactamente datos (en minúsculas) y que los archivos del shapefile estén directamente adentro, no en otra subcarpeta.datos. Haga clic en ella y compruebe que contiene mun_santander_boyaca.shp junto con sus archivos acompañantes (.dbf, .shx, .prj…).Un shapefile no es un solo archivo: son varios con el mismo nombre y distinta extensión. Si falta alguno, R no podrá leer la capa. Copie siempre la carpeta completa.
Al terminar el taller, su proyecto debe verse así:
taller1_geomatica/
├── taller1_geomatica.Rproj ← lo crea RStudio en el paso 1
├── taller1_su_apellido.qmd ← el documento que usted crea
├── taller1_su_apellido.html ← la página que se genera al renderizar
├── datos/ ← la carpeta que entrega la profesora
└── salidas/ ← aquí guardaremos resultados (se crea en el taller)
taller1_geomatica abierto, vaya a File → New File → Quarto Document…Taller 1: Primeros pasos en R) y su nombre como autor. Deje el formato HTML y haga clic en Create.---).Ctrl + S) en la carpeta del proyecto con el nombre taller1_su_apellido.qmd.Deje el encabezado así (cambie su nombre). La línea embed-resources: true hace que la página quede en un solo archivo, necesario para publicarla:
---
title: "Taller 1: Primeros pasos en R"
author: "Su nombre completo"
format:
html:
toc: true
number-sections: true
embed-resources: true
---Un documento Quarto tiene tres ingredientes:
El texto se escribe normalmente y se le da formato con algunos símbolos:
| Usted escribe | Se ve como |
|---|---|
# Título |
título de sección |
## Subtítulo |
subtítulo |
**negrita** |
negrita |
*cursiva* |
cursiva |
`codigo` |
codigo |
- elemento |
viñeta de una lista |
Un bloque de código empieza con ```{r} y termina con ```. Insértelo con Ctrl + Alt + I (Mac: Cmd + Option + I). Por ejemplo, así se ve en su documento una sección con texto y un bloque:
# R como calculadora
Lo más sencillo que R puede hacer es calcular.
```{r}
2 + 3
10 / 4
```Para ejecutar código:
| Acción | Windows / Linux | Mac |
|---|---|---|
| Ejecutar la línea donde está el cursor | Ctrl + Enter |
Cmd + Enter |
| Ejecutar todo el bloque | Ctrl + Shift + Enter |
Cmd + Shift + Enter |
| Insertar un bloque nuevo | Ctrl + Alt + I |
Cmd + Option + I |
También puede hacer clic en el triángulo verde ▶ en la esquina del bloque.
Cuando haga clic en el botón Render (flecha azul, arriba del editor; atajo Ctrl + Shift + K), RStudio ejecuta todo el documento de principio a fin y genera el archivo .html. Hágalo con frecuencia, por ejemplo al terminar cada sección:
Su primer bloque: compruebe dónde está trabajando R.
getwd()[1] "C:/Users/FCA-UN-2240386/OneDrive - Universidad Nacional de Colombia/1_Periodos_Asignaturas/Cursos_2026_2/Geomatica_Basica_20262/Practical/Introduccion_R"
🤔 Pregunta: ¿La ruta que aparece en su documento termina en taller1_geomatica? Si no, guarde su documento, cierre RStudio y vuelva a abrir el proyecto con doble clic en el archivo taller1_geomatica.Rproj. Revise también que su .qmd esté guardado dentro de esa carpeta.
Lo más sencillo que R puede hacer es calcular. Ejecute cada línea con Ctrl + Enter:
2 + 3[1] 5
10 - 4[1] 6
6 * 7[1] 42
10 / 4[1] 2.5
2^3 # potencia: 2 elevado a 3[1] 8
sqrt(16) # raíz cuadrada[1] 4
Todo lo que está después de # es un comentario: R lo ignora. Los comentarios sirven para explicarle a otras personas (y a usted mismo en el futuro) qué hace el código. Úselos mucho.
R respeta el orden de las operaciones de la matemática. Use paréntesis cuando lo necesite:
2 + 3 * 4 # primero multiplica[1] 14
(2 + 3) * 4 # primero suma[1] 20
Un lote rectangular mide 150 m de largo y 80 m de ancho. Calcule su área en m² y luego en hectáreas (1 ha = 10 000 m²).
En el ejercicio anterior tuvo que escribir los números varias veces. En programación preferimos guardar los valores en variables. Una variable es como una caja con una etiqueta: adentro está el valor y la etiqueta es el nombre.
En R se guarda con la flecha <- (se lee “recibe”). Atajo: Alt + -.
largo <- 150
ancho <- 80Fíjese que no apareció nada debajo: R guardó los valores sin mostrarlos. Ahora mire el panel Environment (arriba a la derecha): ahí están largo y ancho. Para ver lo que hay en una variable, escriba su nombre:
largo[1] 150
Ahora podemos calcular con los nombres en vez de con los números:
area_m2 <- largo * ancho
area_ha <- area_m2 / 10000
area_ha[1] 1.2
_ y ., pero no pueden empezar con número ni tener espacios.Largo y largo son dos variables distintas.area_ha es mejor que x.area, no área; ano, no año).R ejecuta las líneas en el orden en que usted las ejecuta, no en el orden en que están escritas. Haga este experimento:
largo <- 200
area_ha[1] 1.2
🤔 Pregunta: Cambiamos el largo a 200, pero area_ha sigue igual. ¿Por qué? ¿Qué tendría que hacer para que area_ha se actualice?
Cree una variable rendimiento con el valor 22 (toneladas de papa por hectárea). Usando area_ha, calcule la producción total del lote y guárdela en una variable llamada produccion_t. Muestre el resultado.
No todo es un número. Los tres tipos de datos que más usaremos son:
| Tipo | Ejemplo | Para qué sirve |
|---|---|---|
numeric (número) |
22.5, 150 |
medir, calcular |
character (texto) |
"papa", "Tunja" |
nombres, categorías, códigos |
logical (lógico) |
TRUE, FALSE |
responder preguntas de sí o no |
El texto siempre va entre comillas. La función class() dice de qué tipo es algo:
cultivo <- "papa"
class(cultivo)[1] "character"
class(area_ha)[1] "numeric"
class(TRUE)[1] "logical"
Las comparaciones producen valores lógicos:
area_ha > 1 # ¿el lote tiene más de 1 ha?[1] TRUE
cultivo == "papa" # ¿el cultivo es papa? (dos signos igual para comparar)[1] TRUE
cultivo != "maiz" # ¿el cultivo es distinto de maíz?[1] TRUE
15 (número) y "15" (texto) no son lo mismo para R. Ejecute:
codigo_numero <- 15
codigo_texto <- "15"
codigo_numero + 1[1] 16
codigo_texto + 1Error in `codigo_texto + 1`:
! argumento no-numérico para operador binario
La última línea da error porque no se puede sumar a un texto. En los datos geográficos de Colombia, los códigos DANE de departamentos y municipios suelen guardarse como texto (por ejemplo "15" para Boyacá o "05" para Antioquia, con el cero a la izquierda). Recuérdelo en la Parte B.
Casi nunca trabajamos con un solo dato. Un vector es una fila de valores del mismo tipo. Se crea con c() (de “combinar”):
# Rendimiento de papa (t/ha) en cinco lotes de una finca
rendimiento <- c(18.5, 22.1, 15.3, 25.0, 19.8)
rendimiento[1] 18.5 22.1 15.3 25.0 19.8
Las funciones de resumen trabajan sobre todo el vector:
length(rendimiento) # ¿cuántos valores hay?[1] 5
mean(rendimiento) # promedio[1] 20.14
max(rendimiento) # máximo[1] 25
min(rendimiento) # mínimo[1] 15.3
sum(rendimiento) # suma[1] 100.7
Las operaciones se aplican a cada elemento a la vez. Para pasar de t/ha a kg/ha:
rendimiento * 1000[1] 18500 22100 15300 25000 19800
Con corchetes [ ] indicamos la posición del elemento (en R se empieza a contar desde 1):
rendimiento[2] # el segundo[1] 22.1
rendimiento[c(1, 3)] # el primero y el tercero[1] 18.5 15.3
Esta es una de las ideas más poderosas de todo el taller. Fíjese en lo que produce una comparación sobre un vector:
rendimiento > 20[1] FALSE TRUE FALSE TRUE FALSE
Es un vector de TRUE/FALSE: uno por cada lote. Si lo ponemos dentro de los corchetes, R se queda solo con los TRUE:
rendimiento[rendimiento > 20][1] 22.1 25.0
Leído en voz alta: “del vector rendimiento, dame los valores donde rendimiento es mayor que 20”. Exactamente esta idea es la que usamos después para seleccionar municipios en un mapa.
lluvia_mm con la precipitación de seis meses: 120, 85, 210, 160, 45, 98.sum() cuenta los TRUE).Ya usó varias funciones: mean(), max(), class(), sqrt(). Una función es una máquina: le entrega algo (los argumentos, dentro de los paréntesis), hace un trabajo y le devuelve un resultado.
Algunas funciones reciben varios argumentos, separados por coma y a veces con nombre:
promedio <- mean(rendimiento)
promedio[1] 20.14
round(promedio, digits = 1) # redondear a 1 decimal[1] 20.1
Para saber qué hace una función y qué argumentos recibe, escriba ? y su nombre en la consola. La ayuda aparece en el panel Help:
?roundCuando un cálculo se repite, conviene convertirlo en una función:
m2_a_ha <- function(m2) {
m2 / 10000
}
m2_a_ha(12000)[1] 1.2
m2_a_ha(c(5000, 25000, 80000)) # ¡también funciona con vectores![1] 0.5 2.5 8.0
Partes de una función: el nombre (m2_a_ha), los argumentos entre paréntesis (m2) y el cuerpo entre llaves { } con el cálculo. La última línea del cuerpo es lo que la función devuelve.
Cree una función llamada produccion que reciba dos argumentos, area_ha y rendimiento_t_ha, y devuelva la producción en toneladas. Pruébela con un lote de 3.5 ha que rinde 20 t/ha.
Los datos reales casi siempre vienen en tablas: filas (observaciones) y columnas (variables), como en Excel. En R una tabla se llama data frame. Cada columna es un vector.
lotes <- data.frame(
lote = c("A", "B", "C", "D", "E", "F"),
cultivo = c("papa", "papa", "maiz", "cafe", "maiz", "papa"),
area_ha = c(2.5, 1.8, 4.0, 3.2, 2.0, 1.2),
rendimiento = c(18.5, 22.1, 5.3, 1.9, 6.1, 25.0) # t/ha
)
lotes lote cultivo area_ha rendimiento
1 A papa 2.5 18.5
2 B papa 1.8 22.1
3 C maiz 4.0 5.3
4 D cafe 3.2 1.9
5 E maiz 2.0 6.1
6 F papa 1.2 25.0
Haga clic en lotes en el panel Environment: se abre como hoja de cálculo.
nrow(lotes) # número de filas[1] 6
ncol(lotes) # número de columnas[1] 4
names(lotes) # nombres de las columnas[1] "lote" "cultivo" "area_ha" "rendimiento"
str(lotes) # estructura: tipo de cada columna'data.frame': 6 obs. of 4 variables:
$ lote : chr "A" "B" "C" "D" ...
$ cultivo : chr "papa" "papa" "maiz" "cafe" ...
$ area_ha : num 2.5 1.8 4 3.2 2 1.2
$ rendimiento: num 18.5 22.1 5.3 1.9 6.1 25
$lotes$area_ha[1] 2.5 1.8 4.0 3.2 2.0 1.2
sum(lotes$area_ha) # área total de la finca[1] 14.7
Crear una columna nueva es asignarle un valor:
lotes$produccion_t <- lotes$area_ha * lotes$rendimiento
lotes lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 C maiz 4.0 5.3 21.20
4 D cafe 3.2 1.9 6.08
5 E maiz 2.0 6.1 12.20
6 F papa 1.2 25.0 30.00
Igual que con los vectores, se usa una condición dentro de corchetes. En una tabla los corchetes llevan dos partes: [filas, columnas]. Dejar vacío después de la coma significa “todas las columnas”:
lotes[lotes$cultivo == "papa", ] lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
6 F papa 1.2 25.0 30.00
La forma anterior funciona, pero se vuelve difícil de leer. El paquete dplyr ofrece funciones con nombres de verbos. Primero hay que cargarlo (en la sección 9 explicamos qué es un paquete):
library(dplyr)lotes |> filter(cultivo == "papa") lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 F papa 1.2 25.0 30.00
El símbolo |> se llama pipe (tubería). Léalo como “y luego”: “tome lotes y luego filtre los de papa”. Atajo: Ctrl + Shift + M. Permite encadenar pasos:
lotes |>
filter(cultivo == "papa") |>
arrange(desc(produccion_t)) # ordenar de mayor a menor producción lote cultivo area_ha rendimiento produccion_t
1 A papa 2.5 18.5 46.25
2 B papa 1.8 22.1 39.78
3 F papa 1.2 25.0 30.00
| Verbo de dplyr | Qué hace |
|---|---|
filter() |
se queda con algunas filas |
select() |
se queda con algunas columnas |
mutate() |
crea o modifica columnas |
arrange() |
ordena las filas |
lote y produccion_t.Todos los programadores, incluso los expertos, ven errores todo el día. La diferencia es que saben leerlos. Ejecute cada línea de este bloque; todas tienen un error a propósito:
rendimeinto # 1
Mean(rendimiento) # 2
c(1, 2 3) # 3
"papa" * 2 # 4Error in parse(text = input): <text>:3:8: unexpected numeric constant
2: Mean(rendimiento) # 2
3: c(1, 2 3
^
| Mensaje (puede salir en inglés o español) | Qué significa casi siempre |
|---|---|
object 'x' not found / objeto 'x' no encontrado |
Nombre mal escrito, mayúscula/minúscula, o no ejecutó la línea donde se creó |
could not find function "f" / no se pudo encontrar la función |
Nombre de función mal escrito o no cargó el paquete con library() |
unexpected symbol / unexpected ')' |
Falta o sobra una coma, comilla o paréntesis |
non-numeric argument / argumento no numérico |
Está haciendo matemáticas con un texto |
Cannot open file / cannot open data source |
La ruta del archivo está mal o el archivo no está en esa carpeta |
Copie a su documento las cuatro líneas con error y, en un bloque nuevo, escriba la versión corregida de cada una. Para que su documento se pueda renderizar con los errores incluidos, empiece el bloque de las líneas con error con la línea #| error: true. Esa línea le dice a Quarto que muestre el error y siga adelante.
+ y no responde
Significa que R está esperando que cierre algo (un paréntesis o una comilla). Haga clic en la consola y presione Esc para cancelar.
R trae funciones básicas. Para tareas especiales (mapas, estadística avanzada, etc.) se usan paquetes que escribe la comunidad. Funciona como las aplicaciones del celular:
install.packages()) es descargar la aplicación: se hace una sola vez en cada computador.library()) es abrirla: se hace cada vez que abre R.Este bloque instala solo los paquetes que le falten. Ejecútelo una vez (puede tardar algunos minutos):
paquetes <- c("sf", "dplyr")
faltan <- setdiff(paquetes, rownames(installed.packages()))
if (length(faltan) > 0) install.packages(faltan)Ejecute este bloque una sola vez. Después, agregue como primera línea del bloque #| eval: false. Así, cada vez que renderice, Quarto mostrará el código pero no volverá a instalar los paquetes.
🤔 Pregunta: Lea el bloque anterior con lo que ya sabe. ¿Qué contiene paquetes? ¿Qué cree que hace setdiff()? ¿Qué pregunta hace el if?
El paquete sf (simple features) permite trabajar con datos vectoriales (puntos, líneas, polígonos), igual que en QGIS.
library(sf)
library(dplyr)Leemos el shapefile de municipios de Boyacá y Santander. Fíjese que la ruta es relativa a la carpeta del proyecto:
ruta_shp <- "datos/mun_santander_boyaca.shp"
municipios <- st_read(ruta_shp)Reading layer `mun_santander_boyaca' from data source
`C:\Users\FCA-UN-2240386\OneDrive - Universidad Nacional de Colombia\1_Periodos_Asignaturas\Cursos_2026_2\Geomatica_Basica_20262\Practical\Introduccion_R\datos\mun_santander_boyaca.shp'
using driver `ESRI Shapefile'
Simple feature collection with 210 features and 90 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -74.66496 ymin: 4.655196 xmax: -71.94885 ymax: 8.14501
Geodetic CRS: MAGNA-SIRGAS
🤔 Pregunta: En el mensaje que apareció, identifique: ¿cuántos municipios (features) hay? ¿cuántos atributos (fields)? ¿qué tipo de geometría? ¿en qué sistema de coordenadas (CRS)?
class(municipios)[1] "sf" "data.frame"
municipios es a la vez sf y data.frame. Es decir: es una tabla como lotes, con una columna especial llamada geometry donde está la forma de cada municipio. Por eso todo lo que aprendió en la Parte A funciona aquí:
nrow(municipios)[1] 210
names(municipios) [1] "DPTO_CCDGO" "MPIO_CCDGO" "MPIO_CNMBR" "MPIO_CDPMP" "VERSION"
[6] "AREA" "LATITUD" "LONGITUD" "STCTNENCUE" "STP3_1_SI"
[11] "STP3_2_NO" "STP3A_RI" "STP3B_TCN" "STP4_1_SI" "STP4_2_NO"
[16] "STP9_1_USO" "STP9_2_USO" "STP9_3_USO" "STP9_4_USO" "STP9_2_1_M"
[21] "STP9_2_2_M" "STP9_2_3_M" "STP9_2_4_M" "STP9_2_9_M" "STP9_3_1_N"
[26] "STP9_3_2_N" "STP9_3_3_N" "STP9_3_4_N" "STP9_3_5_N" "STP9_3_6_N"
[31] "STP9_3_7_N" "STP9_3_8_N" "STP9_3_9_N" "STP9_3_10" "STP9_3_99"
[36] "STVIVIENDA" "STP14_1_TI" "STP14_2_TI" "STP14_3_TI" "STP14_4_TI"
[41] "STP14_5_TI" "STP14_6_TI" "STP15_1_OC" "STP15_2_OC" "STP15_3_OC"
[46] "STP15_4_OC" "TSP16_HOG" "STP19_EC_1" "STP19_ES_2" "STP19_EE_1"
[51] "STP19_EE_2" "STP19_EE_3" "STP19_EE_4" "STP19_EE_5" "STP19_EE_6"
[56] "STP19_EE_9" "STP19_ACU1" "STP19_ACU2" "STP19_ALC1" "STP19_ALC2"
[61] "STP19_GAS1" "STP19_GAS2" "STP19_GAS9" "STP19_REC1" "STP19_REC2"
[66] "STP19_INT1" "STP19_INT2" "STP19_INT9" "STP27_PERS" "STPERSON_L"
[71] "STPERSON_S" "STP32_1_SE" "STP32_2_SE" "STP34_1_ED" "STP34_2_ED"
[76] "STP34_3_ED" "STP34_4_ED" "STP34_5_ED" "STP34_6_ED" "STP34_7_ED"
[81] "STP34_8_ED" "STP34_9_ED" "STP51_PRIM" "STP51_SECU" "STP51_SUPE"
[86] "STP51_POST" "STP51_13_E" "STP51_99_E" "Shape_Leng" "Shape_Area"
[91] "geometry"
Para ver la tabla sin la geometría:
municipios |>
st_drop_geometry() |>
select(DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR, STP27_PERS) |>
head() DPTO_CCDGO MPIO_CCDGO MPIO_CNMBR STP27_PERS
1 15 001 TUNJA 167991
2 15 022 ALMEIDA 1582
3 15 047 AQUITANIA 13860
4 15 051 ARCABUCO 5465
5 15 087 BELÉN 7322
6 15 090 BERBEO 1453
Las columnas que empiezan por STP vienen del Censo Nacional de Población y Vivienda 2018 del DANE. Por ejemplo, STP27_PERS es el total de personas del municipio. Consulte el diccionario de datos del DANE para el significado de las demás.
plot() dibuja la capa. Con st_geometry() dibujamos solo los contornos:
plot(st_geometry(municipios))Si elegimos una columna con corchetes, el mapa se colorea según sus valores:
plot(municipios["DPTO_CCDGO"])plot(municipios["STP27_PERS"], main = "Población total (Censo 2018)")Haga un mapa con otra columna de la tabla y póngale un título con main = "...".
Revise en qué sistema de referencia están los datos:
st_crs(municipios)$epsg[1] 4686
st_bbox(municipios) xmin ymin xmax ymax
-74.664960 4.655196 -71.948854 8.145010
Los datos están en MAGNA-SIRGAS geográficas (EPSG 4686): las coordenadas son grados de longitud y latitud (fíjese en los valores de st_bbox: alrededor de −74 y 4 a 8).
En Colombia, el sistema oficial para cartografía es MAGNA-SIRGAS 2018 / Origen-Nacional (EPSG 9377), una proyección cuyas coordenadas están en metros. Para reproyectar se usa st_transform():
municipios_9377 <- st_transform(municipios, 9377)
st_crs(municipios_9377)$epsg[1] 9377
st_bbox(municipios_9377) xmin ymin xmax ymax
4815712 2072396 5116057 2458100
🤔 Pregunta: Compare los dos st_bbox(). ¿Por qué los números ahora están en los millones? (Pista: busque false easting y false northing en st_crs(municipios_9377)).
Si quiere ver la descripción completa de un sistema de coordenadas, ejecute st_crs(municipios_9377) sin el $epsg.
Como la capa ya está en metros, podemos calcular el área de cada municipio. st_area() devuelve m²; dividimos por 1 000 000 para tener km². Usamos as.numeric() para quedarnos solo con el número, sin la unidad:
municipios_9377$area_km2 <- as.numeric(st_area(municipios_9377)) / 1e6Es exactamente lo mismo que hicimos con lotes$produccion_t: crear una columna nueva a partir de otras. Ahora calculamos la densidad de población (habitantes por km²):
municipios_9377$densidad <- municipios_9377$STP27_PERS / municipios_9377$area_km2
municipios_9377 |>
st_drop_geometry() |>
select(MPIO_CNMBR, STP27_PERS, area_km2, densidad) |>
arrange(desc(densidad)) |>
head(5) MPIO_CNMBR STP27_PERS area_km2 densidad
1 BUCARAMANGA 528855 152.62869 3464.9776
2 FLORIDABLANCA 275109 100.13660 2747.3373
3 TUNJA 167991 119.48492 1405.9599
4 BARBOSA 28769 46.59283 617.4555
5 SOGAMOSO 120462 207.88393 579.4676
plot(municipios_9377["densidad"],
breaks = "quantile",
main = "Densidad de población (hab/km²)")🤔 Pregunta: ¿Qué municipios tienen la mayor densidad? ¿Tiene sentido según lo que conoce de la región?
Recuerde la advertencia de la sección 4. ¿De qué tipo es la columna del código de departamento?
class(municipios_9377$DPTO_CCDGO)[1] "character"
unique(municipios_9377$DPTO_CCDGO)[1] "15" "68"
Los códigos son texto, y en esta capa solo hay dos departamentos: "15" (Boyacá) y "68" (Santander). Por eso el filtro se escribe con comillas:
boyaca <- municipios_9377 |>
filter(DPTO_CCDGO == "15")
nrow(boyaca)[1] 123
plot(st_geometry(boyaca), main = "Municipios de Boyacá")🤔 Pregunta: ¿Qué pasaría si filtrara con un código que no está en la capa, por ejemplo "18"? Pruébelo y mire con nrow() cuántas filas quedan. ¿Le daría R un error, o algo más difícil de detectar?
grandes <- municipios_9377 |>
filter(area_km2 > 1000)
grandes |> st_drop_geometry() |> select(MPIO_CNMBR, area_km2) MPIO_CNMBR area_km2
1 PUERTO BOYACÁ 1512.084
2 CUBARÁ 1174.692
3 BARRANCABERMEJA 1324.926
4 CIMITARRA 3170.518
5 RIONEGRO 1166.437
6 SABANA DE TORRES 1400.656
7 SAN VICENTE DE CHUCURÍ 1114.575
8 PUERTO WILCHES 1505.814
9 BOLÍVAR 1008.889
santander con solo los municipios de Santander y dibújelo.Todo lo que ha hecho vive en la memoria de R: si cierra RStudio sin guardar, se pierde. Para usar los resultados en QGIS hay que escribirlos en un archivo.
Usaremos el formato GeoPackage (.gpkg): es un solo archivo (el shapefile son al menos cuatro), admite nombres de columna largos (el shapefile los corta a 10 caracteres) y QGIS lo abre directamente.
dir.create("salidas", showWarnings = FALSE) # crea la carpeta si no existe
st_write(municipios_9377, "salidas/municipios_9377.gpkg", delete_dsn = TRUE)Deleting source `salidas/municipios_9377.gpkg' using driver `GPKG'
Writing layer `municipios_9377' to data source
`salidas/municipios_9377.gpkg' using driver `GPKG'
Writing 210 features with 92 fields and geometry type Polygon.
st_write(boyaca, "salidas/boyaca_9377.gpkg", delete_dsn = TRUE)Deleting source `salidas/boyaca_9377.gpkg' using driver `GPKG'
Writing layer `boyaca_9377' to data source
`salidas/boyaca_9377.gpkg' using driver `GPKG'
Writing 123 features with 92 fields and geometry type Polygon.
delete_dsn = TRUE reemplaza el archivo si ya existe. Sin eso, la segunda vez que ejecute el bloque obtendrá un error.
Guarde su objeto santander en salidas/santander_9377.gpkg. Si su profesora lo pide, guárdelo también como shapefile cambiando la extensión a .shp. 🤔 Mire la carpeta salidas en el panel Files: ¿cuántos archivos se crearon para el shapefile y cuántos para el GeoPackage?
datos/mun_santander_boyaca.shp y su archivo salidas/municipios_9377.gpkg.area_km2 y densidad?🤔 Pregunta: ¿Qué ventajas y desventajas le ve a reproyectar y calcular atributos con código, comparado con hacerlo con clics en QGIS? Piense en qué pasaría si tuviera que repetir el proceso para los 32 departamentos.
Con todo lo aprendido, en una sección nueva de su documento:
km2_a_ha() que convierta km² a hectáreas.mutate() para agregar a boyaca una columna area_ha usando su función.salidas/reto_boyaca.gpkg.Su entrega es su propia página en RPubs, igual que esta guía.
Taller 1 R - Su nombre completo.https://rpubs.com/su_usuario/123456) y envíelo en el aula virtual.Haga los cambios, vuelva a hacer clic en Render y luego en Publish. RStudio le preguntará si quiere actualizar la publicación existente: diga que sí. Así el enlace sigue siendo el mismo.
Lo que se publica en RPubs es público: cualquiera con el enlace puede verlo. No incluya datos personales como su número de documento o su teléfono.
Marque lo que ya puede hacer sin mirar el taller:
| Término | Significado |
|---|---|
| Variable / objeto | Nombre que guarda un valor (area_ha <- 2.5) |
| Asignar | Guardar un valor en una variable con <- |
| Vector | Varios valores del mismo tipo, creado con c() |
| Data frame | Tabla de filas y columnas; cada columna es un vector |
| Función | Instrucción que recibe argumentos y devuelve un resultado: mean(x) |
| Argumento | Lo que va dentro de los paréntesis de una función |
| Paquete | Conjunto de funciones extra que se instala una vez y se carga con library() |
| Pipe | El símbolo de tubería de la sección 7, que se lee “y luego”: pasa el resultado de un paso al siguiente |
Proyecto (.Rproj) |
Carpeta de trabajo que RStudio reconoce; al abrirlo, las rutas se cuentan desde ahí |
| Ruta relativa | Ubicación de un archivo a partir de la carpeta del proyecto |
Quarto (.qmd) |
Documento que mezcla texto y código, y se convierte en página web al renderizarlo |
| Renderizar | Ejecutar todo el documento y generar el resultado (HTML) |
| RPubs | Sitio gratuito para publicar en internet documentos hechos con R |
| sf | Paquete para datos espaciales vectoriales; un objeto sf es una tabla con columna geometry |
| CRS / EPSG | Sistema de referencia de coordenadas y su código numérico (4686, 9377) |