In [1]:
suppressMessages ( library ( dplyr ) )
suppressMessages ( library ( ggplot2 ) )
options(dplyr.summarise.inform = FALSE)
  1. Os dados a seguir correspondem a médias de uma variável quantitativa de acordo com o genótipo conjunto de dois locos de marcadores moleculares (do tipo Single Nucleotide Polimorphsms, SNP_A e SNP_B)), para 7 populações sob estudo. As ações gênicas nessas populações são denominadas como: P1: Ação gênica intermediária; P2: Dominância completa; P3: Ação gênica complementar; P4: Epistasia complexa; P5: Dominância parcial; P6: Superdominância; P7: Ação gênica duplicada.

TabelaLista2.PNG

a) Para cada população (P1 a P7) construa o gráfico de perfis de médias correspondente. Com base nesse gráfico, há indicação de efeito de interação entre os dois fatores genéticos (SNP_A e SNP_B)? Comente.

In [2]:
# dados para matrizes
medias1 = t ( matrix ( c ( 20 , 18 , 16 , 17 , 15 , 13 , 14 , 12 , 10) , ncol = 3 ) )
medias2 = t ( matrix ( c ( 20 , 20 , 16 , 20 , 20 , 16 , 14 , 14 , 10) , ncol = 3 ) )
medias3 = t ( matrix ( c ( 20 , 20 , 10 , 20 , 20 , 10 , 10 , 10 , 10) , ncol = 3 ) )
medias4 = t ( matrix ( c ( 38.7 , 6.6 , 3.2 , 4 , 2 , 1.3 , 2.7 , 3.4 , 1.6) , ncol = 3 ) )
medias5 = t ( matrix ( c ( 20 , 19 , 16 , 19 , 18 , 15 , 14 , 13 , 10) , ncol = 3 ) )
medias6 = t ( matrix ( c ( 20 , 21 , 16 , 22 , 23 , 18 , 14 , 15 , 10) , ncol = 3 ) )
medias7 = t ( matrix ( c ( 20 , 20 , 20 , 20 , 20 , 20 , 20 , 20 , 10) , ncol = 3 ) )
# Checagem
medias1
A matrix: 3 × 3 of type dbl
201816
171513
141210
In [3]:
mediasTodas = c ( )

for ( i in 1:7 ){
    
    a = matrix ( get ( paste0 ( "medias" , i ) ) , nrow = 9 , ncol = 1 )
    mediasTodas = c ( mediasTodas , a )
}

df = as.data.frame ( cbind ( mediasTodas , rep ( c ( "aa" , "Aa" , "AA" ) , 9*7 ) , c (rep ("bb",3),rep("Bb",3),rep("BB",3) ) , paste0 ("P" ,sort ( rep ( seq ( 1 , 7 ) , 9 ) ) ) ) )
glimpse ( df )
Rows: 189
Columns: 4
$ mediasTodas <fct> 20, 17, 14, 18, 15, 12, 16, 13, 10, 20, 20, 14, 20, 20,...
$ V2          <fct> aa, Aa, AA, aa, Aa, AA, aa, Aa, AA, aa, Aa, AA, aa, Aa,...
$ V3          <fct> bb, bb, bb, Bb, Bb, Bb, BB, BB, BB, bb, bb, bb, Bb, Bb,...
$ V4          <fct> P1, P1, P1, P1, P1, P1, P1, P1, P1, P2, P2, P2, P2, P2,...
In [4]:
colnames ( df ) = c ( "media" , "genA" , "genB" , "pop" )
df$media = as.numeric ( as.character ( df$media ) )
head ( df , 10 )
A data.frame: 10 × 4
mediagenAgenBpop
<dbl><fct><fct><fct>
120aabbP1
217AabbP1
314AAbbP1
418aaBbP1
515AaBbP1
612AABbP1
716aaBBP1
813AaBBP1
910AABBP1
1020aabbP2
In [5]:
df %>% ggplot ( aes ( x = genA , y = media , group = genB , col = genB ) ) + 
geom_line ( aes(linetype=genB) ) + 
geom_point ( ) + 
facet_wrap ( ~pop ) +
labs ( x = "Gene A" , y = "Média" , linetype = "Gene B" , col = "Gene B" , title = "Gráfico de perfil de médias" )

Pode-se observar descritivamente que:

  • Não há evidencias de interação entre os genótipos nas populações 1, 2, 5 e 6;
  • Há evidencias de interação entre os genótipos nas populações 3, 4 e 7.

b) Vamos agora gerar dados de Delineamentos Completamente Aleatorizados (DCA) com esquema Fatorial 3x3 (Fator SNP_A e fator SNP_B, ambos, em 3 níveis genotípicos). Considere $\sigma^2$ =1 e, com base nas 9 médias apresentadas em P1 a P7, gere $r=25$ valores para cada um dos 9 grupos, sob o modelo de distribuição Normal. Em cada caso, obtenha a tabela de ANOVA e interprete os resultados.

In [6]:
# Gerar os dados para os cruzamentos genotípicos para todas as populações

genA = c ( "aa" , "Aa" , "AA" )
genB = c ( "bb" , "Bb" , "BB" )


