Sección 1

Ejercicio 1

Máster en Bioestadística y Bioinformática SAD

Si quieres acceder a la UOC haz clic al enlace: http:www.uoc.edu

En esta tabla encontrarás el listado de profesores y sus correos electrónicos

Consultor Aula Correo electronico
Mª Àngels Carbonell Aula 4
Víctor Peña Aula 3
Alicia Vila Aula 2
Marta Casals Aula 1

Los Laboratorios que usaremos en esta PEC 1 son:

  1. LAB 1. Introducción a R, RStudio y RMarkdown.
  2. LAB 2. Estadística descriptiva y gráficos con R.

Sección 2

Ejercicio 1

# Importar dataset, convirtiendo missing values to NA
Covid19 <- read.csv("COVID-19 Global Statistics Dataset.csv", na.strings = c("", "N/A"))

# Nombres variables
names(Covid19)
##  [1] "Country"           "Total.Cases"       "New.Cases"        
##  [4] "Total.Deaths"      "New.Deaths"        "Total.Recovered"  
##  [7] "New.Recovered"     "Active.Cases"      "Serious..Critical"
## [10] "Tot.Cases.1M.pop"  "Deaths.1M.pop"     "Total.Tests"      
## [13] "Tests.1M.pop"      "Population"
# Primeros registros
head(Covid19)
# Estructura del dataset
str(Covid19)
## 'data.frame':    239 obs. of  14 variables:
##  $ Country          : chr  "USA" "India" "France" "Germany" ...
##  $ Total.Cases      : chr  "111,367,209" "45,028,429" "40,138,560" "38,819,284" ...
##  $ New.Cases        : chr  NA "161" NA "574" ...
##  $ Total.Deaths     : chr  "1,199,031" "533,475" "167,642" "182,439" ...
##  $ New.Deaths       : int  NA 2 NA 28 NA NA NA NA NA NA ...
##  $ Total.Recovered  : chr  "109,053,249" NA "39,970,918" "38,240,600" ...
##  $ New.Recovered    : chr  NA NA NA NA ...
##  $ Active.Cases     : chr  "1,114,929" NA "0" "396,245" ...
##  $ Serious..Critical: chr  "1,771" NA NA NA ...
##  $ Tot.Cases.1M.pop : chr  "332,633" "32,012" "612,013" "462,776" ...
##  $ Deaths.1M.pop    : chr  "3,581" "379" "2,556" "2,175" ...
##  $ Total.Tests      : chr  "1,186,742,917" "935,879,495" "271,490,188" "122,332,384" ...
##  $ Tests.1M.pop     : chr  "3,544,577" "665,334" "4,139,547" "1,458,359" ...
##  $ Population       : chr  "334,805,269" "1,406,631,776" "65,584,518" "83,883,596" ...
# Número observaciones y variables
dim(Covid19)
## [1] 239  14
# Mostrar cuántos missing values hay
table(is.na(Covid19))
## 
## FALSE  TRUE 
##  2299  1047
# Mostrar si existen valores nulos
table(is.null(Covid19))
## 
## FALSE 
##     1

Ejercicio 2.1

# Importar dataset
malaria <- read.csv("malaria.csv")

# Renombrar columnas
colnames(malaria)[colnames(malaria) == 'Entity'] <- 'Región'

colnames(malaria)[colnames(malaria) == 'Year'] <- 'Año'

colnames(malaria)[colnames(malaria) == 'Malaria.Deaths.by.World.Region..WHO..2016..'] <- 'Defunciones'

# Mostrar nuevos nombres de las columnas
colnames(malaria)
## [1] "Región"      "Año"         "Defunciones"
# Media Defunciones
mean(malaria$Defunciones)
## [1] 107112.5
# Tabla contingencia Año y Defunciones
table(malaria$Año, malaria$Defunciones)
##       
##        0 500 1100 1200 1600 3200 3500 4200 7000 7300 8100 15000 32000 44000
##   2000 1   0    0    0    1    0    0    0    0    0    1     1     0     0
##   2005 1   0    0    1    0    0    0    1    0    0    0     1     0     0
##   2010 1   0    1    0    0    0    1    0    1    0    0     0     0     1
##   2015 1   1    0    0    0    1    0    0    0    1    0     0     1     0
##       
##        48000 51000 395000 499000 670000 764000
##   2000     0     1      0      0      0      1
##   2005     1     0      0      0      1      0
##   2010     0     0      0      1      0      0
##   2015     0     0      1      0      0      0

La tabla no tiene sentido porque está contando cada observación de forma separada. Sería más informativa si agrupáramos dichas observaciones en intervalos.

