Chapter 2 Preparar o banco
Preparação do ambiente e manipulação dos bancos.
2.1 Preparar o ambiente
Importar pacotes.
library (flexdashboard)
library (dplyr)
library (mirt)
library (ggplot2)
library (plotly)
library (mirtCAT)
library (DT)
library (xlsx)
library (readxl)
library (lordif)
library (reactable)
library (ModelMetrics)
2.2 Manipular o banco
Importamos os bancos da Unesp já manipulados. Só temos o ID da pessoa, o ano e as respostas.
load('bancos_unesp_mascara.RData')
<- rbind (
banco_unesp
banco_2019,
banco_2020,
banco_2021
)
names (banco_unesp) <- c ('ID', 'ano_aluno', 'anoTP', paste0('i', 1:120))
$grupo <- 'unesp'
banco_unesp
<- select (banco_unesp, ID, anoTP, ano_aluno, grupo, everything()) banco_unesp
Importar o banco da Unicamp.
# importar banco unicamp
<- read_xlsx('../../banco/Dario 3.xlsx')
banco_unicamp <- data.frame (banco_unicamp)
banco_unicamp
# selecionar de 2019 a 2021
<- subset (banco_unicamp, anoTP %in% c(2019:2021))
banco_unicamp
# novo ID (começando com 7777 é Unicamp)
$ID <- paste0('7777', banco_unicamp$ID)
banco_unicamp
# grupo
$grupo <- 'unicamp'
banco_unicamp
# selecionar variáveis de interesse
<- select (banco_unicamp, ID, anoTP, anoCurso, grupo, starts_with('q'))
banco_unicamp
# renomear variáveis
names (banco_unicamp) <- c ('ID', 'anoTP', 'ano_aluno', 'grupo', paste0('i', 1:120))
Juntar todos os bancos e selecionar quem fez pelo menos um ponto na prova. Aqui também vamos excluir as linhas “sujas”do banco original do xls
<- rbind(
banco
banco_unesp,
banco_unicamp
)
names (banco)[5:124] <- paste0('Q', 1:120)
$total <- rowSums(select (banco, starts_with('Q')))
banco
<- subset (banco, total > 0)
banco
# transformar o ano em variável numérica
$ano_aluno <- as.numeric(banco$ano_aluno)
banco$anoTP <- as.numeric(banco$anoTP) banco
É importante lembrar que o mesmo sujeito aparece em mais de um banco, porque ele fez a prova mais de um ano. Cada sujeito possui uma identificação única.
Para montar o banco para a calibração, precisamos juntar os bancos e deixar o banco “wide”. Ou seja, cada linha é um sujeito e cada coluna é um item. Se o sujeito não respondeu aquele item (por exemplo, não fez a prova de 2019), o valor é NA.
É importante ressaltar que só mantivemos o ID dos sujeitos utilizados na ligação entre as provas. Ou seja, os sujeitos do: 1. 5o ano 2019/6o ano 2020 2. 5o ano 2020/6o ano 2021
Para as demais observações, criamos outro ID. Mesmo para os sujeitos que estavam no 5o ano de alguma aplicação listada acima. Por exemplo, o 4o ano 2014, que são as mesmas pessoas do 5o ano 2015.
Primeiro, criar novo ID mantendo o antigo para os sujeitos dos grupos de ligação. As pessoas que erraram tudo serão excluídas do banco
# o ID2 começa em 8888 para todos
$ID2 <- paste0('8888', 1:nrow(banco))
banco
# os pares:
# 2019 com 2020
$ID2 <- ifelse (banco$anoTP == 2019 & banco$ano_aluno == 5, banco$ID, banco$ID2)
banco$ID2 <- ifelse (banco$anoTP == 2020 & banco$ano_aluno == 6, banco$ID, banco$ID2)
banco
# 2020 com 2021
$ID2 <- ifelse (banco$anoTP == 2020 & banco$ano_aluno == 5, banco$ID, banco$ID2)
banco$ID2 <- ifelse (banco$anoTP == 2021 & banco$ano_aluno == 6, banco$ID, banco$ID2)
banco
$ID3 <- paste0(banco$ID, banco$anoTP)
banco
# retirar a pessoa duplicada
<- subset (banco, banco$ID3 != banco$ID3[duplicated(banco$ID3)])
banco
# reordenar as variáveis
<- select (banco, "ID", "ID2", "ID3", "anoTP", "ano_aluno", "grupo", "total", everything())
banco
# objeto com os grupos
<- data.frame(
grupos ID2 = banco$ID2,
grupo = banco$grupo
)
<- grupos[!duplicated(grupos$ID2),] grupos
Agora deixar o banco wide de fato.
<- data.frame()
banco_total for (ano in unique (banco$anoTP))
{# ano = 2020
# selecionar os sujeitos do ano da prova
<- subset(banco, anoTP == ano)
banco_total. names(banco_total.)[8:127] <- c(
paste0(
'Q',
ano,'_',
sprintf('%03d',1:120)
)
)
# selecionar as variáveis necessárias nesse momento (ID2 e os itens)
<- select (banco_total., 'ID2', starts_with('Q'))
banco_total.
# fazer o join
# se já tiver alguém no banco_total, fazer o join. Se não tiver, pega o banco_total.
if(nrow(banco_total)>0)
{<- full_join(banco_total, banco_total., by = 'ID2')
banco_total else {
} <- banco_total.
banco_total
}
}
<- left_join(banco_total, grupos, by = 'ID2') %>%
banco_total select(ID2, grupo, everything())
2.3 Banco para equalização
Agora vamos preparar os bancos para avaliar a equalização dos testes. Primeiro, filtrar o banco pelo ano da prova e a turma do sujeito. Pegar somente quem acertou pelo menos uma
# 2019 com 2020
.5 <- subset (banco, anoTP == 2019 & ano_aluno == 5)
banco19
.6 <- subset (banco, anoTP == 2020 & ano_aluno == 6) %>%
banco20select(ID, starts_with('Q'))
names(banco19.5)[8:127] <- c(
paste0(
'Q',
2019,
'_',
sprintf('%03d',1:120)
)
)
names(banco20.6)[2:121] <- c(
paste0(
'Q',
2020,
'_',
sprintf('%03d',1:120)
)
)
# 2020 com 2021
.5 <- subset (banco, anoTP == 2020 & ano_aluno == 5)
banco20
.6 <- subset (banco, anoTP == 2021 & ano_aluno == 6) %>%
banco21select(ID, starts_with('Q'))
names(banco20.5)[8:127] <- c(
paste0(
'Q',
2020,
'_',
sprintf('%03d',1:120)
)
)
names(banco21.6)[2:121] <- c(
paste0(
'Q',
2021,
'_',
sprintf('%03d',1:120)
) )
Agora montar os bancos dois a dois.
<- inner_join(banco19.5, banco20.6, by = 'ID')
banco19_20 <- inner_join(banco20.5, banco21.6, by = 'ID') banco20_21
Para cada equalização, temos as seguintes observações:
nrow(banco19_20)
## [1] 185
nrow(banco20_21)
## [1] 171
Cada banco possui os seguintes quantitativos de itens:
ncol(banco19_20)-7
## [1] 240
ncol(banco20_21)-7
## [1] 240
2.4 Checagens
Verificar se algum item teve 100% de acerto ou 0% de acerto. Vou criar uma função para excluir esses itens e deixar um aviso.
<- function(x)
acerto_erro
{# verificar a média do item (se der 0, é 100% de erro; se der 1, é 100% de acerto)
<- apply(x[,-c(1:7)], 2, mean, na.rm = TRUE)
media <- select(x, -names(media)[which(media == 1)])
x <- select(x, -names(media)[which(media == 0)])
x
# texto caso tenha havido algum item com 100% de acerto
if (sum(media == 1)>0)
{print(
paste0(
'Os itens ',
paste0(names(media)[which(media == 1)], collapse = ' '),
' tiveram 100% de acerto.'
)
)else {
} print('Nenhum item teve 100% de acerto')
}
# texto caso tenha havido algum item com 100% de erro
if (sum(media == 0)>0)
{print(
paste0(
'Os itens ',
paste0(names(media)[which(media == 0)], collapse = ' '),
' tiveram 100% de erro'
)
)else {
} print('Nenhum item teve 100% de erro')
}
return(x)
}
<- acerto_erro(banco19_20) banco19_20
## [1] "Nenhum item teve 100% de acerto"
## [1] "Os itens Q2020_091 Q2020_105 tiveram 100% de erro"
<- acerto_erro(banco20_21) banco20_21
## [1] "Nenhum item teve 100% de acerto"
## [1] "Os itens Q2020_091 Q2020_105 tiveram 100% de erro"
Agora para o banco_total
.
<- apply(banco_total[,-c(1:2)], 2, mean, na.rm = TRUE)
media
<- select(banco_total, -names(media)[which(media == 1)]) banco_total
Nenhum item teve 100% de acerto
<- apply(banco_total[,-c(1:2)], 2, mean, na.rm = TRUE)
media
<- select(banco_total, -names(media)[which(media == 0)]) banco_total
Nenhum item teve 100% de erro
Agora temos 359 itens. Para fins de checagem, vamos verificar se todos os itens do mesmo período/ano possuem a mesma quantidade de respostas.
for (ano in 2019:2021)
{# selecionar os itens do ano
<- select (banco_total, starts_with(paste0('Q', ano)))
banco.ano
<- apply (
freq # verificar onde não tem NA
data.frame (!is.na (banco.ano)),
2,
sum
)print(paste0(
'Ano: ',
paste0(ano),
': ',
ifelse(min(freq)==max(freq), 'OK', 'Problema')
)
)
print(
paste0(
'min = ',
min(freq),
'; max = ',
max(freq)
)
) }
## [1] "Ano: 2019: OK"
## [1] "min = 1198; max = 1198"
## [1] "Ano: 2020: OK"
## [1] "min = 1157; max = 1157"
## [1] "Ano: 2021: OK"
## [1] "min = 1179; max = 1179"