Carga del archivo de datos y breve descripción

Al abrir el archivo con un editor de texto sencillo como el bloc de notas o el wordpad para Windows, o gedit o VIM para Linux, se puede ver que “,” es el símbolo separador y el punto corresponde al valor decimal. Por lo tanto, hay que leer el fichero con la función read.csv().

Los datos a tratar corresponden a una investigación médica orientada a estudiar la capacidad pulmonar de las personas en función de si eran fumadoras o no. A cada persona se le preguntó, a través de un cuestionario, su género, edad, hábitos de deporte, la ciudad de residencia, si era fumadora, y en caso de que lo fuera, cuántos cigarrillos al día de promedio fumaba y los años que hacía que fumaba. Además, se midió el peso, la altura y la capacidad pulmonar a partir de un test de aire expulsado, desde donde se tomó como capacidad pulmonar la medida FEF (forced expiratory flow), que es la velocidad del aire saliendo del pulmón durante la porción central de una espiración forzada. Se mide en litros / segundo.

El archivo se denomina Fumadores_raw.csv, contiene 300 registros y 9 variables. Estas variables son: Sex, Sport, Years, Cig, PC, City, Weight, Age, Height

Puedes decargar la información de la la siguiente url Fumadores_raw.csv


2 Indicar el tipo de variable estadística de cada una de las variables


# factor
var.factor <- c(1,2,6)
var.integer <- 3:4
var.numeric <- c(5,7,8,9)
var.tipus <- vector(mode="character",length=ncol(mydata))
var.tipus[var.factor] <- "factor"
var.tipus[var.integer] <- "integer"
var.tipus[var.numeric] <- "numeric"

Son variables cualitativas nominales: Sex, City

Son variables cualitativas ordinales: Sport

Son variables cuantitativas discretas: Years, Cig

Son variables cuantitativas continuas: PC, Weight, Age, Height


3 Asignar a cada variable el tipo de variable R adecuada


La lectura del fichero con la función read.csv() ha realizado la seguiente asignación a cada variable

res <- sapply(mydata,class)
kable(data.frame(variables=names(res),clase=as.vector(res)))
variablesclase
Sexfactor
Sportinteger
Yearsinteger
Ciginteger
PCfactor
Cityfactor
Weightinteger
Ageinteger
Heightinteger
var_wrong <- n.var[res != var.tipus]

Per tanto, las variables con asignación equivocada y que es necesario corregir son: Sport, PC, Weight, Age, Height

La asignación a realizar es:

kable(data.frame(variables= var_wrong, clase= c("factor","numeric", "numeric", "numeric", "numeric")))
variablesclase
Sportfactor
PCnumeric
Weightnumeric
Agenumeric
Heightnumeric

3.1 Transformar la variable Sport a tipo factor


Sólo es necesario utilizar la función factor() o ordered() con la codificación adecuada de acuerdo al criterio: 1 igual a N, 2 igual a S, 3 igual a R y 4 igual a E.

mydata[,var_wrong[1]] <- factor(mydata[,var_wrong[1]], levels= c(1,2,3,4), labels= c("N","S","R","E"))

table(mydata[,var_wrong[1]])
##
##   N   S   R   E
## 127  83  48  42

Ahora podemos verificar que la variable Sport es del tipo factor.


3.2 Corregir errores de las variables cuantitativas con confusión de separador decimal


Las variables que tienen confusión con el separador decimal son PC.

Ahora se cambiarán las “,” por el valor “.”, el sumario de los valores de las variables es:

#Change "," to ".""
i <- 2
mydata[,var_wrong[i]] <-  as.numeric( sub(",","\\.",mydata[,var_wrong[i]]) )

summary(mydata[,var_wrong[i]])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's
##   1.557   2.913   3.554   3.332   3.794   4.466       2

Ahora podemos verificar que la variable PC es del tipo numeric.


3.3 Convertir las variables Age, Weight y Height en tipo numérico


Sólo hace falta utilizar la función as.numeric()

for (i in 3:5) {
          mydata[,var_wrong[i]] <- as.numeric(mydata[,var_wrong[i]])
}

