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
# 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
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)))
variables | clase |
---|---|
Sex | factor |
Sport | integer |
Years | integer |
Cig | integer |
PC | factor |
City | factor |
Weight | integer |
Age | integer |
Height | integer |
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")))
variables | clase |
---|---|
Sport | factor |
PC | numeric |
Weight | numeric |
Age | numeric |
Height | numeric |
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.
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.
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.
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
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:
# Treure espais abans i després
kk <- trimws( mydata$Sex )
table(kk )
## kk
## f F m M
## 37 100 38 125
# change upper
kk <- toupper(kk)
table(kk)
## kk
## F M
## 137 163
# Update
mydata$Sex <-as.factor(kk)
Ya ha sido normalizada en el paso 3.1
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:
# 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
# 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
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
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.
# 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]))
9 | 11 | 17 | 41 | 60 | 82 | 90 | 91 | 103 | 113 | 129 | 131 | 132 | 176 | 181 | 183 | 257 | 264 | 266 | 276 | 298 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Years | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Cig | 1 | 5 | 5 | 1 | 3 | 1 | 2 | 1 | 1 | 2 | 3 | 3 | 2 | 5 | 3 | 3 | 5 | 5 | 3 | 1 | 2 |
El siguiente paso es corregirlo:
# posar 0 al valors de Cig
mydata[kk,4] <- 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]))
35 | 69 | 83 | 85 | 106 | 107 | 124 | 138 | 139 | 143 | 157 | 189 | 193 | 205 | 213 | 220 | 233 | 234 | 262 | 263 | 295 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Years | 5 | 5 | 5 | 3 | 5 | 3 | 5 | 1 | 5 | 2 | 2 | 5 | 3 | 1 | 1 | 2 | 4 | 2 | 4 | 3 | 4 |
Cig | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
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
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")
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
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
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")
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")
variables | Media | Mediana | Media.recort.0.05 | Media.winsor.0.05 |
---|---|---|---|---|
Years | 8.46 | 0.00 | 7.01 | 8.11 |
Cig | 7.27 | 0.00 | 6.11 | 7.05 |
PC | 3.33 | 3.55 | 3.36 | 3.33 |
Weight | 67.72 | 68.00 | 67.73 | 67.71 |
Age | 45.59 | 46.00 | 45.49 | 45.54 |
Height | 171.44 | 172.00 | 171.47 | 171.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")
variables | Desv.Standard | IQR | MAD |
---|---|---|---|
Years | 12.54 | 15.25 | 0.00 |
Cig | 10.41 | 13.00 | 0.00 |
PC | 0.63 | 0.88 | 0.54 |
Weight | 3.83 | 6.00 | 4.45 |
Age | 10.63 | 14.00 | 10.38 |
Height | 5.74 | 10.00 | 7.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.
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
# 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
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")
Sex | Sport | City | |
---|---|---|---|
F:137 | N:127 | Barcelona:102 | |
M:163 | S: 83 | Terrassa : 42 | |
R: 48 | Valls : 15 | ||
E: 42 | Tarragona: 14 | ||
Lleida : 13 | |||
Sitges : 13 | |||
(Other) :101 |
kable(summary(mydata)[,var.integer],
digits=2, align='l', caption="Estadística descriptiva de variables cuantitativas discretas")
Years | Cig | |
---|---|---|
Min. : 0.000 | Min. : 0.000 | |
1st Qu.: 0.000 | 1st Qu.: 0.000 | |
Median : 0.000 | Median : 0.000 | |
Mean : 8.463 | Mean : 7.273 | |
3rd Qu.:15.250 | 3rd Qu.:13.000 | |
Max. :51.000 | Max. :47.000 |
kable(summary(mydata)[,var.numeric],
digits=2, align='l', caption="Estadística descriptiva de variables cuantitativas continuas")
PC | Weight | Age | Height | |
---|---|---|---|---|
Min. :1.557 | Min. :57.00 | Min. :19.00 | Min. :158.0 | |
1st Qu.:2.909 | 1st Qu.:65.00 | 1st Qu.:38.00 | 1st Qu.:166.0 | |
Median :3.554 | Median :68.00 | Median :46.00 | Median :172.0 | |
Mean :3.331 | Mean :67.72 | Mean :45.59 | Mean :171.4 | |
3rd Qu.:3.793 | 3rd Qu.:71.00 | 3rd Qu.:52.00 | 3rd Qu.:176.0 | |
Max. :4.466 | Max. :79.00 | Max. :77.00 | Max. :186.0 |
my.newfile <- "Fumadors_clean.csv"
write.csv(mydata, file=my.newfile, row.names = FALSE)