2 conjuntos não pareados

a1 = read.csv("https://www.ic.unicamp.br/~wainer/cursos/1s2020/430/a1.csv", header = F)
b1 = read.csv("https://www.ic.unicamp.br/~wainer/cursos/1s2020/430/b1.csv", header = F)

Usando o pacote BEST

library(BEST)
## Loading required package: HDInterval
aa = BESTmcmc(a1$V1,b1$V1)
## Waiting for parallel processing to complete...
## done.

aa contem a nuvem de pontos que tem a distribuição \(P(\theta | Dados, BEST)\) ou seja a probabilidade dos 5 hiperparametros do modelo BEST (mu1, mu2, sigma1 sigma2, e nu) tendo em vista os dados a1 e b1. São 100 mil pontos para os 5 pontos.

Vejamos os 3 primeiros valores do mu1, mu2, sigma1, sigma2, e nu

aa$mu1[1:3]
## [1]  9.877115 10.234907  7.588416
aa$mu2[1:3]
## [1] 6.110162 6.387353 4.361997
aa$sigma1[1:3]
## [1] 5.698762 5.435023 6.084662
aa$sigma2[1:3]
## [1] 2.641254 2.666794 2.590145
aa$nu[1:3]
## [1] 29.43932 25.95301 51.35026
length(aa$mu1)
## [1] 100002

O summary do aa retorna a média, mediana e outros resumos de cada uma dessas variáveis, e computa outras variávies como a diferença das médias muDiff a diferença dos desvios padrão sigmaDiff, e outros.

O tamanho de efeito effSz é o Cohen D computado usando a media dos desvios padrão dos 2 conjuntos (veja exercício 2) que não é considerado como a melhor medida de tamanho de efeito. Considera-se que a medida do Cohen D usando a media ponderada dos desvios padrão é mais correta (como usamos no exercício 2).

summary(aa)
##            mean median   mode HDI%   HDIlo  HDIup compVal %>compVal
## mu1        8.01  8.011  8.108   95  5.0133  10.95                  
## mu2        5.06  5.060  5.052   95  3.6280   6.48                  
## muDiff     2.95  2.954  3.118   95 -0.3319   6.25       0      96.2
## sigma1     5.48  5.288  4.891   95  3.3623   7.89                  
## sigma2     3.06  2.988  2.850   95  2.0573   4.21                  
## sigmaDiff  2.42  2.273  2.131   95 -0.0779   5.16       0      98.3
## nu        40.17 31.843 16.227   95  2.5836 101.45                  
## log10nu    1.48  1.503  1.601   95  0.8017   2.10                  
## effSz      0.68  0.677  0.643   95 -0.0795   1.43       0      96.2

compVal tem valor 0 (pode ser alterado na chamada do summary) e %>compVal conta a porcentagem dos exemplos (no caso das variáveis computadas com a diferença das medias e desvio padrão) que são maiores que o compVal (0 nesse caso)

Ou seja em 96.3% dos casos a média mu1 menos mu2 é maior que 0, ou seja com probabilidade 0.983 a média de a1 é maior que a média de b1.

Veja que você pode gerar esses valores usando os dados em aa diretamente

mean(aa$mu1)
## [1] 8.010957
median(aa$mu2)
## [1] 5.059592
sum(aa$mu1-aa$mu2>0)/length(aa$mu1)
## [1] 0.9618208

ROPE

Nós definimos que uma diferença ente +1 e -1 entre as médias é irrelevante, ou seja se diferença entre as médias for menor do que 1, então diremos que não há uma diferença prática entre os 2 grupos de medidas.

Pode-se incluir o ROPE na geração do summary passando o parâmetro ROPEm (m para mean). Também é possível passar um ROPE para a diferença entre desvio padrão, ou para tamanho de efeito.

summary(aa, ROPEm=c(-1,1))
##            mean median   mode HDI%   HDIlo  HDIup compVal %>compVal ROPElow
## mu1        8.01  8.011  8.108   95  5.0133  10.95                          
## mu2        5.06  5.060  5.052   95  3.6280   6.48                          
## muDiff     2.95  2.954  3.118   95 -0.3319   6.25       0      96.2      -1
## sigma1     5.48  5.288  4.891   95  3.3623   7.89                          
## sigma2     3.06  2.988  2.850   95  2.0573   4.21                          
## sigmaDiff  2.42  2.273  2.131   95 -0.0779   5.16       0      98.3        
## nu        40.17 31.843 16.227   95  2.5836 101.45                          
## log10nu    1.48  1.503  1.601   95  0.8017   2.10                          
## effSz      0.68  0.677  0.643   95 -0.0795   1.43       0      96.2        
##           ROPEhigh %InROPE
## mu1                       
## mu2                       
## muDiff           1    10.4
## sigma1                    
## sigma2                    
## sigmaDiff                 
## nu                        
## log10nu                   
## effSz