Ahora podemos verificar que las variables Weight, Age, Height son del tipo numeric, numeric, numeric, respectivamente.


4 Normalizar / Estandarizar variables cuantitativas


La precisión para analitar la variable PC no requiere un número tan grande de decimales. Por tanto, redondeamos los valores a 3 cifras decimales.

mydata[,5] <- round(mydata[,5],3)

Para comprobar si se han efectuado bien los cambios se listan 6 valores:

mydata[1:6,5]
## [1] 2.579 1.557    NA 2.762 3.487 4.075

5 Normalizar/Estandarizar variables cualitativas


5.1 Genero

El primer paso es mostrar la tabla con los valores de los diferentes generos registrados y sus frecuencias. De esta manera se pueden observar si existen algunos problemas.

table(mydata$Sex)
##
##      f      F   f      F         m      M   m      M         f      F
##      6     18      2      9      5     23      4      8     24     54
##   f      F         m      M   m      M
##      5     19     19     76     10     18

Se observa que es necesario estandarizar la variable. Se muestra el resultado de cada fase:

  1. Eliminar espacios antes y después de cada valor observado. El resultado es:
# Treure espais abans i després
kk <- trimws( mydata$Sex )
table(kk )
## kk
##   f   F   m   M
##  37 100  38 125
  1. Pasar a mayúsculas los valores observados. El resultado es:
# change  upper
kk <- toupper(kk)
table(kk)
## kk
##   F   M
## 137 163
# Update
mydata$Sex <-as.factor(kk)

5.2 Sport

Ya ha sido normalizada en el paso 3.1

5.3 City

El primer paso es mostrar la tabla con los valores de las diferentes ciudades registradas y sus frecuencias. De esta manera se pueden observar si existe algunos problemas.

table(mydata$City)
##
##                 alcanar                     barcelona
##                          1                          3
##                  Barcelona               barcelona
##                         12                          2
##               Barcelona                        blanes
##                          6                          2
##                  Blanes                       Cardona
##                          1                          1
##                 Cardona                        Girona
##                          1                          3
##                  girona                     Girona
##                          1                          1
##                  La Bisbal                     lleida
##                          2                          1
##                  lleida                     Lleida
##                          1                          2
##                    Montgat              Pineda de Mar
##                          1                          1
##           Pineda de Mar                     Puigcerda
##                          1                          2
##                     Ripoll      Sant Boi de Llobregat
##                          1                          2
##   Sant Boi de Llobregat                     Sitges
##                          1                          2
##                    solsona                  Tarragona
##                          1                          3
##                   terrassa                   Terrassa
##                          3                          6
##                terrassa                   Terrassa
##                          1                          4
##                      Tossa                      valls
##                          2                          2
##                      Valls                    alcanar
##                          2                          2
##                    Alcanar                 Alcanar
##                          8                          1
##                  barcelona                  Barcelona
##                         10                         57
##               barcelona                  Barcelona
##                          4                          8
##                     blanes                     Blanes
##                          2                          4
##                  Blanes                      Cadaques
##                          2                          2
##                   cardedeu                   Cardedeu
##                          1                          2
##                    cardona                    Cardona
##                          2                          2
##                     girona                     Girona
##                          2                          1
##                  Girona                     la bisbal
##                          2                          2
##                  La Bisbal                     lleida
##                          3                          1
##                     Lleida                  Lleida
##                          7                          1
##                    montgat                    Montgat
##                          1                          2
##                 montgat                    Montgat
##                          1                          1
##              Pineda de Mar           Pineda de Mar
##                          5                          4
##               puigcerda                        ripoll
##                          1                          1
##                     Ripoll                  Ripoll
##                          2                          2
##      sant boi de llobregat      Sant Boi de Llobregat
##                          2                          5
##   Sant Boi de Llobregat                        sitges
##                          2                          3
##                     Sitges                  sitges
##                          5                          2
##                  Sitges                       Solsona
##                          1                          2
##                 solsona                    Solsona
##                          1                          1
##                  tarragona                  Tarragona
##                          5                          2
##               tarragona                  Tarragona
##                          2                          2
##                   terrassa                   Terrassa
##                          5                         18
##                terrassa                   Terrassa
##                          1                          4
##                   tossa                      Tossa
##                          2                          3
##                      valls                      Valls
##                          3                          6
##                   valls                      Valls
##                          1                          1