n = 25
sigma = 1
set.seed ( 202010 )
# loop nas populações
for ( i in 1:7 ){
    
#   vetor no qual serão armazenados os valores dos cruzamentos genotipicos para cada população
    pop = c ( )
    
#     loop nas linhas de cada população
    for ( indiceA in 1:length ( genA ) ){
        
#   loop nas colunas de cada população
      for ( indiceB in 1:length ( genB ) ){
        
#       medias é a matriz da população i (de 1 a 7)
        medias = get ( paste0 ( "medias" , i ) )
#       geracao dos valores para a populacao i da combinacao genotipica (indiceA: 1 = aa , 2 = Aa , 3 = AA; indiceB: 1 = bb , 2 = Bb , 3 = BB)
        obs = rnorm ( n , mean = medias [ indiceA , indiceB ] , sd = 1 )
#       guardando valores no loop
        observacoesConjuntas = cbind ( obs , genA [ indiceA ] , genB [ indiceB ]  )
        pop = rbind ( pop , observacoesConjuntas )

      }
  
    }

assign ( paste0 ( "dfCruzamento" , i) , as.data.frame ( pop ) )
assign ( paste0 ( "dfCruzamento" , i) , get ( paste0 ( "dfCruzamento" , i) ) %>% rename ( "Obs" = "obs" , "genA" = "V2" , "genB" = "V3" ) )
assign ( paste0 ( "dfCruzamento" , i) , get ( paste0 ( "dfCruzamento" , i) ) %>% mutate ( Obs = as.numeric ( as.character ( Obs ) ) ) )
assign ( paste0 ( "dfCruzamento" , i) , get ( paste0 ( "dfCruzamento" , i) ) %>% mutate ( genA = as.factor ( genA ) ) )
assign ( paste0 ( "dfCruzamento" , i) , get ( paste0 ( "dfCruzamento" , i) ) %>% mutate ( genB = as.factor ( genB ) ) )
    
}
In [7]:
# função para imprimir tabelas de anova
printTabela = function ( df ){
    
    print ( anova ( aov ( df$Obs ~ df$genA * df$genB ) ) )
    print ( summary ( lm ( df$Obs ~ df$genA * df$genB ) ) )
    
}
In [8]:
for ( i in 1:7 ){
    
    print (paste ( "População" , i ) )
    printTabela ( get ( paste0 ( "dfCruzamento" , i ) ) )
    
}
[1] "População 1"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq  F value Pr(>F)    
df$genA           2 1352.97  676.48 622.3778 <2e-16 ***
df$genB           2  594.04  297.02 273.2655 <2e-16 ***
df$genA:df$genB   4    2.86    0.71   0.6572 0.6224    
Residuals       216  234.78    1.09                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.95184 -0.66356 -0.05399  0.71769  2.63014 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)          19.7308     0.2085  94.626  < 2e-16 ***
df$genAAa            -2.7738     0.2949  -9.406  < 2e-16 ***
df$genAAA            -5.7016     0.2949 -19.335  < 2e-16 ***
df$genBBb            -2.0140     0.2949  -6.830 8.51e-11 ***
df$genBBB            -3.6103     0.2949 -12.243  < 2e-16 ***
df$genAAa:df$genBBb  -0.1111     0.4170  -0.266    0.790    
df$genAAA:df$genBBb  -0.2681     0.4170  -0.643    0.521    
df$genAAa:df$genBBB  -0.4513     0.4170  -1.082    0.280    
df$genAAA:df$genBBB  -0.6464     0.4170  -1.550    0.123    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.043 on 216 degrees of freedom
Multiple R-squared:  0.8925,	Adjusted R-squared:  0.8886 
F-statistic: 224.2 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 2"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq  F value Pr(>F)    
df$genA           2 1948.83  974.42 951.4524 <2e-16 ***
df$genB           2  856.71  428.36 418.2609 <2e-16 ***
df$genA:df$genB   4    1.54    0.39   0.3761 0.8255    
Residuals       216  221.21    1.02                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.1041 -0.7630  0.0066  0.5478  3.6479 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         20.03118    0.20240  98.969   <2e-16 ***
df$genAAa           -0.13877    0.28624  -0.485    0.628    
df$genAAA           -6.08642    0.28624 -21.264   <2e-16 ***
df$genBBb           -0.05079    0.28624  -0.177    0.859    
df$genBBB           -4.08118    0.28624 -14.258   <2e-16 ***
df$genAAa:df$genBBb  0.08111    0.40480   0.200    0.841    
df$genAAA:df$genBBb -0.21657    0.40480  -0.535    0.593    
df$genAAa:df$genBBB  0.06919    0.40480   0.171    0.864    
df$genAAA:df$genBBB -0.38513    0.40480  -0.951    0.342    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.012 on 216 degrees of freedom
Multiple R-squared:  0.927,	Adjusted R-squared:  0.9242 
F-statistic: 342.6 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 3"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq F value    Pr(>F)    
df$genA           2 2160.54 1080.27 1187.40 < 2.2e-16 ***
df$genB           2 2206.96 1103.48 1212.91 < 2.2e-16 ***
df$genA:df$genB   4 1164.54  291.13  320.01 < 2.2e-16 ***
Residuals       216  196.51    0.91                      
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.67445 -0.55463  0.01051  0.62125  2.69973 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)          20.003444   0.190765 104.859   <2e-16 ***
df$genAAa             0.005286   0.269782   0.020    0.984    
df$genAAA           -10.062262   0.269782 -37.298   <2e-16 ***
df$genBBb             0.035349   0.269782   0.131    0.896    
df$genBBB           -10.109306   0.269782 -37.472   <2e-16 ***
df$genAAa:df$genBBb  -0.204649   0.381529  -0.536    0.592    
df$genAAA:df$genBBb   0.057599   0.381529   0.151    0.880    
df$genAAa:df$genBBB   0.041014   0.381529   0.107    0.914    
df$genAAA:df$genBBB  10.335227   0.381529  27.089   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.9538 on 216 degrees of freedom
Multiple R-squared:  0.9657,	Adjusted R-squared:  0.9644 
F-statistic: 760.1 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 4"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq F value    Pr(>F)    
df$genA           2  9345.2  4672.6  4019.8 < 2.2e-16 ***
df$genB           2  7499.2  3749.6  3225.7 < 2.2e-16 ***
df$genA:df$genB   4 12209.3  3052.3  2625.9 < 2.2e-16 ***
Residuals       216   251.1     1.2                      
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.0863 -0.6222 -0.0334  0.7294  2.5299 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)          38.8935     0.2156  180.37   <2e-16 ***
df$genAAa           -34.7921     0.3049 -114.09   <2e-16 ***
df$genAAA           -36.5908     0.3049 -119.99   <2e-16 ***
df$genBBb           -32.6015     0.3049 -106.91   <2e-16 ***
df$genBBB           -35.7250     0.3049 -117.15   <2e-16 ***
df$genAAa:df$genBBb  30.6037     0.4313   70.96   <2e-16 ***
df$genAAA:df$genBBb  33.5576     0.4313   77.81   <2e-16 ***
df$genAAa:df$genBBB  33.1573     0.4313   76.89   <2e-16 ***
df$genAAA:df$genBBB  34.8137     0.4313   80.73   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.078 on 216 degrees of freedom
Multiple R-squared:  0.9914,	Adjusted R-squared:  0.9911 
F-statistic:  3124 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 5"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq  F value Pr(>F)    
df$genA           2 1348.73  674.37 644.9756 <2e-16 ***
df$genB           2  671.74  335.87 321.2320 <2e-16 ***
df$genA:df$genB   4    1.30    0.33   0.3112 0.8703    
Residuals       216  225.84    1.05                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.67837 -0.71263  0.00176  0.68551  2.78375 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)          19.8692     0.2045  97.157  < 2e-16 ***
df$genAAa            -1.0055     0.2892  -3.477 0.000614 ***
df$genAAA            -5.7676     0.2892 -19.942  < 2e-16 ***
df$genBBb            -0.9662     0.2892  -3.341 0.000984 ***
df$genBBB            -4.2014     0.2892 -14.527  < 2e-16 ***
df$genAAa:df$genBBb  -0.1277     0.4090  -0.312 0.755151    
df$genAAA:df$genBBb   0.1994     0.4090   0.487 0.626400    
df$genAAa:df$genBBB   0.2075     0.4090   0.507 0.612441    
df$genAAA:df$genBBB   0.2630     0.4090   0.643 0.520878    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.023 on 216 degrees of freedom
Multiple R-squared:  0.8995,	Adjusted R-squared:  0.8958 
F-statistic: 241.7 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 6"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq  F value Pr(>F)    
df$genA           2 2638.38 1319.19 1354.190 <2e-16 ***
df$genB           2  926.76  463.38  475.674 <2e-16 ***
df$genA:df$genB   4    3.69    0.92    0.948 0.4371    
Residuals       216  210.42    0.97                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.4117 -0.6632 -0.0048  0.5606  2.8203 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         19.77571    0.19740 100.182  < 2e-16 ***
df$genAAa            1.90493    0.27916   6.824 8.81e-11 ***
df$genAAA           -5.80677    0.27916 -20.801  < 2e-16 ***
df$genBBb            0.90628    0.27916   3.246  0.00135 ** 
df$genBBB           -3.57961    0.27916 -12.823  < 2e-16 ***
df$genAAa:df$genBBb  0.48430    0.39480   1.227  0.22127    
df$genAAA:df$genBBb -0.09944    0.39480  -0.252  0.80137    
df$genAAa:df$genBBB  0.09245    0.39480   0.234  0.81508    
df$genAAA:df$genBBB -0.43473    0.39480  -1.101  0.27206    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.987 on 216 degrees of freedom
Multiple R-squared:  0.9443,	Adjusted R-squared:  0.9423 
F-statistic: 457.9 on 8 and 216 DF,  p-value: < 2.2e-16

