Modelos Estadísticos. Grado Biotecnología
Abstract
En este tema introducimos los procedimientos para el tratamiento preliminar de los datos antes de comenzar con el análisis exploratorio necesario para generar conocimiento sobre nuestros datos. Dichos procedimientos consisten en la creación o transformación de nuestras variables como en la selección o filtrado de nuestras observaciones. también veremos como recodificar nuestros factores para una mejor visualización de resultados.Esta unidad mostrará cómo utilizar la visualización y la transformación para explorar los datos de un diseño experimental de una manera sistemática, una tarea que los estadísticos llaman análisis exploratorio de datos, o AED (EDA en inglés) para abreviar. Los contenidos para este tema se han obtenido de Wickham and Grolemund (2016).
EDA es un ciclo iterativo en el que el investigador debe: este caso se irán mezclando los contenidos teóricos con los prácticos para ir mostrando el funcionamiento de las diferentes funciones y procedimientos para el análisis inicial de nuestro banco de datos.
EDA no es un proceso formal con un conjunto estricto de reglas. Más que nada, EDA es un estado mental. Durante las fases iniciales de EDA, debe sentirse libre de investigar cada idea que se le ocurra. Algunas de estas ideas funcionarán, y algunas serán callejones sin salida. A medida que continúe su exploración, se dirigirá a algunas áreas particularmente productivas que eventualmente escribirá y comunicará a otros.
El EDA es una parte importante de cualquier análisis de datos porque siempre debe investigar la calidad de sus datos. La limpieza de datos es solo una aplicación de EDA: el investigador debe hacer preguntas sobre si sus datos cumplen con sus expectativas o no. Para realizar la limpieza de datos, deberá implementar todas las herramientas de EDA: visualización, transformación y modelado.
El objetivo durante EDA es desarrollar una comprensión de los datos experimentales recogidos. La forma más fácil de hacerlo es utilizar preguntas como herramientas para guiar su investigación. Cuando se hace una pregunta, la pregunta centra la atención del investigador en una parte específica del conjunto de datos y le ayuda a decidir qué gráficos, modelos o transformaciones realizar.
EDA es fundamentalmente un proceso creativo. Como la mayoría de los procesos creativos, la clave para hacer preguntas de calidad es generar una gran cantidad de preguntas. Es difícil hacer preguntas reveladoras al comienzo del análisis porque el investigador no sabe qué información contiene su conjunto de datos. Por otro lado, cada nueva pregunta que haga le expondrá a un nuevo aspecto de sus datos y aumentará sus posibilidades de hacer un descubrimiento. Se puede profundizar rápidamente en las partes más interesantes de los datos experimentales recogidos y desarrollar una serie de preguntas que invitan a la reflexión, si se realiza un seguimiento de cada pregunta con una nueva pregunta basada en lo que se encuentre.
No hay una regla sobre qué preguntas se deben hacer para guiar la investigación, ya que debe ser el investigador en función de los objetivos del experimento planteado el que desarrolle dichas preguntas. Sin embargo, dos tipos de preguntas siempre serán útiles para hacer descubrimientos dentro de los datos. Estas preguntas son:
La variabilidad es la tendencia de los valores de una variable a cambiar de medición a medición. Dicha variabilidad se parecía claramente en la vida real; si se mide cualquier variable continua dos veces, se obtendrán dos resultados diferentes. Esto es cierto incluso si se miden cantidades que son constantes, como la velocidad de la luz. Cada una de sus medidas incluirá una pequeña cantidad de error que varía de una medida a otra. Las variables categóricas también pueden variar si se miden diferentes sujetos (por ejemplo, los colores de los ojos de diferentes personas) o en diferentes momentos (por ejemplo, los niveles de energía de un electrón en diferentes momentos). Cada variable tiene su propio patrón de variación, que puede revelar información interesante. La mejor manera de entender ese patrón es visualizar la distribución de los valores de la variable mediante descriptores numéricos o gráficos.
Si la variación describe el comportamiento dentro de una variable, la covariación describe el comportamiento entre las variables. La covariación es la tendencia de los valores de dos o más variables a variar juntas de una manera relacionada. La mejor forma de detectar la covariación es visualizar la relación entre dos o más variables. Cómo hacer eso nuevamente debería depender del tipo de variables involucradas.
La descripción numérica y la visualización gráfica son las herramientas más importantes en los pasos iniciales para la generación de conocimiento sobre los datos experimentales, pero en ocasiones los datos no son recogidos en la forma más efectiva para realizar dichos análisis. A menudo se necesitara crear algunas variables o resúmenes nuevos, o tal vez solo se quiera cambiar el nombre de las variables o reordenar las observaciones para facilitar el trabajo de los datos. En este tema aprenderemos cómo hacer todo eso. Para ejemplificar los procedimientos utilizaremos el conjunto de datos flights
contenido en la librería nycflights13
, que contiene toda la información sobre los vuelos que salieron desde la ciudad de Nueva York en 2013.
Recuerda que debes instalar dicha librería antes de poder reproducir todo los procedimiento que mostramos en las secciones siguientes.
Instalamos la librería (junto con todas las necesarias para la asignatura) y cargamos los datos para poder visualizarlos:
library(tidyverse)
library(stringr)
library(forcats)
library(lubridate)
library(magrittr)
library(broom)
library(datasets)
library(nycflights13)
Visualizamos los primeras 10000 observaciones del banco de datos
flights
Las variables que contiene este banco de datos (336776 observaciones = vuelos) son:
En la cabecera del conjunto de datos se aprecia además el tipo de variable asignada. Los tipos de variables que se admiten en R son: int
para enteros, dbl
para números reales, chr
para vectores de caracteres o cadenas, dttm
para fechas-tiempos (una fecha + una hora), lgl
para vectores lógicos que solo contienen VERDADERO o FALSO, fctr
para factores (que R usa para representar variables categóricas con valores posibles fijos), y date
para fechas.
Los procedimientos para el trabajo con los sujetos de nuestra muestra se reducen al filtrado u ordenación, para quedarnos con un subconjunto de sujetos o para organizar su visualización en otra forma.
Usamos el filtrado para seleccionar un subconjunto de observaciones del data.frame que contiene nuestros datos. Esto se hace a menudo cuando queremos limitar un análisis a un subconjunto de observaciones. El uso básico del filtro se hace mediante la función filter()
:
filter(data_set, <expression1>, <expression2>, ...)
donde data_set
es el nombre del objeto que contiene nuestros datos y <expression1>, <expression2>,...
son uno o más argumentos adicionales, donde cada uno de estos es una expresión de R válida que implica una o más condiciones a aplicar sobre las variables del conjunto de datos. Cada expresión se interpreta como una condición lógica (verdadero o falso).
Para usar el filtrado de manera efectiva, se debe saber cómo seleccionar las observaciones que se desea utilizando los operadores de comparación. R proporciona el paquete estándar: >
(mayor que), >=
(mayor o igual que), <
(menor que), <=
(menor o igual que), !=
(no igual a), y ==
(igual a).
Veamos diferentes posibilidades de filtrado sobre el banco de datos flights
. En primer lugar filtramos todos los vuelos cuya día de origen sea el 1 de enero de 2013
filter(flights, month == 1, day == 1)
El resultado es un conjunto de datos con 842 observaciones donde aparece la información de dichos vuelos. Si queremos almacenar el resultado para un trabajo posterior podemos asignarlo a un nuevo objeto
jan1 <- filter(flights, month == 1, day == 1)
str(jan1) # La función str() nos da la estructura del banco de datos resultante (número de variables y observaciones, así como una muestra de los datos para cada variable)
## Classes 'tbl_df', 'tbl' and 'data.frame': 842 obs. of 19 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_time : int 517 533 542 544 554 554 555 557 557 558 ...
## $ sched_dep_time: int 515 529 540 545 600 558 600 600 600 600 ...
## $ dep_delay : num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_time : int 830 850 923 1004 812 740 913 709 838 753 ...
## $ sched_arr_time: int 819 830 850 1022 837 728 854 723 846 745 ...
## $ arr_delay : num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ carrier : chr "UA" "UA" "AA" "B6" ...
## $ flight : int 1545 1714 1141 725 461 1696 507 5708 79 301 ...
## $ tailnum : chr "N14228" "N24211" "N619AA" "N804JB" ...
## $ origin : chr "EWR" "LGA" "JFK" "JFK" ...
## $ dest : chr "IAH" "IAH" "MIA" "BQN" ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ hour : num 5 5 5 5 6 5 6 6 6 6 ...
## $ minute : num 15 29 40 45 0 58 0 0 0 0 ...
## $ time_hour : POSIXct, format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
Podemos combinar diferentes condiciones de filtrado mediante los operadores lógicos &
es “y” (condición 1 y condición 2), |
es “o” (condición 1 o condición 2).
Queremos seleccionar ahora todos los vuelos con mes de origen igual a Noviembre o Diciembre
nov_dec <- filter(flights, month == 11 | month == 12)
dim(nov_dec) # Para saber cuantas observaciones contiene el banco de datos filtrado
## [1] 55403 19
Los datos filtrados contienen la información completa de 55403 vuelos. Otra forma de conseguir el mismo resultado es con el operador %in%
nov_dec <- filter(flights, month %in% c(11, 12))
dim(nov_dec)
## [1] 55403 19
A veces se pueden simplificar condiciones de filtrado más complicadas sin más que recordar la ley de De Morgan: !(x & y) es lo mismo que
!x | !y, y
!(x | y)es lo mismo que
!x & !y`. Por ejemplo, si se desean obtener todos vuelos que no se retrasaron (en llegada o partida) en más de dos horas, se pueden usar cualquiera de los dos filtros siguientes:
db_sel1 <- filter(flights, !(arr_delay > 120 | dep_delay > 120))
dim(db_sel1)
## [1] 316050 19
db_sel2 <- filter(flights, arr_delay <= 120, dep_delay <= 120)
dim(db_sel2)
## [1] 316050 19
Otro procesamiento muy habitual con los sujetos es reordenar las filas de un objeto que contiene nuestros datos. Esto se usa cuando queremos inspeccionar un conjunto de datos para buscar asociaciones entre las diferentes variables, lo que resulta difícil de hacer si no están ordenados. Para realizar la ordenación se utiliza la función arrange()
. El uso básico de la función es:
arrange(data_set, varname1, varname2, ...)
donde data_set
es el nombre del objeto que contiene nuestros datos y varname1, varname2,...
son las variables que vamos a utilizar para la ordenación. Por ejemplo deseamos ordenar nuestro datos siguiendo el orden año, mes y día:
dbf_ord1 <- arrange(flights, year, month, day)
str(dbf_ord1)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 19 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_time : int 517 533 542 544 554 554 555 557 557 558 ...
## $ sched_dep_time: int 515 529 540 545 600 558 600 600 600 600 ...
## $ dep_delay : num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_time : int 830 850 923 1004 812 740 913 709 838 753 ...
## $ sched_arr_time: int 819 830 850 1022 837 728 854 723 846 745 ...
## $ arr_delay : num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ carrier : chr "UA" "UA" "AA" "B6" ...
## $ flight : int 1545 1714 1141 725 461 1696 507 5708 79 301 ...
## $ tailnum : chr "N14228" "N24211" "N619AA" "N804JB" ...
## $ origin : chr "EWR" "LGA" "JFK" "JFK" ...
## $ dest : chr "IAH" "IAH" "MIA" "BQN" ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ hour : num 5 5 5 5 6 5 6 6 6 6 ...
## $ minute : num 15 29 40 45 0 58 0 0 0 0 ...
## $ time_hour : POSIXct, format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
Podemos introducir la función desc()
para ordenar de forma descendente por la variable seleccionada. Ordenamos nuestros datos (de mayor a menor) por la demora en el tiempo de llegada:
dbf_ord2 <- arrange(flights, desc(arr_delay))
str(dbf_ord2)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 19 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 6 1 9 7 4 3 7 12 5 ...
## $ day : int 9 15 10 20 22 10 17 22 5 3 ...
## $ dep_time : int 641 1432 1121 1139 845 1100 2321 2257 756 1133 ...
## $ sched_dep_time: int 900 1935 1635 1845 1600 1900 810 759 1700 2055 ...
## $ dep_delay : num 1301 1137 1126 1014 1005 ...
## $ arr_time : int 1242 1607 1239 1457 1044 1342 135 121 1058 1250 ...
## $ sched_arr_time: int 1530 2120 1810 2210 1815 2211 1020 1026 2020 2215 ...
## $ arr_delay : num 1272 1127 1109 1007 989 ...
## $ carrier : chr "HA" "MQ" "MQ" "AA" ...
## $ flight : int 51 3535 3695 177 3075 2391 2119 2047 172 3744 ...
## $ tailnum : chr "N384HA" "N504MQ" "N517MQ" "N338AA" ...
## $ origin : chr "JFK" "JFK" "EWR" "JFK" ...
## $ dest : chr "HNL" "CMH" "ORD" "SFO" ...
## $ air_time : num 640 74 111 354 96 139 167 109 149 112 ...
## $ distance : num 4983 483 719 2586 589 ...
## $ hour : num 9 19 16 18 16 19 8 7 17 20 ...
## $ minute : num 0 35 35 45 0 0 10 59 0 55 ...
## $ time_hour : POSIXct, format: "2013-01-09 09:00:00" "2013-06-15 19:00:00" ...
En el resumen de los datos presentados se pueden apreciar las diferencia entre los datos ordenados de una u otra forma.
Los procedimientos para el trabajo con las variables de nuestra muestra se reducen a la selección de un subconjunto de variables, la creación de nuevas variables, el renombrado de variables, y la recodificación en nuevas variables.
Usamos la función select()
para seleccionar un subconjunto de variables de nuestro banco de datos. Esto función se usa cuando tenemos un conjunto de datos con muchas variables, pero solo necesitamos trabajar con un subconjunto de ellas. La función tiene la estructura:
select(data_set, varname1, varname2, ...)
El primer argumento, data_set
, es el nombre del objeto que contiene nuestros datos. A continuación incluimos una serie de uno o más argumentos adicionales, donde cada uno es el nombre de una o más variables en el conjunto de datos. Estas son las variables que aparecerán en el nuevo banco de datos.
Para el conjunto de datos flights
vamos a seleccionar las variables year
, month
, y day
.
dbf_sel1 <- select(flights, year, month, day)
str(dbf_sel1)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 3 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month: int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
A veces es más conveniente establecer la selección especificando aquellas que no necesitamos, en lugar de especificar cuáles guardar. Usamos el operador -
para indicar que variables deben ser eliminadas.
dbf_sel2 <- select(flights, -(year:day)) # NO seleccionamos las varaibles que se encuentran entre las variables year y day
str(dbf_sel2)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 16 variables:
## $ dep_time : int 517 533 542 544 554 554 555 557 557 558 ...
## $ sched_dep_time: int 515 529 540 545 600 558 600 600 600 600 ...
## $ dep_delay : num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_time : int 830 850 923 1004 812 740 913 709 838 753 ...
## $ sched_arr_time: int 819 830 850 1022 837 728 854 723 846 745 ...
## $ arr_delay : num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ carrier : chr "UA" "UA" "AA" "B6" ...
## $ flight : int 1545 1714 1141 725 461 1696 507 5708 79 301 ...
## $ tailnum : chr "N14228" "N24211" "N619AA" "N804JB" ...
## $ origin : chr "EWR" "LGA" "JFK" "JFK" ...
## $ dest : chr "IAH" "IAH" "MIA" "BQN" ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ hour : num 5 5 5 5 6 5 6 6 6 6 ...
## $ minute : num 15 29 40 45 0 58 0 0 0 0 ...
## $ time_hour : POSIXct, format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
Cuando las variables que deseamos eliminar no se muestran de forma consecutiva en nuestro banco de datos podemos utilizar una expresión equivalente
dbf_sel3 <- select(flights, -c(year,month,day))
str(dbf_sel3)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 16 variables:
## $ dep_time : int 517 533 542 544 554 554 555 557 557 558 ...
## $ sched_dep_time: int 515 529 540 545 600 558 600 600 600 600 ...
## $ dep_delay : num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_time : int 830 850 923 1004 812 740 913 709 838 753 ...
## $ sched_arr_time: int 819 830 850 1022 837 728 854 723 846 745 ...
## $ arr_delay : num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ carrier : chr "UA" "UA" "AA" "B6" ...
## $ flight : int 1545 1714 1141 725 461 1696 507 5708 79 301 ...
## $ tailnum : chr "N14228" "N24211" "N619AA" "N804JB" ...
## $ origin : chr "EWR" "LGA" "JFK" "JFK" ...
## $ dest : chr "IAH" "IAH" "MIA" "BQN" ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ hour : num 5 5 5 5 6 5 6 6 6 6 ...
## $ minute : num 15 29 40 45 0 58 0 0 0 0 ...
## $ time_hour : POSIXct, format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
En la creación de variables a partir de las originales en nuestros datos tenemos dos opciones: i) crear una nueva variable sin eliminar las variables originales, ii) crear una nueva variable eliminando las variables originales.
Usamos la función mutate()
para crear nuevas variables en nuestro banco de datos sin eliminar las variables que forman parte de la nueva variable. La función tiene la estructura:
mutate(data_set, <expression1>, <expression2>, ...)
El primer argumento, data_set
, es el nombre del objeto que contiene nuestros datos. A continuación incluimos una serie de uno o más argumentos adicionales, donde cada uno es la expresión para la nueva o nuevas variables.
Veamos un ejemplo de uso de la función
dbf_sel4 <- select(flights, c(year,month,day,dep_delay,arr_delay,distance,air_time)) # Seleccionamos un subconjunto de las variables originales
str(dbf_sel4)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 7 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_delay: num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_delay: num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
# Creamos una varaible que indica la reducción de demora entre salida y llegada
# Calculamos la velocidad del viaje
dbf_new <- mutate(dbf_sel4,
gain = arr_delay - dep_delay,
speed = distance / air_time * 60
)
str(dbf_new)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 9 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_delay: num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_delay: num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ gain : num 9 16 31 -17 -19 16 24 -11 -5 10 ...
## $ speed : num 370 374 408 517 394 ...
Podemos ver que se han añadido las dos variables en el nuevo banco de datos que se ha creado.
Una ventaja de esta función es que resulta posible crear nuevas variables a partir de las nuevas creadas
dbf_new2 <- mutate(dbf_sel4,
gain = arr_delay - dep_delay,
hours = air_time / 60,
gain_per_hour = gain / hours
)
str(dbf_new2)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 10 variables:
## $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_delay : num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_delay : num 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ distance : num 1400 1416 1089 1576 762 ...
## $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
## $ gain : num 9 16 31 -17 -19 16 24 -11 -5 10 ...
## $ hours : num 3.78 3.78 2.67 3.05 1.93 ...
## $ gain_per_hour: num 2.38 4.23 11.62 -5.57 -9.83 ...
Usamos la función transmute()
para crear un banco de datos donde solo aparecen las nuevas variables creadas. La estructura de la función es idéntica a la de la función mutate()
.
dbf_new3 <- transmute(dbf_sel4,
gain = arr_delay - dep_delay,
hours = air_time / 60,
gain_per_hour = gain / hours
)
str(dbf_new3)
## Classes 'tbl_df', 'tbl' and 'data.frame': 336776 obs. of 3 variables:
## $ gain : num 9 16 31 -17 -19 16 24 -11 -5 10 ...
## $ hours : num 3.78 3.78 2.67 3.05 1.93 ...
## $ gain_per_hour: num 2.38 4.23 11.62 -5.57 -9.83 ...
El listado de funciones que podemos usar con las funciones mutate()
y transmute()
son:
+
, -
, *
, /
, ^
log()
, log2()
, log10()
cumsum()
(suma acumulada), cumprod()
(producto acumulado), cummin()
(mínimo acumulado), cummax()
(máximo acumulado), cummean()
(media acumulada).<
, <=
, >
, >=
, !=
La creación de variables tipo factor es un aspecto muy importante en el análisis de datos. Existen tres formas principales de conseguir variables de tipo factor:
Por el momento solo mostraremos las opciones 1 y 2. La función utilizada para estas operaciones es fct_recode()
cuya estructura viene dada por:
fct_recode(varfactor, levelnew1=levelold1, levelnew2=levelold2, ...)
donde varfactor
es la variable factor original, levelnew
son los niveles del factor recodificados y levelold
son los niveles del factor en la variable original.
Vamos a ver un ejemplo de su uso sobre el banco de datos NCBIRTH800 que presentamos en la unidad anterior. Cargamos los datos desde el repositorio y vemos su estructura:
NCBIRTH800=read_csv("https://goo.gl/mB9Jcn", col_types = "dcddcccdccddcc")
En esta base de datos hay varias variables que se han recogido como carácter (aunque se les ha asignado un código numérico). A continuación se presentan dichas variables así como la asignación de valor a cada uno de los códigos numéricos:
sex: "male" = 1,"female" = 2
marital: "married" = 1,"not married" = 2
racemom: "other non white" = 0, "White" = 1,"Black" = 2,"America indian" = 3,"Chinese" = 4,"Hawaiian" = 5,"Filipino" = 6,"Other asian" = 7, "Other" = 8
hispmom: "Cuban" = C, "Mexican" = M, "Non-Hispanic" = N ,"Other" = O,"Puerto Rican" = P, "Central/South american" = S,"U" = Not classificable
smoke: "Yes"=1, "No" = 0
drink: "Yes" = 1 ,"No" = 0
low: "Yes" = 1, "No" = 0
premie: "Yes"= 1, "No" = 0
Realizamos la asignación de los valores
NCBIRTHnew <- mutate(NCBIRTH800,
sex = fct_recode(sex,"male" = "1","female" = "2"),
marital = fct_recode(marital,"married" = "1","not married" = "2"),
racemom = fct_recode(racemom,"other non white" = "0","White" = "1","Black" = "2","America indian" = "3","Chinese" = "4","Hawaiian" = "5","Filipino" = "6","Other asian" = "7","Other" = "8"),
hispmom = fct_recode(hispmom,"Cuban" = "C","Mexican" = "M","Non-Hispanic" = "N","Other" = "O","Puerto Rican" = "P","Central/South american" = "S","U" = "Not classificable"),
smoke = fct_recode(smoke,"Yes" = "1","No" = "0"),
drink = fct_recode(drink,"Yes" = "1","No" = "0"),
low = fct_recode(low,"Yes" = "1","No" = "0"),
premie = fct_recode(premie,"Yes" = "1","No" = "0"))
NCBIRTHnew
En el resultado se aprecia la modificación de los diferentes factores.
Un problema bastante común que parece en la recogida de datos experimentales es que los nombres de las columnas de la base de datos no es una variable en si, sino los valores de una variable. Si tomamos como ejemplo el banco de datos PCKDATA
.
PCKDATA = read_csv("https://goo.gl/W8Bfgv", col_types = "idd")
PCKDATA
Como se puede ver aparecen dos columnas indicando el tratamiento del sujeto, es decir, cada fila no identifica a un único sujeto. Por ese motivo en cada una de ellas aparece el valor del nivel de creatinina. Para poder trabajar de forma óptima cada fila debe contener la información única de cada sujeto. En este caso cada fila contiene la información de dos sujetos: el identificado como 1 en el tratamiento A y el identificado como 1 en el tratamiento B.
La función gather()
nos permite reorganizar los datos de un banco de datos de forma muy sencilla. La estructura básica de la función es:
gather(data_set,var, key = "key", value = "value", ...)
donde data_set
es el banco de datos, var es el conjunto de variables que reorganizamos, key
es el nombre de la variable donde reorganizamos las variables anteriores, y value
es el nombre de la variable donde almacenamos los valores de respuesta. Para el conjunto de datos anterior tenemos:
gather(PCKDATA,`A`,`B`, key = "Grupo", value = creatine)
Podemos ver que se han reorganizado las filas de la base de datos. De hecho se han duplicado el número de filas (hemos ampliado dos variables) y ahora cada columna identifica claramente la información de un sujeto.
Wickham, Hadley, and Garrett Grolemund. 2016. R for Data Science. O’Reilly.
Copyright © 2018 Javier Morales. Universidad Miguel Hernández de Elche.