Para o presente laboratório foi escolhido a seguinte fonte de dados: data/vcu .csv. A partir dos dados, é possível observar as sguintes visualizações:
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dplyr)
library(ggplot2)
library(broom)
library(ggbeeswarm)
library(gridExtra)
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
library(boot)
theme_set(theme_bw())
knitr::opts_chunk$set(tidy = FALSE,
fig.width = 6,
fig.height = 5)
dados = read_csv(here::here("data/vcu .csv"),)
## Rows: 101 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): referrer, sex, iat_exclude
## dbl (2): session_id, d_art
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(dados)
## Rows: 101
## Columns: 5
## $ session_id <dbl> 2448165, 2451903, 2451987, 2457829, 2458789, 2458795, 2458…
## $ referrer <chr> "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "v…
## $ sex <chr> "f", "f", "f", "m", "f", "f", "f", "m", "m", "f", "f", "f"…
## $ d_art <dbl> 1.074677138, 0.293409771, 0.006185518, -0.116358515, 1.011…
## $ iat_exclude <chr> "Include", "Include", "Include", "Include", "Include", "In…
iat = dados %>%
mutate(sex = factor(sex, levels = c("m", "f"), ordered = TRUE))
glimpse(iat)
## Rows: 101
## Columns: 5
## $ session_id <dbl> 2448165, 2451903, 2451987, 2457829, 2458789, 2458795, 2458…
## $ referrer <chr> "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "vcu", "v…
## $ sex <ord> f, f, f, m, f, f, f, m, m, f, f, f, f, f, f, f, m, f, f, f…
## $ d_art <dbl> 1.074677138, 0.293409771, 0.006185518, -0.116358515, 1.011…
## $ iat_exclude <chr> "Include", "Include", "Include", "Include", "Include", "In…
iat %>%
ggplot(aes(x = d_art, fill = sex, color = sex)) +
geom_histogram(binwidth = .2, alpha = .4) +
geom_rug() +
facet_grid(sex ~ ., scales = "free_y") +
theme(legend.position = "None")
iat %>%
ggplot(aes(x = sex, y = d_art)) +
geom_quasirandom(width = .1)
iat %>%
ggplot(aes(x = sex, y = d_art)) +
geom_quasirandom(width = .1) +
stat_summary(geom = "point", fun.y = "mean", color = "red", size = 5)
## Warning: The `fun.y` argument of `stat_summary()` is deprecated as of ggplot2 3.3.0.
## ℹ Please use the `fun` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
iat %>%
group_by(sex) %>%
summarise(media = mean(d_art))
## # A tibble: 2 × 2
## sex media
## <ord> <dbl>
## 1 m 0.0664
## 2 f 0.468
agrupado = iat %>%
group_by(sex) %>%
summarise(media = mean(d_art))
m = agrupado %>% filter(sex == "m") %>% pull(media)
f = agrupado %>% filter(sex == "f") %>% pull(media)
f - m
## [1] 0.401629
theta <- function(d, i) {
agrupado = d %>%
slice(i) %>%
group_by(sex) %>%
summarise(media = mean(d_art))
m = agrupado %>% filter(sex == "m") %>% pull(media)
f = agrupado %>% filter(sex == "f") %>% pull(media)
f - m
}
booted <- boot(data = iat,
statistic = theta,
R = 2000)
ci = tidy(booted,
conf.level = .95,
conf.method = "bca",
conf.int = TRUE)
glimpse(ci)
## Rows: 1
## Columns: 5
## $ statistic <dbl> 0.401629
## $ bias <dbl> 0.0006519254
## $ std.error <dbl> 0.1259744
## $ conf.low <dbl> 0.1475587
## $ conf.high <dbl> 0.6481789
ci %>%
ggplot(aes(
x = "",
y = statistic,
ymin = conf.low,
ymax = conf.high
)) +
geom_pointrange() +
geom_point(size = 3) +
labs(x = "Diferença",
y = "IAT homens - mulheres")
plot_with_statistics <- function(data) {
# Calculando as estatísticas
mean_value <- mean(data$d_art, na.rm = TRUE)
sd_value <- sd(data$d_art, na.rm = TRUE)
# Calculando o intervalo de confiança de 95%
n <- sum(!is.na(data$d_art))
error_margin <- qnorm(0.975) * (sd_value / sqrt(n))
ci_lower <- mean_value - error_margin
ci_upper <- mean_value + error_margin
# Criando um data frame para o ggplot
stats_df <- data.frame(
Statistic = "Statistics",
Mean = mean_value,
SD = sd_value,
CI_Lower = ci_lower,
CI_Upper = ci_upper
)
# Gerando o gráfico
dpr <- ggplot(stats_df, aes(x = Statistic, y = Mean)) +
geom_col(fill = "#69b3a2", width = 0.5) + # Usando um tom pastel
geom_errorbar(aes(ymin = CI_Lower, ymax = CI_Upper), width = 0.2, color = "#404080") + # Tons pastéis
labs(title = "Mean with 95% Confidence Interval",
x = "",
y = "Value") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5),
axis.title.y = element_text(size = 12),
axis.text = element_text(size = 10)
) +
geom_text(aes(label = round(Mean, 2)), vjust = -1.5, hjust = 1.5, color = "#404080", size = 5) + # Adicionando valor da média
geom_point(aes(y = Mean), size = 4, color = "#404080") # Adicionando ponto da média
return(dpr)
}
plot_with_statistics_by_gender <- function(data, column_name, gender_column) {
# Filtrando e agrupando os dados por gênero
stats_df <- data %>%
group_by(!!sym(gender_column)) %>%
summarise(
Mean = mean(!!sym(column_name), na.rm = TRUE),
SD = sd(!!sym(column_name), na.rm = TRUE),
N = sum(!is.na(!!sym(column_name)))
) %>%
mutate(
Error_Margin = qnorm(0.975) * (SD / sqrt(N)),
CI_Lower = Mean - Error_Margin,
CI_Upper = Mean + Error_Margin
)
# Determinando os limites do eixo y, incluindo possíveis valores negativos
y_min <- min(stats_df$CI_Lower, na.rm = TRUE)
y_max <- max(stats_df$CI_Upper, na.rm = TRUE)
# Gerando o gráfico
dpr <- ggplot(stats_df, aes(x = !!sym(gender_column), y = Mean, fill = !!sym(gender_column))) +
geom_col(width = 0.5) +
geom_errorbar(aes(ymin = CI_Lower, ymax = CI_Upper), width = 0.2, color = "gray30") +
scale_fill_manual(values = c("m" = "#69b3a2", "f" = "#ff9999")) + # Usando tons pastéis
labs(title = "Mean with 95% Confidence Interval by Gender",
x = "Gender",
y = "Value") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5),
axis.title.x = element_text(size = 12),
axis.title.y = element_text(size = 12),
axis.text = element_text(size = 10),
legend.position = "none"
) +
geom_text(aes(label = round(Mean, 2)), vjust = -0.3, hjust = 1.5, color = "gray30", size = 4) + # Adicionando valor da média
geom_text(aes(y = CI_Lower, label = round(CI_Lower, 2)), vjust = 1.5, color = "gray30", size = 4) + # Valor do limite inferior
geom_text(aes(y = CI_Upper, label = round(CI_Upper, 2)), vjust = -1, color = "gray30", size = 4) + # Valor do limite superior
geom_text(aes(y = SD, label = round(SD, 2)), vjust = -0.3, hjust = -0.5, color = "blue", size = 4) + # Valor do desvio padrão positivo
geom_point(aes(y = Mean), size = 4, color = "gray30") + # Adicionando ponto da média
geom_point(aes(y = SD), size = 3, color = "blue", shape = 15) + # Ponto para desvio padrão positivo
ylim(y_min - abs(0.1 * y_min), y_max + abs(0.1 * y_max)) # Ajustando os limites do eixo y
return(dpr)
}
# Função para calcular a média (ou qualquer outra estatística de interesse)
mean_stat <- function(data, indices) {
return(mean(data[indices]))
}
# Função para realizar bootstrap e plotar gráfico
bootstrap_ci_plot <- function(data, d_art_col, sex_col, n_bootstrap = 1000, conf_level = 0.95) {
# Dividir dados por sexo
data_split <- split(data, data[[sex_col]])
# Lista para armazenar plots
plots <- list()
for (sex_value in names(data_split)) {
# Realizar o bootstrap
boot_results <- boot(data_split[[sex_value]][[d_art_col]], statistic = mean_stat, R = n_bootstrap)
# Calcular intervalo de confiança
ci <- boot.ci(boot_results, type = "perc", conf = conf_level)
# Extrair estatísticas
boot_means <- boot_results$t
original_mean <- mean(data_split[[sex_value]][[d_art_col]])
lower_ci <- ci$percent[4]
upper_ci <- ci$percent[5]
# Criar dataframe para ggplot
df <- data.frame(boot_means)
# Plotar histograma com intervalo de confiança
plot <- ggplot(df, aes(x = boot_means)) +
geom_histogram(binwidth = 0.1, fill = "skyblue", color = "black", alpha = 0.7) +
geom_vline(aes(xintercept = original_mean), color = "red", linetype = "dashed", size = 1, show.legend = TRUE) +
geom_vline(aes(xintercept = lower_ci), color = "blue", linetype = "dotted", size = 1) +
geom_vline(aes(xintercept = upper_ci), color = "blue", linetype = "dotted", size = 1) +
labs(
title = paste("Bootstrap Distribution with Confidence Interval for", sex_value),
x = "Bootstrap Means",
y = "Frequency"
) +
theme_minimal()
# Adicionar plot à lista
plots[[sex_value]] <- plot
}
# Organizar os plots um abaixo do outro
grid_plot <- do.call(grid.arrange, c(plots, ncol = 1))
return(grid_plot)
}
Para a amostra inteira, com nível de confiança de 95%, temos que a média populacional pode estar descrita no intervalo de confiança abaixo:
print(plot_with_statistics(iat))
Note that the echo = FALSE parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.
Agrupando por gênero, temos as seguintes observações:
print(plot_with_statistics_by_gender(iat, "d_art", "sex"))
Podemos observar que, em média, as mulheres que participaram do experimento tiveram uma associação implícita (medida pelo IAT) contra a matemárica positiva e moderada (média 0.47, desv. padrão 0.51, N = 77). Homens tiveram uma associação positiva e fraca contra a matemática, portanto menor que a das mulheres (média 0.07, desv. padrão 0.57, N = 24).
p1 = iat %>%
ggplot(aes(x = sex, y = d_art)) +
geom_quasirandom(width = .1) +
stat_summary(geom = "point", fun.y = "mean", color = "red", size = 5)
p2 = ci %>%
ggplot(aes(
x = "",
y = statistic,
ymin = conf.low,
ymax = conf.high
)) +
geom_pointrange() +
geom_point(size = 3) +
geom_text(aes(y = conf.low, label = round(conf.low, 2)), vjust = 1.5, color = "gray30", size = 4) + # Valor do limite inferior
geom_text(aes(y = conf.high, label = round(conf.high, 2)), vjust = -0.5, color = "gray30", size = 4) + # Valor do limite superior
ylim(-1, 1) +
labs(x = "Diferença",
y = "IAT mulheres - homens")
grid.arrange(p1, p2, ncol = 2)
Houve portanto uma considerável diferença entre homens e mulheres (diferença das médias 0.41, 95% CI [0.16, 0.66]).
A partir desta amostra, estimamos que:
* mulheres têm uma associação positiva consideravelmente mais forte, com uma média que provavelmente está entre 0.35 e 0.58 ponto na escala IAT, o suficiente para diferenciar uma associação neutra de uma considerável contra a matemática.
* homens têm uma associação positiva menos forte, porém não é claro se essa diferença é grande, moderada ou pequena. É necessário coletar mais dados para determinar se a diferença é relevante ou negligenciável.
Utilizando bootstrap nas visualizações, podemos observar o seguinte:
bootstrap_ci_plot(iat, d_art_col = "d_art", sex_col = "sex")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## TableGrob (2 x 1) "arrange": 2 grobs
## z cells name grob
## m 1 (1-1,1-1) arrange gtable[layout]
## f 2 (2-2,1-1) arrange gtable[layout]
O método escolhido evidencia uma estrutura robusta e flexível para realizar bootstrap em uma ampla variedade de estatísticas e conjuntos de dados. Em comparação com pacotes alternativos, a função boot se destaca pela sua abrangência, integração com outras funções do R e comunidade de usuários ativa.