Se observa que hay estandarizar la variable. Se muestra el resultado de cada fase:

  1. Quitar espacios antes y después de cada valor observado. El resultado es:
# Treure espais abans i després
kk <- trimws( mydata$City )
table(kk )
## kk
##               alcanar               Alcanar             barcelona
##                     3                     9                    19
##             Barcelona                blanes                Blanes
##                    83                     4                     7
##              Cadaques              cardedeu              Cardedeu
##                     2                     1                     2
##               cardona               Cardona                girona
##                     2                     4                     3
##                Girona             la bisbal             La Bisbal
##                     7                     2                     5
##                lleida                Lleida               montgat
##                     3                    10                     2
##               Montgat         Pineda de Mar             puigcerda
##                     4                    11                     1
##             Puigcerda                ripoll                Ripoll
##                     2                     1                     5
## sant boi de llobregat Sant Boi de Llobregat                sitges
##                     2                    10                     5
##                Sitges               solsona               Solsona
##                     8                     2                     3
##             tarragona             Tarragona              terrassa
##                     7                     7                    10
##              Terrassa                 tossa                 Tossa
##                    32                     2                     5
##                 valls                 Valls
##                     6                     9
  1. Pasar a formato título los valores observados. El resultado es:
# change  str_to_title
kk <- str_to_title(kk)
table(kk)
## kk
##               Alcanar             Barcelona                Blanes
##                    12                   102                    11
##              Cadaques              Cardedeu               Cardona
##                     2                     3                     6
##                Girona             La Bisbal                Lleida
##                    10                     7                    13
##               Montgat         Pineda De Mar             Puigcerda
##                     6                    11                     3
##                Ripoll Sant Boi De Llobregat                Sitges
##                     6                    12                    13
##               Solsona             Tarragona              Terrassa
##                     5                    14                    42
##                 Tossa                 Valls
##                     7                    15
  1. Cambiamos la preposición “De” a minúsculas “de”
kk <- sub("De","de",kk)
# Update
mydata$City <-as.factor(kk)

Para comprobar los cambios se presenta la tabla de frecuencias.

table(mydata$City)
##
##               Alcanar             Barcelona                Blanes
##                    12                   102                    11
##              Cadaques              Cardedeu               Cardona
##                     2                     3                     6
##                Girona             La Bisbal                Lleida
##                    10                     7                    13
##               Montgat         Pineda de Mar             Puigcerda
##                     6                    11                     3
##                Ripoll Sant Boi de Llobregat                Sitges
##                     6                    12                    13
##               Solsona             Tarragona              Terrassa
##                     5                    14                    42
##                 Tossa                 Valls
##                     7                    15

6 Revisar posibles inconsistencias entre variables:

6.1 Years vs Cig

La inconsistencia entre las variables Years vs Cig se produce cuando un individuo no fumador (Years = 0) responde que fuma algún cigarrillo (Cig> 0) o también, cuando un individuo fumador (Years> 0) responde que no fuma ningún cigarrillo (Cig = 0). El criterio de corrección es asignar a las dos variables, Years y Cig, el valor de cero.

6.1.1 Caso (Years = 0) y (Cig > 0)

# find wrong values
kk <- which(mydata$Years== 0 & mydata$Cig > 0)

Han aparecido 21 individuos con esta inconsistencia. Los registros son: 9, 11, 17, 41, 60, 82, 90, 91, 103, 113, 129, 131, 132, 176, 181, 183, 257, 264, 266, 276, 298

Y los valores inconsistentes son:

kable(t(mydata[kk,3:4]))
911174160829091103113129131132176181183257264266276298
Years000000000000000000000
Cig155131211233253355312

El siguiente paso es corregirlo:

# posar 0 al valors de Cig

mydata[kk,4] <- 0

6.1.2 Caso (Years > 0) y (Cig = 0)

# find wrong values
kk <- which(mydata$Years > 0 & mydata$Cig == 0)

