Problema 5

Relaciones entre la potencia, el tamaño de los efectos y el tamaño de la muestra

Caso 1

#Gráfica 1

#Se necesita el paquete pwr 
if(!require(pwr)){install.packages("pwr");library("pwr")}
## Cargando paquete requerido: pwr
# t-TEST
# Se aplicará power.t.test del paquete stats (ya en R). Calcula la potencia de la prueba t de una o dos muestras, o determina los parámetros para obtener un valor particular de la potencia.

d<-seq(.1,2,by=.1) # 20 tamaños de los efectos
n<-1:150 # Tamaños muestrales

t.test.power.effect <-as.data.frame(do.call("cbind",lapply(1:length(d),function(i)
{
  sapply(1:length(n),function(j)
  {
    power.t.test(n=n[j],d=d[i],sig.level=0.05,power=NULL,type= "two.sample")$power
  })
})))

# Si algunas potencias no se pueden calcular, se ajustan a cero:
t.test.power.effect[is.na(t.test.power.effect)] <- 0 
colnames(t.test.power.effect)<-paste (d,"effect size")

#Graficando los resultados

prueba <-t.test.power.effect #data frame de 150 X 20 (para graficar)
cuts_num<-c(2,5,8) # cortes

#Cortes basados en: Cohen, J. (1988). Statistical Power Analysis for the Behavioral Sciences (2nd ed.). Hillsdale, NJ: Lawrence Erlbaum Associates, Publishers.
cuts_cat<-c("pequeño","medio","grande") 

columnas <- 1:ncol(prueba) #Lista de los valores 1:20
color_linea<-rainbow(length(columnas), alpha=.5) # Lista de 20 colores
grosor_linea=3 # Grosor de la línea

#Para el tipo de línea: (“blank”, “solid”, “dashed”, “dotted”, “dotdash”, “longdash”, “twodash”) ó  (0, 1, 2, 3, 4, 5, 6). 
#Note que lty = “solid” is idéntica a lty=1.

tipo_linea <- rep(1,length(color_linea))        #Repetir length(color)=20 veces el 1
tipo_linea[cuts_num]<-c(2:(length(cuts_num)+1)) #Asignar 2, 3, 4 en las posiciones 2, 5, 8 de tipo_linea

#Resaltar posiciones importantes
cuts_num<-c(2,5,8) # Cortes

#Cortes basados en: Cohen, J. (1988). Statistical Power Analysis for the Behavioral Sciences (2nd ed.). Hillsdale, NJ: Lawrence Erlbaum Associates, Publishers.
cuts_cat<-c("pequeño","medio","grande") 
color_linea[cuts_num]<-c("black")

efecto <- d # Listado de los 20 valores de 20
efecto[cuts_num] <- cuts_cat  #Reemplazar en "efecto" las posiciones cuts_num (2, 5, 8) por las categorías de cuts_cat

par(fig=c(0,.8,0,1),new=TRUE)
## Warning in par(fig = c(0, 0.8, 0, 1), new = TRUE): llamada par(new=TRUE) sin
## gráfico
#Gráfica
plot(1, type="n", #no produce puntos ni líneas
     frame.plot=FALSE, 
     xlab="Tamaño muestral", ylab="Potencia", 
     xlim=c(1,150),  ylim=c(0,1), 
     main="t-Test", axes = FALSE)

#Editando los ejes, grid, etc.
abline(v=seq(0,150,by=10), col = "lightgray", lty = "dotted") # Grid vertical
abline(h=seq(0,1,by=.05), col = "lightgray", lty = "dotted")  # Grid horizontal
axis(1,seq(0,150,by=10)) # Números en eje X
axis(2,seq(0,1,by=.05))  # Números en eje Y

#Plot de las lineas 
#columnas <- 1:ncol(prueba) # lista de los valores 1:20
for(i in 1:length(columnas)) #length(columnas)=20
{
  lines(1:150,
        #prueba (data frame de 150 X 20, para graficar)
        #columna <- 1:ncol(prueba) listado de valores 1:20 
        prueba[,columnas[i]], #filtrar "prueba" para valor de columna
        col=color_linea[i],   #color_linea[cuts_num]<-c("black")
        lwd=grosor_linea,     #grosor de cada linea
        lty=tipo_linea[i]     #tipo_linea[cuts_num]<-c(2:(length(cuts_num)+1))
  )
}