breaks <- c(-1, 1000, 10000, 100000, Inf)

malaria$intervals <- cut(malaria$Defunciones, breaks = breaks, labels = c("0 - 1000", "1001 - 10000", "10001 - 100000", "> 100000"))

tabla_malaria <- table(malaria$Año, malaria$intervals)

knitr::kable(tabla_malaria, escape = FALSE, format = "html", table.attr = "style='width:60%;'") %>%
  kableExtra::kable_styling(bootstrap_options = "bordered") 
0 - 1000 1001 - 10000 10001 - 100000 > 100000
2000 1 2 2 1
2005 1 2 2 1
2010 1 3 1 1
2015 2 2 1 1

Ejercicio 2.2

# Importar dataset
lung_cancer <- read.csv("lung_cancer_examples.csv")

# Media de edad de los pacientes
(age_mean <- mean(lung_cancer$Age))
## [1] 42.62712
# Edad paciente con máximo cigarros fumados por día
(age_max_smoke <- lung_cancer$Age[lung_cancer$Smokes == max(lung_cancer$Smokes)])
## [1] 26
# Subset pacientes no afectados
paciente_result_0 <- subset(lung_cancer, Result == 0)

head(paciente_result_0)

Ejercicio 3

# Construir vector números asociados a meses
meses_num <- seq(1:10)

