class: title-slide, middle, center background-image: url(data:image/png;base64,#imagenes/liigh_unam_logo.png) background-position: 10% 10% background-size: 15% .center-column[ # ManipulaciĆ³n de datos con funciones de R base ### VieRnes de Bioinformatica ####Dra. Evelia Coss #### 2024/03/8 ] --- ## Paquetes necesarios ```r install.packages("dplyr") # ManipulaciĆ³n de datos install.packages("tidyr") # ManipulaciĆ³n de datos install.packages("tidyverse")# ManipulaciĆ³n de datos install.packages("reshape2") # TransformaciĆ³n de datos install.packages("ggplot2") # VisualizaciĆ³n grafica install.packages("cowplot") # Generar varios graficos en una misma figura ``` --- .center[ <img src = "imagenes/DataStructure.png", height = "400"> ] --- ## Funciones bĆ”sicas en R | FunciĆ³n | Empleo | DocumentaciĆ³n | Ejemplos | |----------------|---------------------|---------------|------------| | `sum()` | AdiciĆ³n / suma | `?sum` | sum(2+7) | | `prod()` | SustracciĆ³n / resta | `?prod` | prod(9-2) | | `max()` | Valor mĆ”ximo | `?max` | max(c(1,2,3,4,5))| | `min()` | Valor mĆnimo | `?min` | min(1:5) | | `range()` | Rango | `?range` | range(c(2,8,7,6,1)) | | `mean()` | Promedio | `?mean` | mean(c(2,8,7,6,1)) | | `median()` | Mediana | `?median` | median(c(2,8,7,6,1)) | | `var()` | Varianza | `?var` | var(1:10); var(1:5, 1:5) | | `cov()` | Covarianza | `?cov` | cov(1:10, 2:11)| | `cor()` | Matriz de correlaciĆ³n | `?cor` | cor(1:10, 2:11)| Existen otras funciones matematicas como `log, exp,log10, log2, sin, cos, tan, asin, acos, atan, abs, sqrt`, etc. --- ## Funciones bĆ”sicas en R | FunciĆ³n | Empleo | DocumentaciĆ³n | Ejemplos | |----------------|--------------------------------------------|---------------|--------------------------------| | `unique()` | Valor unico | ?unique | unique(df$expression) | | `sort()` | Ordenar | ?sort | sort(df$expression) | | `order()` | Ordenar | ?order | df[order(df$expression),] | | `table()` | cuentas de cada valor en tablas | ?table | table(df) | | `subset()` | Extraer informaciĆ³n de una MATRIZ o DATAFRAME | ?subset | subset(df, expression == 1.8) | | `sample()` | Extraer informaciĆ³n de manera aleatoria | ?sample | sample(df$expression, size =3) | | `length()` | NĆŗmero de elementos de un VECTOR | ?length | length(df$expression) | | `dim()` | Dimensiones de una MATRIZ o DATAFRAME | ?dim | dim(df) | | `is.na()` | Es un valor NA? | ?is.na | is.na(df) | | `t()` | Cambiar filas por columnas (transposiciĆ³n) | ?t | t(df) | .left[.footnote[.black[ R for beginners, PĆ”gina 32 ]]] --- ## Otras funciones importantes son `rbind()` y `cbind()` Puedes encontrar su documentaciĆ³n empleando `?rbind` y `?cbind`. ### `cbind()` Podemos unir por las columnas dos vectores. ```r a <- c(1, 3, 3, 4, 5) b <- c(7, 7, 8, 3, 2) new_matrix <- cbind(a, b) new_matrix # a b # [1,] 1 7 # [2,] 3 7 # [3,] 3 8 # [4,] 4 3 # [5,] 5 2 ``` --- ### `cbind()` Crear un dataframe ```r df <- data.frame(genes = paste0("Gen", seq_len(8)), expression = c(3.8, 5.5, 6.3, 1.8, 9, rep(3,3)), treatment =c(rep("Control", 4), rep("Condicion1",4))) ``` Tambien podemos incorporarle una nueva columna a un *dataframe* ```r date_sample <- rep(c(11, 12, 13, 14),2) df <- cbind(df, date_sample) # Renombrar columna 4 colnames(df)[4] <- "Date" head(df) # genes expression treatment Date # 1 Gen1 3.8 Control 11 # 2 Gen2 5.5 Control 12 # 3 Gen3 6.3 Control 13 # 4 Gen4 1.8 Control 14 # 5 Gen5 9.0 Condicion1 11 # 6 Gen6 3.0 Condicion1 12 ``` --- ### `rbind()` Vamos a unir dos *dataframe* pero ambos deben tener el mismo numero y nombre en su columnas. > NOTA: Los rownames deben ser Ćnicos, por lo que no debemos comenzar desde el Gen1. ```r df_v2 <- data.frame(genes = paste0("Gen", 9:16), expression = c(6.1, 6.2, 5, 2, 7, rep(8,3)), treatment = c(rep("Control", 4), rep("Condicion1",4)), Date = rep(c(11, 12, 13, 14),2) ) df_v2$treatment <- as.factor(df_v2$treatment) # conversiĆ³n a factor #unir df_new <- rbind(df, df_v2) head(df_new) # genes expression treatment Date # 1 Gen1 3.8 Control 11 # 2 Gen2 5.5 Control 12 # 3 Gen3 6.3 Control 13 # 4 Gen4 1.8 Control 14 # 5 Gen5 9.0 Condicion1 11 # 6 Gen6 3.0 Condicion1 12 ``` --- ## InformaciĆ³n de la estructura de un dataframe Para ver su estructura e informaciĆ³n: ```r dim(df) # dimensiones [fila, columna] length(df) # largo, nĆŗmero de columnas ncol(df) # nĆŗmero de columnas nrow(df) # nĆŗmero de filas names(df) # nombre de las columnas str(df) # Estructura ``` -- Podemos adornar la salida colocando estas notas. ```r cat("Dimensiones:", dim(df), "\n") # Dimensiones: 8 4 cat("Numero de columnas:", ncol(df), "\n") # Numero de columnas: 4 cat("Numero de filas:", nrow(df), "\n") # Numero de filas: 8 cat("Nombre de las columnas:", names(df), "\n") # Nombre de las columnas: genes expression treatment Date ``` > NOTA: El "\n" indica saltos de linea en el texto. --- ## FunciĆ³n `which()` Podemos usar esta funciĆ³n para extraer la informaciĆ³n y/o las posiciones que cumpla con un argumento logico. DocumentaciĆ³n `?which` ```r x <- c(1, 5, 4, 8, 4) which(x == 4 | x == 1) # condicional que sea igual a 4 o a 1 # [1] 1 3 5 ``` **ĀæCuĆ”ntos nĆŗmeros son iguales a 4 y a 1?** ```r length(which(x == 4 | x == 1)) # [1] 3 ``` --- ## FunciĆ³n `which()` en un matriz ### Ejemplo 1: Obtener las valores que al divirse entre 3 sean iguales a cero ```r m <- matrix(1:12, 3, 4) # Generar una matriz de 3 x 4 # OpciĆ³n A - con R base m[m %% 3 == 0] # [1] 3 6 9 12 # OpciĆ³n B - con la funciĆ³n which div.3 <- m %% 3 == 0 which(div.3) # OR which(m %% 3 == 0) # [1] 3 6 9 12 ``` --- ## FunciĆ³n `which()` en un matriz ### Ejemplo 2: Obtener las posiciones de los numeros que al divirse entre 3 sean iguales a cero ```r # Para obtener la informaciĆ³n de las posiciones podemos usar: which(div.3, arr.ind = TRUE) # row col # [1,] 3 1 # [2,] 3 2 # [3,] 3 3 # [4,] 3 4 # Ejemplo 2 rownames(m) <- paste("Case", 1:3, sep = "_") # renombrar las filas which(m %% 5 == 0, arr.ind = TRUE) # Extraer las posiciones que cumplan con la condiciĆ³n logica # row col # Case_2 2 2 # Case_1 1 4 ``` --- ## Index .pull-left[ Por medio de un **index** podemos: - 1) Obtener la informaciĆ³n de un dato en especĆfico. - 2) Modificar un dato en especĆfico. - 3) Eliminarlo un dato en especĆfico. Podemos hacer la pregunta de dos maneras, 1) ĀæCuĆ”l es el nivel de expresiĆ³n del Gen2? O 2) ĀæQue gen contiene una expresiĆ³n de 5.5? ] .center[.pull-right[ <img src = "figures/dataframe_ejemplo.png", height = "400">]] --- ## FunciĆ³n `which()` en un dataframe **ĀæQue gen contiene una expresiĆ³n de 1.8?** ```r # OpciĆ³n A which(df == 1.8, arr.ind = TRUE) # row col # [1,] 4 2 ``` ```r # OpciĆ³n B df[which(df$expression == 1.8), ] # genes expression treatment Date # 4 Gen4 1.8 Control 14 ``` --- class: center, middle
# Repaso de todo lo aprendido en clases ## Ejercicio practico --- class: center, middle # Paso 1. Crear un RBioProject --- class: center, middle
# Marvel vs DC comics .center[.pull-right[ <img src = "logos/Marvel_Logo.png", height = "250">] ] .center[.pull-left[ <img src = "logos/DC-comic-1.png", height = "250">] ] --- ## Paso 2. Descargar los datos y verificar su ubicaciĆ³n en la carpeta `data/` 1) Descarga los tres datasets de Marvel dando click en este [link](https://github.com/cosmoduende/r-marvel-vs-dc/tree/main/dataset_shdb), debes tener tres archivos en la misma carpeta `charactersStats.csv`, `heroesInformation.csv` y `superHeroPowers.csv`. AsegĆŗrate de guardarlo en el directorio donde hiciste tu Rproject. En mi caso, guarde los datos en la carpeta `data/`. 2) Verifica que se encuentren los tres archivos en la carpeta `data/`. ```r dir("data") # [1] "charactersStats.csv" "dirty_iris.csv" "fullMarvelDc.RData" # [4] "heroesInformation.csv" "Info_data.RData" "marvelDc.RData" # [7] "marvelDcInfo.RData" "MMHOME.csv" "planets.csv" # [10] "superheroes.RData" "superHeroPowers.csv" ``` --- ## Paso 3. Importar los datos en R 3) Importa los archivos en R de la siguiente manera: ```r infoCharacters <- read.csv("data/heroesInformation.csv", na.strings = c("-", "-99")) # La opciĆ³n na.string nos permite sustituir valores - y -99 por NA infoPowers <- read.csv("data/superHeroPowers.csv") infoStats <- read.csv("data/charactersStats.csv", na.strings = "") ``` Visualiza su informaciĆ³n con `head()` o `View()`. > **NOTA:** Primero debes crear la carpeta data/ antes de descargar los archivos. --- ## Buenas prĆ”cticas Nuestro script debe verse asi: ```r ###### # Script de clase "Intro a R" # Evelia Coss # 8 de marzo 2024 ####### indir = "C:/Users/ecoss/OneDrive - CINVESTAV/Documentos/Posdoc_LIIGH/VieRnesBioinfo/ViernesBioinfo_2024/Presentaciones/data/" outdir = "C:/Users/ecoss/OneDrive - CINVESTAV/Documentos/Posdoc_LIIGH/VieRnesBioinfo/ViernesBioinfo_2024/Presentaciones/" # Importar datos infoCharacters <- read.csv(paste0(indir,"heroesInformation.csv"), na.strings = c("-", "-99")) # La opciĆ³n na.string nos permite sustituir valores - y -99 por NA infoPowers <- read.csv(paste0(indir,"superHeroPowers.csv")) infoStats <- read.csv(paste0(indir,"charactersStats.csv"), na.strings = "") ``` --- ## Paso 4. Renombrar la columna **Name** en todos los dataframe Vamos a unificar el nombre las columnas que tienen los nombre en todas las columnas colocando el nombre Name. El dataframe infoStats ya contiene ese nombre en la columna 1. ```r colnames(infoCharacters)[colnames(infoCharacters) == "name"] <- "Name" colnames(infoPowers)[colnames(infoPowers) == "hero_names"] <- "Name" ``` --- ## Paso 5. Seleccionar SOLO los datos de Marvel Comics y DC Comics Podemos usar la funciĆ³n `unique()` para obtener los **valores Ćŗnicos** en un vector o de una columna en un dataframe. ```r # Empresas comprendidas en esta base de datos unique(infoCharacters$Publisher) # [1] "Marvel Comics" "Dark Horse Comics" "DC Comics" # [4] "NBC - Heroes" "Wildstorm" "Image Comics" # [7] "" "Icon Comics" "SyFy" # [10] "Hanna-Barbera" "George Lucas" "Team Epic TV" # [13] "South Park" "HarperCollins" "ABC Studios" # [16] "Universal Studios" "Star Trek" "IDW Publishing" # [19] "Shueisha" "Sony Pictures" "J. K. Rowling" # [22] "Titan Books" "Rebellion" "Microsoft" # [25] "J. R. R. Tolkien" ``` --- ## Paso 5. Seleccionar SOLO los datos de Marvel Comics y DC Comics Filtrar solo los datos de Marvel Comics y DC Comics. ```r marvelDcInfo <- infoCharacters[(infoCharacters$Publisher == "Marvel Comics" | infoCharacters$Publisher == "DC Comics"), ] head(marvelDcInfo, 3) # X Name Gender Eye.color Race Hair.color Height # 1 0 A-Bomb Male yellow Human No Hair 203 # 3 2 Abin Sur Male blue Ungaran No Hair 185 # 4 3 Abomination Male green Human / Radiation No Hair 203 # Publisher Skin.color Alignment Weight # 1 Marvel Comics <NA> good 441 # 3 DC Comics red good 90 # 4 Marvel Comics <NA> bad 441 ``` --- ## Verificamos las dimensiones Esperariamos que cada fila sea un solo personaje, pero este dataframe contiene nombres repetidos. ```r dim(marvelDcInfo) # [1] 603 11 ``` Esperariamos que las **filas representaran el numero de personales**, teniendo un total de 603 personajes y las **columnas representaran las variables**, teniendo un total de 11 variables. Sin embargo, podemos extraer los nombres de los personajes que solo se repitan una vez y veremos que nuestro dataset no esta limpio. Ya que solo tiene un total de 585 personajes. ```r length(unique(marvelDcInfo$Name)) # [1] 585 ``` --- ## Observar valores duplicados Observar cuales se duplican mediante la funciĆ³n [`duplicated()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/duplicated) de R base. ```r head(marvelDcInfo[duplicated(marvelDcInfo$Name), ], 3) # X Name Gender Eye.color Race Hair.color Height Publisher # 49 48 Atlas Male blue God / Eternal Brown 198 DC Comics # 51 50 Atom Male <NA> <NA> <NA> -99 DC Comics # 64 63 Batgirl Female green Human Red 170 DC Comics # Skin.color Alignment Weight # 49 <NA> bad 126 # 51 <NA> good -99 # 64 <NA> good 57 ``` Para saber cuantos personajes duplicados podemos usar `length()` ```r length(marvelDcInfo[duplicated(marvelDcInfo$Name), ]) # [1] 11 ``` Existen 11 personajes que se encuentran duplicados en esta base de datos. --- ## Revisemos un ejemplo de datos duplicados Vamos a obtener la informaciĆ³n de **Batman** y vemos que tiene dos filas pertenecientes al mismo personaje. ```r # OpciĆ³n A marvelDcInfo[marvelDcInfo$Name == "Batman", ] # X Name Gender Eye.color Race Hair.color Height Publisher Skin.color # 69 68 Batman Male blue Human black 188 DC Comics <NA> # 70 69 Batman Male blue Human Black 178 DC Comics <NA> # Alignment Weight # 69 good 95 # 70 good 77 ``` Tambien podemos usar la funciĆ³n `subset()` para extraer informaciĆ³n de algun personaje. ```r # OpciĆ³n B subset(marvelDcInfo, Name == "Batman") # X Name Gender Eye.color Race Hair.color Height Publisher Skin.color # 69 68 Batman Male blue Human black 188 DC Comics <NA> # 70 69 Batman Male blue Human Black 178 DC Comics <NA> # Alignment Weight # 69 good 95 # 70 good 77 ``` --- # Empecemos con la limpieza de los datos ## Paso 6. Eliminar duplicados El signo de exclamaciĆ³n `!` nos permite indicar lo contrario, es decir, devolverme todos los que no esten duplicados seria asi `!duplicated()`. ```r marvelDcInfo <- marvelDcInfo[!duplicated(marvelDcInfo$Name), ] ``` ## Paso 7. Seleccionar columnas ```r marvelDcInfo <- marvelDcInfo[, c("Name", "Gender", "Race", "Publisher")] head(marvelDcInfo, 3) # Name Gender Race Publisher # 1 A-Bomb Male Human Marvel Comics # 3 Abin Sur Male Ungaran DC Comics # 4 Abomination Male Human / Radiation Marvel Comics ``` --- ## Paso 8. Cambiar formatos en algunas columnas Debemos convertir las columnas `Name`, `Gender`, `Race` y `Publisher` de character a factor. ```r str(marvelDcInfo) # 'data.frame': 585 obs. of 4 variables: # $ Name : chr "A-Bomb" "Abin Sur" "Abomination" "Abraxas" ... # $ Gender : chr "Male" "Male" "Male" "Male" ... # $ Race : chr "Human" "Ungaran" "Human / Radiation" "Cosmic Entity" ... # $ Publisher: chr "Marvel Comics" "DC Comics" "Marvel Comics" "Marvel Comics" ... ``` Para cambiar a factor usamos la funciĆ³n `as.factor()`. ```r marvelDcInfo$Name <- as.factor(marvelDcInfo$Name) marvelDcInfo$Gender <- as.factor(marvelDcInfo$Gender) marvelDcInfo$Race <- as.factor(marvelDcInfo$Race) marvelDcInfo$Publisher <- as.factor(marvelDcInfo$Publisher) ``` --- ## Ejercicios 1) ĀæCuĆ”ntos personajes hay por cada empresa? 2) ĀæCuĆ”ntos personajes son mujeres y hombres hay por cada empresa? 3) ĀæCuĆ”ntas razas hay en el dataframe? 4) ĀæCuĆ”les son las razas predominantes de cada empresa? --- ## Ejercicios 1) ĀæCuĆ”ntos personajes hay por cada empresa? ### OpciĆ³n A ```r summary(marvelDcInfo$Publisher) # DC Comics Marvel Comics # 206 379 ``` ### OpciĆ³n B ```r table(marvelDcInfo$Publisher) # # DC Comics Marvel Comics # 206 379 ``` --- ## Ejercicios 2) ĀæCuĆ”ntos personajes son mujeres y hombres hay por cada empresa? ### DC Comics ```r cat("DC Comics, hombres:", nrow(subset(marvelDcInfo, Publisher == "DC Comics" & Gender == "Male")), "\n") # DC Comics, hombres: 147 cat("DC Comics, mujeres:", nrow(subset(marvelDcInfo, Publisher == "DC Comics" & Gender == "Female")), "\n") # DC Comics, mujeres: 58 ``` ## Marvel ```r cat("Marvel, hombres:", nrow(subset(marvelDcInfo, Publisher == "Marvel Comics" & Gender == "Male")), "\n") # Marvel, hombres: 245 cat("Marvel, mujeres:", nrow(subset(marvelDcInfo, Publisher == "Marvel Comics" & Gender == "Female")), "\n") # Marvel, mujeres: 110 ``` --- ## Ejercicios 3) ĀæCuĆ”ntas razas hay en el dataframe? ### OpciĆ³n A Eliminamos los `NA` que tengamos con `!is.na()`, posteriormente, obtenemos los nombres unicos y medimos. ```r length(unique(marvelDcInfo$Race[!is.na(marvelDcInfo$Race)])) # [1] 48 ``` ### OpciĆ³n B Como esta columna se encuentra en factores, podemos ver el numero de niveles con a funcion `nlevels()`. ```r nlevels(marvelDcInfo$Race) # [1] 48 ``` --- ## Ejercicios 4) ĀæCuĆ”les son las razas predominantes de cada empresa? Podemos usar la funciĆ³n [`sort()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/sort) para ordenar los datos de mayor a menor, usando el argumento `decreasing = TRUE`. La raza ***Human o humana*** es la mas predominante en ambas empresas, seguida de la mutante en el caso de Marvel Comics. ```r head(sort(table(marvelDcInfo$Race), decreasing = TRUE), 10) # # Human Mutant Human / Radiation God / Eternal # 167 58 11 10 # Symbiote Alien Kryptonian Android # 8 7 7 6 # Cyborg Asgardian # 6 5 ``` --- # Guardar variables para la siguiente clase Guardar una sola variable ```r save(marvelDcInfo, file = "Presentaciones/data/marvelDcInfo.RData") ``` Guardar varias variables ```r save(infoStats, infoPowers, marvelDcInfo, file = "Presentaciones/data/Info_data.RData") ``` --- class: center, middle
# Viernes 15 de marzo 2024 ## ManipulaciĆ³n de datos usando dplyr Gracias por tu atenciĆ³n, respira y comĆ©ntame tus dudas.