#Leyendas
par(fig=c(.65,1,0,1),new=TRUE)
plot.new()
legend("top",legend=efecto, col=color_linea, lwd=3, lty=tipo_linea, title="Tamaño efecto", 
       bty="n" #Opciones: o (complete box), n (no box), 7, L, C, U
)

#Gráfica 2

#plot using ggplot2

library(ggplot2)
library(reshape)
## 
## Adjuntando el paquete: 'reshape'
## The following objects are masked from 'package:tidyr':
## 
##     expand, smiths
library(plotly)
## 
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:reshape':
## 
##     rename
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
obj <- cbind(size=1:150, prueba) #Agregando el tamaño al data frame "prueba" 

# Usar melt y unir con "effect" para el mapeo
#El data frame "obj" se reconstruye con respecto al parámetro id="size". 
melted <- cbind(reshape::melt(obj, id="size"), effect=rep(d,each=150)) 

p<- ggplot(data=melted, aes(x=size, y=value, color=as.factor(effect))) + 
  geom_line(size=0.7,alpha=.5) +
  ylab("Potencia") + 
  xlab("Tamaño muestral") + 
  ggtitle("t-Test")+
  theme_bw() +
  #guides(fill=guide_legend(title="Efecto"))
  #scale_fill_discrete(name = "Efecto")
  #labs(fill='Efecto') 
  #scale_fill_manual("Efecto"#,values=c("orange","red")
  scale_color_discrete(name = "Tamaño del efecto")    
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Interactive plot
plotly::ggplotly(p)

Análisis Caso 1

Al variar segun las instrucciones de la actividad los datos en el código suministrado se nota:

Comportamiento del efecto:

  • Efectos pequeños de 0.1 y 0.2, requieren tamaños de muestra mas grandes para alcanzar una potencia aceptable.
  • Efecto mediano de 0.5 requiere tamaños de muestra moderados para obtener buena potencia.
  • Efecto Grande de 0.8 genera alta potencia con tamaños de muestra más pequeños.

Comportamiento del nivel de significancia:

Un Nivel de significancia bajo de 0.01 alpha reduce la potencia de la prueba, especialmente en muestras pequeñas. Un nivel de significancia alto de 0.2 alpha aumenta la potencia, facilitando la detección de efectos con tamaños de muestra menores.

Tamaño de Muestra:

  • Muestras equeñas (20), proporcionan menor potencia, es más dificil detectar efectos, especialmente el tamaño del efecto o el nivel de significancia son bajos.
  • Muestras medianas (60, 100) mejoran la potencia, tienen una relación más fuerte entre el tamaño del efecto y la potencia.
  • Muestras grandes (140), presentan alta potencia, el impacto del nivel de significancia se vuelve menos crítico, ya que se detectan los efectos con mayor facilidad.
library(dplyr)    
## 
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:reshape':
## 
##     rename
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)    #Para manipulación de datos: separate, gather, spread
library(ggplot2)  
library(plotly)   #Para curvas de potencias interactivas
library(pwr)      #Para cálculo de las potencias

#Generar cálculos de las potencias con la funcion pwr.t2n.test.
#Es un t-test para 2 muestras con tamaños diferentes 
#Aquí: d es el tamaño del efecto, Power= potencia de la prueba= 1-beta): 

#pwr.t2n.test(n1 = NULL, n2= NULL, d = NULL, sig.level = 0.05, power = NULL,  alternative = c("two.sided",  "less","greater"))

ptab <- cbind(NULL, NULL)       