[1] "População 7"
Analysis of Variance Table

Response: df$Obs
                 Df  Sum Sq Mean Sq F value    Pr(>F)    
df$genA           2  521.57 260.785  286.37 < 2.2e-16 ***
df$genB           2  613.25 306.624  336.71 < 2.2e-16 ***
df$genA:df$genB   4 1170.09 292.524  321.22 < 2.2e-16 ***
Residuals       216  196.70   0.911                      
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Call:
lm(formula = df$Obs ~ df$genA * df$genB)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.30238 -0.66452  0.05194  0.64053  2.37053 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)          19.94550    0.19086 104.505   <2e-16 ***
df$genAAa             0.29550    0.26991   1.095    0.275    
df$genAAA             0.30378    0.26991   1.125    0.262    
df$genBBb             0.20776    0.26991   0.770    0.442    
df$genBBB             0.08922    0.26991   0.331    0.741    
df$genAAa:df$genBBb  -0.32799    0.38171  -0.859    0.391    
df$genAAA:df$genBBb  -0.09505    0.38171  -0.249    0.804    
df$genAAa:df$genBBB  -0.29920    0.38171  -0.784    0.434    
df$genAAA:df$genBBB -10.37333    0.38171 -27.176   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.9543 on 216 degrees of freedom
Multiple R-squared:  0.9214,	Adjusted R-squared:  0.9185 
F-statistic: 316.4 on 8 and 216 DF,  p-value: < 2.2e-16

Assim como havíamos deduzido a partir dos gráficos, temos que nas populações 3, 4 e 7 há evidencias para se rejeitar a hipótese de que não há interação entre os genótipos, enquanto que nas demais não.

  1. Considere os dados do arquivo “map.txt” que traz informações de 13 variáveis fenotípicas ("SEX", "Peso", "Altura", "CIRCABD", "GLICOSE", "CTOTAL", "TRIG", "Idade", "mediaPAS", "mediaPAD", "MedPres", "MedCol", "MedDb"), além do genótipo de 102 SNPs ("rs12628452_A" "rs7289830_T", etc.) para uma amostra de 1675 indivíduos.

a) Seguindo o princípio da Aleatorização Mendeliana (Burgess and Thompson, 2015), suponha que o nível genotípico (aa=0, Aa=1, AA=2) de cada SNP foi aleatoriamente atribuído a cada indivíduo. Assim, escolha uma das variáveis quantitativas do banco de dados, e avalie o efeito de cada SNP sobre essa variável por meio de um modelo de ANOVA. Adote um esquema DCA com 1 fator em 3 níveis. Caso seja necessário, proponha uma transformação da variável para atender às premissas clássicas.

In [9]:
base2 = read.table ( "map.txt" , header = T , stringsAsFactors = F )
head ( base2 )
A data.frame: 6 × 115
SEXPesoAlturaCIRCABDGLICOSECTOTALTRIGIdademediaPASmediaPAD...rs16981741_Grs175148_Ars165650_Crs165652_Trs165757_Grs17435801_Grs175152_Ars165645_Trs5746906_Grs165670_A
<int><int><int><int><dbl><dbl><dbl><int><dbl><dbl>...<int><int><int><int><int><int><int><int><int><int>
1182600178101 85.1184.0234.762135.6794.67...111 1111000
2273000170 96130.5223.8147.759144.6771.00...011 1101000
3266400156 80 86.9216.6219.045136.6784.67...001 1101101
4294200188 98 74.1216.0219.234119.0073.00...010 0000212
5275200183 87116.1174.1128.128107.0077.00...101 1101102
6287600163101109.1221.5131.843120.3389.67...010NA000212
In [10]:
base2$Peso = base2$Peso/1000
head(base2)
A data.frame: 6 × 115
SEXPesoAlturaCIRCABDGLICOSECTOTALTRIGIdademediaPASmediaPAD...rs16981741_Grs175148_Ars165650_Crs165652_Trs165757_Grs17435801_Grs175152_Ars165645_Trs5746906_Grs165670_A
<int><dbl><int><int><dbl><dbl><dbl><int><dbl><dbl>...<int><int><int><int><int><int><int><int><int><int>
1182.6178101 85.1184.0234.762135.6794.67...111 1111000
2273.0170 96130.5223.8147.759144.6771.00...011 1101000
3266.4156 80 86.9216.6219.045136.6784.67...001 1101101
4294.2188 98 74.1216.0219.234119.0073.00...010 0000212
5275.2183 87116.1174.1128.128107.0077.00...101 1101102
6287.6163101109.1221.5131.843120.3389.67...010NA000212
In [11]:
fenotipos = c("SEX", "Peso", "Altura", "CIRCABD", "GLICOSE", "CTOTAL", "TRIG", "Idade", "mediaPAS", "mediaPAD", "MedPres", "MedCol", "MedDb")
snps = setdiff ( colnames ( base2 ) , fenotipos )
infosRelevantes = c ( )