Poderíamos ter feito as contas direto nos dados

sum(abs(aa$mu1-aa$mu2)<1)/length(aa$mu1)
## [1] 0.1035679

Usando o bayes.t.test

A função bayes.t.test tem a vantagem de ser um substituto direto para a função t.test, com os mesmos parâmetros e uma saída similar.

library(BayesianFirstAid)
## Loading required package: rjags
## Loading required package: coda
## Linked to JAGS 4.3.0
## Loaded modules: basemod,bugs
bayes.t.test(a1$V1,b1$V1)
## 
##  Bayesian estimation supersedes the t test (BEST) - two sample
## 
## data: a1$V1 (n = 15) and b1$V1 (n = 20)
## 
##   Estimates [95% credible interval]
## mean of a1$V1: 8.0 [5.0, 11]
## mean of b1$V1: 5.1 [3.6, 6.4]
## difference of the means: 3.0 [-0.33, 6.2]
## sd of a1$V1: 5.3 [3.4, 7.9]
## sd of b1$V1: 3.0 [2.1, 4.2]
## 
## The difference of the means is greater than 0 by a probability of 0.961 
## and less than 0 by a probability of 0.039

Compare a media mean of a1$V1 como mean de mu1 acima, e intervalo de confiança (chamado de credible interval aqui) com o HDI acima (HDI e credible interval são sinônimos). Compare também difference of the means

Mas o bayes.t.test não permite incluir um ROPE (porque o t.test também não tem um ROPE). Para usar o ROPE é preciso acessar a nuvem de pontos gerados, que é mais complicado nessa função

bb=bayes.t.test(a1$V1,b1$V1)
str(bb)
## List of 11
##  $ x           : num [1:15] 1.23 7.76 14.14 11.05 2.75 ...
##  $ y           : num [1:20] 1.528 4.827 4.654 4.207 0.908 ...
##  $ comp        : num 0
##  $ cred_mass   : num 0.95
##  $ x_name      : chr "a1$V1"
##  $ y_name      : chr "b1$V1"
##  $ data_name   : chr "a1$V1 and b1$V1"
##  $ x_data_expr : chr "a1$V1"
##  $ y_data_expr : chr "b1$V1"
##  $ mcmc_samples:List of 3
##   ..$ : 'mcmc' num [1:10000, 1:10] 4.51 7.58 7.23 10.71 8.57 ...
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : NULL
##   .. .. ..$ : chr [1:10] "mu_x" "sigma_x" "mu_y" "sigma_y" ...
##   .. ..- attr(*, "mcpar")= num [1:3] 601 10600 1
##   ..$ : 'mcmc' num [1:10000, 1:10] 10.17 8.84 8.47 7.89 6.63 ...
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : NULL
##   .. .. ..$ : chr [1:10] "mu_x" "sigma_x" "mu_y" "sigma_y" ...
##   .. ..- attr(*, "mcpar")= num [1:3] 601 10600 1
##   ..$ : 'mcmc' num [1:10000, 1:10] 6.93 6.79 7.12 6.2 5.73 ...
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : NULL
##   .. .. ..$ : chr [1:10] "mu_x" "sigma_x" "mu_y" "sigma_y" ...
##   .. ..- attr(*, "mcpar")= num [1:3] 601 10600 1
##   ..- attr(*, "class")= chr "mcmc.list"
##  $ stats       : num [1:10, 1:16] 8.02 5.45 5.07 3.06 2.96 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:10] "mu_x" "sigma_x" "mu_y" "sigma_y" ...
##   .. ..$ : chr [1:16] "mean" "sd" "HDI%" "comp" ...
##  - attr(*, "class")= chr [1:2] "bayes_two_sample_t_test" "bayesian_first_aid"

str mostra os campos de um tipo de dado complexo (neste caso uma matriz dentro de listas dentro de listas) bb$mcmc_samples é uma lista de 3 data frames com a nuvem de pontos

