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ónc()
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 vectore_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.
- El vector numérico, formado por números (pueden aceptar decimales).
- 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. - 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.
- 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)
oclass(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 marcamos1:3
será como si pidiéramosc(1,2,3)
mientras que si marcamos10:20
será como si pidiéramosc(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 demd_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)
## Rows: 8
## Columns: 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, 927…
## $ 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óntbl_df()
el marco de datos ya creado. - Crear el marco de datos directamente con la función
tibble()
o la funcióntbl_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 ejemplohelp(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] 4 1 9 2 7 8 3 10 6 5
## [1] 84.1 78.2 56.3 72.4 64.6
## [1] 5 10 9
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á quesize
tendrá la longitud dex
. Si no indicamos lo contrario, el argumentoreplace
será FALSE yprob
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] 7 6 10
## [1] 8 10 7
## [1] 56.3 84.1
## [1] 72.4 72.4
## [1] 84.1 72.4
También podemos dir ‘extraer’ los elementes de un vector↩︎