## [1] "PassengerId" "Survived" "Pclass" "Name" "Sex"
## [6] "Age" "SibSp" "Parch" "Ticket" "Fare"
## [11] "Cabin" "Embarked"
## PassengerId Survived Pclass Name
## Min. : 1.0 Min. :0.0000 Min. :1.000 Length:714
## 1st Qu.:222.2 1st Qu.:0.0000 1st Qu.:1.000 Class :character
## Median :445.0 Median :0.0000 Median :2.000 Mode :character
## Mean :448.6 Mean :0.4062 Mean :2.237
## 3rd Qu.:677.8 3rd Qu.:1.0000 3rd Qu.:3.000
## Max. :891.0 Max. :1.0000 Max. :3.000
## Sex Age SibSp Parch
## Length:714 Min. : 0.42 Min. :0.0000 Min. :0.0000
## Class :character 1st Qu.:20.12 1st Qu.:0.0000 1st Qu.:0.0000
## Mode :character Median :28.00 Median :0.0000 Median :0.0000
## Mean :29.70 Mean :0.5126 Mean :0.4314
## 3rd Qu.:38.00 3rd Qu.:1.0000 3rd Qu.:1.0000
## Max. :80.00 Max. :5.0000 Max. :6.0000
## Ticket Fare Cabin Embarked
## Length:714 Min. : 0.00 Length:714 Length:714
## Class :character 1st Qu.: 8.05 Class :character Class :character
## Mode :character Median : 15.74 Mode :character Mode :character
## Mean : 34.69
## 3rd Qu.: 33.38
## Max. :512.33
library(ggplot2)
ggplot(data = NOMBRE DE LA BASE DE DATOS, aes(x = VARIABLE)) +
geom_histogram(aes(y = ..density.., fill = ..count..)) +
scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
stat_function(fun = dnorm, colour = "firebrick",
args = list(mean = mean(NOMBRE DE LA BASE DE DATOS $ VARIABLE),
sd = sd(NOMBRE DE LA BASE DE DATOS $ VARIABLE))) +
ggtitle("Histograma con curva normal teórica") +
theme_bw()Ejemplo con la edad de los pasajeros del Titanic
library(ggplot2)
ggplot(data = datos, aes(x = Age)) +
geom_histogram(aes(y = ..density.., fill = ..count..)) +
scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
stat_function(fun = dnorm, colour = "firebrick",
args = list(mean = mean(datos$Age),
sd = sd(datos$Age))) +
ggtitle("Histograma con curva normal teórica") +
theme_bw()## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Modificando el número de columnas
ggplot(data = datos, aes(x = Age)) +
geom_histogram(bins = 10, aes(y = ..density.., fill = ..count..)) +
scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
stat_function(fun = dnorm, colour = "firebrick",
args = list(mean = mean(datos$Age),
sd = sd(datos$Age))) +
ggtitle("Histograma con curva normal teórica") +
theme_bw()ggplot(data = datos, aes(x = Age)) +
geom_histogram(bins = 5, aes(y = ..density.., fill = ..count..)) +
scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
stat_function(fun = dnorm, colour = "firebrick",
args = list(mean = mean(datos$Age),
sd = sd(datos$Age))) +
ggtitle("Histograma con curva normal teórica") +
theme_bw()ggplot(data = datos, aes(x = Age)) +
geom_histogram(bins = 3, aes(y = ..density.., fill = ..count..)) +
scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
stat_function(fun = dnorm, colour = "firebrick",
args = list(mean = mean(datos$Age),
sd = sd(datos$Age))) +
ggtitle("Histograma con curva normal teórica") +
theme_bw()Usaremos el Test de Shapiro-Wilk con muestras pequeñas (n < 50) y Variables cuantitativas continuas (ej.: peso, altura, presión, tiempo)
H₀: los datos provienen de una distribución normal
H₁: los datos no provienen de una distribución normal
Se ejecuta con la función shapiro.test
##
## Shapiro-Wilk normality test
##
## data: datos$Age
## W = 0.98146, p-value = 7.337e-08
Usaremos el Test de Kolmogorov-Smirnov con muestras grandes. Solo es válido si los parámetros de la distribución (media y desviación) son conocidos.
H₀: los datos provienen de una distribución normal
H₁: los datos no provienen de una distribución normal
Se ejecuta con la función ks.test()
ks.test(x = NOMBRE DE LA BASE DE DATOS $ VARIABLE,"pnorm",
mean(NOMBRE DE LA BASE DE DATOS $ VARIABLE),
sd(NOMBRE DE LA BASE DE DATOS $ VARIABLE))##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: datos$Age
## D = 0.064567, p-value = 0.005196
## alternative hypothesis: two-sided
Usaremos la Modificación de Lillefors cuando queramos usar Kolmogorov-Smirnov pero no conozcamos los parámetros de la distribución (media y desviación).
H₀: los datos provienen de una distribución normal
H₁: los datos no provienen de una distribución normal
Se ejecuta con la función lillie.test() del paquete
nortest
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: datos$Age
## D = 0.064567, p-value = 1.862e-07
El supuesto de homogeneidad de varianzas, también conocido como supuesto de homocedasticidad, considera que la varianza es constante (no varía) en los diferentes niveles de un factor, es decir, entre diferentes grupos.
H0 : no hay diferencia entre las varianzas de cada población: μ(nf)−μ(f)=0
Ha: si hay diferencia entre las varianzas de cada población: μ(nf)−μ(f)≠0
Trabaremos con la variable Pclass de la bada de datos del Titánic
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
datos3 <- titanic_train
datos3 <- na.omit(datos3)
datos3$Pclass <- as.character(datos3$Pclass)
datos3$Pclass <- recode(datos3$Pclass,
"1" = "Primera Clase",
"2" = "Segunda Clase",
"3" = "Tercera Clase")El F-test o F-Snedecor Es muy potente, pero no es un test recomendable si no se tiene mucha certeza de que las poblaciones se distribuyen de forma normal.
p > 0.05 → se asume homocedasticidad
p ≤ 0.05 → no hay homogeneidad de varianzas
ggplot(datos3, aes(x = Pclass, y = Age, colour = Pclass)) +
geom_violin(width=0.3) +
geom_boxplot(width=0.1, alpha= 1, width=1.8)+
geom_jitter(color="black", size=1, alpha=0.1) +
theme(legend.position = "none") var.test(x = datos3[datos3$Pclass == "Primera Clase", "Age"],
y = datos3[datos3$Pclass == "Segunda Clase", "Age"])##
## F test to compare two variances
##
## data: datos3[datos3$Pclass == "Primera Clase", "Age"] and datos3[datos3$Pclass == "Segunda Clase", "Age"]
## F = 1.1178, num df = 185, denom df = 172, p-value = 0.4593
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
## 0.8319658 1.4994641
## sample estimates:
## ratio of variances
## 1.11781
var.test(x = datos3[datos3$Pclass == "Primera Clase", "Age"],
y = datos3[datos3$Pclass == "Tercera Clase", "Age"])##
## F test to compare two variances
##
## data: datos3[datos3$Pclass == "Primera Clase", "Age"] and datos3[datos3$Pclass == "Tercera Clase", "Age"]
## F = 1.4034, num df = 185, denom df = 354, p-value = 0.00706
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
## 1.096223 1.814950
## sample estimates:
## ratio of variances
## 1.40343
var.test(x = datos3[datos3$Pclass == "Segunda Clase", "Age"],
y = datos3[datos3$Pclass == "Tercera Clase", "Age"])##
## F test to compare two variances
##
## data: datos3[datos3$Pclass == "Segunda Clase", "Age"] and datos3[datos3$Pclass == "Tercera Clase", "Age"]
## F = 1.2555, num df = 172, denom df = 354, p-value = 0.07743
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
## 0.9753835 1.6351088
## sample estimates:
## ratio of variances
## 1.255517
El test no encuentra diferencias significativas entre las varianzas de la Primera Clase y la Tercerca Clase y entre las varianzas de la Segunda Clase y la Tercera Clase.
El test de Levene se puede aplicar con la función
leveneTest() del paquete car. Se caracteriza,
además de por poder comparar 2 o más poblaciones, por permitir elegir
entre diferentes estadísticos de centralidad: mediana (por defecto),
media, media truncada. Esto es importante a la hora de contrastar la
homocedasticidad dependiendo de si los grupos se distribuyen de forma
normal o no.
p > 0.05 → se asume homocedasticidad
p ≤ 0.05 → no hay homogeneidad de varianzas
## Cargando paquete requerido: carData
##
## Adjuntando el paquete: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
El test encuentra diferencias significativas entre las varianzas de los tres grupos.
H0 : no hay diferencia entre las medias poblacionales: μ(nf)−μ(f)=0
Ha: si hay diferencia entre las medias poblacionales: μ(nf)−μ(f)≠0
library(titanic)
library(dplyr)
datos2 <- titanic_train
datos2 <- na.omit(datos2)
datos2$Survived <- as.character(datos2$Survived)
datos2$Survived <-dplyr:: recode(datos2$Survived,
"0" = "No sobrevivió",
"1" = "Sí sobrevivió")sobrevivió <- datos2 %>% filter(Survived == "Sí sobrevivió") %>% pull(Age)
no_sobrevivió <- datos2 %>% filter(Survived == "No sobrevivió") %>% pull(Age)
mean(no_sobrevivió) - mean(sobrevivió) ## [1] 2.28249
ggplot(datos2,aes(x = Age)) +
geom_histogram(aes(y = ..density.., colour = Survived)) +
facet_grid(.~ Survived) +
theme_bw() + theme(legend.position = "none") +
stat_function(fun = dnorm, colour = "blue",
args = list(mean = mean(datos2$Age),
sd = sd(datos2$Age)))## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
par(mfrow = c(1, 2))
qqnorm(no_sobrevivió, xlab = "", ylab = "",
main = "no sobrevivió", col = "firebrick")
qqline(no_sobrevivió)
qqnorm(sobrevivió, xlab = "", ylab = "",
main = "sobrevivió", col = "springgreen4")
qqline(sobrevivió)##
## Shapiro-Wilk normality test
##
## data: sobrevivió
## W = 0.98273, p-value = 0.001426
##
## Shapiro-Wilk normality test
##
## data: no_sobrevivió
## W = 0.96894, p-value = 7.816e-08
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: sobrevivió
## D = 0.056016, p-value = 0.02839
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: no_sobrevivió
## D = 0.090734, p-value = 6.462e-09
Se ejecuta con la función t.test()
t.test(
x = sobrevivió,
y = no_sobrevivió,
alternative = "two.sided",
m = 0,
var.equal = TRUE,
conf.level = 0.95)##
## Two Sample t-test
##
## data: sobrevivió and no_sobrevivió
## t = -2.0667, df = 712, p-value = 0.03912
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -4.450798 -0.114181
## sample estimates:
## mean of x mean of y
## 28.34369 30.62618
Calculamos el tamaño de efecto
##
## Cohen's d
##
## d estimate: 0.157486 (negligible)
## 95 percent confidence interval:
## lower upper
## 0.007654626 0.307317318
Grafica que puede acompañar la explicación
ggplot(datos2, aes(x = Survived, y = Age, fill = Survived)) +
geom_violin(width=0.3) +
geom_boxplot(width=0.1, color="black", alpha= 1, width=1.8)+
geom_jitter(color="black", size=1, alpha=0.1) +
theme(legend.position = "none") +
labs(x = "Superviviencia", y = "Edad")Dado que el p-valor es inferior a 0.05 (<. 05) existe evidencia para coonsiderar que existe una diferencia estadística en la edad entre las persons que sobrevivieron y las que no. Sin ebmargo, el tamaño de efecto medido por d-Cohen es inapreciable (.16)
Se reporta como : t712 = -2.0667, p = .04
Se puede ejecutar con la función wilcox.test()
wilcox.test(x = no_sobrevivió, y = sobrevivió,
alternative = "two.sided",
mu = 0, paired = FALSE, conf.int = 0.95)##
## Wilcoxon rank sum test with continuity correction
##
## data: no_sobrevivió and sobrevivió
## W = 65278, p-value = 0.1605
## alternative hypothesis: true location shift is not equal to 0
## 95 percent confidence interval:
## -0.9999982 3.9999465
## sample estimates:
## difference in location
## 1.000022
Dado que el p-valor es superior a 0.05 (>. 05) no existe evidencia para coonsiderar que existe una diferencia estadística en la edad entre las persons que sobrevivieron y las que no.
Se reporta como: W = 65278, p = .16
Es necesario trabajar con una tabla de contingencia
##
## No sobrevivió Sí sobrevivió
## female 64 197
## male 360 93
Se usa para n > 5. Se ejecuta con la función
chisq.test
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: tabla
## X-squared = 205.03, df = 1, p-value < 2.2e-16
Dado que el p-valor es inferior a 0.05 (<. 05) existe evidencia para coonsiderar que existe una diferencia estadística en el sexo de las persona que sobrevivieron.
Se reporta como: X2 = 454.5, p < .00
H0 : no hay diferencia entre las medias poblacionales: μ(nf)−μ(f)=0
Ha: si hay diferencia entre las medias poblacionales: μ(nf)−μ(f)≠0
La prueba ANOVA se realiza creando un objeto con el resultado de la
función AOV()
## Df Sum Sq Mean Sq F value Pr(>F)
## datos3$Pclass 2 20930 10465 57.44 <2e-16 ***
## Residuals 711 129527 182
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Dado que el p-value es inferior a 0.05 hay evidencias suficientes para considerar que al menos dos medias son distintas.
Para poder calcular el tamaño de efecto (n2), neceistamos
instalar la librería effectsize y aplicar la función
eta_squared()
## For one-way between subjects designs, partial eta squared is equivalent
## to eta squared. Returning eta squared.
Los niveles de clasificación más empleados para el tamaño del efecto son:
0.01 = pequeño
0.06 = mediano
0.14 = grande
Para poder entender entre qué poblaciones existían las diferencias,
aplicamos el método de TukeyHSD. Se realiza con la funci´n
Tukey()
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = datos3$Age ~ datos3$Pclass)
##
## $`datos3$Pclass`
## diff lwr upr p adj
## Segunda Clase-Primera Clase -8.355811 -11.704133 -5.007489 0.0000000
## Tercera Clase-Primera Clase -13.092821 -15.962198 -10.223445 0.0000000
## Tercera Clase-Segunda Clase -4.737010 -7.676279 -1.797742 0.0004884
Se observa que las diferencias son entre todas las poblaciones.
Se reporta como: F(2,711) = 57.44, p < .001, n2 = .14
El test de Kruskal-Wallis, también conocido como test H, es la alternativa no paramétrica al test ANOVA. Se trata de una extensión del test de Mann-Whitney para más de dos grupos. Se trata por lo tanto de un test que emplea rangos para contrastar la hipótesis de que k muestras han sido obtenidas de una misma población.
H0 : las muestras pertenecen a una misma población: μ(nf)−μ(f)=0
Ha: las muestras no pertenecen a una misa población: μ(nf)−μ(f)≠0
Se usa la función ‘kruskal.test()’
##
## Kruskal-Wallis rank sum test
##
## data: Age by Pclass
## Kruskal-Wallis chi-squared = 95.995, df = 2, p-value < 2.2e-16
El test encuentra significancia en la diferencia de al menos dos grupos. Para identificar donde se encuentran estas dierencias tenemos que proceder con el test de Mann Whitney Wilcoxon que ya habíamos visto
##
## Pairwise comparisons using Wilcoxon rank sum test with continuity correction
##
## data: datos3$Age and datos3$Pclass
##
## Primera Clase Segunda Clase
## Segunda Clase 1.1e-06 -
## Tercera Clase < 2e-16 6.7e-05
##
## P value adjustment method: bonferroni
Visualización de los resultados con el paquete ggpubr
library(ggpubr)
ggplot(datos3, aes(x = Pclass, y = Age, fill = Pclass))+
geom_boxplot()+
geom_point()+
ylim(0,40)+
stat_compare_means(method = "kruskal",label.y = 40)+
stat_compare_means(method = "wilcox.test", ref.group = "Control",
label = "p.signif", label.y = 40)+ theme_classic()Con Kruskal Wallis no se puede calcular el tamaño de efecto.
Se reporta como: H(2) = 95,995, p < 0,001
Se usa para analizar la relación entre dos variables. El calculo es independiente del orden de asignación de las variables ya que no considera las dependencias. Los datos osiclarán entre +1 (correlación positiva perfecta) y -1 (correlación negativa perfecta).
Como medidas de fuerza, o tamaño de efecto, se emplean los siguientes intervalos:
0: asociación nula.
0.1: asociación pequeña.
0.3: asociación mediana.
0.5: asociación moderada.
0.7: asociación alta.
0.9: asociación muy alta.
Usaremos tres coeficientes de asociación distintos (estadísticos)
La correlación de Pearson funciona bien con variables cuantitativas que tienen una distribución normal.
Además del valor obtenido para el coeficiente de correlación, es
necesario calcular su significancia. Solo si el p-value es significativo
se puede aceptar que existe correlación, y esta será de la magnitud que
indique el coeficiente. Por muy cercano que sea el valor del coeficiente
de correlación a +1 o −1 , si no es significativo, se ha de interpretar
que la correlación de ambas variables es 0, ya que el valor observado
puede deberse a simple aleatoriedad.
Se puede usar la funcióncor.test()`
cor.test(x = datos3$Age,
y = datos3$Fare,
alternative = "two.sided",
conf.level = 0.95,
method = "pearson")##
## Pearson's product-moment correlation
##
## data: datos3$Age and datos3$Fare
## t = 2.5753, df = 712, p-value = 0.01022
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.02285549 0.16825304
## sample estimates:
## cor
## 0.09606669
Un ejemplo de representación gráfica podría ser el siguiente
El coeficiente de Spearman es el equivalente al coeficiente de Pearson pero con una previa transformación de los datos a rangos. Se emplea como alternativa cuando los valores son ordinales, o bien, cuando los valores son continuos pero no satisfacen la condición de normalidad requerida por el coeficiente de Pearson.
Se puede usar la función cor.test()
cor.test(x = datos3$Age,
y = datos3$Fare,
alternative = "two.sided",
conf.level = 0.95,
method = "spearman")##
## Spearman's rank correlation rho
##
## data: datos3$Age and datos3$Fare
## S = 52472641, p-value = 0.0002958
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.1350512
Trabaja con rangos, por lo que requiere que las variables cuya relación se quiere estudiar sean ordinales o que se puedan transformar en rangos. Al ser no paramétrico, es otra alternativa al Coeficiente de correlación de Pearson cuando no se cumple la condición de normalidad. Parece ser más aconsejable que el coeficiente de Spearman cuando el número de observaciones es pequeño o los valores se acumulan en una región.
Se puede usar la función cor.test()
datos3 <- datos2
datos3$Survived <-dplyr:: recode(datos3$Survived,
"No sobrevivió" = "0",
"Sí sobrevivió" = "1")
datos3$Survived <- as.numeric(datos3$Survived)
datos3$Pclass <- as.numeric(datos3$Pclass)
cor.test(x = datos3$Pclass,
y = datos3$Survived,
alternative = "two.sided",
conf.level = 0.95,
method = "kendall")##
## Kendall's rank correlation tau
##
## data: datos3$Pclass and datos3$Survived
## z = -9.6303, p-value < 2.2e-16
## alternative hypothesis: true tau is not equal to 0
## sample estimates:
## tau
## -0.3421052
datos3 <- datos2
datos3$Sex <-dplyr:: recode(datos3$Sex,
"female" = "0",
"male" = "1")
datos3$Sex <- as.numeric(datos3$Sex)
datos4<- datos3[ , -c(1,2,4,7,8,9,11,12)]
library(PerformanceAnalytics)## Cargando paquete requerido: xts
## Cargando paquete requerido: zoo
##
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Adjuntando el paquete: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
##
## Adjuntando el paquete: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
library(apaTables)
apa.cor.table(
datos4,
filename = NA,
table.number = NA,
show.conf.interval = TRUE,
show.sig.stars = TRUE,
landscape = TRUE
)##
##
## Means, standard deviations, and correlations with confidence intervals
##
##
## Variable M SD 1 2 3
## 1. Pclass 2.24 0.84
##
## 2. Sex 0.63 0.48 .16**
## [.08, .23]
##
## 3. Age 29.70 14.53 -.37** .09*
## [-.43, -.30] [.02, .17]
##
## 4. Fare 34.69 52.92 -.55** -.18** .10*
## [-.60, -.50] [-.25, -.11] [.02, .17]
##
##
## Note. M and SD are used to represent mean and standard deviation, respectively.
## Values in square brackets indicate the 95% confidence interval.
## The confidence interval is a plausible range of population correlations
## that could have caused the sample correlation (Cumming, 2014).
## * indicates p < .05. ** indicates p < .01.
##