Objetos y funciones

El objetivo de esta sección es mostrar la estructura básica del análisis de datos con R. Principalmente trabajaremos con:

Objetos

Un objeto es cualquier dato que tengamos almacenada dentro de R: desde un solo número hasta millones de números y caracteres diferentes. A continuación encontraréis ejemplos de las diferentes formas que puede tomar un objeto. Copiad el contenido de la siguiente caja a vuestro RStudio. Tened en cuenta que, a medida que vamos pulsando CTRL + ENTER en cada línea de código, los objetos nos van apareciendo en la ventana de Environment. Esto significa que estamos creando objetos nuevos que se van almacenando en R. Si, una vez creado, introducimos el nombre del objeto en una línea de código y pulsamos CTRL + ENTER, reproduciremos su contenido y nos aparecerá visible en la consola:

  • El objeto tres toma la forma de un número. El número 3.
tres <- 3
  • El objeto operación también tomará la forma de un número, que es el resultado de sumar 7 y 5 y dividir el resultado entre dos. Como R colapsa los resultados, dentro del objeto lo almacenará el número 6.
operacion <- (7 + 5) / 2
  • Utilizamos un objeto ya creado para hacer una operación nueva y lo guardamos como operacion_nueva.
operacion_nueva <- operacion * 3
  • El objeto paises almacena un vector con el nombre de varios países. Crearemos los vectores con la función c() y dentro ubicaremos la cadena de valores. En este caso, en lugar de números, almacenamos caracteres. Por eso lo llamaremos el vector de carácter.
paises <- c("Alemania", "Argentina", "España", "Marruecos", "Sudan")
  • El objeto md_hdi almacena un marco de datos. Dentro del marco de datos hay cuatro vectores diferentes: el primero es un vector de carácter, el segundo es un vector numérico, el tercero es un vector entero y el último es un vector lógico.
md_hdi <- data.frame(pais = c("Alemania", "Argentina", "España", 
                              "Marruecos", "Sudan"),
                     pnb = c(36.2, 15.5, 28.3, 10.2, 2.8), 
                     e_vida = c(78, 73, 79, 67, 54),
                     dem = c(TRUE, TRUE, TRUE, FALSE, FALSE))

Para visualizar un objeto que hemos creado debemos teclear su nombre y pulsar CTRL+ENTER. A continuación visualizamos el marco de datos md_hdi.

pais pnb e_vida dem
Alemania 36.2 78 TRUE
Argentina 15.5 73 TRUE
España 28.3 79 TRUE
Marruecos 10.2 67 FALSE
Sudan 2.8 54 FALSE

Ejercicio 1: Realiza las actividades y responde a las siguientes preguntas:

  • Prueba a crear un objeto formado por un vector de carácter donde figure tu nombre.
  • ¿Cuál es la diferencia entre el vector pnb y el vector e_vida?
  • ¿Por qué crees que el vector dem es TRUE algunas veces y FALSE algunas otras?
  • Qué significado tiene en relación a los paises del marco de datos?

Vectores

Existen diferentes tipos de valores que puede contener un vector. Principalmente en distinguiremos cuatro: numéricos, enteros, caracteres y lógicos. Fíjaos en el código siguiente.

  1. El vector numérico, formado por números (pueden aceptar decimales).
  2. El vector entero está formado por números enteros (no aceptan decimales). Para que R sepa que son enteros, colocaremos una L después de cada número.
  3. El vector de carácter puede contener todo tipo de valores: carácteres, números, símbolos … Normalmente almacenaremos caracteres en él. A la hora de crearlo pondremos cada valor entre comillas.
  4. El vector lógico puede adoptar dos valores: TRUE o FALSE.
vector_numerico <- c(78.2, 56.3, 72.4, 64.6, 84.1)
vector_entero <- c(1L, 5L, 7L, 4L, 4L, 4L, 7L, 8L)
vector_caracter <- c("azul", "amarillo", "verde", "azul")
vector_logico <- c(TRUE, FALSE, FALSE, FALSE, TRUE)

Es importante recordar que un vector sólo puede almacenar valores de un solo tipo. Es decir, en un mismo vector, no podemos tener a la vez valores numéricos y valores de carácter, por ejemplo. Si lo hacemos, R nos coercionarà algunos valores.

Ejercicio 2. Coerciones: En el ejemplo siguiente hemos probado de almacenar un vector con diferentes combinaciones de valores.

  • ¿Qué crees que pasará en cada caso?
  • Para saber la respuesta, examinad qué tipo y clase es cada vector con typeof(nombre_del_vector) o class(nombre_del_vector). Como veréis, R convierte los elementos del vector en valores de un solo tipo.
  • Sabríais intuir cómo decide R esta conversión?
num_log <- c(34, TRUE)
car_log <- c("Hello", TRUE)
num_car <- c(34, "Hello")
num_car_log <- c(34, "Hello", TRUE)

Podéis ampliar la información sobre los tipos de vectores y las coerciones en este vídeo:

Fuente: Datacamp

Seleccionar elementos de un vector

Una manera de seleccionar 1 los valores de un vector es utilizando los corchetes [ ], que ubicaremos immediatamente después del vector o del objeto que contiene un vector.

  • Dentro de los corchetes pondremos un vector que indique la posición de los valores que queremos que nos devuelva del vector en cuestión.
  • Tened en cuenta que el símbolo : es un atajo para marcar una cadena de números. Si marcamos 1:3 será como si pidiéramos c(1,2,3) mientras que si marcamos 10:20 será como si pidiéramos c(10,11,12,13,14,15,16,17,18,19,20).
vector_caracter[1:3]
vector_logico[c(2,4)]
vector_numerico[c(1:3,5)]
vector_entero[-c(5,8)]
## [1] "azul"     "amarillo" "verde"
## [1] FALSE FALSE
## [1] 78.2 56.3 72.4 84.1
## [1] 1 5 7 4 4 7

Operaciones con un vector

Con un vector podemos realizar dos tipos de operaciones:

  • Operación de un vector con un número.
nombre_por_vector <- 3 * c(3,4,5)
nombre_por_vector
## [1]  9 12 15
  • Vectores con otro vector de igual longitud.
vector_por_vector <-c(3,4,5) * c(3,4,5)
vector_por_vector
## [1]  9 16 25

Marco de datos

Podemos entender un marco de datos como una agrupación de varios vectores de igual longitud. Lo crearemos con la función data.frame() o (ver también las funciones tibble). Podemos crear el marco de datos de dos maneras:

  • Creamos primero los vectores y luego los introducimos en el marco de datos.
vector1 <- c( "A", "B", "C")
vector2 <- c(1, 2, 3)
vector3 <- c(TRUE, TRUE, FALSE)
data.frame(vector1, vector2, vector3)
  • O bien indicamos el contenido de los vectores y el nombre directamente dentro la función data.frame(), como vemos en el siguiente ejemplo, que le hemos puesto el nombre de md_agr:
md_agr <- data.frame(pais = c("Francia", "Francia", "Reino Unido", "Reino Unido", 
                              "Polonia", "Polonia", "Congo", "Congo"), 
                     año = c(1980, 2010, 1980, 2010, 1980, 2010, 1980, 2010), 
                     dem = c(TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE), 
                     pib_cap = c(12672.18, 40638.33, 10032.06, 38893.02, 5241.75,
                                 12597.86, 927.10, 2737.34), 
                     agr = c(56.8, 52.8, 76.8, 71.2, 64.5, 47.2, 30.8, 31), 
                     stringsAsFactors = FALSE)
pais año dem pib_cap agr
Francia 1980 TRUE 12672.18 56.8
Francia 2010 TRUE 40638.33 52.8
Reino Unido 1980 TRUE 10032.06 76.8
Reino Unido 2010 TRUE 38893.02 71.2
Polonia 1980 FALSE 5241.75 64.5
Polonia 2010 TRUE 12597.86 47.2
Congo 1980 FALSE 927.10 30.8
Congo 2010 FALSE 2737.34 31.0

Para visualizar el contenido del marco de datos, podemos simplemente teclear el nombre del objeto donde lo hemos guardado o bien podemos visualizarlo de forma vertical mediante la función str(). La función glimpse() del paquete dplyr nos ofrece una visualización parecida.

library(dplyr)
glimpse(md_agr)
## Observations: 8
## Variables: 5
## $ pais    <chr> "Francia", "Francia", "Reino Unido", "Reino Unido", "Polonia"…
## $ año     <dbl> 1980, 2010, 1980, 2010, 1980, 2010, 1980, 2010
## $ dem     <lgl> TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE
## $ pib_cap <dbl> 12672.18, 40638.33, 10032.06, 38893.02, 5241.75, 12597.86, 92…
## $ agr     <dbl> 56.8, 52.8, 76.8, 71.2, 64.5, 47.2, 30.8, 31.0

Los marcos de datos tibble

Una versión mejorada de los marcos de datos son los tipos tibble. Para crearlos, tenemos varias maneras:

  • Aplicar la función tibble() o la función tbl_df() el marco de datos ya creado.
  • Crear el marco de datos directamente con la función tibble() o la función tbl_df().
  • También existe la función tribble(), que nos crea el marco de datos de forma vertical.
md_agr <- tbl_df(md_agr)
tribble(~country, ~year, ~number, 
        "Argentina", 1980, 2304, 
        "Brasil", 1990, 2045)

Seleccionar elementos de un marco de datos

Para seleccionar o extraer elementos del marco de datos también utilizaremos los corchetes, pero en este caso siempre ubicaremos una coma en medio [ , ]. A la izquierda de la coma seleccionaremos las filas y en la derecha las columnas. Observad los siguientes ejemplos:

md_agr[3, ]
md_agr[2:4,c(1,4)]
md_agr[ ,-4]
md_agr[-c(2:4,6), "año"]
##          pais  año  dem  pib_cap  agr
## 3 Reino Unido 1980 TRUE 10032.06 76.8
##          pais  pib_cap
## 2     Francia 40638.33
## 3 Reino Unido 10032.06
## 4 Reino Unido 38893.02
##          pais  año   dem  agr
## 1     Francia 1980  TRUE 56.8
## 2     Francia 2010  TRUE 52.8
## 3 Reino Unido 1980  TRUE 76.8
## 4 Reino Unido 2010  TRUE 71.2
## 5     Polonia 1980 FALSE 64.5
## 6     Polonia 2010  TRUE 47.2
## 7       Congo 1980 FALSE 30.8
## 8       Congo 2010 FALSE 31.0
## [1] 1980 1980 1980 2010

Si queremos cambiar los títulos de las columnas del marco de datos utilizaremos la función names(), por ejemplo:

names(md_agr) <- c("País", "Año", "Dem", "PIB_cap", "Agr")
names(md_agr)[3] <- c("Democracia")

Funciones

Una función es una operación concreta que podemos aplicar a un objeto determinado. Su lógica es relativamente fácil. Supongamos que queremos crear una función que se llame por_dos() que multiplique por dos un vector determinado. La función que crearíamos es la siguiente:

por_dos <- function(x) {
  x * 2
}

Ahora tratamos de aplicar esta función en vector_numerico que habíamos creado anteriormente:

por_dos(vector_numerico)
## [1] 156.4 112.6 144.8 129.2 168.2

Como veis, nos ha multiplicado por dos cada valor del vector_numerico. Esto es lo que hace una función: una determinada operación a un objeto. Hay funciones muy sencillas, como la que acabamos de crear, y funciones muy sofisticadas. Veamos ejemplos de otras funciones que podemos aplicar a los objetos que hemos creado:

  • round(): Nos redondea los decimales de un vector.
  • sum(): Nos suma los valores de un vector.
  • max(): Nos encuentra el valor máximo de un vector.
  • length(): Nos cuenta el número de valores de un vector.
round(vector_numerico)
## [1] 78 56 72 65 84
sum(c(5, 1, 9, 8, 2))
## [1] 25
max(vector_entero)
## [1] 8
length(vector_caracter)
## [1] 4

Utilizar la ayuda: Es importante que aprendáis a consultar el cuadro de ayuda para saber cómo utilizar las funciones.

  • El cuadro de ayuda aparece cuando introduce el nombre de la función precedido por el símbolo ?. Por ejemplo, ?sample.
  • También aparece mediante la función help(), por ejemplo help(sample).
  • En internet también encontréis muchas páginas con información útil sobre cada función.

Hay miles de funciones. Una función interesante es la función sample(), que nos devuelve valores de forma aleatoria.

sample(10)
sample(vector_numerico)
sample(10, 3)
##  [1]  9 10  7  6  3  4  8  5  1  2
## [1] 78.2 72.4 56.3 64.6 84.1
## [1]  5 10  6

Como el resultado es aleatorio, es probable que al reproducir el código no aparezca el mismo resultado. Reproduzca varias veces el código. Verá que el resultado cambia.

Argumentos

Una función puede tener varios argumentos. Los argumentos son maneras diferentes que tiene la función de comportarse. De los argumentos, debemos tener en cuenta:

  • Ubicaremos los argumentos dentro de la función, separados por comas:
funcion(argumento1, argumento2, argumento3, ...)
  • El argumento1 suele ser el objeto al que queremos aplicar la operación.
  • Para saber los argumentos de una función, lo mejor es mediante la función args() o bien con la ayuda ?función.
sample(x, size, replace = FALSE, prob = NULL)
  • No es necesario poner todos los argumentos de una función cuando la usamos. Algunos argumentos tienen asociados un valor predeterminado. Por ejemplo, en la función sample() solo es necesario indicar los dos primeros argumentos, x ysize (en la ayuda también vemos que si sólo introducimos un valor, interpretará que size tendrá la longitud de x. Si no indicamos lo contrario, el argumento replace será FALSE y prob será NULL.
  • Si alteramos orden de los argumentos, tendremos que indicar expresamente a qué nos referimos en cada momento.

En el ejemplo siguiente, hemos realizado varias combinaciones con los argumentos de la función sample(). Intentad interpretar cada línea de código:

sample(10, 3)
sample(size = 3, x = 10)
sample(vector_numerico, 2, TRUE, c(0.3, 0.1, 0.3, 0.2, 0.1))
sample(x = vector_numerico, size = 2, replace = TRUE, prob = c(0.3, 0.1, 0.3, 0.2, 0.1))
sample(replace = TRUE,size = 2, prob = c(0.3, 0.1, 0.3, 0.2, 0.1), x = vector_numerico)
## [1]  8  9 10
## [1] 7 8 4
## [1] 72.4 78.2
## [1] 78.2 64.6
## [1] 78.2 72.4

  1. También podemos dir ‘extraer’ los elementes de un vector↩︎

Next