knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)
knitr::opts_knit$set(root.dir = normalizePath(".."))Introdução
Nesse último notebook sobre análise de dados, trabalharemos exclusivamente com moderação e com formas de interpretar uma moderação. Partiremos de uma forma comum, embora equivocada, de analisar efeitos individuais em moderações para, então, trabalhar com o conceito de Spotlight. Além disso, trabalharemos com o conceito de Floodlight para interpretar interações envolvendo (pelo menos) uma variável contínua.
Spotlight
Eu vou usar a mesma base de dados que eu criei no início do semestre, quando exploramos a sintaxe do R, visualização e testes de hipóteses entre participantes (ANOVA, teste T e Regressão).
Contextualizando, esses dados são fictícios mas representam um design 2 x 2 entre participantes, variando valência e tipo de compra. Respondentes receberam instruções para descrever uma compra material negativa, material positiva, experiencial negativa ou experiencial positiva. A seguir eu reimporto esses dados e apresento estatísticas iniciais e um gráfico.
dados<-read.csv("~/Google Drive/Drive/UFRGS/Ensino/20211/ADP - Experimentos/Scripts Aulas/felicidade.csv",
header = T)
head(dados)## Felicidade Valencia Tipo
## 1 3 -1 -1
## 2 2 -1 -1
## 3 3 -1 -1
## 4 3 -1 -1
## 5 2 -1 -1
## 6 3 -1 1
require(knitr)
require(psych)
require(ggplot2)
require(wesanderson)Notem pelas primeiras linhas da base, que Tipo de Compra e Valência são variáveis condificadas com códigos de contraste, onde -1 são compras materiais e +1 compras experienciais, para o Tipo de Compra, e -1 são compras negativas e +1 compras positivas. Para ajudar na visualização dos dados, eu vou criar variáveis do tipo “fatores” com um rótulo compreensível. Em seguida, apresentarei frequências, médias e um gráfico.
dados$tipo.f<-factor(dados$Tipo, levels = c(-1,1), labels = c("Material","Experiencial"))
dados$valencia.f<-factor(dados$Valencia, levels = c(-1,1), labels = c("Negativa","Positiva"))
t.cond<-data.frame(table(dados$tipo.f,dados$valencia.f))
colnames(t.cond)<-c("Tipo de Compra","Valência","Freq.")
kable(t.cond,caption = "Número de respondentes por condição")| Tipo de Compra | Valência | Freq. |
|---|---|---|
| Material | Negativa | 5 |
| Experiencial | Negativa | 5 |
| Material | Positiva | 5 |
| Experiencial | Positiva | 5 |
int.feliz<-describeBy(dados$Felicidade,list(dados$tipo.f,dados$valencia.f),mat = TRUE,digits = 2)
names(int.feliz)[names(int.feliz) == 'group1'] = 'Tipo de Compra'
names(int.feliz)[names(int.feliz) == 'group2'] = 'Valencia'
row.names(int.feliz)<-NULL
kable(int.feliz[,c(2,3,5:7)])| Tipo de Compra | Valencia | n | mean | sd |
|---|---|---|---|---|
| Material | Negativa | 5 | 2.6 | 0.55 |
| Experiencial | Negativa | 5 | 2.2 | 0.84 |
| Material | Positiva | 5 | 5.4 | 0.55 |
| Experiencial | Positiva | 5 | 6.8 | 0.45 |
ggplot(int.feliz, aes(x = Valencia, y = mean, fill = `Tipo de Compra`))+
geom_bar(stat='identity', position=position_dodge(width=0.9))+
geom_errorbar(aes(ymax = mean + (1.96*se), ymin=mean - (1.96*se)),
position=position_dodge(width=0.9), width=0.25)+
coord_cartesian(ylim = c(1, 7))+
labs(title = "Interação do Tipo de Compra com Valência", y="Felicidade")+
scale_fill_manual(values=wes_palette(n=2, name="GrandBudapest1"))Uma vez visualizados os efeitos, precisamos testar a interação! Ela é significativa? Como vimos anteriormente no semestre, podemos fazer isso através de uma ANOVA ou através de uma regressão. Usarei uma regressão, mas apresentarei também uma ANOVA, para nos certificarmos de que os resultados são iguais.
int.ANOVA <- aov(Felicidade ~ valencia.f*tipo.f, data = dados)
summary(int.ANOVA)## Df Sum Sq Mean Sq F value Pr(>F)
## valencia.f 1 68.45 68.45 182.533 3.63e-10 ***
## tipo.f 1 1.25 1.25 3.333 0.08661 .
## valencia.f:tipo.f 1 4.05 4.05 10.800 0.00465 **
## Residuals 16 6.00 0.37
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Pela ANOVA, a interação é signficativa, sendo F(1,16) = 10.8, p < .05. Vamos testar pela regressão.
int.reg <- lm(Felicidade ~ Valencia*Tipo, data = dados)
summary(int.reg)##
## Call:
## lm(formula = Felicidade ~ Valencia * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.2500 0.1369 31.038 1.00e-15 ***
## Valencia 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo 0.2500 0.1369 1.826 0.08661 .
## Valencia:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
O resultado é exatamente o mesmo! Notem que o valor de t é exatamente idêntico à raiz quadrada do valor de F. Ou seja, t(16) = 3.28, p < .05. Notem na especificação do modelo que eu usei a versão numérica das variáveis da minha base. Isso porque eu estou trabalhando com uma regressão linear, que requer variáveis numéricas.
Com leríamos esse resultado? Diríamos que existe uma interação entre o tipo de compra e valência, tal que para compras positivas, compras experienciais levam a mais felicidade do que compras materiais, o que não acontece para compras negativas. Não podemos dizer isso! O teste de moderação que realizamos só nos diz que existe uma interação. Ele não diz nada a respeito dos efeitos individuais em cada lado do gráfico!
Retomando o gráfico da interação anterior. Digamos que eu queira saber se, dentre as compras positivas, existe diferença significativa entre compras materiais e experienciais. Visualmente, quero saber se existe diferença entre as barras da direita.
“Efeitos na valência positiva”
Uma das abordagens, e a mais comumente vista na literatura, é simplesmente “dividir” a amostra, ficando apenas com respostas de condições de valência positiva e, então, testar a diferença entre os dois grupos de tipos de compra através de um teste t. Isso está incorreto!
so_positivo <- subset(dados, Valencia == 1)
t.test(Felicidade ~ tipo.f, data = so_positivo, var.equal = T)##
## Two Sample t-test
##
## data: Felicidade by tipo.f
## t = -4.4272, df = 8, p-value = 0.002205
## alternative hypothesis: true difference in means between group Material and group Experiencial is not equal to 0
## 95 percent confidence interval:
## -2.1292225 -0.6707775
## sample estimates:
## mean in group Material mean in group Experiencial
## 5.4 6.8
O resultado do teste é significativo, mas notem que perdemos muito do poder estatístico. Os graus de liberdade caem pela metade e agora t(8) = -4.42, p < .05. Existe uma forma melhor de fazer isso. Usando spotlight. A spotlight parte do pressuposto que o ZERO tem um significado e que o valor da interação pressupõe o valor médio dos seus termos independentes. Nesse caso, temos códigos de contraste -1 e 1 para as condições experimentais e o mesmo tamanho da amostra (n = 5) para cada condição. Naturalmente o valor médio ja é ZERO para cada fator. O que precisamos fazer para investigar a diferença entre compras materiais e experienciais para a condição positiva é “deslocar” esse ZERO do meio para o valor POSITIVO. Essa é a iluminação do spot… é colocar a luz (ZERO) sobre a condição de interesse. Para fazermos isso, subtraímos o valor da condição de interesse dos códigos de contraste originais, para que valência positiva seja 0. Consequentemente, a valência negativa passa a ser -2. Vamos fazer isso então:
dados$Valencia.Pos <- dados$Valencia - 1
table(dados$Valencia.Pos, dados$valencia.f)##
## Negativa Positiva
## -2 10 0
## 0 0 10
Agora nós (re)rodamos o modelo original, só que com essa variável nova no lugar da variável de valência original. Para isso, precisamos usar a estimação por regressão.
int.reg.pos <- lm(Felicidade ~ Valencia.Pos*Tipo, data = dados)
summary(int.reg.pos)##
## Call:
## lm(formula = Felicidade ~ Valencia.Pos * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.1000 0.1936 31.500 7.95e-16 ***
## Valencia.Pos 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo 0.7000 0.1936 3.615 0.00233 **
## Valencia.Pos:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
Examinamos a nossa variável de interesse que, nesse caso, é o Tipo de Compra. Como existe diferença significativa no tipo de compra, podemos afirmar que, para compras positivas, compras experienciais levam a mais felicidade que compras materiais, t(16) = 3.61, p < .05. Vamos comparar os dois outputs: o da regressão original e o da spotlight nas compras positivas.
summary(int.reg)##
## Call:
## lm(formula = Felicidade ~ Valencia * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.2500 0.1369 31.038 1.00e-15 ***
## Valencia 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo 0.2500 0.1369 1.826 0.08661 .
## Valencia:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
summary(int.reg.pos)##
## Call:
## lm(formula = Felicidade ~ Valencia.Pos * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.1000 0.1936 31.500 7.95e-16 ***
## Valencia.Pos 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo 0.7000 0.1936 3.615 0.00233 **
## Valencia.Pos:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
Notem que a interação permanece a mesma, bem como o efeito principal da valência, uma vez que transformações lineares nos dados não afetam a significância dos efeitos lineares. O único afetado é o intercept, o que não influencia as decisões de signficância, mas somente e visualização dos efeitos.
Agora responderemos a outra questão. Será que existe diferença significativa na felicidade com as compras materiais e experiencias negativas? As barras de erro nos dão uma valiosa pista, mas podemos descobrir isso com um spotlight. Criaremos uma nova variável, onde subtraíremos do código original o valor referente à Valência negativa (-1). Assim, a nova variável será a valência original -(-1), ou seja +1. O novo ZERO é o valor da compra negativa, enquanto compras positivas serão +2.
dados$Valencia.Neg <- dados$Valencia - (-1)
table(dados$Valencia.Neg, dados$valencia.f)##
## Negativa Positiva
## 0 10 0
## 2 0 10
int.reg.neg <- lm(Felicidade ~ Valencia.Neg*Tipo, data = dados)
summary(int.reg.neg)##
## Call:
## lm(formula = Felicidade ~ Valencia.Neg * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.4000 0.1936 12.394 1.29e-09 ***
## Valencia.Neg 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo -0.2000 0.1936 -1.033 0.31706
## Valencia.Neg:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
Não existe diferença significativa entre a felicidade trazida pela compra material e experiencial quando essas compras são negativas, t(16) = -1.03, p = 0.31. Assim, podemos finalmente ler a interação de forma completa.
> "O tipo de compra modera o efeito da valência da compra na felicidade, t(16) = 3.28, p < .05, onde, para compras positivas, experiências trazem mais felicidade do que compras materiais, t(16) = 3.61, p < .05, mas para compras negativas não existe diferença enrte os dois tipos de compra, t(16) = -1.03, p = 0.31.
Podemos fazer a mesma análise de spotlight só para compras materiais e só para experienciais? Claro. Para tanto procedemos com o mesmo código, tornando ZERO a condição material primeiro e ZERO a condição experiencial depois.
Suponhamos a seguinte situação. Digamos que exista uma terceira condição de valência, uma condição de controle com valência neutra, codificada com 0. Assim, teríamos -1 para a condição negativa, 0 para a condição neutra e +1 para a condição positiva. Nesse caso, existiria um “spotlight natural” na condição de controle, onde os efeitos principais observados na variável do tipo de compra aconteceriam na condição de controle (neutra). Para investigarmos o que acontece na condição negativa, é preciso fazer um spotlight na condição negativa e fazer dela o 0. Assim, teríamos: 0 para a condição negativa, +1 para a neutra e +2 para a positiva, e assim por diante.
A ideia toda da spotlight parte, como lemos no texto do Spiller et al. (2013), da interpretabilidade dos efeitos principais na presença de uma interação quando os valores estão centrados em ZERO, ou quando estão centrados na média (e portanto centrados em ZERO). E isso parte da equação da reta em uma regressão linear que testa efeitos de interação. Vejamos: \(y = \beta_0 + \beta_1x_1 + \beta_2x_2 + \beta_3x_1x_2\). No nosso caso: \(Felicidade = \beta_0 + \beta_{Valencia}Valencia + \beta_{Tipo de Compra}Tipo + \beta_{Interacao}Valencia*Tipo de Compra\). Assim, quando fazemos da valência negativa o ZERO, para todos os efeitos temos \(Felicidade_{negativo} = \beta_0 + \beta_{Valencia}*0 + \beta_{TipodeCompra}Tipo + \beta_{Interacao}*0*TipodeCompra\) e, consequentemente,
\(Felicidade_{negativo} = \beta_0 + \beta_{TipodeCompra}Tipo\)
E se tivéssemos valência dummy coded, onde negativa é 0 e positiva é 1. Bem, nesse caso temos um outro “spotlight natural” na condição negativa. Vamos testar o que acontece nesse caso. Eu vou criar uma outra variável onde Valência é dummy coded e rodar um novo teste de interação.
dados$Valencia.dummy <- 0
dados$Valencia.dummy[dados$Valencia == -1] <- 0
dados$Valencia.dummy[dados$Valencia == +1] <- 1
int.reg.dummy <- lm(Felicidade ~ Valencia.dummy*Tipo, data = dados)
summary(int.reg.dummy)##
## Call:
## lm(formula = Felicidade ~ Valencia.dummy * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.4000 0.1936 12.394 1.29e-09 ***
## Valencia.dummy 3.7000 0.2739 13.510 3.63e-10 ***
## Tipo -0.2000 0.1936 -1.033 0.31706
## Valencia.dummy:Tipo 0.9000 0.2739 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
Notem que o efeito do tipo de compra, nesse caso, é o mesmo do efeito encontrado na spotlight para valência negativa!
summary(int.reg.neg)##
## Call:
## lm(formula = Felicidade ~ Valencia.Neg * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.4000 0.1936 12.394 1.29e-09 ***
## Valencia.Neg 1.8500 0.1369 13.510 3.63e-10 ***
## Tipo -0.2000 0.1936 -1.033 0.31706
## Valencia.Neg:Tipo 0.4500 0.1369 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
summary(int.reg.dummy)##
## Call:
## lm(formula = Felicidade ~ Valencia.dummy * Tipo, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.2 -0.4 0.2 0.4 0.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.4000 0.1936 12.394 1.29e-09 ***
## Valencia.dummy 3.7000 0.2739 13.510 3.63e-10 ***
## Tipo -0.2000 0.1936 -1.033 0.31706
## Valencia.dummy:Tipo 0.9000 0.2739 3.286 0.00465 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6124 on 16 degrees of freedom
## Multiple R-squared: 0.9248, Adjusted R-squared: 0.9107
## F-statistic: 65.56 on 3 and 16 DF, p-value: 3.31e-09
Os coeficientes (betas) são diferentes porque existe 1 ponto de distância entre 0 e 1, ao invés de 2 entre -1 e 1, mas os testes de significância são idênticos! A lição é utilizem códigos de contraste centrados em zero!. Para duas condições: -1 e 1. Para três: -1, 0, 1. Para quatro: -2, -1, 1, 2, e assim por diante!
Floodlight
E se as variáveis envolvidas forem contínuas? Como fazer um spotlight. Nós podemos (1) escolher níveis de nosso interesse e focar neles ou (2) fazer um “spotlight” e vários pontos ao mesmo tempo, o que Spiller e outros chamam de floodlight. Notem que, em inglês, um spotlight é uma luz dirigida, focada em um ponto específico. Algo como o nosso “spot” de iluminação comercial ou residencial. O floodlight, entretanto, é um holofote e ilumina uma grande área ao mesmo tempo. Essa analogia é pertinente.
Sobre os dados
A página 281 tem um bom resumo dos dados: >“Again, the dependent variable (Y) is the number of candies the participant takes. The dichotomous independent variable (Z) is the number of candies the confederate takes (2 candies, coded as 0, vs. 30 candies, coded as 1). The continous variable (X) is the confederate’s BMI.”
Ou seja, “Candies” é a variável dependente, “LargeQuantModel” é a independente, manipulada em dois níveis (0 para 2 candies e 1 para 30 candies) e “BMI” é a moderadora, o BMI do pesquisador / confederado. Vamos importar os dados e replicar a regressão proposta.
require(readr)
spot2c <- read_csv("~/Google Drive/Drive/UFRGS/Ensino/20211/ADP - Experimentos/Scripts Aulas/Spotlight_2xCont.txt",
skip = 1)Como de costume, eu vou transformar a variável independente em um fator para ajudar a visualização, mas não para estimar o modelo. Para isso, utilizarei os valores dummy de 0 e 1 originais.
spot2c$Quantities <- factor (spot2c$LargeQuantModel, levels = c(0,1),
labels = c("Smaller Quantity", "Larger Quantity"))
interaction.graph <- ggplot(spot2c) +
aes(x = BMI, y = Candies, color = Quantities) +
geom_smooth(method = "lm", se = FALSE)+
xlim(16,32)+
ylim(0,20)+
labs (title = "Relação entre BMI e Número de Doces", x = "BMI",
y = "Candies", color = "Quantities")+
scale_color_manual(values=wes_palette(n=2, name="Darjeeling1"))
interaction.graphAgora, rodarei o mesmo modelo de interação que Spiller e colegas rodaram.
spiller <- lm(Candies ~ LargeQuantModel*BMI, data = spot2c)
summary(spiller)##
## Call:
## lm(formula = Candies ~ LargeQuantModel * BMI, data = spot2c)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.8049 -1.6738 -0.1384 2.1854 9.3451
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.6466 3.9278 0.928 0.35552
## LargeQuantModel 18.5606 5.5410 3.350 0.00116 **
## BMI 0.1919 0.1741 1.102 0.27310
## LargeQuantModel:BMI -0.5670 0.2502 -2.266 0.02571 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.575 on 96 degrees of freedom
## Multiple R-squared: 0.4554, Adjusted R-squared: 0.4384
## F-statistic: 26.76 on 3 and 96 DF, p-value: 1.154e-12
Notem que encontramos o mesmo resultado reportado pelos autores na Figura 1A (abaixo).
Spiller et al. não estão interessados em usar a spotlight para descobrir se as retas / slopes são significativas. Mas nós podemos fazer isso. Primeiro, podemos investigar se a reta da “Smaller Quantity” é significativa, ou seja, se a relação entre BMI e Candies Taken é significativa para indivíduos alocados na condição “Smaller Quantity (2 candies)”. E a resposta é… não. Claro. Como essa condição já está codificada como 0, o coeficiente do BMI é 0.19 e esse coeficiente não é significativo, t(96) = 1.102, p = 0.27. Agora, podemos fazer uma spotlight focando em idivíduos que viram a condição Larger Quantity (30 candies). Para isso, vamos inverter a codificação, fazendo do 0 os 30 candies e 1 os 2 candies.
spot2c$SmallQuantModel <- ifelse(spot2c$LargeQuantModel == 0, 1, 0)
spiller30<-lm(Candies ~ SmallQuantModel*BMI, data = spot2c)
summary(spiller30)##
## Call:
## lm(formula = Candies ~ SmallQuantModel * BMI, data = spot2c)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.8049 -1.6738 -0.1384 2.1854 9.3451
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 22.2072 3.9084 5.682 1.42e-07 ***
## SmallQuantModel -18.5606 5.5410 -3.350 0.00116 **
## BMI -0.3751 0.1798 -2.087 0.03957 *
## SmallQuantModel:BMI 0.5670 0.2502 2.266 0.02571 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.575 on 96 degrees of freedom
## Multiple R-squared: 0.4554, Adjusted R-squared: 0.4384
## F-statistic: 26.76 on 3 and 96 DF, p-value: 1.154e-12
Porque a codificação era 0 e 1, não precisávamos rodar esse modelo para saber que a relação entre BMI e o número de doces para indivíduos na condição de grandes quantidades é negativa, com um coeficiente de - 0.3751. Entretanto, precisamos fazer isso para saber que esse coeficiente é significativo, t(96) = -2.08, p < .05. Agora, entretanto, vamos fazer uma spotlight nos valores de BMI para saber quando o número de doces (2 ou 30) é significativo. Spiller e outros argumentam contra usar -1 sd e +1 sd para “baixo” e “alto” BMI respectivamente. Como BMI (body mass index) é um número com significado, podemos usar um ponto de corte padrão de 25 para investigar essa relação. O processo é exatamente o mesmo, só que agora para o BMI. Precisamos fazer com que a nova variável (que eu chamarei de BMI25) seja 0 quando costumava ser 25. Ou seja, precisamos computar BMI25 = BMI - 25. Só isso!
spot2c$BMI25 <- spot2c$BMI - 25
spiller.spot25 <- lm(Candies ~ LargeQuantModel*BMI25, data = spot2c)
summary(spiller.spot25)##
## Call:
## lm(formula = Candies ~ LargeQuantModel * BMI25, data = spot2c)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.8049 -1.6738 -0.1384 2.1854 9.3451
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.4435 0.6814 12.392 < 2e-16 ***
## LargeQuantModel 4.3862 1.0499 4.178 6.49e-05 ***
## BMI25 0.1919 0.1741 1.102 0.2731
## LargeQuantModel:BMI25 -0.5670 0.2502 -2.266 0.0257 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.575 on 96 degrees of freedom
## Multiple R-squared: 0.4554, Adjusted R-squared: 0.4384
## F-statistic: 26.76 on 3 and 96 DF, p-value: 1.154e-12
Para um BMI de 25, existe diferença significativa entre a quantidade consumida de doces entre participantes na condição que viu outros comerem poucos (2) e comerem muitos (30) doces, t(96) = 4.18, p < .05.
Muitas vezes, nós não temos necessariamente um interesse em um ponto específico da distribuição ou apenas queremos explorar quando, no espaço da variável contínua, as relações entre a variável independente e a variável dependente são estatisticamente significativas. Para isso, identificamos os pontos de Johnson-Neyman, através de uma “floodlight”. A floodlight é uma técnica onde é realizada uma spotlight para cada valor da variável moderadora contínua.
require(interactions)
fit <- lm(Candies ~ LargeQuantModel*BMI, data = spot2c)
summary(fit)##
## Call:
## lm(formula = Candies ~ LargeQuantModel * BMI, data = spot2c)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.8049 -1.6738 -0.1384 2.1854 9.3451
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.6466 3.9278 0.928 0.35552
## LargeQuantModel 18.5606 5.5410 3.350 0.00116 **
## BMI 0.1919 0.1741 1.102 0.27310
## LargeQuantModel:BMI -0.5670 0.2502 -2.266 0.02571 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.575 on 96 degrees of freedom
## Multiple R-squared: 0.4554, Adjusted R-squared: 0.4384
## F-statistic: 26.76 on 3 and 96 DF, p-value: 1.154e-12
johnson_neyman(fit, pred = LargeQuantModel, modx = BMI)## JOHNSON-NEYMAN INTERVAL
##
## When BMI is OUTSIDE the interval [27.36, 109.27], the slope of
## LargeQuantModel is p < .05.
##
## Note: The range of observed values of BMI is [16.50, 29.00]
johnson_neyman(fit, pred = LargeQuantModel, modx = BMI)$bounds[[1]]## [1] 27.36455
jn_value <- round(johnson_neyman(fit, pred = LargeQuantModel, modx = BMI)$bounds[[1]],2)
#probe_interaction(fit, pred = quant.cc, modx = BMI)
interaction.graph +
geom_vline(xintercept=jn_value,
linetype='dashed', color='darkgrey', show.legend = TRUE)+
annotate("text", x = jn_value+1,
y = 15, label = jn_value,
color = "darkgrey")Nesse caso, o ponto de Johnson-Neyman é o BMI de 27.36. Ou seja, a partir de 27.36, nesse caso, a diferença entre a média de doces comidos pelos participantes nas condições between que viram poucos (2) ou muitos (30) doces serem comidos deixa de ser significativa. Antes disso, para cada valor de BMI (23 por exemplo), existe diferença significativa. Esse último gráfico acima esclarece isso. A partir do ponto de Johnson-Neyman, as duas retas não estão mais distantes (significativamente) entre si.
Existe uma forma de encontrar o Johnson-Neyman pelo PROCESS e, portanto, no SPSS e no SAS também. Vamos ver se encontramos a mesma coisa abaixo.
setwd("/home/lnicolao/Google Drive/Drive/UFRGS/Ensino/20211/ADP - Experimentos/Scripts Aulas")
source("process.R")##
## ***************** PROCESS for R Version 3.5.3 beta0.6 *****************
##
## Written by Andrew F. Hayes, Ph.D. www.afhayes.com
## Documentation available in Hayes (2018). www.guilford.com/p/hayes3
##
## ***********************************************************************
##
## PROCESS is now ready for use.
## Copyright 2020 by Andrew F. Hayes ALL RIGHTS RESERVED
##
## Distribution of this beta release of PROCESS is prohibited
## without written authorization from the copyright holder.
process(spot2c, y = "Candies", x = "LargeQuantModel", w = "BMI", model = 1, jn = 1)##
## ***************** PROCESS for R Version 3.5.3 beta0.6 *****************
##
## Written by Andrew F. Hayes, Ph.D. www.afhayes.com
## Documentation available in Hayes (2018). www.guilford.com/p/hayes3
##
## ***********************************************************************
##
## Model : 1
## Y : Candies
## X : LargeQuantModel
## W : BMI
##
## Sample size: 100
##
##
## ***********************************************************************
## Outcome Variable: Candies
##
## Model Summary:
## R R-sq MSE F df1 df2 p
## 0.6748 0.4554 12.7804 26.7593 3.0000 96.0000 0.0000
##
## Model:
## coeff se t p LLCI ULCI
## constant 3.6466 3.9278 0.9284 0.3555 -4.1500 11.4431
## LargeQuantModel 18.5606 5.5410 3.3497 0.0012 7.5617 29.5595
## BMI 0.1919 0.1741 1.1023 0.2731 -0.1537 0.5374
## Int_1 -0.5670 0.2502 -2.2658 0.0257 -1.0637 -0.0703
##
## Product terms key:
## Int_1 : LargeQuantModel x BMI
##
## Test(s) of highest order unconditional interaction(s):
## R2-chng F df1 df2 p
## X*W 0.0291 5.1340 1.0000 96.0000 0.0257
## ----------
## Focal predictor: LargeQuantModel (X)
## Moderator: BMI (W)
##
## Conditional effects of the focal predictor at values of the moderator(s):
## BMI effect se t p LLCI ULCI
## 19.1160 7.7223 1.0130 7.6228 0.0000 5.7114 9.7332
## 21.8500 6.1721 0.7227 8.5402 0.0000 4.7376 7.6067
## 24.7000 4.5563 0.9967 4.5712 0.0000 2.5778 6.5348
##
## Moderator value(s) defining Johnson-Neyman significance region(s):
## Value % below % above
## 27.3645 93.0000 7.0000
##
## Conditional effect of focal predictor at values of the moderator:
## BMI effect se t p LLCI ULCI
## 16.5000 9.2055 1.5443 5.9610 0.0000 6.1401 12.2708
## 17.1250 8.8511 1.4079 6.2866 0.0000 6.0564 11.6459
## 17.7500 8.4968 1.2762 6.6578 0.0000 5.9635 11.0300
## 18.3750 8.1424 1.1507 7.0761 0.0000 5.8583 10.4265
## 19.0000 7.7880 1.0336 7.5348 0.0000 5.7363 9.8397
## 19.6250 7.4337 0.9282 8.0088 0.0000 5.5912 9.2761
## 20.2500 7.0793 0.8388 8.4395 0.0000 5.4143 8.7444
## 20.8750 6.7250 0.7711 8.7208 0.0000 5.1943 8.2556
## 21.5000 6.3706 0.7312 8.7131 0.0000 4.9193 7.8219
## 22.1250 6.0162 0.7235 8.3155 0.0000 4.5801 7.4524
## 22.7500 5.6619 0.7491 7.5578 0.0000 4.1748 7.1489
## 23.3750 5.3075 0.8049 6.5938 0.0000 3.7097 6.9053
## 24.0000 4.9531 0.8852 5.5957 0.0000 3.1961 6.7102
## 24.6250 4.5988 0.9839 4.6741 0.0000 2.6458 6.5518
## 25.2500 4.2444 1.0961 3.8722 0.0002 2.0686 6.4202
## 25.8750 3.8901 1.2181 3.1935 0.0019 1.4721 6.3080
## 26.5000 3.5357 1.3473 2.6244 0.0101 0.8614 6.2100
## 27.1250 3.1813 1.4817 2.1471 0.0343 0.2403 6.1224
## 27.3645 3.0455 1.5343 1.9850 0.0500 -0.0000 6.0910
## 27.7500 2.8270 1.6200 1.7450 0.0842 -0.3887 6.0427
## 28.3750 2.4726 1.7614 1.4038 0.1636 -1.0237 5.9689
## 29.0000 2.1183 1.9051 1.1119 0.2690 -1.6634 5.8999
##
## ******************** ANALYSIS NOTES AND ERRORS ************************
##
## Level of confidence for all confidence intervals in output: 95
##
## W values in conditional tables are the 16th, 50th, and 84th percentiles.