meses <- factor(meses_num, levels = meses_num, labels = c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre"))

# Construir vector producción mensual
produccion <- c(100, 90.5, 91.03, 68.14, 45.6, 25.45, 12.05, 16.48, 34.58, 88.5)

prod_naranjas <- data.frame(meses, produccion)

# Representación gráfica producción naranjas (línea continua)
plot(as.numeric(meses), produccion, type = "l", col = "blue", xlab = "Meses del año", ylab = "Toneladas de naranjas")

# Representación línea y puntos
plot(as.numeric(meses), produccion, type = "b", col = "blue", xlab = "Meses del año", ylab = "Toneladas de naranjas")

# Representación escalera
plot(as.numeric(meses), produccion, type = "s", col = "blue", xlab = "Meses del año", ylab = "Toneladas de naranjas")

# Representación histograma
plot(as.numeric(meses), produccion, type = "h", col = "blue", xlab = "Meses del año", ylab = "Toneladas de naranjas")

# Suma producción naranjas
sum(produccion)
## [1] 572.33

También se pueden representar los datos utilizando la librería ggplot2.

ggplot(prod_naranjas, aes(y = produccion, x = meses)) + xlab("Meses del año") + ylab("Toneladas de naranjas") + geom_line(color = "blue", group = 1)

Sección 3

Ejercicio 1

# Importar dataset
sleep_health <- read.csv("Sleep_health_and_lifestyle_dataset.csv")

# Diagrama cajas duración del sueño y niveles de estrés
boxplot(Sleep.Duration ~ Stress.Level, data = sleep_health, col= palette.colors(), xlab = "Stress Level", ylab = "Sleep Duration")

Los diagramas de cajas nos permiten representar la distribución de los datos en cada categoría. Podemos observar que las distribuciones son asimétricas y se alejan de una normal, ya que sus medianas no se encuentran centradas.

También, nos permite visualizar de forma sencilla si existen valores atípicos (puntos).

# Modelo de regresión lineal
model_reg <- lm(Sleep.Duration ~ Stress.Level, data = sleep_health)
summary(model_reg)
## 
## Call:
## lm(formula = Sleep.Duration ~ Stress.Level, data = sleep_health)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.13574 -0.18117 -0.04481  0.32790  0.99155 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    9.0903     0.0771  117.90   <2e-16 ***
## Stress.Level  -0.3636     0.0136  -26.74   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4661 on 372 degrees of freedom
## Multiple R-squared:  0.6578, Adjusted R-squared:  0.6568 
## F-statistic:   715 on 1 and 372 DF,  p-value: < 2.2e-16

Podría indicar que existe una relación lineal negativa entre los niveles de estrés y la duración del sueño, ya que la pendiente (-0.36) es negativa.

El valor R-Squared nos indica qué proporción de la varianza de nuestra variable dependiente se explica de acuerdo al modelo. En este caso, se explica el 65%, lo cual es un valor intermedio.

El p-value nos ayuda a comparar distintos modelos, siendo aquel con menor p-value el modelo que se ajusta mejor a nuestros datos.

# Diagrama de puntos con modelo de regresión
plot(sleep_health$Stress.Level, sleep_health$Sleep.Duration, xlab = "Stress Level", ylab = "Sleep Duration")

# Añadir línea de regresión
abline(model_reg, col= "red")

# Matriz de correlación
cor_sh <- cor(sleep_health[sapply(sleep_health,is.numeric)])
kable(cor_sh, digits = 2)
Person.ID Age Sleep.Duration Quality.of.Sleep Physical.Activity.Level Stress.Level Heart.Rate Daily.Steps
Person.ID 1.00 0.99 0.30 0.43 0.15 -0.39 -0.23 0.04
Age 0.99 1.00 0.34 0.47 0.18 -0.42 -0.23 0.06
Sleep.Duration 0.30 0.34 1.00 0.88 0.21 -0.81 -0.52 -0.04
Quality.of.Sleep 0.43 0.47 0.88 1.00 0.19 -0.90 -0.66 0.02
Physical.Activity.Level 0.15 0.18 0.21 0.19 1.00 -0.03 0.14 0.77
Stress.Level -0.39 -0.42 -0.81 -0.90 -0.03 1.00 0.67 0.19
Heart.Rate -0.23 -0.23 -0.52 -0.66 0.14 0.67 1.00 -0.03
Daily.Steps 0.04 0.06 -0.04 0.02 0.77 0.19 -0.03 1.00
corrplot(cor_sh, method = "color", type = "lower", order = "hclust", tl.col = "black", tl.srt = 45, addCoef.col = "black", number.cex = 0.75, number.digits = 1, diag = FALSE)

La matriz nos muestra la correlación lineal entre las variables estudiadas. Existen variables entre las que hay una relación fuerte, como por ejemplo, la duración del sueño y su calidad (correlación positiva), o la calidad del sueño y el nivel de estrés (correlación negativa). También nos indica entre qué variables no existe una correlación lineal, cuando el coeficiente es más bajo, siendo el mínimo 0.

# Calcular y representar residuos
residuals_plot <- ggplot(data = sleep_health, aes(x = valores.ajustados, y = residuos)) + geom_point()

residuos <- rstandard(model_reg)
valores.ajustados <- fitted(model_reg)
plot(valores.ajustados, residuos)

Al visualizar los residuos, se puede observar que no se distribuyen de forma uniforme en los distintos valores. Esto indica que la varianza de los residuos no es constante. A su vez, en la siguiente gráfica, la desviación de los residuos con respecto a la diagonal indica que los residuos no están distribuidos de acuerdo a una normal. Realizamos una segunda comprobación con los tests de normalidad y homocedasticidad.

# Q-Q plot residuos
qqnorm(residuos)
qqline(residuos)

# Comprobar normalidad residuos y homocedasticidad
by(sleep_health$Sleep.Duration, sleep_health$Stress.Level, shapiro.test)
## sleep_health$Stress.Level: 3
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.88205, p-value = 7.138e-06
## 
## ------------------------------------------------------------ 
## sleep_health$Stress.Level: 4
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.86962, p-value = 2.967e-06
## 
## ------------------------------------------------------------ 
## sleep_health$Stress.Level: 5
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.89716, p-value = 4.321e-05
## 
## ------------------------------------------------------------ 
## sleep_health$Stress.Level: 6
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.74637, p-value = 1.513e-07
## 
## ------------------------------------------------------------ 
## sleep_health$Stress.Level: 7
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.86508, p-value = 4.065e-05
## 
## ------------------------------------------------------------ 
## sleep_health$Stress.Level: 8
## 
##  Shapiro-Wilk normality test
## 
## data:  dd[x, ]
## W = 0.87251, p-value = 3.732e-06
bartlett.test(sleep_health$Sleep.Duration, sleep_health$Stress.Level)
## 
##  Bartlett test of homogeneity of variances
## 
## data:  sleep_health$Sleep.Duration and sleep_health$Stress.Level
## Bartlett's K-squared = 193.16, df = 5, p-value < 2.2e-16

Al representar el Q-Q plot de los residuos, vemos que estos no tienen una distribución normal en principio. Cuando realizamos el test de Shapiro-Wilk y prueba de homocedasticidad por test de Barlett vemos que, efectivamente, los p-values son menores a 0.05.

Ejercicio 2

# Importar dataset
estudiantes <- read_xlsx("Estudiantes.xlsx")

# Resumen estadístico dataset
summary(estudiantes)
##   Observación         ID                Sexo              SexoNum    
##  Min.   : 1.00   Length:50          Length:50          Min.   :0.00  
##  1st Qu.:13.25   Class :character   Class :character   1st Qu.:0.00  
##  Median :25.50   Mode  :character   Mode  :character   Median :0.00  
##  Mean   :25.50                                         Mean   :0.44  
##  3rd Qu.:37.75                                         3rd Qu.:1.00  
##  Max.   :50.00                                         Max.   :1.00  
##       Edad           Fuma             Estatura           Colegio         
##  Min.   :14.56   Length:50          Length:50          Length:50         
##  1st Qu.:16.64   Class :character   Class :character   Class :character  
##  Median :18.41   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :18.72                                                           
##  3rd Qu.:21.07                                                           
##  Max.   :22.56
# Convertir variables character a factor
estudiantes[sapply(estudiantes, is.character)] <- lapply(estudiantes[sapply(estudiantes, is.character)], as.factor)

Vemos que, en nuestro dataset, las variables cualitativas son de tipo “character”. Convendría convertir dichas variables a factor, ya que muchas de las operaciones estadísticas así lo requieren.

# Muestras con observaciones 1-4, columnas 3-5
(muestra1 <- estudiantes[3:5][1:4,])
# Tabla frecuencias Sexo
prop.table(table(estudiantes$Sexo))
## 
##  Femenino Masculino 
##      0.54      0.46
# Tabla contingencia Sexo y Fuma
tabla_cont <- table(estudiantes$Fuma, estudiantes$Sexo)

Podemos ver que la representación entre chicas y chicos es prácticamente el 50%. Se puede observar de que existe una mayor proporción de chicas o chicos que fuman que los que no.

# Crear layout gráficas
plot.new()
vector <- c(1,2,3)

layout <- layout(matrix(vector, ncol = 3))

# Gráfico de barras Sexo y Fuma
barplot(tabla_cont, legend = TRUE, ylim = c(0, 20), beside = TRUE, xlab = "Sexo", ylab = "Estudiantes", args.legend=list(title="Fuma", x ='topright', bty='n', inset=c(0.05, -0.05)))

# Crear intervalos edad
intervalos <- c(14, 17, 20, Inf)

edad_intervalos <- cut(estudiantes$Edad, breaks = intervalos, labels = c("14-17", "18-20", "> 21"))

# Histograma Edad
plot(edad_intervalos, ylim = c(0,20), xlab = "Edad", ylab = "Estudiantes")

# Gráfico pastel Edad
pie(table(edad_intervalos), main = "Número estudiantes por edad")

# Gráfico qplot Edad 
qplot(edad_intervalos, xlab = "Edad", ylab = "Estudiantes")

# Gráfico pastel Edad & Estatura
# Crear subset con intervalos edad, estatura y colegio
subset_data <- as.data.frame(table(edad_intervalos, Estatura = estudiantes$Estatura, Colegio = estudiantes$Colegio))

# Crear nueva variable a partir de la combinación intervalos de edad y estatura
subset_data$n_var_est <- paste(subset_data$edad_intervalos, subset_data$Estatura)

# Representar gráfico pastel clases
ggplot(subset_data, aes(x= "", y= Freq, fill = n_var_est)) + geom_col(color = "black") + coord_polar(theta="y") + geom_text(aes(label = Freq), position = position_stack(vjust = 0.5)) + guides(fill = guide_legend(title = "Edad & Estatura"))

He elegido representar de nuevo la edad en el gráfico de tallo y hojas, ya que creo que no es muy informativo realizar dicho gráfico con variables cualitativas.

# Gráfico tallo y hojas Edad
stem(estudiantes$Edad)
## 
##   The decimal point is at the |
## 
##   14 | 66
##   15 | 39
##   16 | 000006666666
##   17 | 0011
##   18 | 0004444444
##   19 | 
##   20 | 9999
##   21 | 1111113444499
##   22 | 066

Reflexión sobre Ética y valores en la Investigación

La ética es una disciplina que está cobrando mucha importancia en la actualidad debido a la existencia de prácticas inapropiadas, que pueden tener consecuencias graves para la sociedad, la salud y medio ambiente. A veces, las conductas no éticas no dependen sólo del investigador individual, quien puede subestimar las implicaciones sociales de la investigación, sino que pueden ser promovidas por causas estructurales o culturales. Por ello, se ve la necesidad de crear más mecanismos institucionales o comités éticos, que puedan evaluar los proyectos de investigación desde el punto de vista ético desde el inicio, así como tomar responsabilidad de los resultados de los proyectos. Otro aspecto a tener en cuenta es la educación en valores éticos desde edades tempranas de la población y de los futuros investigadores. También destaca la posición altruista de los revisores, la cual podría ser compensada para poder exigir mayores competencias y responsabilidades. En conclusión, es importante realizar una investigación, aunque el avance sea más lento, que respete los códigos éticos, ya que eso ayuda a la sociedad, al prestigio de la ciencia y a su propio avance.