for (i in seq(0,1, length.out = 200)){
  pwrt1 <- pwr.t2n.test(n1 = 28, n2 = 1406, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  pwrt2 <- pwr.t2n.test(n1 = 144, n2 = 1290, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  pwrt3 <- pwr.t2n.test(n1 = 287, n2 = 1147, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  pwrt4 <- pwr.t2n.test(n1 = 430, n2 = 1004, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  pwrt5 <- pwr.t2n.test(n1 = 574, n2 = 860, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  pwrt6 <- pwr.t2n.test(n1 = 717, n2 = 717, 
                        sig.level = 0.05, power = NULL, 
                        d = i, alternative="two.sided")
  
  #Es un data frame de tamaño 200 por 12: 
  ptab <- rbind(ptab, cbind(pwrt1$d, pwrt1$power,
                            pwrt2$d, pwrt2$power,
                            pwrt3$d, pwrt3$power,
                            pwrt4$d, pwrt4$power,
                            pwrt5$d, pwrt5$power,
                            pwrt6$d, pwrt6$power))
}


#Es un data frame de tamaño 200 por 13 (la 1ra columna es ID)
ptab <- cbind(seq_len(nrow(ptab)), ptab)

colnames(ptab) <- c("id","n1=28, n2=1406;effect size","n1=28, n2=1406;power",
                    "n1=144, n2=1290;effect size","n1=144, n2=1290;power",
                    "n1=287, n2=1147;effect size","n1=287, n2=1147;power",
                    "n1=430, n2=1004;effect size","n1=430, n2=1004;power",
                    "n1=574, n2=860;effect size","n1=574, n2=860;power",
                    "n1=717, n2=717;effect size","n1=717, n2=717;power")

#gather se usa  para "reunir" un par key-value. En este caso, en 3 columnas: ID, variables y respuestas numericas
temp1 <- ptab %>% as.data.frame() %>%   gather(key = name, value = val, 2:13)

#Separar celdas en columnas, de acuerdo a una condición (sep=). En este caso, se separó "name" en dos columnas: samples y pruebas 
temp2 <- temp1 %>%   separate(col = name, into = c("samples", "pruebas"), sep = ";")


#La función spread hace lo opuesto a gather. Son funciones complementarias. 
#Es decir, si al resultado de aplicar la función spread le aplicamos la función gather llegamos al dataset original.
temp3 <- temp2 %>%   spread(key = pruebas, value = val)

#Convertir la variable "samples" a factor.
temp3$samples <- factor(temp3$samples, 
                        levels = c("n1=28, n2=1406", "n1=144, n2=1290", 
                                   "n1=287, n2=1147", "n1=430, n2=1004",
                                   "n1=574, n2=860", "n1=717, n2=717")
)

#Gráfica
p<- ggplot(temp3, aes(x = `effect size`, y = power, color = samples)) +
  geom_line(size=1) + 
  
  theme_bw() + 
  theme(axis.text=element_text(size=10), 
        axis.title=element_text(size=10), 
        legend.text=element_text(size=10)) +
  
  geom_vline(xintercept = .54, linetype = 2) +
  geom_hline(yintercept = 0.80, linetype = 2)+
  
  labs(x="Effect size", y="Power") +
  scale_color_discrete(name = "Sampling size") 

# so simple to make interactive plots
plotly::ggplotly(p)

Análisis Caso 2

Al variar segun las instrucciones de la actividad los datos en el código suministrado se nota:

Manteniendo fijo un alpha del 0.05

  • Con tamaños de muestra desequilibrados, se necesita un tamaño del efecto más grande para alcanzar una potencia aceptable del 80%.
  • Los tamaños muestrales equilibrados (n1 = n2) muestran la mayor potencia para cualquier tamaño del efecto dado.
  • la potencia cambia consistentemente con el tamaño del efecto para diferentes tamaños de muestra.

Variando el nivel de significancia

  • Con un nivel de significancia bajo del 0.01 se necesita una evidencia más fuerte para rechazar la hipótesis nula. Esto reduce la potencia.
  • Con un nivel de significancia alto del 0.2 se detectan diferencias con menos evidencia, lo que aumenta la potencia.

Comparativa con tamaños de muestra no equilibrados

  • los tamaños de muestra altamente desequilibrados (n1 = 28, n2 = 1406) aún requieren tamaños de efecto significativamente mayores para alcanzar el 80% de potencia.
  • La potencia es más baja y el tamaño del efecto necesario para alcanzar una potencia del 80% se incrementa.
  • En el caso de tamaños muestrales desequilibrados, esto significa que la prueba será menos sensible a detectar efectos reales, aumentando la probabilidad de errores Tipo II.