En esta practica se estudiaran los primeros conceptos acerca del manejo del entorno de R, la creación y manipulación de los objetos en el ambiente de trabajo además de otros relacionados con el acceso a información desde fuentes de datos internas y externas.
El entorno de R, se puede entender como el la creación y acceso a objetos desde la consola, elemento principal en la edición de código R, así se muestran a continuación las características mas importantes de este elemento.
Para edición de código cualquier herramienta de texto disponible es suficiente aún así el manejo de herramientas como RStudio puede facilitar la implementación del código en R.
# Calcula 3 + 4
3 + 4
# Calcula 6 + 12
6 + 12
Un primer vistazo al funcionamiento de la herramienta R, es bajo la perspectiva de la realización de cálculos aritméticos. A continuación se muestran algunas de las operaciones básicas que se pueden realizar con simples llamados a funciones genéricas y utilitarias.
# Una suma
5 + 5
[1] 10
# Una resta
5 - 5
[1] 0
# Una multiplicación
3 * 5
[1] 15
# Una división
(5 + 5)/2
[1] 5
# Una exponenciación
2^5
[1] 32
# Modulo por división
28 %% 6
[1] 4
# Raiz cuadrada
2^16
[1] 65536
En R se pueden almacenar números acorde al tipo de datos, es importante para los casos en donde el resultado de un calculo es precisamente un número
3/0; -3/0;
[1] Inf
[1] -Inf
exp(-Inf); 0/Inf
[1] 0
[1] 0
(0:3)^Inf; 0/0
[1] 0 1 Inf Inf
[1] NaN
Inf - Inf; Inf/Inf
[1] NaN
[1] NaN
is.finite(10)
[1] TRUE
is.finite(Inf)
[1] FALSE
Para concluir este apartado en el que R puede ser visto como una herramienta de cálculos se muestran a continuación algunas funciones de uso genérico.
# Raíz cuadrada
sqrt(4)
[1] 2
# Exponencial
exp(1); exp(2)
[1] 2.718282
[1] 7.389056
# Funciones trigonométricas
cos(pi); tan(pi/4); sin(pi)
[1] -1
[1] 1
[1] 1.224647e-16
# Funciones para redondear
round(sin(pi),10); round(1.34562, 2)
[1] 0
[1] 1.35
floor(sin(pi)); floor(1.34562)
[1] 0
[1] 1
ceiling(sin(pi)); ceiling(1.34562)
[1] 1
[1] 2
Un concepto básico del análisis de datos en Estadística es el de variable, en R las variables son objetos vistos desde el tipo de datos que se le asigna, entonces es importante conocer los tipos de operadores de asignación como se muestra a continuación
# Asignando un valor 45 a "x" e "y"
x <- 45
y = 45
45 -> z
# Imprimiendo de manera automatica el valor de "x"
x; y; z
[1] 45
[1] 45
[1] 45
Los nombres de variables siguen una serie de restricciones en R debido a que en este entorno se distinguen mayúsculas, minúsculas y palabras reservadas entre otros.
x <- 2; X <- 2
un.numero.grande <- 126597264
x_1o <- 36
%un.numero.grande <- 12457
Error: unexpected input in "%un.numero.grande <- 12457"
Los tipos de datos en R, como en cualquier otro lenguaje de programación cobran vital importancia, debido a esto el conocer cada uno de los tipos de datos se puede entender como el proceso almacenamiento interno de datos en R.
# Declarando distintos tipos de variables
my_numeric <- 42
my_character <- "forty-two"
my_logical <- FALSE
# Investigar el tipo de datos
class(my_numeric)
[1] "numeric"
class(my_character)
[1] "character"
class(my_logical)
[1] "logical"
Todo en R puede ser visto como un objeto, esto implica a su vez que tiene nombre, contenido y atributos.
x <- rnorm(10); names(x) <- paste("Pos", 1:10)
x
Pos 1 Pos 2 Pos 3 Pos 4 Pos 5
-0.245003490 -1.377579727 -0.022812200 1.008184695 -1.119920494
Pos 6 Pos 7 Pos 8 Pos 9 Pos 10
-0.007174784 -0.276150953 -1.230713078 0.739840763 -0.391343039
mode(x); length(x); class(x)
[1] "numeric"
[1] 10
[1] "numeric"
Cuando el objeto adquiere más atributos y dimensiones es fácil observar estas a través de las funciones genéricas dim() y attributes()
data("mtcars")
dim(mtcars)
[1] 32 11
attributes(mtcars)
$names
[1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
[11] "carb"
$row.names
[1] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710"
[4] "Hornet 4 Drive" "Hornet Sportabout" "Valiant"
[7] "Duster 360" "Merc 240D" "Merc 230"
[10] "Merc 280" "Merc 280C" "Merc 450SE"
[13] "Merc 450SL" "Merc 450SLC" "Cadillac Fleetwood"
[16] "Lincoln Continental" "Chrysler Imperial" "Fiat 128"
[19] "Honda Civic" "Toyota Corolla" "Toyota Corona"
[22] "Dodge Challenger" "AMC Javelin" "Camaro Z28"
[25] "Pontiac Firebird" "Fiat X1-9" "Porsche 914-2"
[28] "Lotus Europa" "Ford Pantera L" "Ferrari Dino"
[31] "Maserati Bora" "Volvo 142E"
$class
[1] "data.frame"
El objeto más simple y de mayor uso para el calculo de cantidades es el vector a continuación veremos las múltiples formas de declarar y manipular un vector en R.
# Declarando vectores, "vector()"
numeric_integer <- vector("integer"); numeric_integer
integer(0)
numeric_vector <- vector("numeric"); numeric_vector
numeric(0)
character_vector <- vector("character"); character_vector
character(0)
boolean_vector <- vector("logical"); boolean_vector
logical(0)
complex_vector <- vector("complex"); complex_vector
complex(0)
La forma mas común de declarar un vector en mediante la función concatenar c() como se muestra a continuación.
numeric_vector <- c(1, 10, 49)
character_vector <- c("a", "b", "c")
boolean_vector <- c(T, F, T)
Una ultima pero no única forma de crear vectores es a través de las funciones de ejecución de secuencias.
# Operador dos puntos
vector_integer <- 1:10
vector_integer
[1] 1 2 3 4 5 6 7 8 9 10
# Función "seq()"
seq(1, 20, 2)
[1] 1 3 5 7 9 11 13 15 17 19
# Función "seq_along()"
seq_along(letters)
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
[24] 24 25 26
Aquí algunos ejemplos de manipulación de los atributos del objeto en este caso empezamos con los nombres.
poker_vector <- c(140, -50, 20, -120, 240)
roulette_vector <- c(-24, -50, 100, -350, 10)
names(poker_vector) <- c("Monday", "Tuesday", "Wednesday",
"Thursday", "Friday")
names(roulette_vector) <- c("Monday", "Tuesday", "Wednesday",
"Thursday", "Friday")
Otra forma de realizar el proceso anterior el creando el vector de nombres en primera instancia.
poker_vector <- c(140, -50, 20, -120, 240)
roulette_vector <- c(-24, -50, 100, -350, 10)
days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
names(poker_vector) <- days_vector
names(roulette_vector) <- days_vector
poker_vector; roulette_vector
Monday Tuesday Wednesday Thursday Friday
140 -50 20 -120 240
Monday Tuesday Wednesday Thursday Friday
-24 -50 100 -350 10
Las operaciones sobre vectores se hacen de manera posicional.
poker_vector <- c(140, -50, 20, -120, 240)
roulette_vector <- c(-24, -50, 100, -350, 10)
total_roulette <- sum(roulette_vector)
total_poker <- sum(poker_vector)
total_week <- total_poker + total_roulette
total_poker
[1] 230
total_roulette
[1] -314
total_week
[1] -84
La indexación de vectores se realiza de manera convencional a través del operador [ de manera tal que siempre se obtenga un vector como resultado
poker_vector <- c(140, -50, 20, -120, 240)
roulette_vector <- c(-24, -50, 100, -350, 10)
###
days_vector <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
names(roulette_vector) <- days_vector
names(poker_vector) <- days_vector
ans <- total_poker > total_roulette
poker_wednesday <- poker_vector[3]
poker_midweek <- poker_vector[c(2:4)]
average_midweek_gain <- mean(poker_vector[c(1:3)])
selection_vector <- poker_vector > 0
Como pudimos observar en el capítulo anterior las matrices pueden definirse como un vector de dos dimensiones, así veamos como se declaran y manipulan en el entorno R.
## Con la función matrix()
matrix(1:9, byrow = T, nrow = 3)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
Otra forma es mediante el uso de vectores declarados
new_hope <- c(460.998, 314.4)
empire_strikes <- c(290.475, 247.900)
return_jedi <- c(309.306, 165.8)
star_wars_matrix <- matrix(c(new_hope, empire_strikes, return_jedi),
byrow = T, nrow = 3)
colnames(star_wars_matrix)<-c("US", "non-US")
rownames(star_wars_matrix)<-c("A New Hope", "The Empire Strikes Back",
"Return of the Jedi")
star_wars_matrix
US non-US
A New Hope 460.998 314.4
The Empire Strikes Back 290.475 247.9
Return of the Jedi 309.306 165.8
Las primeras operaciones sobre matrices que se pueden realizar son los resúmenes teniendo en cuenta las dimensiones de la misma. Recuerde las funciones cbind() y rbind() también pueden crear matrices.
box_office_all <- c(461, 314.4, 290.5, 247.9, 309.3, 165.8)
movie_names <- c("A New Hope","The Empire Strikes Back",
"Return of the Jedi")
col_titles <- c("US","non-US")
star_wars_matrix <- matrix(box_office_all, nrow = 3,
byrow = TRUE, dimnames = list(movie_names,
col_titles))
worldwide_vector <- rowSums(star_wars_matrix)
all_wars_matrix <- cbind(star_wars_matrix, worldwide_vector)
all_wars_matrix
US non-US worldwide_vector
A New Hope 461.0 314.4 775.4
The Empire Strikes Back 290.5 247.9 538.4
Return of the Jedi 309.3 165.8 475.1
Como en el caso anterior se pueden añadir filas en vez de columnas, el objeto sigue siendo una matriz si la declaración tiene sentido
total_revenue_vector <- colSums(all_wars_matrix)
total_revenue_vector
US non-US worldwide_vector
1060.8 728.1 1788.9
La indexación en matrices se hace de manera similar a los vectores teniendo en cuenta que en este caso el atributo dimensión juega un papel muy importante
box_office_all <- c(461, 314.4, 290.5, 247.9, 309.3, 165.8)
movie_names <- c("A New Hope","The Empire Strikes Back",
"Return of the Jedi")
col_titles <- c("US","non-US")
star_wars_matrix <- matrix(box_office_all, nrow = 3,
byrow = TRUE,
dimnames = list(movie_names, col_titles))
non_us_all <- mean(star_wars_matrix[,2]) ; non_us_all
[1] 242.7
non_us_some <- mean(star_wars_matrix[1:2,2]); non_us_some
[1] 281.15
En R los factores son la base para el tratamiento de variables categóricas, su definición parte de una cadena de caracteres y su tratamiento depende de esta característica.
## Creación de factores con `factor()`
gender_vector <- c("Male", "Female", "Female", "Male", "Male")
factor_gender_vector <- factor(gender_vector); factor_gender_vector
[1] Male Female Female Male Male
Levels: Female Male
Parte de la manipulación de los factores de la especificación de sus niveles como se muestra a continuación.
animals_vector <- c("Elephant", "Giraffe", "Donkey", "Horse")
temperature_vector <- c("High", "Low", "High","Low", "Medium")
factor_animals_vector <- factor(animals_vector)
factor_animals_vector
[1] Elephant Giraffe Donkey Horse
Levels: Donkey Elephant Giraffe Horse
factor_temperature_vector <- factor(temperature_vector,
order = TRUE,
levels = c("Low", "Medium", "High"))
factor_temperature_vector
[1] High Low High Low Medium
Levels: Low < Medium < High
summary(factor_temperature_vector)
Low Medium High
2 1 2
La indexación se realiza de forma similar a la vista en casos anteriores, tenga en cuenta que cambiar la naturaleza de un factor en un código donde se analizan variables categóricas es de cuidado.
survey_vector <- c("M", "F", "F", "M", "M")
factor_survey_vector <- factor(survey_vector)
levels(factor_survey_vector) <- c("Female", "Male")
factor_survey_vector[1]
[1] Male
Levels: Female Male
factor_survey_vector[2]
[1] Female
Levels: Female Male
Otra forma de tener variables ordinales es teniendo en cuenta los parámetros ordered y levels de la función factor()
speed_vector <- c("Fast", "Slow", "Slow", "Fast", "Ultra-fast")
factor_speed_vector <- factor(speed_vector,
ordered = T,
levels = c("Slow","Fast","Ultra-fast"))
factor_speed_vector
[1] Fast Slow Slow Fast Ultra-fast
Levels: Slow < Fast < Ultra-fast
summary(factor_speed_vector)
Slow Fast Ultra-fast
2 2 1
El objeto tabular de mayor uso en R, es el data frame posee las características de una lista como veremos permite realizar muchas de las tareas más comunes en el análisis de datos.
data("mtcars")
head(mtcars)
tail(mtcars)
Siempre se hace necesario revisar la estructura del data frame observado debido a los distintos datos que puede traer la lectura del mismo, esto sin importar la fuente de los datos.
str(mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
la forma de creación manual de estructuras tabulares es con la función data.frame() teniendo en cuenta las estructuras de los vectores fuentes
planets <- c("Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune");
type <- c("Terrestrial planet", "Terrestrial planet",
"Terrestrial planet", "Terrestrial planet",
"Gas giant", "Gas giant", "Gas giant", "Gas giant")
diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883);
rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67);
rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE);
planets_df <- data.frame(planets, type, diameter, rotation, rings)
planets_df
La indexación se realiza con el operador [ de forma similar a los vectores y a las matrices.
closest_planets_df <- planets_df[1:3,]
furthest_planets_df <- planets_df[6:8,]
closest_planets_df
furthest_planets_df
furthest_planets_diameter <- planets_df[3:8, 3]
Se pueden hacer manipulaciones basadas en creación de nuevas variables
rings_vector <- planets_df[, "rings"]
planets_with_rings_df <- planets_df[rings_vector, ]
planets_with_rings_df
La tarea principal del analista de datos muchas veces se remite a la obtención de subconjuntos de datos de una lista o marco de datos.
small_planets_df <- subset(planets_df, subset = (diameter < 1))
small_planets_df
small_planets_df[order(small_planets_df$diameter), ]
Las listas se muestran como el objeto de mayor impacto en cuanto a manipulación de datos se refiere, a continuación se muestran ejemplos de creación y manipulación de objetos tipo listas en R.
my_vector <- 1:10
my_matrix <- matrix(1:9, ncol = 3)
my_df <- mtcars[1:10,]
# Se construye una lista con la función `list()` en distintos tipos de datos
my_list <- list(vec = my_vector, mat = my_matrix, df = my_df)
my_list
$vec
[1] 1 2 3 4 5 6 7 8 9 10
$mat
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
$df
NA
La forma de indexar listas es con base al operador [[, así teniendo en cuenta la posición del nodo y el objeto que contiene se puede obtener el resultado deseado.
act <- c("Jack Nicholson", "Shelley Duvall",
"Danny Lloyd", "Scatman Crothers", "Barry Nelson")
mov <- c("The Shining")
rev <- data.frame(scores = c(4.5, 4, 5),
sources = c("IMDb1","IMDb2", "IMDb3"),
comments = c("Best Horror Film I Have Ever Seen",
"A truly brilliant and scary film from Stanley Kubrick",
"A masterpiece of psychological horror"))
shining_list <- list(moviename = "The Shining",
actors = act, reviews = rev)
shining_list$actors
[1] "Jack Nicholson" "Shelley Duvall" "Danny Lloyd"
[4] "Scatman Crothers" "Barry Nelson"
shining_list[[2]][2]
[1] "Shelley Duvall"
shining_list_full <- c(shining_list, year = 1980)
str(shining_list_full)
List of 4
$ moviename: chr "The Shining"
$ actors : chr [1:5] "Jack Nicholson" "Shelley Duvall" "Danny Lloyd" "Scatman Crothers" ...
$ reviews :'data.frame': 3 obs. of 3 variables:
..$ scores : num [1:3] 4.5 4 5
..$ sources : Factor w/ 3 levels "IMDb1","IMDb2",..: 1 2 3
..$ comments: Factor w/ 3 levels "A masterpiece of psychological horror",..: 3 2 1
$ year : num 1980