Capítulo 5 Funciones
5.1 Resumen
En este capítulo:
- Finalizamos la introducción a algunos de los elementos básicos del trabajo estadístico en R: objetos, bases de datos y funciones.
- Mostramos cómo aplicar funciones existentes y cómo escribir funciones nuevas que nos ayuden a analizar datos.
- Ilustramos el potencial de ambas cuestiones con una corta aplicación a la política colombiana.
Principales conceptos: función; datos no disponibles (NA
); estadísticas resumen.
Funciones clave: mean()
; table()
; cor()
; is.na()
; function()
.
5.1.1 Librerías
Vamos a utilizar las siguientes librerías:
library(tidyverse)
5.1.2 Datos
Debemos descargar los siguientes archivos de datos y guardarlos en la carpeta /data
de nuestro proyecto:
- Datos de ingreso ficticios: link. Para descargar, hacer click derecho, “Guardar como…”.
5.2 Qué es una función
En general, queremos hacer algo con los objetos en R (o sea, con los datos). Como ya hemos visto, en R hacemos operaciones usando funciones que toman un input y producen un output tras un procedimiento. Podemos aplicale funciones a valores individuales, vectores, bases de datos, variables y otros objetos.
Recapitulando, una función toma un input, le aplica una operación y nos devuelve un output. Por ejemplo, en la función \(f(x) = x + 1\):
- Input: la información que queremos transformar (\(x\)).
- Operación: la transformación o relación (\(x + 1\)).
- Output: el resultado de aplicar la función (si \(x = 1\), entonces \(f(x) = 1 + 1 = 2\)).
En R, esto se vería así:
# definimos la funcion
<- function(a){a + 1}
sumar_uno # definimos unos valores para evaluar la funcion
<- 1
x # aplicamos la funcion a esos valores
sumar_uno(x)
## [1] 2
Si quisiéramos aplicar esta función a más de un valor al mismo tiempo:
# definimos unos valores para evaluar la funcion
<- 1:10
var # aplicamos la funcion a esos valores
sumar_uno(var)
## [1] 2 3 4 5 6 7 8 9 10 11
En R, las funciones toman argumentos, separados por comas: nombre_funcion(argumento1 = valor, argumento2 = valor, ...)
. Por ejemplo, para encontrar la mediana de un vector, usamos median()
. Esta función toma como primer argumento un vector para encontrar el valor mediano. Adicionalmente, puede tomar un argumento na.rm =
con un valor TRUE
o FALSE
(na.rm = FALSE
o na.rm = TRUE
) que elimina los valores NA
antes de hallar la mediana. Veamos qué pasa si tenemos un valor NA
e intentamos calcular la mediana:
<- c(1, 1, 2, 3, 5, 8, 13, 21, 34, NA)
mis_numeros median(mis_numeros)
## [1] NA
Como hay un NA
en mis_numeros
, R no puede estimar la mediana del vector. Por eso, usamos el argumento na.rm = TRUE
:
median(mis_numeros, na.rm = TRUE)
## [1] 5
Podemos consultar los argumentos de una función y sus valores por defecto ejecutando ?
en la consola, seguido del nombre de la función. Por ejemplo, intenten ejecutar ?median
o ?tibble
:
?tibble
Es posible especificar los argumentos de una función de manera explícita o implícita. Cuando hacemos explícito un argumento, usamos el nombre del argumento, como hicimos arriba con na.rm =
. Aquí hacemos lo mismo con la función rnorm()
y los argumentos mean =
y sd =
:
set.seed(42) # para asegurar replicabilidad
head(rnorm(n = 10000, mean = 0, sd = 1))
## [1] 1.3709584 -0.5646982 0.3631284 0.6328626 0.4042683 -0.1061245
En contraste, podemos dejar los argumentos implícitos. Cada función tiene un orden predefinido de sus argumentos; podemos consultar este orden para una función con ?
. El siguiente bloque de código es equivalente al anterior:
head(rnorm(10000, 0, 1)) # diferencias en el resultado son producto de la aleatoriedad de rnorm()
## [1] 1.1631089 -0.1902346 -0.2894558 -0.3988458 0.7092426 -1.6226473
Muchas funciones tienen valores por defecto para cada argumento. En el caso de rnorm()
, mean = 0
y sd = 1
a menos que los definamos de manera diferente. Podemos comprobarlo:
<- rnorm(10000)
normal_sim mean(normal_sim)
## [1] 0.008092089
sd(normal_sim)
## [1] 1.01399
Podemos cambiar el orden en que van los argumentos si usamos sus nombres (o sea, si somos explícitos):
head(rnorm(mean = 0, sd = 1, n = 10000))
## [1] 0.680923388 1.013496371 -0.009105223 0.560053416 -1.478541110
## [6] 0.952096837
Comparen lo anterior con el siguiente código que produce 1 observación distribuida normalmente, con media de 10000 y desviación estándar de 0.
head(rnorm(1, 10000, 0))
## [1] 10000
5.3 Funciones básicas
Hay funciones básicas para crear o modificar objetos en R. Muchas ya vienen instaladas y ya hemos usado varias. Otras funciones están en librerías adicionales que descargamos y cargamos, como las del tidyverse
. Aquí hay algunos ejemplos:
c()
pega, combina o concatena valores y objetos.data.frame()
crea un marco de datos;tibble()
crea un tibble.read_csv()
yread_dta()
leen archivos de datos CSV o de Stata, respectivamente.as_tibble
para convertir undata.frame
u otro objeto existente en un tibble.as.factor()
para convertir una variable numérica en una categórica yfactor()
para crear un factor (una variable categórica).- Además, funciones de la librería
forcats
para trabajar con factores.
- Además, funciones de la librería
as.numeric()
,as.character()
, etc.
A continuación, revisamos algunas funciones centrales para usar R en el contexto de hacer análisis de datos.
5.3.1 Estadisticas resumen
Algunas funciones básicas resumen datos numéricos. Estas incluyen median()
, mean()
y muchas más. Por ejemplo:
sum(mis_numeros, na.rm = TRUE) # suma todos los elementos del vector
## [1] 88
min(mis_numeros, na.rm = TRUE) # encontrar el valor mínimo
## [1] 1
max(mis_numeros, na.rm = TRUE) # encontrar el valor máximo
## [1] 34
range(mis_numeros, na.rm = TRUE) # rango (mínimo y máximo)
## [1] 1 34
Hablando de resumir, en R usamos la función round()
para redondear variables numéricas. pi
es una función de R que nos da el valor de la constante \(\pi\). Especificamos el número de dígitos de \(\pi\) después del decimal con el argumento digits =
:
round(pi, digits = 2) # redondea al segundo decimal
## [1] 3.14
Finalmente, podemos hacer resúmenes de objetos más grandes –por ejemplo, una base de datos– con summary()
. Este resumen incluye información importante sobre cada columna/variable:
summary(mtcars)
## mpg cyl disp hp
## Min. :10.40 Min. :4.000 Min. : 71.1 Min. : 52.0
## 1st Qu.:15.43 1st Qu.:4.000 1st Qu.:120.8 1st Qu.: 96.5
## Median :19.20 Median :6.000 Median :196.3 Median :123.0
## Mean :20.09 Mean :6.188 Mean :230.7 Mean :146.7
## 3rd Qu.:22.80 3rd Qu.:8.000 3rd Qu.:326.0 3rd Qu.:180.0
## Max. :33.90 Max. :8.000 Max. :472.0 Max. :335.0
## drat wt qsec vs
## Min. :2.760 Min. :1.513 Min. :14.50 Min. :0.0000
## 1st Qu.:3.080 1st Qu.:2.581 1st Qu.:16.89 1st Qu.:0.0000
## Median :3.695 Median :3.325 Median :17.71 Median :0.0000
## Mean :3.597 Mean :3.217 Mean :17.85 Mean :0.4375
## 3rd Qu.:3.920 3rd Qu.:3.610 3rd Qu.:18.90 3rd Qu.:1.0000
## Max. :4.930 Max. :5.424 Max. :22.90 Max. :1.0000
## am gear carb
## Min. :0.0000 Min. :3.000 Min. :1.000
## 1st Qu.:0.0000 1st Qu.:3.000 1st Qu.:2.000
## Median :0.0000 Median :4.000 Median :2.000
## Mean :0.4062 Mean :3.688 Mean :2.812
## 3rd Qu.:1.0000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :1.0000 Max. :5.000 Max. :8.000
Más adelante, veremos cómo crear tablas con estadísticas resumen.
5.3.2 Datos NA
o no disponibles
A veces, no tenemos información para una observación y/o una variable. Decimos entonces que el dato no está disponible (en inglés, “not available” o N/A). R tiene un tipo de datos específicamente para esta situación: NA
. Para saber si tenemos NA
en un objeto (y dónde están), usamos is.na()
, lo cual nos da una respuesta lógica (TRUE
o FALSE
) a nuestra pregunta:
is.na(mis_numeros)
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Si queremos contar cuántos NA
tenemos en un vector, podemos aprovechar que los vectores lógicos como el producido por is.na()
pueden ser “sumados”. Cada TRUE
es igual a 1 y cada FALSE
es igual a 0. Y si aplicamos la función sum()
, obtenemos el número de NA
en el vector:
sum(is.na(mis_numeros)) # contar cuantos NA
## [1] 1
Es importante entender que hay una diferencia importante entre datos verdaderamente no disponibles (que R marca como NA
) y celdas vacías o con valores como "N/A"
, "No disponible"
o incluso "NA"
. También es distinto a códigos de valores no disponibles que a veces se utilizan en bases de datos (como -99). R interpreta estos como valores, no como datos no disponibles:
is.na(c(1, 3, NA, "N/A", "No disponible", "NA", -99))
## [1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE
Más adelante veremos cómo convertir estos en verdaderos NA
.
5.3.3 Dimensiones de un objeto
Podemos ver cuantos elementos tiene un objeto y cuáles son sus dimensiones. Carguemos una base de datos que creamos en un capítulo anterior:
<- read_csv("data/datos_ingreso.csv") datos_ingreso
##
## -- Column specification --------------------------------------------------------
## cols(
## nombre = col_character(),
## edad = col_double(),
## ciudad = col_character(),
## ingreso = col_double()
## )
datos_ingreso
## # A tibble: 7 x 4
## nombre edad ciudad ingreso
## <chr> <dbl> <chr> <dbl>
## 1 José 28 Barranquilla 8000000
## 2 Antonio 25 Medellín 4000000
## 3 María 32 Medellín 9500000
## 4 Inés 30 Medellín 7300000
## 5 Pablo 35 Barranquilla 6500000
## 6 Catalina 33 Bogotá 6000000
## 7 Cristóbal 42 Bogotá 9000000
Ahora, miremos sus dimensiones:
length(datos_ingreso$nombre) # cuantos elementos en un vector (filas en una columna)
## [1] 7
nrow(datos_ingreso) # número de filas
## [1] 7
ncol(datos_ingreso) # número de columnas
## [1] 4
dim(datos_ingreso) # dimensiones (filas por columnas)
## [1] 7 4
Vemos que esta base de datos tiene 7 filas y ncol(datos_ingreso)
columnas.
5.3.4 Medidas de tendencia central y de dispersión
Las medidas de tendencia central y de dispersión son dos pilares de los cursos de estadística de bachillerato y universidad. Supongamos que tenemos una variable distribuida normalmente, con una media de 5 y una desviación estándar de 2. Creemos un vector con esas características:
<- rnorm(1000, mean = 5, sd = 2) x
Tomemos ese vector y miremos dos medidas de tendencia central:
mean(x) # media aritmética
## [1] 5.058195
median(x) # mediana
## [1] 5.029246
Y ahora, dos de dispersión:
sd(x) # desviación estándar
## [1] 1.933959
var(x) # varianza
## [1] 3.740196
La estadística descriptiva e inferencial depende crucialmente de medidas de dispersión y de tendencia central como estas.
5.3.5 Relaciones entre variables
Con frecuencia, no nos interesa saber algo sobre una variable aislada. Más bien, queremos ver cómo se relaciona con otras. Digamos que queremos calcular el coeficiente de correlación entre x
como la definimos arriba y otra variable y
definida así:
<- rnorm(1000, 10, 3) # argumentos implícitos y
¿Cuál es la correlación? Usemos la función cor()
:
cor(x, y)
## [1] -0.000156751
Podemos aprovechar las propiedades de los vectores en R para crear nuevos objetos a partir de los ya existentes, como una vector de valores z
que dependen del valor de x
:
<- x + 3 z
En este caso, la correlación entre x
y z
es perfecta porque una está definida en términos de la otra, sin distorsión alguna:
cor(x, z)
## [1] 1
Pero podría haber algo de distorsión, que agregamos aquí con e
, una variable aleatoria con distribución normal:
<- rnorm(1000)
e <- x + e
z cor(x, z)
## [1] 0.8890784
cor()
funciona también con bases de datos. Por ejemplo, veamos que en nuestros datos ficticios de ingreso individual hay una correlación positiva entre edad e ingreso:
cor(datos_ingreso$edad, datos_ingreso$ingreso)
## [1] 0.5456026
5.4 Anidar funciones
No estamos limitados a utilizar una función a la vez. En R, es fácil usar múltiples funciones al mismo tiempo para realizar operaciones más complejas. Para esto, las “anidamos”. El orden de operaciones es sencillo: se leen de adentro hacia afuera. Pero esto a veces puede ser confuso – ¡hay que tener cuidado con los paréntesis!
round(mean(mis_numeros, na.rm = TRUE)) # si no especificamos, redondea al primer decimal
## [1] 10
mean(x) - mean(y))^2 (
## [1] 23.94037
Más adelante, vamos a introducir el operador %>%
(“pipe”, tubo o tubería) de la librería magrittr
(y usado extensivamente en el tidyverse
), una aproximación que no exige anidar funciones, simplifica la lectura del código y facilita realizar operaciones complejas. Como abrebocas, podemos reescribir la primera operación del bloque de código anterior de la siguiente manera:
# tomamos nuestro vector
%>%
mis_numeros # se lo pasamos a una funcion para calcular la media
# noten que si el objeto pasa a ser el primer argumento de la funciona no tenemos que nombrarlo
mean(na.rm = TRUE) %>%
# redondeamos el resultado de ese calculo
round()
## [1] 10
5.5 Tablas y resúmenes
Hay funciones para contar o hacer resúmenes de variables cualitativas. Por ejemplo, table()
crea una tabla sencilla que cuenta cuántas veces aparece cada número en el vector mis_numeros
. Todos, excepto el número 1, aparecen una sola vez.
table(mis_numeros)
## mis_numeros
## 1 2 3 5 8 13 21 34
## 2 1 1 1 1 1 1 1
A veces queremos “cruzar” variables categóricas, esto es, ver cuántas observaciones tienen distintas combinaciones de valores de dos variables. table()
también sirve para hacer lo que llamamos una tabla cruzada, tabulación cruzada o tabla de contingencia entre dos variables discretas o categóricas. En este caso, el tipo de transmisión y el número de cilindros de los carros en mtcars
:
table(mtcars$am, mtcars$cyl)
##
## 4 6 8
## 0 3 4 12
## 1 8 3 2
¿Cuántos carros de 8 cilindros en esta muestra tienen transmisión automática?
5.6 Escribir funciones
A veces no existe la función para lo que queremos hacer. Podemos crear nuestras propias funciones para hacer otras operaciones o incluso construir indicadores – ¿o cómo creían que se calculaba el coeficiente de Gini o la volatilidad electoral? Con frecuencia, esta parte del trabajo es considerada “programación”, pero en realidad cualquier serie de operaciones es un “programa”. Ya hemos escrito funciones propias en un par de ocasiones (¿sí saben dónde?).
Las funciones también son útiles cuando queremos hacer algo muchas veces o cuando queremos simplificar nuestro código. Algunos sugieren que si hacemos la misma operación mas de 2 veces, deberíamos escribir una función.6
El proceso para crear una función en R tiene tres pasos:
- Darle un nombre descriptivo a la función (
calc_indicador
en vez demi_funcion
). - Listar los argumentos que toma.
- Escribir el código que especifica las operaciones que realiza.
Este proceso lo hacemos con la función function()
.
Como ejercicio, escribamos una función. Digamos que queremos tomar unos datos numéricos y ponerlos en una escala que vaya de 0 a 1, donde 1 sea el valor más alto. Formalmente, lo que queremos hacer se puede representar de la siguiente manera:
\[ f(x) = (x - min) / (max - min) \]
Donde \(x\) es un vector numérico, \(min\) es el valor mínimo del vector y \(max\) el valor máximo. Así, cada valor de \(x\) va a tener un nuevo valor entre 0 y 1.
Para crear la función en R, seguimos los tres pasos especificados arriba. Primero, le damos nombre a la función: digamos reescalar01
. Segundo, definimos qué argumentos toma la función: en este caso, uno solo, que vamos a llamar x
. Tercero, escribimos el código de la operación que realiza nuestra función:
# nombre y argumentos de la función
<- function(x){
reescalar01 # operaciones
<- min(x, na.rm = TRUE) # encontrar el mínimo y guardarlo
minimo <- max(x, na.rm = TRUE) # encontrar el máximo y guardarlo
maximo <- (x - minimo) / (maximo - minimo) # calcular
reescalados # resultado
return(reescalados)
}
Aplicamos nuestra función a un vector de números cualquiera:
<- c(0, 25, 60, 80)
vector_num reescalar01(vector_num)
## [1] 0.0000 0.3125 0.7500 1.0000
5.6.1 Media aritmética
Ahora supongamos que queremos hallar la media de un conjunto de datos numérico. Y ahora supongamos que esa función no existe ya en R (sí existe, pero supongamos…). ¡Podemos escribir una función! Formalmente, la media \(m\) de un conjunto \(x\) se define como:
\[ m = \frac{\sum(x_i)}{n} \]
Donde \(x_i\) son todos los valores de \(x\) y \(n\) es el número de observaciones. Entonces, creamos un objeto llamado media
que es la función. Esa función recibe un solo argumento, que aquí llamamos z
. La función toma z
, suma todos sus elementos y los divide por el numero de elementos, antes de “devolvernos” el resultado:
# nombre y argumentos de la función
<- function(z){
media # operaciones
<- sum(z)/length(z)
med # resultado
return(med)
}
Apliquemos la función para ver si sirve:
media(vector_num)
## [1] 41.25
Afortunadamente, ya sabemos que R cuenta con una función que calcula la media. Comparemos ambas. El operador lógico ==
evalúa si dos objetos son idénticos (estrictamente iguales), así que podemos utilizarlo para evaluar si nuestra función está funcionando como queremos:
media(vector_num) == mean(vector_num)
## [1] TRUE
¡Muy bien!
5.6.2 Número efectivo de partidos
Queremos saber cuántos partidos efectivos hay en una legislatura o congreso. Escribimos una función siguiendo la formula clásica de M. Laakso y R. Taagepera.7 Formalmente:
\[ NEP = \frac{1}{\sum_{i=1}^{n}{p_i^2}} \] Donde \(NEP\) es el indicador del número efectivo de partidos, \(n\) el número de partidos \(i\) que ganaron votos o curules y \(p_i\) es la proporción de votos o de curules obtenidas por cada partido.
Para implementar esta función en R, empezamos por asignarle un nombre: nep
. Siguiendo la fórmula, esta tiene un solo argumento: votos =
, el número de votos o curules por partido. Vamos a suponer que no tenemos proporciones aún, solo votos o curules. Entonces, hallamos la proporción del total de votos que obtuvo cada partido: dividimos los votos de cada partido por el total de votos con sum()
. Elevamos al cuadrado esa proporción usando el operador ^
. Finalmente, sumamos los cuadrados de las proporciones con sum()
y hallamos el inverso (dividimos sobre 1):
# nombre y argumentos de la función
<- function(votos){
nep # operaciones
<- votos/sum(votos) # hallar prop.
proporcion_votos <- proporcion_votos^2 # elevar prop. al cuadrado
proporcion_votos2 <- sum(proporcion_votos2) # sumar props.
sum_proporcion_votos2 <- 1/sum_proporcion_votos2
nep # resultado
return(nep)
}
Ahora, solo necesitamos unos resultados electorales para probar nuestra función, específicamente cuántos votos o curules sacaron todos los partidos. Como primera prueba, creamos un vector con números de votos de una elección ficticia dominada por el partido B
:
= tibble(
eleccion1 partido = LETTERS[1:6],
num_votos = c(10000, 500000, 35000, 66000, 3000, 1700)
)
Veamos estos datos:
eleccion1
## # A tibble: 6 x 2
## partido num_votos
## <chr> <dbl>
## 1 A 10000
## 2 B 500000
## 3 C 35000
## 4 D 66000
## 5 E 3000
## 6 F 1700
Aplicamos la función a los datos y obtenemos el resultado, un NEP bastante bajo:
nep(eleccion1$num_votos)
## [1] 1.482585
Intentemos aplicar la función a un conjunto de datos distinto en el que los votos están distribuidos más y con más partidos:
<- tibble(
eleccion2 partido = LETTERS[1:8],
num_votos = c(10000, 30000, 20000, 25000, 13000, 18000, 3000, 4000)
) eleccion2
## # A tibble: 8 x 2
## partido num_votos
## <chr> <dbl>
## 1 A 10000
## 2 B 30000
## 3 C 20000
## 4 D 25000
## 5 E 13000
## 6 F 18000
## 7 G 3000
## 8 H 4000
El resultado es bastante diferente y refleja la distribución de votos en este contexto:
nep(eleccion2$num_votos)
## [1] 5.949273
5.7 Ejercicio: partidos en el Congreso colombiano, 2018-2022
Las elecciones ficticias de la sección anterior están muy bien, ¿pero sí podemos usar nuestra función en un conjunto de datos reales? ¿Cuántos partidos efectivos hay en la Cámara de Representantes de Colombia en la legislatura 2018-2022? Intentemos responder esta pregunta aplicando la función que acabamos de escribir. Para eso, necesitamos datos.
Como pueden ver (list.files("data/")
), no contamos con una base de datos con información sobre los partidos colombianos y sus votos o curules… Pero, podemos crearla con información fácilmente disponible: Wikipedia. Recuperar información de una página web que no tiene un archivo de datos se conoce como web scraping y es precisamente lo que vamos a hacer.
Para este ejercicio, nos vamos a apoyar en varias funciones de la librería rvest
(también del tidyverse
). Son varios pasos:
- Especificamos la URL de la página de Wikipedia que tiene los resultados de las elecciones a Congreso de 2018 (
read_html()
). - Usando trucos de magia,8 le señalamos a R qué elemento en la página web tiene la información que queremos usar (
html_node()
) y le decimos que se trata de una tabla (html_table()
). - Limpiamos un poco las variables dentro de la función
mutate()
:- La librería
janitor
nos permite limpiar un poco los nombres de las variables conclean_names()
- Convertimos la variable
escanos
de texto a número conas.numeric()
. - Codificamos los nombres de candidatos más votados no disponibles (partidos con lista cerrada) como
NA
. - Eliminamos los puntos en la variable
votos
y la convertimos de texto a número.
- La librería
- Desechamos las dos últimas filas de la tabla con
slice()
, pues se trata de los totales y una nota al pie que venía en la tabla original de Wikipedia.
En todo el proceso, nos apoyamos en el operador %>%
para simplificar el código -menos funciones anidadas- y leerlo de manera lineal:
# cargar librerias adicionales
library(rvest)
library(janitor)
# definir la URL donde esta la informacion
<- "https://es.wikipedia.org/wiki/Elecciones_legislativas_de_Colombia_de_2018"
url
# crear la base de datos
<- url %>%
camara2018 # leer la url como html
read_html() %>%
# señalar el elemento que contiene la tabla
html_node(xpath = '//*[@id="mw-content-text"]/div[1]/table[3]') %>%
# extraer la tabla
html_table() %>%
# convertir a tibble
as_tibble() %>%
# homogeneizar nombres de variables
clean_names() %>%
# eliminar ultimas filas de la tabla
slice(1:(n()-2)) %>%
# modificar variables
mutate(
escanos = as.numeric(escanos),
candidato_a_mas_votado_a = na_if(candidato_a_mas_votado_a, "—"),
votos = str_remove_all(votos, "\\.") %>% as.numeric()
)
Después de todo esto, tenemos esta pequeña base de datos:
camara2018
## # A tibble: 13 x 5
## partido_o_movimiento votos porcentaje candidato_a_mas_vot~ escanos
## <chr> <dbl> <chr> <chr> <dbl>
## 1 Partido Liberal Colombiano 2.47e6 16,57% Nubia López Morales 35
## 2 Centro Democrático 2.39e6 16,19% Edward David Rodríg~ 32
## 3 Partido Cambio Radical 2.14e6 14,23% Hernando José Padau~ 30
## 4 Partido Social de Unidad Naci~ 1.84e6 12,13% Wilmer Ramiro Carri~ 25
## 5 Partido Conservador Colombiano 1.82e6 12,14% Yamil Hernando Aran~ 21
## 6 Alianza Verde 8.84e5 6,04% Inti Raúl Asprilla ~ 9
## 7 Polo Democrático Alternativo 4.45e5 3,00% Germán Navas Talero 2
## 8 Opción Ciudadana 3.11e5 2,04% Franklin Lozano de ~ 2
## 9 Partido MIRA 5.52e5 3,98% Irma Luz Herrera Ro~ 1
## 10 Lista de la Decencia 2.55e5 1,84% Maria José Pizarro 2
## 11 Colombia Justa Libres 1.10e5 0,79% <NA> 1
## 12 Alternativa Santandereana (Po~ 7.12e4 0,51% <NA> 1
## 13 Colombiano Dignidades por Col~ 4.40e4 0,30% César Augusto Pachó~ 1
Si la queremos guardar para después, podemos crear un archivo tipo CSV:
write_csv(camara2018, "data/camara2018.csv")
Esto también significa que los datos están disponibles para descargar directamente en este link para cargar en una sesión de R. Así, pueden completar el ejercicio sin hacer el web scraping.
Ahora, por fin, estamos listos para calcular el número efectivo de partidos en la Cámara. En este caso, como la fórmula del NEP está diseñada tanto para votos (NEP electoral), como para curules (NEP parlamentario), podemos hacer el cálculo con el número de escaños o curules.
Entonces: ¿cuántos partidos hay en la Cámara de Representantes colombiana en el periodo 2019-2022?
Wickham, Hadley, y Garrett Grolemund. R for Data Science: Import, Tidy, Transform, Visualize, and Model Data. O’Reilly Media, 2016.↩︎
Si estamos en RStudio Cloud, debemos empezar por subirlos y ubicarlos en una carpeta dentro del proyecto. Vamos al panel inferior derecho, pestaña
Files
, click enUpload
y seguimos las indicaciones.↩︎Hagan clic derecho en la página de Wikipedia y escojan la opción “Inspeccionar”.↩︎