for ( coluna in snps ){
  
    baseAux = base2 [ (!is.na ( base2 [ , coluna ] ))&(!is.na(base2$Peso)) , ]
    if ( nrow ( baseAux [ baseAux[ , coluna ] == 2 , ] ) == 1 ){
        
        baseAux = baseAux [ baseAux [ , coluna ] < 2 , ]
        
    }
#     print ( nrow ( baseAux ) )
    baseAux[ , coluna ] = as.factor ( baseAux[ , coluna ] )
#     print ( nrow ( baseAux ) )
    modelo = lm ( baseAux$Peso ~ baseAux[,coluna] )
#     print ( length ( modelo$residuals ) )
    obj = anova ( modelo )
    transf = "N"
    shapiroTest = shapiro.test ( modelo$residuals )
    bart = bartlett.test ( modelo$residuals ~ baseAux[ , coluna ] )
    ind = snpar::runs.test( modelo$residuals )
    
    if ( shapiroTest$p.value < 0.01 ){
        
        box = EnvStats::boxcox( lm ( baseAux$Peso ~ baseAux[,coluna] ) , objective.name = "Shapiro-Wilk" , optimize=T , lambda = c ( -2,2 ))
        modelo = lm ( ((baseAux$Peso^box$lambda)-1)/box$lambda ~ baseAux[,coluna] )
        transf = "S"
        shapiroTest = shapiro.test ( modelo$residuals )
        bart = bartlett.test ( modelo$residuals ~ baseAux[ , coluna ] )
        ind = snpar::runs.test( modelo$residuals )
        
    }
        
        
    
    infosRelevantes = rbind ( infosRelevantes , c ( coluna , obj$Df[1] , obj$`Pr(>F)`[1] , nrow ( baseAux ) , shapiroTest$p.value , bart$p.value , ind$p.value , transf ) )
  
}
In [12]:
resultados = infosRelevantes %>% as.data.frame ()
glimpse ( resultados )
Rows: 102
Columns: 8
$ V1 <fct> rs12628452_A, rs7289830_T, rs5746356_A, rs10154759_C, rs7354790_...
$ V2 <fct> 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2...
$ V3 <fct> 0.643563349946583, 0.776267007661512, 0.9021059997094, 0.5928297...
$ V4 <fct> 828, 819, 819, 827, 763, 819, 805, 825, 814, 809, 828, 771, 827,...
$ V5 <fct> 0.0244171310959916, 0.022179794800643, 0.0249360885744693, 0.023...
$ V6 <fct> 0.233184802147091, 0.390675997587133, 0.384480277895809, 0.65383...
$ V7 <fct> 0.000843080026010348, 0.000898060830733, 0.000183409104758606, 0...
$ V8 <fct> S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S...
In [13]:
colnames ( resultados ) = c ( "snp" , "gl" , "valP" , "n" , "normalidade" , "homocedasticidade" , "indep" , "transf" )

resultados$gl = as.numeric( as.character ( resultados$gl ) )
resultados$valP = as.numeric( as.character ( resultados$valP ) )
resultados$n = as.numeric( as.character ( resultados$n ) )
resultados$normalidade = as.numeric( as.character ( resultados$normalidade ) )
resultados$homocedasticidade = as.numeric( as.character ( resultados$homocedasticidade ) )
resultados$indep = as.numeric( as.character ( resultados$indep ) )

glimpse ( resultados )
Rows: 102
Columns: 8
$ snp               <fct> rs12628452_A, rs7289830_T, rs5746356_A, rs1015475...
$ gl                <dbl> 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2...
$ valP              <dbl> 0.6435633499, 0.7762670077, 0.9021059997, 0.59282...
$ n                 <dbl> 828, 819, 819, 827, 763, 819, 805, 825, 814, 809,...
$ normalidade       <dbl> 0.024417131, 0.022179795, 0.024936089, 0.02333637...
$ homocedasticidade <dbl> 0.233184802, 0.390675998, 0.384480278, 0.65383731...
$ indep             <dbl> 0.0008430800, 0.0008980608, 0.0001834091, 0.00057...
$ transf            <fct> S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S...
In [14]:
sig = 0.01
nrow ( resultados[resultados$indep > sig , ] )
0

Como pode-se observar, nenhum dos modelos apresenta a premissa da independencia (considerando o nível de significancia de 1%).

In [15]:
print ( paste ( "Existem" , nrow ( resultados [resultados$normalidade > sig & resultados$homocedasticidade > sig , ] ) , "modelos que atendem simultaneamente as premissas de normalidade e homocedasticidade." ) )
print ( "Dos quais apenas os modelos com os snps abaixo possuem efeito sobre a resposta (considerando nível de significancia a 5%) " )
resultados [ resultados$normalidade > sig & resultados$homocedasticidade > sig & resultados$valP < 0.05 , ]
[1] "Existem 98 modelos que atendem simultaneamente as premissas de normalidade e homocedasticidade."
[1] "Dos quais apenas os modelos com os snps abaixo possuem efeito sobre a resposta (considerando nível de significancia a 5%) "
A data.frame: 5 × 8
snpglvalPnnormalidadehomocedasticidadeindeptransf
<fct><dbl><dbl><dbl><dbl><dbl><dbl><fct>
7rs1041770_A20.00020194498050.027882570.16191831.611281e-04S
13rs2027649_G20.03532923038270.012606470.41566122.471733e-03S
32rs5746647_G20.02535555308270.028546370.56828563.386390e-04S
41rs5993646_T20.01067428308270.041498350.55948996.298785e-05S
46rs5993848_G20.00832496718220.043474160.55532822.165900e-04S

b) Apresente os valores-p da estatística F do teste global da ANOVA em um “gráfico Manhattan” (gráfico de dispersão: -log10(valor-p) x índice do SNP). Interprete os resultados. Discuta sobre possíveis correções para os múltiplos (102) testes realizados simultaneamente.

Primeira das versões

In [16]:
# Atribuído cromossomo "aleatório" para os snps
resultados$Chr = 1

# ordenação por nome
resultados = resultados %>% mutate ( tam = nchar ( as.character ( resultados$snp ) ) ) %>% arrange ( tam , snp ) %>% mutate ( Ord = 1:nrow ( resultados ) )
resultados  %>% head ( 4 )
A data.frame: 4 × 11
snpglvalPnnormalidadehomocedasticidadeindeptransfChrtamOrd
<fct><dbl><dbl><dbl><dbl><dbl><dbl><fct><dbl><int><int>
1rs131560_C20.56175138190.023309340.087075560.0008961202S1101
2rs140378_G20.76104268240.013226980.088077950.0008188235S1102
3rs165645_T20.48882878250.012733110.754806570.0002543754S1103
4rs165650_C20.75025678280.016809650.277010490.0003002141S1104
In [17]:
# Ordenação do valor-P para calcular a significância por FDR e pelo método de Holm
correcoes = resultados %>% select ( snp , valP ) %>% arrange ( valP )
correcoes %>% head ( 5 )
A data.frame: 5 × 2
snpvalP
<fct><dbl>
1rs1041770_A0.0002019449
2rs5993848_G0.0083249671
3rs5993646_T0.0106742830
4rs5746647_G0.0253555530
5rs2027649_G0.0353292303
In [18]:
# Cálculo da significância por FDR e pelo método de Holm

encontraSignif = function ( df , coluna ){
    
    holm = 0

    for ( indice in 1 : nrow ( df ) ){

        if ( holm == 0 ){
            
                if ( df [ indice , coluna ] < .05/( nrow ( df ) - indice + 1 ) ) {

            df [ indice , "Holm" ] = "S"

                } else {

                    df [ indice:nrow ( df ) , "Holm" ] = "N"
                    holm = 1

        }

        }

        if ( df [ nrow (df) - indice + 1 , coluna ] < .05*(nrow (df) - indice + 1)/nrow ( df ) ){

            df [ nrow (df) - indice + 1 , "FDR" ] = "S"

        } else {

            df [ nrow (df) - indice + 1 , "FDR" ] = "N"

        }

    }
    
    return ( df )
}

