Tema 2: Análisis exploratorio de datos 20582 - Análisis de Datos 📊 Curso 2022-23 ♾️Grado de Matemáticas - UIB Prof. Irene García Herramientas básicas de R Directorio de trabajo Lo primero que hay que hacer es establecer el directorio de trabajo para la sesión de RStudio. setwd("especifica aquí el path") Otra forma de especificarlo es usando el menú de RStudio: Sesión | Establecer Directorio de Trabajo | Elegir Directorio en el menú de RStudio. Para ver una lista de todas las variables en el directorio: ls() Objetos Usamos el término objeto para describir cosas que están almacenadas en R. Utilizamos <- para asignar valores a las variables. También podemos asignar valores usando =. a<-1 a print(a) Para crear un vector en R se llama a la función c() y se le pasa una lista de valores del mismo tipo. Para extraer los elementos individuales pasamos un número de índice. x<- c("estudiante 1", "estudiante 2") length(x); x[2] ## [1] 2 ## [1] "estudiante 2" Funciones Una vez que se definen las variables, el proceso de análisis de datos generalmente se puede describir como una serie de funciones aplicadas a los datos. R incluye varias funciones predefinidas y la mayoría de las líneas de análisis que construimos hacen uso extensivo de ellas. A continuación se muestra un ejemplo de cómo asignamos un objeto al argumento de la función log. a<-1 log(a) ## [1] 0 Se puede obtener ayuda utilizando la función help: help("log"); args(log) Otros objetos predefinidos Hay varios conjuntos de datos que se incluyen para que los usuarios practiquen y prueben las funciones. Pueden ver todos los sets de datos disponibles escribiendo: data() Por ejemplo, si escriben: co2 R les mostrará los datos de concentración de CO2 atmosférico. Otros objetos predefinidos son cantidades matemáticas, como π e ∞: pi;Inf+1 ## [1] 3.141593 ## [1] Inf Tipos de datos Las variables en R pueden ser de diferentes tipos. Por ejemplo, necesitamos distinguir números de cadenas de caracteres y tablas de listas sencillas de números. La función class nos ayuda a determinar qué tipo de objeto tenemos: a <-2 ; class(a); ## [1] "numeric" b <- as.factor(c("estudiante 1", "estudiante 2")); class(b) ## [1] "factor" Para trabajar eficientemente en R, es importante aprender los diferentes tipos de variables y qué podemos hacer con ellos. Ordenando factores Puede haber ocasiones en las que se quiera ordenar la salida del factor. mes <- as.factor(c("marzo", "abril", "enero", "noviembre", "enero"," table(mes) ## mes ## abril agosto diciembre enero ## 2 4 1 3 ## mayo noviembre octubre septiembre ## 1 5 1 3 febrero 2 julio 1 mes <- factor(mes, levels=c("enero","febrero","marzo", "abril", "may table(mes) ## mes ## enero febrero marzo ## 3 2 1 ## agosto septiembre diciembre abril 2 mayo 1 junio 0 Data frames Conceptualmente, podemos pensar en un data frame como una tabla con filas que representan observaciones y con columnas que representan las diferentes variables recopiladas para cada observación. Los data frames son particularmente útiles porque podemos combinar diferentes tipos de datos en un solo objeto. nombre <-c("José", "Joana", "Sinty", "Marta") edad <- c(23,21,22,21) fumador <- c(0,0,1,1) df <- data.frame(nombre,edad,fumador) df ;class(df) ## ## ## ## ## 1 2 3 4 nombre edad fumador José 23 0 Joana 21 0 Sinty 22 1 Marta 21 1 ## [1] "data.frame" La función str es útil para obtener más información sobre la estructura de un objeto. str(co2) ## Time-Series [1:468] from 1959 to 1998: 315 316 316 318 318 ... Otro ejemplo: Imagina que te ofrecen un trabajo en una empresa estadounidense con muchas ubicaciones por todo EE.UU. Es un gran trabajo, pero noticias con titulares como la tasa de homicidios con armas de fuego en EE.UU. te preocupa. Tienes opciones de dónde puedes vivir y deseas determinar la seguridad de cada estado en particular. El examinar los datos relacionados con asesinatos con armas de fuego de EE.UU. en 2010 podría ayudar. library(dslabs); data(murders); str(murders) ## ## ## ## ## 'data.frame': $ state : $ abb : $ region : $ population: 51 obs. of 5 variables: chr "Alabama" "Alaska" "Arizona" "Arkansas" ... chr "AL" "AK" "AZ" "AR" ... Factor w/ 4 levels "Northeast","South",..: 2 4 4 2 num 4779736 710231 6392017 2915918 37253956 ... El operador de acceso $ Para tener acceso a las diferentes variables del data frame utilizamos: murders$population En general usamos el término vectores para referirnos a objetos con varias entradas. Otro tipo importante de vectores son los vectores lógicos. Estos solo toman valores TRUE o FALSE. z <- 3 == 2 z ## [1] FALSE class(z) ## [1] "logical" En murders, se podría esperar que la región también sea un vector de caracteres. Sin embargo, no lo es: class(murders$region) ## [1] "factor" levels(murders$region) ## [1] "Northeast" "South" "North Central" "West" Otra forma de especificar orden en el factor es con la función reorder. El siguiente código toma la suma del total de asesinatos en cada región y reordena el factor según estas sumas. region <- murders$region; value <- murders$total region <- reorder(region, value, FUN = sum) levels(region) ## [1] "Northeast" "North Central" "West" "South" El nuevo orden indica que hay menos asesinatos en el Noreste y más en el Sur. Listas Los data frames son un caso especial de listas. Las listas son útiles porque pueden almacenar cualquier combinación de diferentes tipos de datos. Se puede crear una lista utilizando la función lista: registro <- list(nombre = "Joan March", id = 23, notas = c(9, 8, 8.5, 6, 7), nota_final = "Sobresaliente") class(registro) ## [1] "list" Al igual que con los data frames, pueden extraer los componentes de una lista con el operador de acceso: $. registro$id ## [1] 23 También podemos usar corchetes dobles ([[) así: registro[["id"]] ## [1] 23 Podemos encontrar listas sin nombres de variables: registro2 <- list("Joan March", 1234) registro2 ## ## ## ## ## [[1]] [1] "Joan March" [[2]] [1] 1234 Si una lista no tiene nombres, no pueden extraer los elementos con $, pero todavía pueden usar el método de corchetes. En vez de dar el nombre de la variable, pueden usar el índice de la lista de la siguiente manera: registro[[1]] ## [1] "Joan March" Matrices Las matrices son similares a los data frames en que son bidimensionales: tienen filas y columnas. Sin embargo, al igual que los vectores numéricos, de caracteres y lógicos, las entradas en las matrices deben ser del mismo tipo. Podemos definir una matriz usando la función matrix. mat <- matrix(1:12, 4, 3); mat ## ## ## ## ## [1,] [2,] [3,] [4,] [,1] [,2] [,3] 1 5 9 2 6 10 3 7 11 4 8 12 Se puede acceder a entradas específicas en una matriz usando corchetes ([). mat[2, 3] ## [1] 10 mat[2, ] ## [1] 2 6 10 mat[, 3] ## [1] 9 10 11 12 mat[, 2:3] ## ## ## ## ## [1,] [2,] [3,] [4,] [,1] [,2] 5 9 6 10 7 11 8 12 Podemos convertir las matrices en data frames usando la función as.data.frame: as.data.frame(mat) ## ## ## ## ## 1 2 3 4 V1 1 2 3 4 V2 5 6 7 8 V3 9 10 11 12 Nombres A veces es útil nombrar las entradas de un vector. Por ejemplo, al definir un vector de códigos de países codigo <- c(italia = 380, canada = 124, egipto = 818) codigo ## italia canada egipto ## 380 124 818 El objeto codigo sigue siendo un vector numérico class(codigo) ## [1] "numeric" pero con nombres names(codigo) ## [1] "italia" "canada" "egipto" También podemos asignar nombres usando la función names codigo <- c(380, 124, 818) pais <- c("italia","canada","egipto") names(codigo) <- pais codigo ## italia canada egipto ## 380 124 818 Subconjuntos Usamos los corchetes para tener acceso a elementos específicos de un vector. Para el vector codigo que definimos anteriormente: codigo[c(1,3)] ## italia egipto ## 380 818 codigo[1:2] ## italia canada ## 380 124 codigo[c("egipto", "italia")] ## egipto italia ## 818 380 La conversión forzada En general, la conversión forzada (coercion en inglés) es un intento de R de ser flexible con los tipos de datos. Cuando una entrada no coincide con lo esperado, algunas de las funciones predefinidas de R tratan de adivinar lo que uno intentaba antes de devolver un mensaje de error. R se comporta de manera bastante diferente a la mayoría de los otros idiomas en cuanto a esto. Veamos unos ejemplos. Dijimos que los vectores deben ser todos del mismo tipo. Entonces, si tratamos de combinar, por ejemplo, números y caracteres, pueden esperar un error: x <- c(1, "canada", 3) ¡Pero no nos da un error, ni siquiera una advertencia! ¿Que pasó? x ## [1] "1" "canada" "3" class(x) ## [1] "character" R forzó una conversión de los datos a caracteres. Esto puede causar muchos errores inadvertidos en R. R también ofrece funciones para cambiar de un tipo a otro. Por ejemplo, pueden convertir números en caracteres con: x <- 1:5; y <- as.character(x); y ## [1] "1" "2" "3" "4" "5" Podemos revertir lo anterior as.numeric(y) Not available (NA) Cuando una función intenta forzar una conversión de un tipo a otro y encuentra un caso imposible, generalmente nos da una advertencia y convierte la entrada en un valor especial llamado NA que significa no disponible (Not Available en inglés). x <- c("1", "b", "3") as.numeric(x) ## [1] 1 NA 3 R no sabe el número que queríamos cuando escribimos b y no lo intenta adivinar. Nos encontraremos con el NA frecuentemente ya que se usa generalmente para datos faltantes (missing data en inglés), un problema común en los conjuntos de datos del mundo real.