# Detección de datos perdidos

## El problema de los datos perdidos (missing data)

Uno de los problemas que aparece en el análisis de datos con frecuencia es la existencia de **datos** **faltantes** o **ausentes**, también llamados **datos missing** (en inglés).

Se producen cuando las observaciones de nuestros datos no están completas. La presencia de datos missing en una muestra puede ser debida a numerosas causas:

* Ausencia natural de la información que se busca
* Una observación errónea o dato atípico que habremos convertido en missing en el proceso de detección y tratamiento
* Una falta de respuesta, por ejemplo en una encuesta

Será importante un buen diseño de la muestra para impedir en lo posible esta información faltante. Por ejemplo, si se trabaja con cuestionarios, es fundamental además de elaborarlos adecuadamente, enseñar al personal para que todas las preguntas sean respondidas.&#x20;

## Datos missing en R

**`NA`**&#x20;

Es como se representa en R los datos perdidos o missing. Recuerda que en el [Tema 1 ](https://silvia-pineda.gitbook.io/depuracion-de-datos-tfg3/tema-1-analisis-exploratorio-de-datos/codificacion-y-transformacion#deteccion-inicial-de-errores)vimos que los datos missing pueden estar representados de muchas formas ("99", "Missing", "Unknown", " ") y hay que detectarlos y convertirlos en `NA`&#x20;

```r
5/NA
```

Versiones especiales de **`NA:`**

**`NULL`**

Es un valor reservado en R que se usa para devolver de una expressión o función  si el valor está definido. Por ejemplo si tratamos de recuperar la edad de una persona encuestada que no existe.&#x20;

```
5 / Inf
```

**`NaN`**

Son valores imposibles, por ejemplo cuando fuerzas a R a dividir 0 por 0.

```
0/0
```

**`Inf`**

Representa un valor infinito, como por ejemplo si fuerzas a R a dividir un número por 0&#x20;

```
5 / 0
```

Ejemplo ilustrativo de como esto puede afectar a tus análisis:

```r
z <- c(1,7, 22, NA, Inf, NaN, 5, 8, 10, 15, NA, 12)
max(z)                           # returns NA
max(z, na.rm=T)                  # returns Inf
max(z[is.finite(z)])             # returns 22
```

“NAs introduced by coercion” es un warning común en R. Por ejemplo, si intenta convertir en numérico un vector que tiene caracteres:

```r
as.numeric(c("10", "20", "thirty", "40"))
## Warning message: NAs introduced by coercion
## [1] 10 20 NA 40
```

## Funciones útiles en R

#### <mark style="color:green;">`is.na()`</mark> y <mark style="color:green;">`!is.na()`</mark>

Estas funciones devuelven un valor lógico (`TRUE` or `FALSE`)

```r
my_vector <- c(1, 4, 56, NA, 5, NA, 22)
is.na(my_vector)
## [1] FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE

!is.na(my_vector)
## [1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE

sum(is.na(my_vector))
## [1] 2
```

#### <mark style="color:green;">`na.omit()`</mark>

Esta función quitará los datos *missing*, si lo aplicas a un vector quitará los datos `NA` y si es sobre un data frame quitará las filas donde haya un valor *missing*.

```r
na.omit (my_vector)
## [1]  1  4 56  5 22
## attr(,"na.action")
## [1] 4 6
## attr(,"class")
## [1] "omit"
```

#### <mark style="color:green;">`na.rm = TRUE`</mark>

Cuando se utilizan funciones matemáticas como <mark style="color:green;">**`max()`**</mark><mark style="color:green;">**,**</mark><mark style="color:green;">**&#x20;**</mark><mark style="color:green;">**`min()`**</mark><mark style="color:green;">**,**</mark><mark style="color:green;">**&#x20;**</mark><mark style="color:green;">**`sum()`**</mark> <mark style="color:green;"></mark><mark style="color:green;">or</mark> <mark style="color:green;"></mark><mark style="color:green;">**`mean()`**</mark>si hay valores NA los eliminara para hacer el cálculo

```r
my_vector <- c (1, 4, 56, NA, 5, NA, 22)

mean(my_vector)     
## [1] NA

mean(my_vector, na.rm = TRUE)
## [1] 17.6
```

## Cuantificar y visualizar datos missing en una base de datos&#x20;

Para ello vamos a usar una base de datos de simulación de una **epidemia de Ebola**&#x20;

{% file src="<https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/TaLLz8y8PUYcSOXUEcYT/linelist_cleaned.csv>" %}

y un paquete de R que se llama **`naniar`**

```r
library(naniar)
linelist<-read.csv("linelist_cleaned.csv")
head(linelist)

```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/umovDSgKALLystciPUMF/image.png" alt=""><figcaption></figcaption></figure>

Lo primero que vamos a hacer es trabjar la base de datos como hemos visto en el [Tema 1](https://silvia-pineda.gitbook.io/depuracion-de-datos-tfg3/tema-1-analisis-exploratorio-de-datos/tipos-de-variables)

* Los datos missing no se han leido como NA sino como un dato vacío sin nada " "

```
library (dplyr)
linelist <- mutate_all(linelist, funs(replace(., .=="", NA)))
```

* Las fechas están declaradas como caracteres en vez de formato fecha

```r
linelist$date_infection<-as.Date(linelist$date_infection,format = "%d/%m/%y")
linelist$date_onset<-as.Date(linelist$date_onset,format = "%d/%m/%y")
linelist$date_hospitalisation<-as.Date(linelist$date_hospitalisation,format = "%d/%m/%y")
linelist$date_outcome<-as.Date(linelist$date_outcome,format = "%d/%m/%y")
```

### Cuantificación&#x20;

Para saber el **número** y **porcentaje** de valores que son missing usamos las funciones <mark style="color:green;">**`pct_miss()`**</mark> y <mark style="color:green;">**`n_miss()`**</mark>:

```r
# percent of ALL data frame values that are missing
pct_miss(linelist)
## [1] 6.688745

#Number of missing data
 n_miss(linelist)
 ## [1] 11815

# Percent of rows that are complete (no values missing)  
pct_complete_case(linelist) # use n_complete() for counts
## [1] 30.87636
```

### Visualización&#x20;

Para visualizar los datos missing podemos hace usop de la función <mark style="color:green;">**`gg_miss_var()  o vis_miss()`**</mark>que nos muestra el % de valores missing que hay en cada columna. Con esta función se puede:

```r
gg_miss_var(linelist, show_pct = TRUE)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/jFw1Vj7mTfm4JMp5zIKu/image.png" alt="" width="563"><figcaption></figcaption></figure>

Si queremos visualizar los datos missing por sexo haríamos uso del arguemnto `facet =`

```r
gg_miss_var(linelist, show_pct = TRUE,facet = gender)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/eZ2lnN8zO3rzbzz2kmX1/image.png" alt=""><figcaption></figcaption></figure>

Una cosa interesante que vemos al clasificar los datos por sexo, es que los valores perdidos de la variable edad corresponden a los valores perdidos de la variable sexo.&#x20;

<details>

<summary>Ejercicio</summary>

Representa los datos missing por la variable outcome&#x20;

</details>

You can use `vis_miss()` to visualize the data frame as a heatmap, showing whether each value is missing or not. You can also [`select()`](https://dplyr.tidyverse.org/reference/select.html) certain columns from the data frame and provide only those columns to the function.

```r
# Heatplot of missingness across the entire data frame  
vis_miss(linelist)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/yZrsHGGmzO3hvVA1iS3x/image.png" alt="" width="563"><figcaption></figcaption></figure>

TExploración y visualización de datos missing entre dos variables

¿Cómo visualizamos algo que está perdido? <mark style="color:green;">**`ggplot()`**</mark> por ejemplo elimina las observaciones con valores missing.&#x20;

El paquete **`naniar`** ofrece una solución con <mark style="color:green;">**`geom_miss_point()`**</mark>. Al crear un gráfico de dispersión de dos columnas, los registros con uno de los valores faltantes y el otro valor presente se muestran configurando los valores faltantes en un 10% menos que el valor más bajo en la columna, y se les asigna un color distintivo.

En el gráfico de dispersión a continuación, los puntos rojos representan registros donde el valor de una columna está presente, pero el valor de la otra columna falta. Esto permite visualizar la distribución de los valores faltantes en relación con los valores no faltantes.

```r
library(ggplot2)
ggplot(data = linelist, aes (x = age_years, y = temp)) +       
    geom_miss_point()
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/xVJlsWxPSOX7HzhbZ35J/image.png" alt="" width="563"><figcaption></figcaption></figure>

Para evaluar la ausencia de datos estratificados por otra variable, podemos utilizar <mark style="color:green;">**`gg_miss_fct()`**</mark>, que devuelve un heatmap del porcentaje de datos faltantes según la variable categórica que le digamos:

```r
gg_miss_fct(linelist, age_cat5)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/pmBydqQg66AVkNiDYHzC/image.png" alt="" width="563"><figcaption></figcaption></figure>

Esta función también la podemos usar para ver la evolución de los datos missing en el tiempo si tenemos variables que nos indiquen fechas:

```
gg_miss_fct(linelist, date_onset)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/EtXuDDMrSTGrAEQtTXkr/image.png" alt="" width="563"><figcaption></figcaption></figure>

También se puede hacer uso de la función <mark style="color:green;">**`bind_shadow()`**</mark> para ver la proporción de missing de una variable respecto a la distribución de otra variable. Esta función crea una columna binaria `NA/no_NA` para cada columna existente y une todas estas nuevas columnas al conjunto de datos original con el apéndice `"_NA"`.

```r
shadowed_linelist <- linelist %>% bind_shadow()
names(shadowed_linelist)
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/SOJQPV0OPsUmYrxDZE0f/image.png" alt="" width="563"><figcaption></figcaption></figure>

Con ggplot se puede representar cada variable con su variable\_NA y así ver diferencias en la distribución

```r
ggplot (data = shadowed_linelist,            # data frame with shadow columns
  mapping = aes(x = date_hospitalisation,       # numeric or date column
                colour = age_years_NA)) +   # shadow column of interest
geom_density()                              # plots the density curves
```

<figure><img src="https://content.gitbook.com/content/rM42Q5mZztagDRQM9E7z/blobs/tNnK8oh65aVxjDuGjpet/image.png" alt="" width="563"><figcaption></figcaption></figure>