correcoes = encontraSignif ( correcoes , "valP" )
correcoes %>% head ( 5 )
A data.frame: 5 × 4
snpvalPHolmFDR
<fct><dbl><chr><chr>
1rs1041770_A0.0002019449SS
2rs5993848_G0.0083249671NN
3rs5993646_T0.0106742830NN
4rs5746647_G0.0253555530NN
5rs2027649_G0.0353292303NN
In [19]:
table ( correcoes$FDR , correcoes$Holm )
# Apenas um SNP teve o efeito significante e em ambas as correções
   
      N   S
  N 101   0
  S   0   1
In [20]:
mergeDfs = merge ( resultados , correcoes , by = c ( "snp" , "valP" ) )
head ( mergeDfs )
A data.frame: 6 × 13
snpvalPglnnormalidadehomocedasticidadeindeptransfChrtamOrdHolmFDR
<fct><dbl><dbl><dbl><dbl><dbl><dbl><fct><dbl><int><int><chr><chr>
1rs10154759_C0.592829725118270.023336370.65383730.0005756431S11291NN
2rs1041770_A 0.000201944928050.027882570.16191830.0001611281S11114SS
3rs11089179_G0.675477480128210.024384080.26040850.0001409980S11292NN
4rs11089263_C0.340440394728190.017592940.27216870.0014656446S11293NN
5rs11089264_G0.421602178728080.014595980.20971830.0031070624S11294NN
6rs12628452_A0.643563349918280.024417130.23318480.0008430800S11295NN
In [21]:
# Correção de Bonferroni
bF = .05/nrow ( mergeDfs )
# Snps identificados por Holm e FDR
qqman::manhattan ( mergeDfs , chr = "Chr" , bp = "Ord" , p = "valP" , snp = "snp" , genomewideline =  -log10(bF) , highlight = mergeDfs[ ( mergeDfs$Holm == "S" ) & ( mergeDfs$FDR == "S" ) , "snp"])

Conclusão

Por todos os critérios, o snp rs1041770_A foi o único que, considerando nível de significância a 5%, teve evidências de ter efeito sobre a variável resposta peso. Algumas considerações importantes:

  • O critério de Bonferroni é o mais simples e aplicável dos métodos. Pode ser utilizado para testes (ou intervalos) que não necessariamente precisam ser independentes, ou do mesmo tipo, ou relacionados de alguma forma;
  • O método de Holm é uma modificação do método de Bonferroni, mais poderoso no sentido de comparar apenas o menor valor-P com $\frac{\alpha}{k}$ (neste caso, deveríamos encontrar a mesma quantidade ou mais snp's significantes do que no método anterior). Porém não pode ser utilizado para se realizar intervalos de confiança;
  • O método FDR controla a taxa de descobertas falsas (i.e., a quantidade esperada de rejeições de $H_0$ falsas em relação a todas as rejeições de $H_0$), além de ser menos conservador. Também existe o ponto de que este método é adequado apenas a testes estatisticamente independentes.

c) Para cada SNP, teste seu efeito aditivo, $H_0: \mu_{AA} - \mu_{aa} = 0$. Apresente os resultados desses testes por meio de um “gráfico vulcão” (gráfico de dispersão: -log10(valor-p) x estimativa do contraste ( $\mu_{AA} - \mu_{aa}$ ) ). Interprete os resultados

In [22]:
infosRelevantesContraste = c ( )

for ( coluna in snps ){
  
    baseAux = base2 [ (!is.na ( base2 [ , coluna ] ))&(!is.na(base2$Peso)) , ]
    if ( nrow ( baseAux [ baseAux[ , coluna ] == 2 , ] ) <= 1 ){
        
        print ( paste ( "O snp" , coluna , "não será utilizado pois não possui homozigotos AA" ) )
        
    } else{
                
        baseAux[baseAux[,coluna] == 0 , "x1" ] = -1
        baseAux[baseAux[,coluna] == 1 , "x1" ] = 0
        baseAux[baseAux[,coluna] == 2 , "x1" ] = 1

        baseAux[baseAux[,coluna] == 0 , "x2" ] = 0
        baseAux[baseAux[,coluna] == 1 , "x2" ] = 1
        baseAux[baseAux[,coluna] == 2 , "x2" ] = 0


        modelo = lm ( baseAux$Peso ~ baseAux$x1 + baseAux$x2 )
        
#         Aditividade
        coefC = modelo$coefficients[2][[1]]
#         Dominancia
        coefD = modelo$coefficients[3][[1]]
        
        sumMod = summary ( modelo )
        
#         Aditividade
        valPC = sumMod$coefficients[2,4]
#         Dominancia
        valPD = sumMod$coefficients[3,4]
    
    infosRelevantesContraste = rbind ( infosRelevantesContraste , c ( coluna , coefC , valPC , coefD , valPD , nrow ( baseAux ) ) )

        
    }

  
}
[1] "O snp rs12628452_A não será utilizado pois não possui homozigotos AA"
[1] "O snp rs10154759_C não será utilizado pois não possui homozigotos AA"
[1] "O snp rs9712893_G não será utilizado pois não possui homozigotos AA"
[1] "O snp rs6010318_A não será utilizado pois não possui homozigotos AA"
[1] "O snp rs6010418_A não será utilizado pois não possui homozigotos AA"
[1] "O snp rs5994019_G não será utilizado pois não possui homozigotos AA"
[1] "O snp rs2379981_G não será utilizado pois não possui homozigotos AA"
[1] "O snp rs9604967_T não será utilizado pois não possui homozigotos AA"
[1] "O snp rs2845362_G não será utilizado pois não possui homozigotos AA"
[1] "O snp rs2215075_A não será utilizado pois não possui homozigotos AA"
[1] "O snp rs5994011_T não será utilizado pois não possui homozigotos AA"
[1] "O snp rs5994015_A não será utilizado pois não possui homozigotos AA"
[1] "O snp rs16981694_T não será utilizado pois não possui homozigotos AA"
[1] "O snp rs6518619_G não será utilizado pois não possui homozigotos AA"
In [23]:
resultadosContraste = infosRelevantesContraste %>% as.data.frame ()
colnames ( resultadosContraste ) = c ( "snp" , "difMediasC" , "valPC" , "difMediasD" , "valPD" , "n" )

resultadosContraste$difMediasC = as.numeric( as.character ( resultadosContraste$difMediasC ) )
resultadosContraste$valPC = as.numeric( as.character ( resultadosContraste$valPC ) )

resultadosContraste$difMediasD = as.numeric( as.character ( resultadosContraste$difMediasD ) )
resultadosContraste$valPD = as.numeric( as.character ( resultadosContraste$valPD ) )

resultadosContraste$n = as.numeric( as.character ( resultadosContraste$n ) )

