Capítulo 1 Introducción

Para cuando llega el momento de analizar los datos, la mayor parte del trabajo ya está hecho. Antes de tener un conjunto de datos se ha tenido que definir el problema de investigación, desarrollar e implementar un plan de muestreo, decidir las escalas de medidas y desarrollar un diseño de investigación. Si se ha hecho bien este trabajo, el análisis de los datos puele ser bastante sencillo.

En la mayoría de las investigaciones de ciencias sociales, el análisis de datos implica tres pasos principales, realizados aproximadamente en este orden:

  1. Limpieza y organización de los datos para su análisis (preparación de datos)
  2. Describir los datos (estadística descriptiva)
  3. Prueba de hipótesis y modelos (estadística inferencial)

La preparación de datos implica verificar o registrar los datos, comprobar su exactitud, cargar los datos en el software de análisis, transformar los datos y crear una base de datos adecuada para el análisis que se vaya a realizar.

Las estadísticas descriptivas se utilizan para describir las características básicas de los datos en un estudio. Proporcionan resúmenes sencillos sobre la muestra y las medidas. Junto con el análisis gráfico simple, forman la base de prácticamente todos los análisis cuantitativos de datos. Las estadísticas descriptivas simplemente se describen los datos.

La estadística inferencial investiga preguntas, modelos e hipótesis. En muchos casos, las conclusiones de las estadística inferencial se extienden más allá de los datos inmediatos por sí solos. Por ejemplo, usamos estadísticas inferenciales para tratar de inferir de los datos de la muestra lo que piensa la población total. También utilizamos estadística inferencial para hacer juicios sobre la probabilidad de que una diferencia observada entre grupos sea confiable o si podría haber ocurrido por casualidad en este estudio. Por lo tanto, usamos estadísticas inferenciales para inferir lo que sucede más allà de nuestros datos.

En la mayoría de los estudios de investigación, la sección de análisis sigue estas tres fases de análisis. Las descripciones de cómo se prepararon los datos tienden a ser breves y a centrarse solo en los aspectos más exclusivos de su estudio, como las transformaciones de datos específicas que se realizan. Las estadísticas descriptivas que observa en realidad pueden ser voluminosas. En la mayoría de los estudios, las estadísticas descriptivas se seleccionan cuidadosamente y se organizan en tablas de resumen y gráficos que solo muestran la información más relevante o importante. Por lo general, el investigador vincula cada uno de los análisis inferenciales con preguntas o hipótesis de investigación específicas que se plantearon en la introducción, o toma nota de los modelos que se probaron y que surgieron como parte del análisis. En la mayoría de los informes de análisis, es especialmente importante “no dejar que los arboles nos impidan ver el bosque”. Si se presentan demasiados detalles sobre el análisis, es posible que se pierda de vista el problema de la realidad que estemos estudiando.

Todos estos pasos del análisis se pueden realizar habitualmente en todos los paquetes estadísticos. En este curso nos centraremos en el uso de R, por lo que a continuación haremos una breve introducción.

1.1 R como lenguaje de programación

R fue creado en 1992 por Ross Ihaka y Robert Gentleman en la Universidad de Auckland, Nueva Zelanda. R es una implementación gratuita de código abierto del lenguaje de programación estadística S creado inicialmente en Bell Labs. En esencia, R es un lenguaje de programación funcional (sus principales funcionalidades giran en torno a la definición y ejecución de funciones). Sin embargo, ahora es compatible, y se usa comúnmente como un lenguaje de programación imperativo (enfocado en instrucciones sobre variables y estructuras de control de programación) y orientado a objetos (que involucra estructuras de objetos complejas).

En términos simples, hoy en día, la programación en R se enfoca principalmente en diseñar una serie de instrucciones para ejecutar una tarea, más comúnmente, cargar y analizar un conjunto de datos (Wickham and Grolemund 2017).

Como tal, R se puede usar para programar creando secuencias de instrucciones que involucren variables, que son entidades con nombre que pueden almacenar valores. Ese será el tema principal de esta sesión práctica. Las instrucciones pueden incluir estructuras de flujo de control, como puntos de decisión (if/else) y bucles, que serán el tema de la próxima sesión práctica. Las instrucciones también se pueden agrupar en funciones, que también veremos en la próxima sesión práctica.