Han aparecido 21 individuos con esta inconsistencia. Los registros son: 35, 69, 83, 85, 106, 107, 124, 138, 139, 143, 157, 189, 193, 205, 213, 220, 233, 234, 262, 263, 295

Y los valores inconsistentes son:

kable(t(mydata[kk,3:4]))
35698385106107124138139143157189193205213220233234262263295
Years555353515225311242434
Cig000000000000000000000

El siguiente paso es corregirlo:

# posar 0 al valors de Cig

mydata[kk,3] <- 0

Como comprobación final se presenta la tabla siguiente:

table( mydata[,3]==0, mydata[,4]==0)
##
##         FALSE TRUE
##   FALSE   131    0
##   TRUE      0  169

7 Buscar valores atípicos en variables cuantitativas

Se presenta un boxplot de cada variable cuantitativa. Además se realiza una tabla con las estimaciones robustas y no robustas de tendencia central y dispersión para cada variable cuantitativa.

res <- sapply(mydata,class)
res <- which(res=="numeric")

7.1 Presentar un boxplot para cada variable cuantitativa

Se muestran los boxplots de las variables Years, Cig, PC, Weight, Age, Height

par(mfrow=c(2,2))
for (i in 1:4){
            boxplot(mydata[,res[i]], main=names(mydata)[res[i]],col="gray")
}
Boxplot

Boxplot

par(mfrow=c(1,1))
par(mfrow=c(1,2))
for (i in 5:6){
            boxplot(mydata[,res[i]], main=names(mydata)[res[i]],col="gray")
}
Boxplot

Boxplot

par(mfrow=c(1,1))

Aún que se observan algunos valores atípicos en los boxplots de las variables Years y Cig podemos considerar que son un artefacto debido a que hay dos grupos de datos: ceros y diferentes de cero, con una proporción similar.

Ahora se presentan los valores atípicos del resto de las variables cuantitativas:

# Outlier values
vars.cuantitativas <- res[-c(1,2)]
for(i in 1:length(vars.cuantitativas) ) {
            # i <- 1
  #print(boxplot.stats(mydata[,i])$out)
  indices <- which(mydata[,vars.cuantitativas[i]]  %in%  boxplot.stats(mydata[,vars.cuantitativas[i]])$out)
  cat(names(mydata)[vars.cuantitativas[i]],":", toString(indices), "\n" )
  }
PC : 2
Weight : 9, 11, 13, 14, 21, 34, 48, 53, 61, 94, 104, 110, 125, 133, 147, 180, 207, 213, 222, 267
Age : 247, 254
Height :  

La variable que tiene un mayor número valores atípicos es Weight y claramente fuera de las magnitudes lógicas para pesos de personas expresadas en Kg. Esto hace pensar que se trate de un error, tal como se indica en el enunciado. Posiblemente se trate de un cambio de unidades de medida, en lugar de kg están medidos en gramos. El resto de variables presentan valores atípicos que no se pueden considerar erróneos.

Pasemos a corregir los valores erroneos de la variable Weight:

i <- 2

indices <- which(mydata[,vars.cuantitativas[i]]  %in%  boxplot.stats(mydata[,vars.cuantitativas[i]])$out)

mydata[indices, vars.cuantitativas[i]] <- mydata[indices, vars.cuantitativas[i]]/1000

Ahora se comprueba con un boxplot los cambios efectuados:

boxplot(mydata[,vars.cuantitativas[i]], main=names(mydata)[vars.cuantitativas[i]],col="gray")

7.2 Tabla de las estimaciones de tendencia central y dispersión (robustas y no robustas) para cada variable cuantitativa

mean.n <- as.vector(sapply( mydata[,res ],mean,na.rm=TRUE ) )
std.n <- as.vector(sapply(mydata[,res ],sd, na.rm=TRUE))
median.n <- as.vector(sapply(mydata[,res],median, na.rm=TRUE))
mean.trim.0.05 <- as.vector(sapply(mydata[,res],mean, na.rm=TRUE, trim=0.05))
mean.winsor.0.05 <- as.vector(sapply(mydata[,res],winsor.mean, na.rm=TRUE,trim=0.05))
IQR.n <- as.vector(sapply(mydata[,res],IQR, na.rm=TRUE))
mad.n <- as.vector(sapply(mydata[,res],mad, na.rm=TRUE))