head ( resultadosContraste )
A data.frame: 6 × 6
snpdifMediasCvalPCdifMediasDvalPDn
<fct><dbl><dbl><dbl><dbl><dbl>
1rs7289830_T-0.057281550.970076156-0.72925960.68704224819
2rs5746356_A-0.597263500.657907230 0.44026660.79152490819
3rs7354790_T 0.978713910.146788464-0.10913130.91064458763
4rs6423472_C 1.309749120.051111226-1.60194800.08486209819
5rs1041770_A 7.613778580.004524599-4.44118740.11320510805
6rs7285246_T-1.919647020.178526968 0.57190330.73009282809
In [24]:
resultadosContrasteC = resultadosContraste %>% mutate ( logEscalaC = -log10(valPC) ) %>% arrange ( -logEscalaC )
resultadosContrasteC %>% head(10)
A data.frame: 10 × 7
snpdifMediasCvalPCdifMediasDvalPDnlogEscalaC
<fct><dbl><dbl><dbl><dbl><dbl><dbl>
1rs1041770_A 7.61377860.004524599 -4.44118740.1132051008052.3444199
2rs5993848_G-2.38299120.011073985 3.56461270.0031270608221.9556961
3rs5993646_T-2.21466910.012711140 3.30531810.0046769918271.8958155
4rs5748651_A 7.53723400.047109569 -8.85932950.0277183218051.3268909
5rs6423472_C 1.30974910.051111226 -1.60194800.0848620908191.2914837
6rs5993792_G-1.96633160.061022981 2.95276660.0219687898191.2145066
7rs4535153_C 7.54035090.105406159-10.00435500.0400656898280.9771340
8rs4010560_C 7.31271190.114960058-10.58524730.0344623828180.9394530
9rs5748617_T-0.99138780.133583440 0.75842230.4196904328270.8742474
10rs5993671_G 1.90974610.134282547 -2.93647240.0558050198230.8719804
In [25]:
CorrecoesContrastesC = encontraSignif ( resultadosContrasteC , "valPC" )
CorrecoesContrastesC %>% head ( 10 )
A data.frame: 10 × 9
snpdifMediasCvalPCdifMediasDvalPDnlogEscalaCHolmFDR
<fct><dbl><dbl><dbl><dbl><dbl><dbl><chr><chr>
1rs1041770_A 7.61377860.004524599 -4.44118740.1132051008052.3444199NN
2rs5993848_G-2.38299120.011073985 3.56461270.0031270608221.9556961NN
3rs5993646_T-2.21466910.012711140 3.30531810.0046769918271.8958155NN
4rs5748651_A 7.53723400.047109569 -8.85932950.0277183218051.3268909NN
5rs6423472_C 1.30974910.051111226 -1.60194800.0848620908191.2914837NN
6rs5993792_G-1.96633160.061022981 2.95276660.0219687898191.2145066NN
7rs4535153_C 7.54035090.105406159-10.00435500.0400656898280.9771340NN
8rs4010560_C 7.31271190.114960058-10.58524730.0344623828180.9394530NN
9rs5748617_T-0.99138780.133583440 0.75842230.4196904328270.8742474NN
10rs5993671_G 1.90974610.134282547 -2.93647240.0558050198230.8719804NN
In [26]:
bfContrastesC = -log10 ( 0.05/ nrow ( CorrecoesContrastesC ) )
CorrecoesContrastesC %>% ggplot ( aes ( x = difMediasC , y = logEscalaC , colour = Holm ) ) + 
geom_point () + 
geom_hline ( yintercept = bfContrastesC , col = "green" ) +
labs ( x = "Estimativa do efeito aditivo" , y = "-log10(p)" , title = "Gráfico de Vulcão - Aditividade - método de Holm" )

CorrecoesContrastesC %>% ggplot ( aes ( x = difMediasC , y = logEscalaC , colour = FDR ) ) + 
geom_point () + 
geom_hline ( yintercept = bfContrastesC , col = "green" ) +
labs ( x = "Estimativa do efeito aditivo" , y = "-log10(p)" , title = "Gráfico de Vulcão - Aditividade - método FDR" )

Conclusão

Pelos métodos de Bonferroni,Holm e FDR não encontramos evidências de efeito aditivo para nenhum dos snps considerando a variável peso como resposta.

d) Agora, para cada SNP, teste seu efeito de dominância, $H_0: \mu_{Aa} - \frac{(\mu_{AA} - \mu_{aa})}{2} = 0$. Apresente os resultados desses testes por meio de um “gráfico vulcão” (gráfico de dispersão: -log10(valor-p) x estimativa do contraste $H_0: \mu_{Aa} - \frac{(\mu_{AA} - \mu_{aa})}{2} = 0$. Interprete os resultados.

In [27]:
resultadosContrasteD = resultadosContraste %>% mutate ( logEscalaD = -log10(valPD) ) %>% arrange ( -logEscalaD )
resultadosContrasteD %>% head(10)
A data.frame: 10 × 7
snpdifMediasCvalPCdifMediasDvalPDnlogEscalaD
<fct><dbl><dbl><dbl><dbl><dbl><dbl>
1rs5993848_G-2.382991200.01107398 3.5646130.0031270608222.504864
2rs5993646_T-2.214669080.01271114 3.3053180.0046769918272.330033
3rs5993792_G-1.966331580.06102298 2.9527670.0219687898191.658194
4rs5748651_A 7.537234040.04710957 -8.8593300.0277183218051.557233
5rs1987558_T 1.407867130.32386559 -3.6822920.0315785458141.500608
6rs4010560_C 7.312711860.11496006-10.5852470.0344623828181.462655
7rs4535153_C 7.540350880.10540616-10.0043550.0400656898281.397227
8rs5993671_G 1.909746090.13428255 -2.9364720.0558050198231.253327
9rs8138488_G-0.018666370.98184843 -2.0691940.0573810858281.241231
10rs5748657_G-0.159374610.80961657 1.7403690.0647755127901.188589
In [28]:
CorrecoesContrastesD = encontraSignif ( resultadosContrasteD , "valPD" )
CorrecoesContrastesD %>% head ( 10 )
A data.frame: 10 × 9
snpdifMediasCvalPCdifMediasDvalPDnlogEscalaDHolmFDR
<fct><dbl><dbl><dbl><dbl><dbl><dbl><chr><chr>
1rs5993848_G-2.382991200.01107398 3.5646130.0031270608222.504864NN
2rs5993646_T-2.214669080.01271114 3.3053180.0046769918272.330033NN
3rs5993792_G-1.966331580.06102298 2.9527670.0219687898191.658194NN
4rs5748651_A 7.537234040.04710957 -8.8593300.0277183218051.557233NN
5rs1987558_T 1.407867130.32386559 -3.6822920.0315785458141.500608NN
6rs4010560_C 7.312711860.11496006-10.5852470.0344623828181.462655NN
7rs4535153_C 7.540350880.10540616-10.0043550.0400656898281.397227NN
8rs5993671_G 1.909746090.13428255 -2.9364720.0558050198231.253327NN
9rs8138488_G-0.018666370.98184843 -2.0691940.0573810858281.241231NN
10rs5748657_G-0.159374610.80961657 1.7403690.0647755127901.188589NN
In [29]:
bfContrastesD = -log10 ( 0.05/ nrow ( CorrecoesContrastesD ) )
CorrecoesContrastesD %>% ggplot ( aes ( x = difMediasD , y = logEscalaD , colour = Holm ) ) + 
geom_point () + 
geom_hline ( yintercept = bfContrastesD , col = "green" ) +
labs ( x = "Estimativa do efeito aditivo" , y = "-log10(p)" , title = "Gráfico de Vulcão - Dominância - método de Holm" )

CorrecoesContrastesD %>% ggplot ( aes ( x = difMediasD , y = logEscalaD , colour = FDR ) ) + 
geom_point () + 
geom_hline ( yintercept = bfContrastesD , col = "green" ) +
labs ( x = "Estimativa do efeito aditivo" , y = "-log10(p)" , title = "Gráfico de Vulcão - Dominância - método FDR" )

Conclusão

Pelos métodos de Bonferroni e Holm, não encontramos evidências de efeito aditivo para nenhum dos snps considerando a variável peso como resposta.

e) Hipoteticamente, assuma que há interesse, e é apropriado, realizar uma meta-análise dos resultados de significância do efeito aditivo desses 102 marcadores. Use as fórmulas apresentadas a seguir para combinar os resultados e obter um valor-p global. tabelaLista2_1.PNG