R es interpretado, no compilado. Lo que significa que un intérprete de R (si está utilizando R Studio, el intérprete de R simplemente está oculto en el backend y R Studio es el frontend que le permite interactuar con el intérprete) recibe una instrucción que escribe en R, la interpreta y la ejecuta . Otros lenguajes de programación requieren que su código sea compilado en un ejecutable para ser ejecutado en un ordenador.

1.2 Utilizando RStudio

La interfaz de RStudio se divide en dos secciones principales. En el lado izquierdo, encontrará la Consola, así como el editor de secuencias de comandos R, cuando se está editando una secuencia de comandos. La Consola en una ventana de entrada/salida en el intérprete de R, donde se pueden escribir instrucciones y se muestra la salida calculada.

Por ejemplo, si escribís en la Consola

1 + 1

el intérprete de R entiende eso como una instrucción para sumar uno más uno, y produce el resultado (dado que los materiales para este módulo se crean en RMarkdown, la salida del cálculo siempre está precedida por ‘##’).

## [1] 2

Fíjate cómo el valor de salida 2 está precedido por [1], lo que indica que la salida está constituida por un solo elemento. Si la salida está constituida por más de un elemento, como la lista de números a continuación, cada fila de la salida está precedida por el índice del primer elemento de la salida.

##  [1]   1   4   9  16  25  36  49  64  81 100 121 144 169 196 225 256 289 324 361
## [20] 400

En el lado derecho, encontrarás dos grupos de paneles. En la parte superior derecha, el elemento principal es el panel Entorno, que es una representación del estado actual de la memoria del intérprete y, como tal, muestra todas las variables, conjuntos de datos y funciones almacenados. En la parte inferior derecha, encontrarás el panel Archivos, que muestra el sistema de archivos (archivos y carpetas del ordenador), así como el panel Ayuda, que le muestra las páginas de ayuda cuando sea necesario. Discutiremos los otros paneles más adelante.

1.3 Interpretación de valores

Cuando se escribe un valor en la Consola, el intérprete simplemente devuelve el mismo valor. En los ejemplos siguientes, 2 es un valor numérico simple, mientras que "Valor de cadena" es un valor textual, que en R se conoce como un valor de carácter y en programación también se conoce comúnmente como una cadena (abreviatura de una cadena de caracteres).

Ejemplo númerico

2
## [1] 2

Ejemplo de cadena

"String value"
## [1] "String value"

Tened en cuenta que los valores de los caracteres deben comenzar y terminar con comillas simples o dobles ('o"), que no forman parte de la información en sí. La Guía de estilo de Tidyverse sugiere usar siempre comillas dobles ("), así que serán las que usaremos en este curso.

Todo lo que sigue a un símbolo # se considera un comentario y el intérprete lo ignora. Cada lenguaje de programación puede usar sus propios símbolos para identificar los comentarios. Por ejemplo cabe destacar la diferencia entre # en Markdown que identifica un título de primer nivel, mientras que los comentarios en un fichero de Rmarkdown se identifican entre < y >.

# Este comentario es ignorado por R. Solo sirve para documentar el código.

Como se ha mencionado anteriormente, el intérprete también comprende operaciones aritméticas simples sobre valores numéricos.

1 + 1
## [1] 2

Además, también hay una gran cantidad de funciones predefinidas, por ejemplo, raíz cuadrada: sqrt.

sqrt(2)
## [1] 1.414214

Las funciones se recopilan y almacenan en bibliotecas (a veces denominadas paquetes), que contienen funciones relacionadas. Las bibliotecas pueden variar desde la biblioteca base, que incluye la función sqrt anterior, hasta la biblioteca rgdal, que funciona como un puente hacia las funciones de la GDAL (Biblioteca de abstracción de datos geoespaciales), que es una importante librería en el mundo de los Sistemas de Información Geográfica. Por lo tanto, es mediante la creación de librerías que podemos extender las capacidades de R.

1.4 Variables

Una variable se puede definir usando un identificador (por ejemplo, una_variable) a la izquierda de un operador de asignación <-, seguido del objeto que se vinculará al identificador, como un valor (por ejemplo, 1) que se asignará a la derecha. Una vez realizada la asignación, el valor de la variable se puede probar/invocar simplemente especificando el identificador.

una_variable <- 1
una_variable
## [1] 1

Si escribes una_variable <- 1 en la Consola de RStudio, aparece un nuevo elemento en el panel Environment (derecha-arriba), que representa la nueva variable en la memoria. La parte izquierda de la entrada contiene el identificador una_variable, y la parte derecha contiene el valor asignado a la variableuna_variable, es decir, 1.

No es necesario aportar un valor directamente. La parte derecha de la tarea puede ser una llamada a una función. En ese caso, la función se ejecuta en la entrada proporcionada y el resultado se asigna a la variable.

una_variable <- sqrt(4)
una_variable
## [1] 2

Observa cómo, al escribir una_variable <- sqrt (4) en la Consola de RStudio, el elemento en el panel Environment cambia para reflejar el nuevo valor asignado a una_variable, que ahora es el resultado de sqrt (4), es decir 2.

En el siguiente ejemplo, se crea otra variable llamada otra_variable y se suma a una_variable, guardando el resultado en suma_de_dos_variables. La raíz cuadrada de esa suma se almacena en la variable raiz_cuadrada_de_suma.

otra_variable <- 4
otra_variable
## [1] 4
suma_de_dos_variables <- una_variable + otra_variable

raiz_cuadrada_de_suma <- sqrt(suma_de_dos_variables)
raiz_cuadrada_de_suma
## [1] 2.44949

1.5 Tipos basicos

1.5.1 Números

El tipo numeric representa números en general (tanto enteros como reales), pero R es capaz de distinguirlos utilizando funciones.

un_numero <- 1.41
is.numeric(un_numero)
## [1] TRUE
is.integer(un_numero)
## [1] FALSE
is.double(un_numero) # i.e., es real
## [1] TRUE

Operadores numéricos básicos.

Operador Significado Ejemplo Resultado
+ Suma 5+2 7
- Resta 5-2 3
* Multiplicación 5*2 10
/ División 5/2 2.5
%/% Div. de enteros 5%/%2 2
%% Módulo 5%%2 1
^ Potencia 5^2 25

Algunas funciones predefinidas en R son:

abs(-2) # Valor absoluto
## [1] 2
ceiling(3.475) # Redondeo al alza
## [1] 4
floor(3.475) # Redondeo a la baja
## [1] 3
trunc(5.99) # Truncar
## [1] 5
log10(100) # Logaritmo en base 10
## [1] 2
log(exp(2)) # Logaritmo natural y exponencial
## [1] 2

Como en cualquier otro entorno, podéis utilizar paréntesis simples para especificar el orden de ejecución. Si no se especifica, el orden predeterminado es: potencia, multiplicación y división, suma y resta al final.

un_numero <- 1
(un_numero + 2) * 3
## [1] 9
un_numero + (2 * 3)
## [1] 7
un_numero + 2 * 3
## [1] 7

R devuelve el resultado NaN (Not a number)cuando el resultado de una operación no es un número.

0/0
## [1] NaN
is.nan(0/0)
## [1] TRUE

No hay que confundir NaNcon NA (No Available), que sirve para identificar datos faltantes.

1.5.2 Lógicos o booleanos

El tipo lógico codifica dos valores dicotómicos: Verdadero y Falso.

valor_logico <- TRUE
is.logical(valor_logico)
## [1] TRUE
isTRUE(valor_logico)
## [1] TRUE
as.logical(0) # se pueden convertir 1/0 a TRUE/FALSE
## [1] FALSE

Operadores lógicos básicos

Operador Significado Ejemplo Resultado
== Igual 5==2 FALSE
!= No igual 5!=2 TRUE
> Mayor que 5>2 TRUE
< Menor que 5<2 FALSE
>= Mayor o igual 5>=2 TRUE
<= Menor o igual 5<=2 FALSE
! No !TRUE FALSE
& Y TRUE & FALSE FALSE
| O TRUE | FALSE TRUE

1.5.3 Cádenas de caracteres

El tipo character representa objetos de texto, incluidos caracteres individuales y cadenas de caracteres (es decir, objetos de texto de más de un carácter, comúnmente denominados simplemente cadenas o strings en informática).

una_cadena <- "¡Hola!"
is.character(una_cadena)
## [1] TRUE
is.numeric(una_cadena)
## [1] FALSE
as.character(2) # Conversión de número a cadena (en inglés, hacer un 'cast')
## [1] "2"
as.numeric("2")
## [1] 2
as.numeric("¡Hasta luego!")
## Warning: NAs introduced by coercion
## [1] NA

1.6 Estructuras de datos

Estos tipos de datos más básicos se gestiónan habitualmente dentro de estructuras de datos más complejas. R tiene muchas otras estructuras de datos pero las más básicas comprenden:

  • Vectores
  • Listas
  • Matrices
  • data frames (se usa el término en inglés por comodidad).
  • Factores

1.6.1 Vectores

1.6.2 Listas

1.6.3 Matrices

1.6.4 Data frames

1.6.5 Factores

1.7 Funciones

Hasta este punto ya habéis visto y usado varias funciones. Por ejemplo, la función c() se puede usar para combinar objetos en un vector. En general, todas las llamadas a funciones tienen el mismo aspecto: el nombre de una función siempre va seguido de paréntesis. A veces, los paréntesis incluyen argumentos como sucede también en el siguiente ejemplo:

# Crea el vector `z` a partir de la función seq (secuenciar).
z <- seq(from = 1, to = 5, by = 1)

En este ejemplo usamos una función llamada seq() para crear una secuencia que progresa por unidades, desde 1 a 5 (probad de modificar los parámetros para obtener otras secuencias distintas).

Si no estáis seguros de qué argumentos acepta una función, siempre se puede consultar la documentación de dicha función (todas las librerías oficiales suelen tener una buena documentación). Por ejemlo, supongamos que no estamos seguros de cómo funcionan los argumentos necesarios para seq(). Podemos escribir ?seq en la consola y, al ejecutar este comando, la página de documentación para esa función aparece en el panel inferior derecho de RStudio. En la sección Argumentos está toda la información que buscamos. En la parte inferior de casi todas las páginas de ayuda, suele haber ejemplos sobre cómo utilizar las funciones correspondientes.

1.8 Tidyverse

Como se ha mencionado anteriormente, las librerias o paquetes son colecciones de funciones y/o conjuntos de datos. Las librerias se pueden instalar en R usando la función install.packages() o usando el menú Herramientas> Instalar Librerias ...en RStudio. Algunas librerias de R están relacionadas entre sí o forman parte de flujos de trabajo mayores. A dia de hoy la meta-librería Tidyverse contiene algunas de las librerías más utilizadas en el análisis de datos (Wickham et al. 2019). Solo por mencionar algunas:

  • ggplot2 para crear gráficos.
  • dplyr para manipular datos (filtrar, seleccionar, agregar, sumarizar, etc).
  • tidyr para organizar los datos de un modo que las otras librerias del Tidyverse puedan trabajar mejor.
  • readr para importar tablas de datos a partir de formatos habituales (csv, tsv, o fwf). Permite minimizar la introducción de errores en la importación.
  • purrr se utiliza para facilitar la automatización de tareas en R, mientras se escribe menos código.
  • stringr facilita la manipulación de cadenas de texto (unir, separar, filtrar palabras en un documento, etc).
  • forcats para trabajar con factores.
  • tibble

Se puede cargar una librería usando la función library(), como se muestra a continuación (tened en cuenta que el nombre de la biblioteca no está entrecomillado). Una vez que una librería está instalada en un ordenador, no es necesario que la instale nuevamente, pero cada secuencia de comandos o script debe cargar todas las librerías que utiliza. Una vez que se carga una librería, se pueden utilizar todas sus funciones.

library(tidyverse)

1.8.1 stringr

El siguiente código presenta un mínimo ejemplo del uso de las funciones de la librería stringr.

str_length("Tarragona")
## [1] 9
str_detect("Tarragona", "a")
## [1] TRUE
str_replace_all("Tarragona", "r", "R")
## [1] "TaRRagona"

1.8.2 El operador pipe

El operador pipe (tuberia) es útil para reducir el número de asignaciones en operaciones más complejas. Un pipe (%>%) toma el resultado de una función y lo pasa a la siguiente función como primer argumento, de este modo ya no hace falta repetir el resultado de la primera función en el código.

El siguiente código muestra un ejemplo sencillo. El número 2 se toma como entrada para el primer pipe que lo pasa como primer argumento a la función sqrt. El valor de salida 1.4142136 se toma como entrada para el segundo pipe, que lo pasa como primer argumento a la función trunc. Finalmente se devuelve la salida final “1”.

2 %>%
  sqrt() %>%
  trunc()
## [1] 1
sqrt(2) %>%
 round(digits = 2)

El primer paso de una secuencia de pipes puede ser un valor, una variable o una función que incluya argumentos. El siguiente código muestra una serie de ejemplos de diferentes formas de lograr el mismo resultado. Los ejemplos usan la función round, que también permite un segundo argumento digits = 2. Tened en cuenta que, cuando se utiliza el operador %>%, solo se proporciona el segundo argumento nominalmente a la función round, es decir, round(digits = 2)

# R básico, sin utilizar '%>%', pero en varios pasos
variable_temporal_a <- 2
variable_temporal_b <- sqrt(variable_temporal_a)
round(variable_temporal_b, digits = 2)

# R básico, sin utilizar '%>%', pero sin asignaciones
round(sqrt(2), digits = 2)

# Pipe a partir de un valor
2 %>%
  sqrt() %>%
  round(digits = 2)

# Pipe a partir de una variable
el_numero_dos <- 2
el_numero_dos %>%
  sqrt() %>%
  round(digits = 2)

# Pipe empezando por una función
sqrt(2) %>%
 round(digits = 2)

Figura 1.1: Ejecución del código sin o con %>%. Sin pipes los resultados intermedios tienen que guardarse en una variable en memoria.

Una operación compleja creada mediante el uso de %>% se puede usar en el lado derecho de una asignación <-, de modo que se guarda resultado de toda la operación de la derecha.

raiz_cuadrada_de_dos <- 2 %>%
  sqrt() %>%
  round(digits = 2)

1.9 Ejercicios

Crea un script para responder a cada pregunta. En las preguntas de la 4 a la 8 es posible que tengas que consultar la referencia de la librería stringr (stringr.tidyverse.org/reference) o a otras funciones de R base.

  1. Escribe un fragmento de código utilizando el operador %>% que haga lo siguiente:
    • tomar como entrada el número 1632
    • calcular el logaritmo en base 10
    • redondear el número a la baja
    • truncar la parte entera y
    • verificar si se trata de un número entero.
  2. Escribe un fragmento de código utilizando el operador %>% que haga lo siguiente:
    • tomar como entrada el número 1632
    • calcular la raíz cuadrada,
    • redondear al alza y quedarse con la parte entera, y
    • verificar que se trata de un entero.
  3. Escribe un fragmento de código utilizando el operador %>% que haga lo siguiente:
    • tomar como entrada la cadena 1632
    • convertirla a número
    • comprobar si el resultado es o no un número.
  4. Escribe un fragmento de código utilizando el operador %>% que haga lo siguiente:
    • tomar como entrada la cadena "-16.32"
    • transformarla en un número
    • calcular el valor absoluto y truncarlo
    • comprobar si el resultado es o no un número.
  5. Escribe un fragmento de código utilizando el operador %>% y la librería and the stringr que haga lo siguiente:
    • tomar la cadena "Siempre r que r" como entrada
    • transformar la cadena a mayúsculas.
  6. Escribe un fragmento de código utilizando el operador %>% y la librería and the stringr que haga lo siguiente:
    • tomar la cadena "Siempre r que r" como entrada
    • truncarla para dejar solamente ‘Siempre R’.

Referencias

Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. “Welcome to the Tidyverse.” Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.

Wickham, Hadley, and Garrett Grolemund. 2017. R for Data Science: Import, Tidy, Transform, Visualize, and Model Data. 1st ed. O’Reilly Media, Inc.