xx = bb$mcmc_samples
xx[[1]][1:3,]
##          mu_x  sigma_x     mu_y  sigma_y    mu_diff sigma_diff       nu
## [1,] 4.513573 5.990897 4.811379 2.850797 -0.2978055   3.140099 64.47552
## [2,] 7.577622 7.056462 5.533887 3.180129  2.0437342   3.876333 70.47086
## [3,] 7.232481 8.061409 5.564539 2.615377  1.6679420   5.446033 34.59055
##         eff_size    x_pred   y_pred
## [1,] -0.06347945 15.724783 3.513329
## [2,]  0.37342303 17.257272 3.491619
## [3,]  0.27832585 -7.242325 8.380250

a ultima linha é as 3 primeiras linhas do 1a matriz com os pontos. Para calcular a porcentagem dentro do ROPE podemos fazer

soma1 = sum(abs(xx[[1]][,1] - xx[[1]][,3]) < 1)
soma2 = sum(abs(xx[[2]][,1] - xx[[2]][,3]) < 1)
soma3 = sum(abs(xx[[3]][,1] - xx[[3]][,3]) < 1)
l1 = length(xx[[1]][,1])
l2 = length(xx[[2]][,1])
l3 = length(xx[[3]][,1])
(soma1+soma2+soma3)/(l1+l2+l3)
## [1] 0.1035

Comparar com o inROPE acima.

Dados pareados

  pa = read.csv("https://www.ic.unicamp.br/~wainer/cursos/1s2020/430/paired.csv", header = F)

Usando o BEST

o BEST não permite o modelo de dados pareados diretamente. Mas como eu mencionei no exercício, uma analise de 2 conjuntos pareados é equivalente a analise de 1 conjunto onde esse conjunto é a diferença (pareada) dos dados pareados.

cc =  BESTmcmc(pa$V1-pa$V2)
## Waiting for parallel processing to complete...done.
summary(cc,ROPEm=c(-1,1))
##          mean median mode HDI% HDIlo HDIup compVal %>compVal ROPElow ROPEhigh
## mu       1.39   1.39 1.43   95 0.488  2.29       0      99.6      -1        1
## sigma    1.31   1.24 1.10   95 0.678  2.15                                   
## nu      32.42  23.82 7.92   95 1.000 90.02                                   
## log10nu  1.34   1.38 1.44   95 0.489  2.08                                   
## effSz    1.15   1.12 1.08   95 0.230  2.09       0      99.6                 
##         %InROPE
## mu         17.6
## sigma          
## nu             
## log10nu        
## effSz

Veja que isso NAO é equivalente a

cc2 =  BESTmcmc(pa$V1,pa$V2)
## Waiting for parallel processing to complete...done.
summary(cc2,ROPEm=c(-1,1))
##             mean median   mode HDI%  HDIlo HDIup compVal %>compVal ROPElow
## mu1       14.402 14.400 14.421   95 12.588 16.23                          
## mu2       13.053 13.048 13.031   95 11.975 14.21                          
## muDiff     1.348  1.346  1.406   95 -0.762  3.48       0      90.4      -1
## sigma1     2.676  2.523  2.302   95  1.364  4.33                          
## sigma2     1.630  1.537  1.407   95  0.800  2.64                          
## sigmaDiff  1.046  0.963  0.859   95 -0.744  3.05       0      89.7        
## nu        33.122 24.416  8.797   95  1.199 91.51                          
## log10nu    1.357  1.388  1.469   95  0.564  2.08                          
## effSz      0.631  0.626  0.643   95 -0.313  1.60       0      90.4        
##           ROPEhigh %InROPE
## mu1                       
## mu2                       
## muDiff           1    34.9
## sigma1                    
## sigma2                    
## sigmaDiff                 
## nu                        
## log10nu                   
## effSz

Este logo acima é a comparação **NAO PAREADA* do pa$V1 e pa$V2. Compare a linha do mu na pareada com a linha do muDiff na não pareada - não são os mesmos resultados!

Usando o bayes.t.test

por ser um drop in replacement ao t.test, podemos passar o parâmetro paired=T para essa função e obter a análise pareada

bayes.t.test(pa$V1,pa$V2,paired=T)
## 
##  Bayesian estimation supersedes the t test (BEST) - paired samples
## 
## data: pa$V1 and pa$V2, n = 10
## 
##   Estimates [95% credible interval]
## mean paired difference: 1.4 [0.48, 2.3]
## sd of the paired differences: 1.2 [0.67, 2.2]
## 
## The mean difference is more than 0 by a probability of 0.996 
## and less than 0 by a probability of 0.004

Vou deixar como exercício para os interessados extrair a porcentagem no inROPE!