Introducción a R

Semillero de Investigación de Estudiantes de Economía (SIEDE)

2/12/2021

¿Qué es R? ¿Por qué usarlo?

El programa abierto y libre, R, es una herramienta profesional desarrollada en 1993 por Robert Gentleman y Ross Ihaka del Departamento de Estadística de la Universidad de Auckland. Es utilizado en áreas como la economia, ingeniería, ciencias exactas, medicina, entre otras. Creada para ayudar al usuario al momento de realizar análisis, estadísticas descriptivas y predicciones de datos. Existen lenguajes similares como Python o STATA y las empresas en la actualidad buscan profesionales con conocimientos en el mundo de los datos.

¿Cómo descargarlo y configurarlo?

  1. Descargar R
  2. Descargar RStudio
  3. Instalarlos.
    #Tenemos que aprender cómo se instala para guiarlos tanto en windows como en Mac.

Análisis del entorno

Una vez instalados ambos programas, daremos un vistazo a la interfaz de RStudio, el cual está compuesto principalmente por cuatro ventanas:consola, editor, espacio de trabajo y la ventana de archivos/gráficos/paquetes/ayuda.


La consola es la sección principal de R, ya que en esta se ejecutan los comandos y se visualizan los resultados. Además en esta también aparecerán las adevertencias o errores cuando haya un incoveniente con nuestro código. El editor permite crear scripts, en donde se almacenan los diferentes códigos de interés, para correr una línea dentro del script se debe presionar CTRL+ENTER o el botón Run. El espacio de trabajo permite visualizar los objetos que tengamos guardados en nuestra memoria de R ya sea de forma temporal o permanente si decidimos guardarlos. En la última ventana se pueden realizar múltiples tareas como abrir archivos, visualizar gráficas, descargar paquetes y consultar más información sobre algún código de interés.

Tipos de objetos en R

Como ejercicio inicial, se observa que al ejectuar la operación matemática, aparecerá el resultado en la consola.

4*3
## [1] 12

Adicionalmente, es posible guardar dichos resultados como objetos dentro de nuestro entorno de la siguiente manera:

a <- 4*3
a
## [1] 12
b <- c(1, 2, 3, 4, 5)
b
## [1] 1 2 3 4 5
c <- 1:5
c
## [1] 1 2 3 4 5
d <- c("Ana", "Pablo", "Juan")
d[2]
## [1] "Pablo"

Nótese que estos ejemplos incluyen datos escalares (a) y vectores.

También será posible manipular los objetos mediante operadores (aritméticos, lógicos y comparativos)

a-4
## [1] 8
is.numeric(a)
## [1] TRUE

Lista de operadores lógicos:

Para gestionar estos objetos dentro del entorno:

ls() # arroja todos los objetos
## [1] "a" "b" "c" "d"

rm() # remueve un objeto

rm(list = ls()) # elimina todos los objetos de nuestro entorno

Matrices, dataframes y listas.

Estos arreglos bidimensionales son muy usados para el análisis estadístico por lo que es importante conocer cómo manipularlos en R.

mat <- matrix(data = 1:9, ncol = 3)

mat[1,] # Muestra la fila 1 de nuestra matriz
## [1] 1 4 7
mat[3,2] # Muestra el objeto ubicado en la tercer fila, primera columna
## [1] 6
mean(mat)
## [1] 5

Ahora, los data frames son igualmente bidimensionales pero además, pueden almacenar elementos de diferentes tipos (números y texto). Lo que facilita el reconocimiento de cada variable (columna) en el DF. Un ejemplo:

e <- data.frame(x = 5:8, y = c(2, 6, 9, 1), z = c(-1, 0, 7, 8))
e
##   x y  z
## 1 5 2 -1
## 2 6 6  0
## 3 7 9  7
## 4 8 1  8
mean(e$x)
## [1] 6.5
e <- e[-4,] # Para remover la cuarta fila
e$w <- NA   # Para crear una nueva columna 
e$w <- e$x*e$y 
names(e)[names(e) == 'w'] <- 'Edad' # Renombrar una columna 
e
##   x y  z Edad
## 1 5 2 -1   10
## 2 6 6  0   36
## 3 7 9  7   63

Si queremos observar los atributos de nuestro data frame:

dim(e)
## [1] 3 4
colnames(e)
## [1] "x"    "y"    "z"    "Edad"
#rownames(e) si nuestras observaciones (filas) tuvieran un nombre o indicador
El último tipo de objetos son las listas, estos objetos son unidimensionales y permiten almacenar diferentes tipos de objetos. Es decir, es un vector en el cual puede haber ya sea un vector, matriz, data frame o lista en cada posición. Un ejemplo:
f <- list(x = 'hola', y = 1:5, z = e)
f
## $x
## [1] "hola"
## 
## $y
## [1] 1 2 3 4 5
## 
## $z
##   x y  z Edad
## 1 5 2 -1   10
## 2 6 6  0   36
## 3 7 9  7   63
f$w = letters
f
## $x
## [1] "hola"
## 
## $y
## [1] 1 2 3 4 5
## 
## $z
##   x y  z Edad
## 1 5 2 -1   10
## 2 6 6  0   36
## 3 7 9  7   63
## 
## $w
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"

Librerías y directorio de trabajo

Las librerías son paquetes que contienen un conjunto de funciones.Para descargarlas y llamarlas:

install.packages("dplyr")
library(dplyr)

Algunas funciones:

mean(x= b)
## [1] 3
rnorm(n= 10, mean= 0, sd= 1)
##  [1]  0.1232009 -1.6527588 -0.7035235  0.2543691  1.7242090  0.7182252
##  [7] -1.0532977 -1.9584864 -1.4453349 -2.1441604
x <- rnorm(n= 100, mean= 0, sd= 1) # para guardarlo
plot(x)

Ahora, es importante configurar nuestro directorio de trabajo en caso de que sea necesario importar o exportar archivos de nuestro computador. Esta es la ruta que seguirá el programa para abrir/guardar un archivo.

setwd("C:/Users/Sebastian/OneDrive - Universidad EAFIT/Curso SIEDE")

Importar, exportar y convertir

La librería rio simplificará estos procesos para cualquier tipo de archivo (.csv, .txt, .xls, .dta)

install.packages('rio')
library(rio)

data <- import(file = 'wage2.xls')
export(x = e, file = 'ejemplo1.xlsx') #Exportar a .xlsx
convert(in_file = 'ejemplo1.xlsx', out_file = 'ejemplo1.csv')

La base de datos importada contiene 935 observaciones con información sobre el salario, número de horas trabajadas y otras variables demográficas del individuo. Fue tomada de Woolridge (2000)

Transformaciones

Si quisieramos observar cuánto gana un individuo por hora podríamos generar una nueva variable mediante dos posibles opciones:

data$wageperhour <- data$wage/(data$hours*4) data

O empleamos la función mutate de la librería dplyr:

data = mutate(.data = data, wageperhour = wage/(hours*4))

Otro ejercicio interesante sería analizar el resultado del coeficiente individual del individuo, que de acuerdo con Resing y Blok (2002) se compone de los siguientes niveles:

data = mutate(data, inteligencia = case_when(IQ < 80 ~ 'retraso mental',
                                             IQ >= 80 & IQ < 90 ~ 'inteligencia por debajo de la media',
                                             IQ >= 90 & IQ < 111 ~ 'inteligencia media', 
                                             IQ >= 111 & IQ < 121 ~ 'inteligencia por encima de la media', 
                                             IQ >= 121 & IQ < 131 ~ 'dotada', 
                                             IQ >= 131 ~ 'súper dotada'))  
head(x = data$inteligencia, n = 5)
## [1] "inteligencia media"                  "inteligencia por encima de la media"
## [3] "inteligencia media"                  "inteligencia media"                 
## [5] "retraso mental"

Y similarmente con los años de educación:

data = mutate(data, niveleducativo = case_when(educ == 0 ~ 'Ninguno', 
                                               educ >= 1 & educ < 6 ~'Básica primaria',
                                               educ >= 6 & educ < 10 ~ 'Básica secundaria',
                                               educ >= 10 & educ < 12 ~ 'Media',
                                               educ >= 12 & educ < 18 ~ 'Superior', 
                                               educ >= 18 ~ 'Posgrado'))

head(x = data$niveleducativo, n = 5)
## [1] "Superior" "Posgrado" "Superior" "Superior" "Media"

Otra modificación que se le podría hacer a las variables sería agregar una etiqueta a las variables de estado civil (married) y raza (black):

data$married <- factor(data$married, levels = c(1,0), labels = c('Married', 'Not married'))
data$black <- factor(data$black, levels = c(1,0), labels = c('Black', 'Not black'))

Ahora, si quisiera crear un subset de mis datos donde solo incluya aquellos individuos con un nivel educativo de posgrado:

subset <- data %>% filter(niveleducativo == 'Posgrado')
head(x = subset, n = 5)
##   wage hours  IQ KWW educ exper tenure age     married     black south urban
## 1  808    50 119  41   18    11     16  37     Married Not black     0     1
## 2 1081    40 114  50   18     8     14  38     Married Not black     0     1
## 3  930    43 132  44   18     8     13  38     Married Not black     0     0
## 4  800    40 115  39   18    11      1  35     Married Not black     1     1
## 5  635    40 128  35   18     8     13  36 Not married Not black     0     1
##   sibs brthord meduc feduc wageperhour                        inteligencia
## 1    1      NA    14    14    4.040000 inteligencia por encima de la media
## 2    2       3     8    NA    6.756250 inteligencia por encima de la media
## 3    1       1    13    14    5.406977                        súper dotada
## 4    0       1     8     8    5.000000 inteligencia por encima de la media
## 5    2       1    16    16    3.968750                              dotada
##   niveleducativo
## 1       Posgrado
## 2       Posgrado
## 3       Posgrado
## 4       Posgrado
## 5       Posgrado

Si quisieramos eliminar una o varias columnas de esta nueva base de datos podemos usar la función select()

subset <- select(subset, -c('KWW', 'sibs'))

Combinar Dataframes

Es importante saber cómo combinar conjuntos de datos dado que esto permitirá crear data frames más completos. Generemos entonces dos pequeños data frames:

estudiantes <- data.frame(Nombre = c('Sara', 'Julián', 'Ana',
                                     'Pedro'), 
                          Carrera = c('Economía', 'Finanzas', 'IDP',
                                      'Admin. de Negocios'))
staff <- data.frame(Nombre= c('Carlos', 'Ana', 'Julián'),
                              Cargo= c('Jefe dpto.', 'Monitor',
                              'Tutor'))

Vemos que hay algunos estudiantes que también tienen cargos dentro de la universidad, podemos pensarlo como un diagrama de Venn. Podemos unir las bases de acuerdo con los datos que queramos conservar:

# Si queremos obtener todos los datos hariamos un full join
df <- full_join(x = estudiantes, y = staff, by = 'Nombre')
# Si queremos obtener la intersección (aquellos que son estudiantes y staff) hacemos un inner join
df2 <- inner_join(x = estudiantes, y = staff, by = 'Nombre')
# Si queremos datos de solo los estudiantes, pero también saber su cargo si son staff hacemos un left join (cuidado con el orden de las bases)
df3 <- left_join(x = estudiantes, y = staff, by = 'Nombre')
#Similarmente con la información del staff
df4 <- right_join(x = estudiantes, y = staff, by = 'Nombre')

Además de agregar variables horizontalmente, también podemos agregar observaciones verticalmente:

covid <- data.frame(Dpto = c('Antioquia', 'Bogotá', 'Caldas',
                             'Huila'), 'Fallecidos 25-01-22' = c(43,
                    22, 6, 11), 'Casos en UCI '= c(93, 410, 14, 11))
covid2 <- data.frame(Dpto = c('Meta', 'Quindio', 'Tolima'),
                    'Fallecidos 25-01-22' = c(11, 4, 4))
covidtotal <- bind_rows(covid, covid2, .id = 'Group')

Missing objects

Frecuentemente habrán valores faltantes en las bases de datos y es importante saber trabajar con estos. En R, estos valores están representados por NA y aquellos valores imposibles (como una divisón por cero) aparecerán como NaN. AL observar nuestra base de datos encontramos varios NAs en la variable referente a la educación del padre, indicando que no hay información sobre esta.

# Lo primero es detectar y validar la información

nafeduc <- is.na(data$feduc)
head(nafeduc, 10)
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE

El objeto nafeduc es de tipo lógico y será verdadero cuando haya un NA en esa observación. La presencia de estas observaciones impide el análisis de la variable:

mean(data$feduc)    # Arrojará un NA
## [1] NA
mean(data$feduc, na.rm = TRUE) # Omitirá los NAs y ejecutará la función
## [1] 10.21727

Otra opción es omitir las observaciones a las que les falte un valor en cualquier variable, reduciendo la base de datos:

data2 <- na.omit(data)

Vemos que pasamos de tener 935 observaciones a 663.

Además, algunas bases de datos completan estas observaciones con un número (p.e: 99), de forma que al trabajar con estas debemos convertirlos a NAs.

datos$feduc[datos$feduc == 99] <- NA

Estadísticas descriptivas

Retomando nuestra base de datos, podemos obtener las estadísticas descriptivas de las variables de interés:

Tablas de frecuencias

table(data$educ) # Para las frecuencias absolutas
## 
##   9  10  11  12  13  14  15  16  17  18 
##  10  35  43 393  85  77  45 150  40  57
prop.table(table(data$educ)) # FRecuencias relativas
## 
##          9         10         11         12         13         14         15 
## 0.01069519 0.03743316 0.04598930 0.42032086 0.09090909 0.08235294 0.04812834 
##         16         17         18 
## 0.16042781 0.04278075 0.06096257
cumsum(table(data$educ)) #Frecuencia acumulada
##   9  10  11  12  13  14  15  16  17  18 
##  10  45  88 481 566 643 688 838 878 935
table1 <- cbind('Frec' =table(data$educ), 'F. acum' = 
                  cumsum(table(data$educ)),
                '%'  = prop.table(table(data$educ)))

Frecuencias cruzadas

Hay dos formas de obtener las frecuencias relativas:

# Horizontalmente:
prop.table(table(data$niveleducativo, data$black), 1)
##                    
##                          Black  Not black
##   Básica secundaria 0.40000000 0.60000000
##   Media             0.23076923 0.76923077
##   Posgrado          0.01754386 0.98245614
##   Superior          0.12278481 0.87721519
# Verticalmente
prop.table(table(data$niveleducativo, data$black), 2)
##                    
##                           Black   Not black
##   Básica secundaria 0.033333333 0.007361963
##   Media             0.150000000 0.073619632
##   Posgrado          0.008333333 0.068711656
##   Superior          0.808333333 0.850306748

Media, mediana, cuartiles y desviación estándar

summary(data$wageperhour)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.575   3.769   5.256   5.580   6.924  25.650
sd(data$wageperhour)
## [1] 2.469222

La interpretación de estos estadísticos es fundamental, por ejemplo para el tercer cuartil podemos decir que solo el 25% de la muestra gana más de $6,924 USD/hora. Además, en promedio las personas ganan $ 5,580 USD/hora. Finalmente, la mediana divide la muestra en dos, por lo que el 50% de la muestra gana menos de $ 5,256 USD/hora.

Ahora, la desviación estándar básicamente explica la dispersión de los datos, por lo que un valor de $2,4692 USD/hora puede ser relevante.

También podemos obtener los estadísticos para varias variables:

summary(data[, c("educ","exper","age")])
##       educ           exper            age       
##  Min.   : 9.00   Min.   : 1.00   Min.   :28.00  
##  1st Qu.:12.00   1st Qu.: 8.00   1st Qu.:30.00  
##  Median :12.00   Median :11.00   Median :33.00  
##  Mean   :13.47   Mean   :11.56   Mean   :33.08  
##  3rd Qu.:16.00   3rd Qu.:15.00   3rd Qu.:36.00  
##  Max.   :18.00   Max.   :23.00   Max.   :38.00

Si quisieramos obtenerlos para un grupo determinado (p. ej. si es afroamericano o no)

summary(data$wageperhour[data$black=="Black"])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.625   3.073   4.195   4.505   5.708  11.229
summary(data$wageperhour[data$black=="Not black"])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.575   3.954   5.407   5.739   7.122  25.650

Gráficas

Caja de bigotes

Empezemos entonces con una caja de bigotes, una gráfica simple pero muy intuitiva al momento de ver como están los datos. En el primer ejemplo lo haremos entonces con datos aleatorios suministrado por R, en el segundo ejemplo lo haremos con datos reales.

Ejemplo 1

### Ejemplo 2

En éste ejemplo haremos con datos reales, para ello utilizaremos datos del DANE frente a la edad de los antioqueños

Gráfica de torta.

Este tipo de gráfica nos muestra como están los datos distribuidos a función del datos que más se repite, se sugiere utilizarlo en datos tipo caulitativas y ver que tipo de sector o personas tienen más control frente a la variable a utilizar.

Ejemplo 1

Simularemos la participación en el mercado de automoviles en Colombia, para saber cual marca tiene mayor control en este tema. Los datos serán escogidos del 2019.

ejemplo 2.

Ahora Simularemos el genero.

Correlación y regresión lineal simple

Documentación

Jeffrey M. Wooldridge, 2000. “Wage2,” Instructional Stata datasets for econometrics wage2, Boston College Department of Economics. Resing, W.C.M., y Blok, J.B. (2002). The classification of intelligence scores. Proposal for an unambiguous system. The psychologist, 37, 244-249.