Para esta quinta aula prática de Estatística Não Paramétrica, precisaremos dos seguintes pacotes:
require(DescTools) # Faz os testes Q de Cochran e Page
require(multcompView) # Auxilia nas comparações múltiplas
require(PCMRMplus) # Fas os testes de Friedman e Nemenyi
Para fazer o teste Q de Cochran no R,
basta utilizar a função CochranQTest() do
pacote DescTools. Essa função tem o
seguinte argumento:
A função CochranQTest retorna as seguintes saídas:
Considere a avaliação da eficácia de quatro métodos de treinamento (A, B, C e D) na memorização de palavras em um grupo de 23 estudantes. Cada estudante foi submetido a todos os métodos, e depois de cada sessão, responderam corretamente (1) ou incorretamente (0) a um teste de memorização. Os dados com as respostas dos 23 estudantes são dados a seguir:
Queremos verificar se há diferenças significativas na proporção de respostas corretas entre os métodos. Para isto, vamos utilizar o teste Q de Cochran com um nível de significância global de 5%.
As hipóteses de interesse serão, portanto:
Inicialmente, precisamos salvar a base de dados em um objeto. Os comandos a seguir fazem isso:
Dados <- matrix(
c(0, 0, 1, 1,
0, 1, 1, 1,
0, 1, 1, 1,
0, 0, 1, 1,
1, 1, 1, 1,
1, 1, 0, 1,
0, 0, 1, 0,
1, 1, 1, 0,
0, 1, 1, 1,
0, 1, 0, 1,
0, 0, 1, 1,
0, 1, 1, 1,
1, 1, 1, 1,
0, 1, 1, 1,
1, 1, 0, 1,
1, 1, 1, 0,
0, 1, 1, 1,
0, 1, 0, 1,
0, 0, 1, 1,
0, 1, 1, 1,
1, 1, 1, 1,
0, 1, 1, 1,
1, 1, 0, 1),
nrow = 23, byrow = TRUE
)
colnames(Dados) <- c("Metodo_A", "Metodo_B", "Metodo_C", "Metodo_D")
rownames(Dados) <- paste("Estudante", 1:23)
Com os dados armazenados, o teste é realizado com o seguinte comando:
TesteQ = CochranQTest(Dados)
TesteQ
##
## Cochran's Q test
##
## data: y
## Q = 16, df = 3, p-value = 0.001134
Com um valor p de 0,0011 rejeita-se a hipótese nula. Isto é, há evidências de que pelo menos um dos métodos fornece uma proporção de respostas corretas diferente.
Como o exemplo anterior indicou que há diferenças na proporção de respostas corretas entre os métodos, é importante conduzir mais um passo na análise e fazer as comparações múltiplas segundo o teste de McNemar em cada par de combinações dos métodos.
Como já visto nesta disciplina, o teste de McNemar é feito
com a função mcnemar.test e testa a
hipótese de diferença na distribuição das categorias entre dois
tratamentos (condições). O código a seguir é uma função
completa que faz o teste de McNemar em todas as combinações par a par e
salva os valores-p destas comparações:
### Função para comparações múltiplas com o teste de McNemar
multiplas_comparacoes_McNemar <- function(dados) {
n_colunas <- ncol(dados) # número de tratamentos (condições)
p_values <- c() # Vetor para armazenar os p-values
comparacoes <- c() # Vetor para armazenar as comparações
for (i in 1:(n_colunas - 1)) { # Varrendo todas as combinações
for (j in (i + 1):n_colunas) { # par a par
# Criando a tabela de contingência
tabela <- table(dados[, i], dados[, j])
# Realizando o teste de McNemar e corrigindo se b+c < 25
if (tabela[2]+tabela[3]>=25) {
mcnemar_result <- mcnemar.test(tabela,correct = FALSE)
}else{
mcnemar_result <- mcnemar.test(tabela,correct = TRUE)
}
# Adicionando o valor p ao vetor
p_values <- c(p_values, mcnemar_result$p.value)
# Criando o nome da comparação com base nos nomes das colunas
comparacao_nome <- paste(colnames(dados)[i], colnames(dados)[j], sep = "-")
comparacoes <- c(comparacoes, comparacao_nome)
}
}
names(p_values)= comparacoes
return(p_values)
}
Portanto, esta função retorna um vetor com os valores-p dos testes de McNemar com o indicativo de qual comparação foi realizada.
Vamos executar essa função nos dados dos métodos de treinamento:
valor_p = multiplas_comparacoes_McNemar(Dados)
valor_p
## Metodo_A-Metodo_B Metodo_A-Metodo_C Metodo_A-Metodo_D Metodo_B-Metodo_C
## 0.004426526 0.024448945 0.005959526 1.000000000
## Metodo_B-Metodo_D Metodo_C-Metodo_D
## 0.683091398 0.723673610
Entretanto, estes valores-p ainda não estão
ajustados para corrigir a inflação do erro tipo
I atrelado ao nível de significância global.
Para ajustar os valores-p conforme cada uma das
correções vistas em sala (Bonferroni, Holm-Bonferroni, e BH)
utilizamos a função p.adjust que
necessita de um vetor com os valores-p e o método.
Tem-se, portanto, os seguintes comandos:
valor_p_bonf = p.adjust(valor_p,method="bonferroni")
valor_p_holm = p.adjust(valor_p,method="holm")
valor_p_BH = p.adjust(valor_p,method="BH")
valor_p_bonf
## Metodo_A-Metodo_B Metodo_A-Metodo_C Metodo_A-Metodo_D Metodo_B-Metodo_C
## 0.02655916 0.14669367 0.03575716 1.00000000
## Metodo_B-Metodo_D Metodo_C-Metodo_D
## 1.00000000 1.00000000
valor_p_holm
## Metodo_A-Metodo_B Metodo_A-Metodo_C Metodo_A-Metodo_D Metodo_B-Metodo_C
## 0.02655916 0.09779578 0.02979763 1.00000000
## Metodo_B-Metodo_D Metodo_C-Metodo_D
## 1.00000000 1.00000000
valor_p_BH
## Metodo_A-Metodo_B Metodo_A-Metodo_C Metodo_A-Metodo_D Metodo_B-Metodo_C
## 0.01787858 0.04889789 0.01787858 1.00000000
## Metodo_B-Metodo_D Metodo_C-Metodo_D
## 0.86840833 0.86840833
Note a diferença nos níveis de conservadorismo das correções.
Com os valores-p ajustados, o próximo passo é
colocar as letras que indiquem os resultados das comparações
efetuadas. Isso é feito com o comando
multcompLetters do pacote MultcompView que
apenas precisa receber um vetor com valores-p em que cada valor
tem um rótulo com a comparação efetuada:
multcompLetters(valor_p_bonf)
## Metodo_A Metodo_B Metodo_C Metodo_D
## "a" "b" "ab" "b"
multcompLetters(valor_p_holm)
## Metodo_A Metodo_B Metodo_C Metodo_D
## "a" "b" "ab" "b"
multcompLetters(valor_p_BH)
## Metodo_A Metodo_B Metodo_C Metodo_D
## "a" "b" "b" "b"
Como para este exemplo não temos um número muito elevado de comparações múltiplas, podemos utilizar as correções de Bonferroni ou Holm-Bonferroni. Ambas as correções concordam que o método A é diferente dos métodos B e D
Imagine que você deseja avaliar a eficácia de quatro tratamentos para reduzir dores de cabeça (Tratamentos A, B, C e D). Foram selecionados 30 pacientes e cada um foi exposto a todos os tratamentos, reportando se a dor foi reduzida (1) ou não (0) para cada tratamento.
Os dados coletados são os seguintes:
Dados <- matrix(c(
1, 1, 0, 0,
0, 0, 0, 1,
1, 1, 0, 0,
1, 1, 1, 0,
1, 0, 0, 1,
0, 1, 0, 0,
1, 1, 0, 0,
1, 0, 0, 1,
1, 1, 0, 0,
1, 0, 1, 1,
1, 1, 0, 0,
0, 1, 0, 0,
1, 0, 0, 1,
1, 1, 1, 0,
1, 1, 0, 0,
1, 1, 0, 0,
1, 0, 0, 1,
0, 1, 1, 0,
1, 0, 0, 1,
1, 1, 0, 0,
1, 1, 0, 0,
1, 1, 0, 0,
0, 0, 0, 1,
1, 1, 0, 0,
1, 1, 0, 0,
1, 1, 1, 0,
1, 0, 0, 1,
1, 1, 0, 0,
0, 1, 0, 0,
1, 0, 1, 1
), nrow = 30, byrow = TRUE)
# Nomeando as linhas e colunas
rownames(Dados) <- paste("Paciente", 1:30)
colnames(Dados) <- c("Trat A", "Trat B", "Trat C", "Trat D")
Utilize o teste Q de Cochran para investigar se a proporção de melhora das dores de cabeça é igual para todos os tratamentos. Caso necessário, recorra às comparações múltiplas. Considere \(\alpha=5\%\)
Para executar o teste de Page no R,
utilizaremos a função PageTest do pacote
DescTools. A função PageTest precisa
do seguinte argumento:
A função PageTest retorna as seguintes saídas:
Foi desenvolvido um programa para reduzir os níveis de estresse de trabalhadores. Para determinar se o programa foi bem-sucedido, uma amostra de 15 trabalhadores foi selecionada e seu nível de estresse foi medido (pontuações baixas indicam níveis mais altos de estresse) antes do programa, bem como 1, 2 e 3 semanas após o início do programa. Os dados obtidos estão abaixo:
Utilize o teste de Page com um nível de significância de 5% para investigar se há uma tendência crescente no escore associado ao stress. Ou seja, investigue se o programa está sendo eficaz.
As hipóteses de interesse serão, portanto:
Inicialmente, precisamos salvar a base de dados em um objeto. Os comandos a seguir fazem isso:
Dados <- matrix(
c(16,22,23,25,
12,18,24,29,
23,24,26,27,
8,20,28,30,
3,12,13,17,
5,13,11,15,
19,22,25,26,
22,22,23,26,
12,20,22,24,
16,22,26,29,
14,25,18,21,
24,26,21,23,
9,12,20,23,
3,9,13,16,
2,8,6,10),
nrow = 15, byrow = TRUE
)
colnames(Dados) <- c("Antes", "Semana 1", "Semana 2", "Semana 3")
rownames(Dados) <- paste("Trabalhador", 1:15)
Como a hipótese alternativa objetiva verificar uma tendência crescente e, com os dados armazenados, o teste é realizado com o seguinte comando:
TesteL = PageTest(Dados)
TesteL
##
## Page test for ordered alternatives
##
## data: Dados
## L = 436.5, p-value = 1.24e-10
Com um valor-p bem próximo de 0, a hipótese nula é rejeitada e há evidências de que o treinamento é eficaz, propiciando uma tendência crescente no escore de stress.
Se fosse necessário testar uma tendência decrescente, basta executar o seguinte comando para inverter as colunas antes de rodar o teste:
DadosInv<-Dados[, ncol(Dados):1]
Considere o interesse de analisar o desempenho acadêmico de 10 alunos após a aplicação sequencial de 3 métodos de ensino (A, B e C):
Dados <- matrix(c(
60, 75, 72,
58, 65, 67,
70, 68, 78,
50, 60, 55,
80, 85, 83,
55, 58, 62,
65, 72, 70,
60, 63, 68,
67, 70, 75,
62, 65, 64
), nrow = 10, byrow = TRUE)
colnames(Dados) <- c("Método A", "Método B", "Método C")
rownames(Dados) <- paste("Aluno", 1:10)
Queremos verificar, com o teste de Page, se há uma tendência crescente nas notas ao nível de significância de \(\alpha = 5%\)
Para fazer o teste de Friedman no R,
basta utilizar a função friedmanTest() do
pacote PMCMRplus. Essa função tem o
seguinte argumento:
A função friedmanTest retorna as seguintes saídas:
O departamento de vendas de uma empresa deseja avaliar quatro tipos de serviços realizados no processo de pós-venda. Foram entrevistados 18 clientes para identificar a preferência em relação aos quatros tipos de serviço. As quatro alternativas foram apresentadas e foi solicitado a cada entrevistado que ordenasse os tipos de serviço, atribuindo o valor 1 para o menos preferido até o valor 4 para o mais preferido. Os dados coletados são fornecidos abaixo:
Considerando um nível de significância de 5%, deseja-se saber se há diferença significativa na preferência dos clientes pelos quatro serviços realizados pela empresa no processo de pós-venda.
As hipóteses de interesse serão, portanto:
Inicialmente, precisamos salvar a base de dados em um objeto. Os comandos a seguir fazem isso:
Dados <- matrix(c(
4, 3, 2, 1,
4, 2, 3, 1,
3, 1, 2, 4,
3, 1, 2, 4,
4, 2, 1, 3,
3, 1, 2, 4,
1, 3, 2, 4,
4, 2, 1, 3,
3, 1, 2, 4,
4, 1, 3, 2,
4, 2, 3, 1,
3, 1, 2, 4,
4, 3, 2, 1,
4, 3, 2, 1,
1, 2, 3, 4,
4, 2, 3, 1,
4, 3, 2, 1,
2, 1, 4, 3),
nrow = 18, byrow = TRUE)
colnames(Dados) <- c("Servico 1", "Servico 2", "Servico 3", "Servico 4")
rownames(Dados) <- paste("Entrevistado", 1:18)
Com os dados armazenados, o teste é realizado com o seguinte comando:
TesteF = PMCMRplus::friedmanTest(Dados)
TesteF
##
## Friedman rank sum test
##
## data: y
## Friedman chi-squared = 11.133, df = 3, p-value = 0.01103
Com um valor p de 0,01103 rejeita-se a hipótese nula. Isto é, há evidências de que pelo menos um dos serviço possui uma mediana das preferências diferente.
Como o exemplo anterior indicou que há diferenças na medianas das preferências dos serviços entre os métodos, é importante conduzir mais um passo na análise e fazer as comparações múltiplas segundo o teste de Nemenyi em cada par de combinações dos métodos.
O pacote PMCMRplus possui a função
frdAllPairsNemenyiTest() que já faz todas as
comparações múltiplas necessárias. Basta colocar os
dados como argumento. Segue o comando:
matriz_p_value = PMCMRplus::frdAllPairsNemenyiTest(Dados)$p.value
matriz_p_value
## Servico 1 Servico 2 Servico 3
## Servico 2 0.006846536 NA NA
## Servico 3 0.092643123 0.8028740 NA
## Servico 4 0.335169780 0.4080497 0.9171545
Essa matriz contempla todos os valores-p para as comparações múltiplas entre os serviços. Lembre-se que este teste já incorpora uma correção e não temos que fazer ajustes adicionais. Vamos transformar essa matriz em um vetor para extrair as letras.
vetor_p_value <- as.vector(matriz_p_value)
names(vetor_p_value) <- paste(rep(colnames(matriz_p_value),
each = nrow(matriz_p_value)),
rep(rownames(matriz_p_value),
times = ncol(matriz_p_value)),sep = "-")
vetor_p_value <- vetor_p_value[!is.na(vetor_p_value)]
vetor_p_value
## Servico 1-Servico 2 Servico 1-Servico 3 Servico 1-Servico 4 Servico 2-Servico 3
## 0.006846536 0.092643123 0.335169780 0.802873960
## Servico 2-Servico 4 Servico 3-Servico 4
## 0.408049698 0.917154513
Agora sim temos um objeto pronto para ser usado na
função multcompLetters() para extrair as
letras:
letras = multcompLetters(vetor_p_value)
letras
## Servico 1 Servico 2 Servico 3 Servico 4
## "a" "b" "ab" "ab"
Portanto, há evidências que o serviço 1 proporcione uma diferença na preferência com respeito ao serviço 2.
Suponha que estamos analisando o efeito de três diferentes tratamentos de reabilitação (Tratamento A, Tratamento B e Tratamento C) em uma condição específica de saúde, com um número maior 20 participantes. A recuperação dos pacientes com respeito a cada um dos métodos foi medida com uma pontuação de 0 a 10, sendo 0 a recuperação mínima e 10 a recuperação máxima. Os dados estão disponíveis abaixo:
Dados <- matrix(c(
7.5, 6.0, 8.2,
5.3, 7.0, 6.5,
7.1, 8.0, 6.8,
5.5, 7.9, 8.1,
7.3, 6.7, 7.4,
6.9, 5.6, 7.2,
6.4, 8.3, 6.4,
7.2, 6.5, 7.8,
6.9, 7.3, 8.0,
6.3, 6.8, 7.0,
7.6, 7.5, 6.7,
7.9, 6.2, 6.9,
7.1, 8.2, 6.1,
7.4, 8.0, 7.5,
8.3, 7.8, 7.9,
8.2, 8.1, 7.9,
8.5, 7.6, 7.8,
8.4, 7.9, 8.2,
8.3, 7.7, 8.1,
7.8, 7.5, 8.0), nrow = 20, byrow = FALSE)
colnames(Dados) <- c("Método A", "Método B", "Método C")
rownames(Dados) <- paste("Aluno", 1:20)
Queremos verificar, com o teste de Friedman, se existe diferença nas medianas das pontuações em pelo menos um dos tratamentos ao nível de significância de \(\alpha = 5%\). Conduza as comparações múltiplas, se necessário.
Na lista prática, resolva os exercícios 5-9.