Obs: A fórmula correta é $P = 2\phi(-|Z|)$ - é mais coerente com o que é dito no artigo.

In [30]:
infosNecessarias = CorrecoesContrastesC %>% select ( snp , difMediasC , valPC , n ) %>% mutate ( w = sqrt ( n ) , z = qnorm ( valPC/2 ) , sentido = sign ( difMediasC ) ) %>% mutate ( bigZNum = z*sentido*w )
head( infosNecessarias )
A data.frame: 6 × 8
snpdifMediasCvalPCnwzsentidobigZNum
<fct><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
1rs1041770_A 7.6137790.00452459980528.37252-2.839065 1-80.55142
2rs5993848_G-2.3829910.01107398582228.67054-2.540355-1 72.83337
3rs5993646_T-2.2146690.01271114082728.75761-2.491761-1 71.65710
4rs5748651_A 7.5372340.04710956980528.37252-1.985314 1-56.32836
5rs6423472_C 1.3097490.05111122681928.61818-1.950545 1-55.82103
6rs5993792_G-1.9663320.06102298181928.61818-1.873329-1 53.61126
In [31]:
pnorm ( sum(infosNecessarias$bigZNum)/sum(infosNecessarias$w^2) )
0.497043444862869
In [32]:
2 * pnorm ( - abs ( sum(infosNecessarias$bigZNum)/sum(infosNecessarias$w^2) ) )
print ( paste ( "Z-score:" , sum(infosNecessarias$bigZNum)/sum(infosNecessarias$w^2)))
0.994086889725737
[1] "Z-score: -0.00741105254208443"

Baseado no valor calculado, conclui-se com o valor-p global obtido que não há significância de efeito aditivo para a variável peso.

f) Ainda, considerando o banco de dados “map.txt”, escolha um dentre os 102 SNPs e avalie o possível efeito de interação do SNP e do sexo do indivíduo sobre a variável que está sendo analisada. Para tanto, ajuste um modelo ANOVA para um esquema DCA Fatorial 3x2.

Tomando o SNP rs5993848_G para avaliar o possível efeito de interação com a variável sexo, temos que:

In [33]:
snpEscolhido = "rs5993848_G"
dfMod = base2 [ (!is.na ( base2 [ , snpEscolhido ] ))&(!is.na(base2$Peso)) , c ( "SEX" , "Peso" , snpEscolhido ) ]
head ( dfMod )
A data.frame: 6 × 3
SEXPesors5993848_G
<int><dbl><int>
1182.60
2273.01
3266.40
4294.20
5275.20
6287.61
In [34]:
dfMod$rs5993848_G = as.factor ( dfMod$rs5993848_G )
dfMod$SEX = as.factor ( dfMod$SEX )

anovaMod = aov ( Peso ~ SEX*rs5993848_G , data = dfMod)
anova(anovaMod)
A anova: 4 × 5
DfSum SqMean SqF valuePr(>F)
<int><dbl><dbl><dbl><dbl>
SEX 1 6435.109376435.1093739.0697806.584656e-10
rs5993848_G 2 1906.66630 953.33315 5.7880163.191242e-03
SEX:rs5993848_G 2 51.19556 25.59778 0.1554138.560869e-01
Residuals816134401.81180 164.70810 NA NA
In [35]:
dfMod %>% ggplot ( ) + geom_boxplot ( aes ( y = Peso , x = rs5993848_G , fill = SEX ) ) + facet_wrap(~SEX)

A partir da tabela de ANOVA conclui-se que, apesar de não podermos rejeitar a hipótese de que a interação é nula, temos que tanto o efeito de SNP quanto o efeito de sexo existem sobre a variável resposta peso.

  1. Os dados a seguir se referem à contagem diferencial de um tipo de pulgão que ocorre em plantas, antes e depois de um tratamento por 10 dias. Três tratamentos, com água (T1), esporos (T2) e com óleo natural (T3) foram usados em 5 plantas para avaliar o controle da infestação pelo pulgão. No experimento, três folhas contaminadas foram selecionadas de cada uma das plantas, e os tratamentos foram então aleatoriamente atribuídos às folhas. A contagem de pulgões em quadrantes definidos nas folhas foi feita antes e depois do tratamento e a diferença registrada. Os dados estão indicados a seguir. tabelaLista2_2.PNG

a) Complete a casela faltante (indicada como ?) e realize uma análise de variância destes dados. Que suposições foram adotadas na análise? Essas estão satisfeitas?

In [36]:
# Uma possibilidade
col1 = c ( -7 , 2 , 7 , 11 , 22 , 32 , 10 , 2 , 15 , NA , 2 , 16 , 4 , 5 , 10 )
col2 = rep ( c ( "Agua" , "Esporos" , "Oleo" ) , 5 )
col3 = sort ( rep ( c ( "P1" , "P2" , "P3" , "P4" , "P5" ) , 3 ) )
df3 = as.data.frame ( cbind ( col1 , col2 , col3 ) )
df3 %>% head ( 10 )
A data.frame: 10 × 3
col1col2col3
<fct><fct><fct>
1-7Agua P1
22 EsporosP1
37 Oleo P1
411Agua P2
522EsporosP2
632Oleo P2
710Agua P3
82 EsporosP3
915Oleo P3
10NAAgua P4
In [37]:
df3 = df3 %>% rename ( "Delta" = "col1" , "Trat" = "col2" , "Planta" = "col3" ) %>% mutate ( Delta = as.numeric ( as.character ( Delta ) ) )
head ( df3 )
A data.frame: 6 × 3
DeltaTratPlanta
<dbl><fct><fct>
1-7Agua P1
2 2EsporosP1
3 7Oleo P1
411Agua P2
522EsporosP2
632Oleo P2
In [38]:
mod3 = lm ( Delta ~ Trat + Planta , data = df3 )
valorMissing = predict ( object = mod3 , newdata = df3[10,] )
print ( paste ( "Uma possibilidade para o valor faltante é:" , valorMissing[[1]] ) )
[1] "Uma possibilidade para o valor faltante é: 1.625"