kable(data.frame(variables= names(mydata)[res],
                 Media = mean.n,
                 Mediana = median.n,
                 Media.recort.0.05= mean.trim.0.05,
                 Media.winsor.0.05= mean.winsor.0.05
                 ),
      digits=2, caption="Estimaciones de Tendencia Central")
Estimaciones de Tendencia Central
variablesMediaMedianaMedia.recort.0.05Media.winsor.0.05
Years8.460.007.018.11
Cig7.270.006.117.05
PC3.333.553.363.33
Weight67.7268.0067.7367.71
Age45.5946.0045.4945.54
Height171.44172.00171.47171.43
kable(data.frame(variables= names(mydata)[res],
                 Desv.Standard = std.n,
                 IQR = IQR.n,
                 MAD = mad.n
                 ),
      digits=2, caption="Estimaciones de Dispersión")
Estimaciones de Dispersión
variablesDesv.StandardIQRMAD
Years12.5415.250.00
Cig10.4113.000.00
PC0.630.880.54
Weight3.836.004.45
Age10.6314.0010.38
Height5.7410.007.41

Se puede observar que para las variables Years y Cig las medidas robustas discrepan bastante de las ordinarias debido a que los datos contienen un gran número de ceros.


8 Valores perdidos


Las variables que tienen valores perdidos son:

PC

v.p.p <- which(names(mydata)==v.p)

La variable con valores perdidos es la 5 de la lista de variables.

Esta variable tiene valores perdidos en las posiciones 3, 7

8.1 Imputar los valores a partir de los k-vecinos más cercanos usando la distancia de Gower con la información de todas las variables.

# kNN Imputation i Gower distance
# 6 last variables

mydata.completo <- kNN(mydata, variable=colnames(mydata)[v.p.p])

# Asignation
mydata[v.p.p.v,v.p.p] <- mydata.completo[v.p.p.v,v.p.p]

Los valores imputados son: 3.747, 2.773


9 Finalmente, hacer un breve estudio descriptivo de los datos una vez depurados


Se presenta un estudio descriptivo agrupado por el tipo de variable estadística.

options(knitr.kable.NA = '')

kable(summary(mydata)[,var.factor],
      digits=2, align='l', caption="Estadística descriptiva de variables cualitativas")
Estadística descriptiva de variables cualitativas
SexSportCity
F:137N:127Barcelona:102
M:163S: 83Terrassa : 42
R: 48Valls : 15
E: 42Tarragona: 14
Lleida : 13
Sitges : 13
(Other) :101
kable(summary(mydata)[,var.integer],
      digits=2, align='l', caption="Estadística descriptiva de variables cuantitativas discretas")
Estadística descriptiva de variables cuantitativas discretas
YearsCig
Min. : 0.000Min. : 0.000
1st Qu.: 0.0001st Qu.: 0.000
Median : 0.000Median : 0.000
Mean : 8.463Mean : 7.273
3rd Qu.:15.2503rd Qu.:13.000
Max. :51.000Max. :47.000
kable(summary(mydata)[,var.numeric],
      digits=2, align='l', caption="Estadística descriptiva de variables cuantitativas continuas")
Estadística descriptiva de variables cuantitativas continuas
PCWeightAgeHeight
Min. :1.557Min. :57.00Min. :19.00Min. :158.0
1st Qu.:2.9091st Qu.:65.001st Qu.:38.001st Qu.:166.0
Median :3.554Median :68.00Median :46.00Median :172.0
Mean :3.331Mean :67.72Mean :45.59Mean :171.4
3rd Qu.:3.7933rd Qu.:71.003rd Qu.:52.003rd Qu.:176.0
Max. :4.466Max. :79.00Max. :77.00Max. :186.0

10 Crear el archivo limpio

my.newfile <- "Fumadors_clean.csv"
write.csv(mydata, file=my.newfile, row.names = FALSE)