Agora que completamos o valor faltante, vamos à ANOVA:

In [39]:
df3 [ 10 , "Delta" ] = valorMissing[[1]]
anova3 = aov ( Delta ~ Trat + Planta , data = df3 )
summary ( anova3 )
            Df Sum Sq Mean Sq F value  Pr(>F)   
Trat         2  402.2  201.10  10.051 0.00657 **
Planta       4  728.8  182.19   9.106 0.00450 **
Residuals    8  160.1   20.01                   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
In [40]:
# Criando funcao para gerar grafico QQ
graficoQQ = function ( modelo , valoresInf , valoresSup ) { 
    
    residuosAjust = modelo$residuals / sigma ( modelo )
    numObs = length ( residuosAjust )
    quantisRes = quantile ( residuosAjust , c ( ( 1 : ( numObs - 1) )/numObs , ( numObs - 0.5 ) / numObs ) )
    quantisNorm = qnorm ( c ( ( 1 : ( numObs - 1) )/numObs , ( numObs - 0.5 ) / numObs ) )

    dfQQ = as.data.frame ( cbind ( quantisRes , quantisNorm , valoresInf , valoresSup ) )
    
    print (
    dfQQ %>% ggplot ( ) + 
    geom_point ( aes ( x = quantisNorm , y = quantisRes ) ) +
#     geom_line ( aes ( x = quantisNorm , y = valoresInf ) , col = 'red' ) +
#     geom_line ( aes ( x = quantisNorm , y = valoresSup ) , col = 'red' ) +
    geom_abline ( intercept = 0 , slope = 1 ) +
    ggtitle ( "Gráfico dos quantis de resíduos ajustados em relação a quantis normais" ) +
    labs ( x = "Quantis normais" , y = "Quantis dos resíduos" )
    )
    
}
# Homocedasticidade
graficoHomo = function ( modelo ) {

    dfHomocedast = as.data.frame ( cbind ( modelo$residuals / sigma ( modelo ) , modelo$fitted.values ) )
    names ( dfHomocedast ) = c ( "Residuo" , "Ajuste" )
    
    print ( 
        
    dfHomocedast  %>% ggplot (  ) + 
    geom_point ( aes ( x = Ajuste , y = Residuo ) ) + 
    geom_hline ( yintercept = 0 , col = "red" ) + 
    ggtitle ( "Gráfico de resíduos ajustados em relação a valores ajustados" ) +
    labs ( x = "Valores ajustados" , y = "Resíduos ajustados" )
        
    )
    
}

# Residuos
graficoResiduos = function ( modelo ) {

    residuosDf = as.data.frame ( modelo$residuals )
    colnames ( residuosDf ) = c ( "residuo" )
    residuosDf$indice = row ( residuosDf )
    
    print (
        
        residuosDf %>% ggplot (  ) + 
        geom_point ( aes ( x = indice , y = residuo ) ) +
        geom_hline ( yintercept = 0 , col = "red" ) +
        ggtitle ( "Gráfico dos resíduos" ) +
        labs ( x = "Índice" , y = "Resíduo" )
        
    )
    
}

# plota tudo
plotaGeral = function ( modelo , valoresInf , valoresSup ){
    
    graficoQQ ( modelo , valoresInf , valoresSup )
    graficoHomo ( modelo )
    graficoResiduos ( modelo )
    
}

plotaGeral ( lm ( Delta ~ Trat + Planta , data = df3 ) , NULL , NULL )
In [41]:
print ( bartlett.test ( anova3$residuals ~ df3[ , "Trat" ]  ) )
print ( snpar::runs.test( anova3$residuals ) )
print ( shapiro.test ( anova3$residuals ) )
	Bartlett test of homogeneity of variances

data:  anova3$residuals by df3[, "Trat"]
Bartlett's K-squared = 0.93019, df = 2, p-value = 0.6281


	Approximate runs rest

data:  anova3$residuals
Runs = 7, p-value = 0.4297
alternative hypothesis: two.sided


	Shapiro-Wilk normality test

data:  anova3$residuals
W = 0.97125, p-value = 0.8761

Levando-se em consideração que existem poucas observações no experimento, não se percebe grandes desvios das premissas.

b) Compare as fontes de variação presentes no experimento.

In [42]:
bartlett.test ( anova3$residuals ~ df3[ , "Planta" ]  )
	Bartlett test of homogeneity of variances

data:  anova3$residuals by df3[, "Planta"]
Bartlett's K-squared = 1.6015, df = 4, p-value = 0.8085

Não há evidências para se rejeitar a hipótese de que exista diferença entre as fontes de variação.

c) Suspeitando que a hipótese de normalidade não é apropriada a estes dados, construa um Teste de Aleatorização para o efeito global dos tratamentos.

Uma possibilidade de teste seria criar um algoritmo para, fixados os valores observados, permutar-se os grupos aos quais os mesmos foram observados e a cada iteração, realizar o cálculo da estatística F (desta forma, teremos uma distribuição de comparações entre grupos). Assim, se o valor F que calcularmos for extremo nesta distribuição, teremos indícios de que o "grupo" aos quais as observações pertencem têm algum tipo de associação com a resposta.

In [43]:
nSim = 10^3
valF = c ( )

set.seed(123)
for ( i in 1:nSim ){
    
    trat = sample ( df3$Trat , nrow ( df3 ) , replace = F )
    resp = df3$Delta
    tabela = anova ( aov ( resp ~ trat ) )
    valF = c ( valF , tabela$`F value`[1] )
    
}

dfValf = valF %>% as.data.frame ()
colnames ( dfValf ) = c ( "fAleat" )
dfValf %>% head ( 5 )
A data.frame: 5 × 1
fAleat
<dbl>
10.92999407
20.42369051
30.73068025
42.01862036
50.09634133
In [44]:
tabelaOrig = anova ( aov ( resp ~ trat ) )
valFOrig = tabelaOrig$`F value`[1]
print ( paste ( "A estatística F dos dados originais é:" , round ( valFOrig , 3 ) ) )

dfValf %>% ggplot ( aes ( x = fAleat ) ) +
geom_histogram ( bins = 50 ) +
geom_vline ( xintercept = valFOrig ) +
geom_vline ( xintercept = 1 , col = "red" ) +
labs ( x = "Valores observados" , y = "Frequência absoluta" , title = "Histograma da distribuição de valores F do teste de aleatorização" )
[1] "A estatística F dos dados originais é: 0.459"
In [45]:
valP = 100 * ( sum ( dfValf$fAleat < valFOrig ) + sum ( dfValf$fAleat > 1/valFOrig ) ) / nrow ( dfValf )
print ( paste0 ( "Temos que o valor-p observado para o teste bicaudal é dado por: " , valP , "%" ) )
[1] "Temos que o valor-p observado para o teste bicaudal é dado por: 48.3%"

Considerando o teste de aleatorização realizado, temos que não há evidências para se rejeitar a hipótese de que os tratamentos são iguais (valor-p dado por 58,9%).